Skip to content

Commit

Permalink
App item editor file upload
Browse files Browse the repository at this point in the history
  • Loading branch information
dennisreimann committed Sep 17, 2024
1 parent d717333 commit 715037a
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 12 deletions.
94 changes: 84 additions & 10 deletions BTCPayApp.UI/Components/AppItemsEditor.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
@using BTCPayApp.Core.Auth
@using BTCPayApp.Core.Contracts
@using BTCPayApp.UI.Models
@using BTCPayApp.UI.Util
@using Plk.Blazor.DragDrop
@inject IJSRuntime JS
@inject IAccountManager AccountManager
@inject IDataDirectoryProvider DataDirectoryProvider

<div @attributes="InputAttributes" class="@CssClass">
<div class="row align-items-start">
Expand Down Expand Up @@ -60,7 +65,7 @@
<div class="bg-tile w-100 p-xl-4 rounded">
@if (SelectedItem != null)
{
<ValidationEditContext @ref="_validationEditContext" Model="SelectedItem" id="item-form" class="item">
<ValidationEditContext @ref="_validationEditContext" Model="SelectedItem" id="item-form" class="item" ErrorMessage="@_errorMessage">
<DataAnnotationsValidator />
<div class="form-group">
<label for="Title" class="form-label" data-required>Title</label>
Expand Down Expand Up @@ -95,11 +100,28 @@
}
<ValidationMessage For="@(() => SelectedItem.Price)" />
</div>

<div class="form-group">
<label for="ImageUrl" class="form-label">Image Url</label>
<InputText @bind-Value="SelectedItem.ImageUrl" id="ImageUrl" class="form-control" type="url"/>
<ValidationMessage For="@(() => SelectedItem.ImageUrl)" />
<div class="form-group d-flex align-items-center justify-content-between gap-2">
<div class="flex-grow-1">
<div class="d-flex align-items-center justify-content-between gap-2">
<label for="ImageUrl" class="form-label">Image Url</label>
@if (!string.IsNullOrEmpty(SelectedItem.ImageUrl))
{
<button type="button" class="btn btn-link p-0 text-danger" @onclick="UnsetImage">
<Icon Symbol="cross"/> Remove
</button>
}
</div>
<InputText @bind-Value="SelectedItem.ImageUrl" id="ImageUrl" class="form-control mb-2" type="url"/>
<ValidationMessage For="@(() => SelectedItem.ImageUrl)"/>
<div class="d-flex align-items-center gap-2">
<InputFile OnChange="LoadImage" @key="@_inputFileId" id="Image" class="form-control"/>
<button class="btn btn-primary" type="button" @onclick="UploadImage" disabled="@(string.IsNullOrEmpty(SelectedItem.ImagePath))">Upload</button>
</div>
</div>
@if (!string.IsNullOrEmpty(SelectedItem.ImageUrl))
{
<img src="@SelectedItem.ImageUrl" alt="@SelectedItem.Title" class="item-image"/>
}
</div>
<div class="form-group">
<label for="Description" class="form-label">Description</label>
Expand Down Expand Up @@ -136,6 +158,8 @@
</div>

@code {
[Parameter, EditorRequired]
public string AppId { get; set; } = null!;
[Parameter, EditorRequired]
public string Currency { get; set; } = null!;

Expand All @@ -148,18 +172,19 @@
}
}

private List<AppItemModel>? _items;

[Parameter(CaptureUnmatchedValues = true)]
public Dictionary<string, object>? InputAttributes { get; set; }

private List<AppItemModel>? _items;
private Guid _inputFileId = Guid.NewGuid();
private ValidationEditContext? _validationEditContext;
private string? _successMessage;

private AppItemModel? SelectedItem { get; set; }
private string? _successMessage;
private string? _errorMessage;

private async Task SelectItem(AppItemModel? item)
{
_errorMessage = null;
SelectedItem = item;
await (SelectedItem != null ? ShowOffcanvas() : HideOffcanvas());
}
Expand Down Expand Up @@ -193,5 +218,54 @@
if (string.IsNullOrEmpty(SelectedItem?.Id) && !string.IsNullOrEmpty(SelectedItem?.Title)) SelectedItem.Id = SelectedItem.Title;
}

private async Task LoadImage(InputFileChangeEventArgs e)
{
try
{
var appData = await DataDirectoryProvider.GetAppDataDirectory();
var fileName = e.File.Name;
var dirPath = Path.Combine(appData, "tmp");
var filePath = Path.Combine(dirPath, fileName);
Directory.CreateDirectory(dirPath);

await using FileStream fs = new(filePath, FileMode.Create);
await e.File.OpenReadStream().CopyToAsync(fs);
await fs.FlushAsync();
SelectedItem!.ImagePath = filePath;
_errorMessage = null;
}
catch (Exception ex)
{
_errorMessage = $"Image could not be applied: {ex.Message}";
}
}

private async Task UploadImage()
{
if (string.IsNullOrEmpty(SelectedItem!.ImagePath)) return;
try
{
var path = SelectedItem.ImagePath;
var mimeType = FileHelper.GetContentType(path);
var upload = await AccountManager.GetClient().UploadAppItemImage(AppId, path, mimeType);
SelectedItem.ImageUrl = upload.Url;
// cleanup
File.Delete(path);
SelectedItem.ImagePath = null;
_inputFileId = Guid.NewGuid();
}
catch (Exception ex)
{
_errorMessage = $"Image could not be uploaded: {ex.Message}";
}
}

private async Task UnsetImage()
{
SelectedItem!.ImageUrl = null;
SelectedItem.ImagePath = null;
_inputFileId = Guid.NewGuid();
}

private string CssClass => $"editor {(InputAttributes?.ContainsKey("class") is true ? InputAttributes["class"] : "")}".Trim();
}
6 changes: 6 additions & 0 deletions BTCPayApp.UI/Components/AppItemsEditor.razor.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
border-radius: var(--btcpay-border-radius);
}

.editor .item-image {
height: 2.1rem;
width: 2.1rem;
object-fit: cover;
}

.editor fieldset .list-group-item {
padding: var(--btcpay-space-m) 0 var(--btcpay-space-m);
}
Expand Down
3 changes: 3 additions & 0 deletions BTCPayApp.UI/Models/AppItemModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ public class AppItemModel
public string? Categories { get; set; }
public int? Inventory { get; set; }
public string? Description { get; set; }
[Url]
[JsonPropertyName("image")]
public string? ImageUrl { get; set; }
[JsonIgnore]
public string? ImagePath { get; set; }
public string? BuyButtonText { get; set; }
public bool Disabled { get; set; }
[JsonIgnore]
Expand Down
2 changes: 1 addition & 1 deletion BTCPayApp.UI/Pages/Settings/PosPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
{
<h2>Products</h2>
<fieldset class="box">
<AppItemsEditor @bind-Items="@Model.Items" Currency="@Model.Currency"/>
<AppItemsEditor @bind-Items="@Model.Items" AppId="@AppId" Currency="@Model.Currency"/>
</fieldset>
}

Expand Down
2 changes: 1 addition & 1 deletion submodules/btcpayserver
Submodule btcpayserver updated 27 files
+10 −0 BTCPayServer.Client/BTCPayServerClient.Apps.cs
+0 −1 BTCPayServer.Data/ApplicationDbContext.cs
+1 −0 BTCPayServer.Data/BTCPayServer.Data.csproj
+9 −0 BTCPayServer.Data/DBScripts/003.RefactorPendingInvoicesPayments.sql
+4 −3 BTCPayServer.Data/Data/InvoiceData.cs
+2 −1 BTCPayServer.Data/Data/PaymentData.cs
+15 −0 BTCPayServer.Data/Migrations/20240913034505_refactorpendinginvoicespayments.cs
+63 −5 BTCPayServer/Controllers/GreenField/GreenfieldAppsController.cs
+11 −0 BTCPayServer/Controllers/GreenField/LocalBTCPayServerClient.cs
+0 −9 BTCPayServer/Controllers/UIInvoiceController.UI.cs
+0 −15 BTCPayServer/Events/InvoiceStopWatchedEvent.cs
+2 −2 BTCPayServer/Extensions.cs
+0 −1 BTCPayServer/HostedServices/InvoiceEventSaverService.cs
+6 −66 BTCPayServer/HostedServices/InvoiceWatcher.cs
+7 −0 BTCPayServer/Payments/Bitcoin/BitcoinPaymentModelExtension.cs
+14 −25 BTCPayServer/Payments/Bitcoin/NBXplorerListener.cs
+18 −1 BTCPayServer/Services/Altcoins/Monero/Payments/MoneroPaymentModelExtension.cs
+16 −23 BTCPayServer/Services/Altcoins/Monero/Services/MoneroListener.cs
+17 −1 BTCPayServer/Services/Altcoins/Zcash/Payments/ZcashPaymentModelExtension.cs
+11 −16 BTCPayServer/Services/Altcoins/Zcash/Services/ZcashListener.cs
+20 −60 BTCPayServer/Services/Invoices/InvoiceRepository.cs
+6 −0 BTCPayServer/Services/Invoices/PaymentBlob.cs
+4 −9 BTCPayServer/Views/Shared/Bitcoin/ViewBitcoinLikePaymentData.cshtml
+6 −9 BTCPayServer/Views/Shared/Monero/ViewMoneroLikePaymentData.cshtml
+6 −9 BTCPayServer/Views/Shared/Zcash/ViewZcashLikePaymentData.cshtml
+1 −0 BTCPayServer/wwwroot/img/readme/supporter_unbank.svg
+1 −0 README.md

0 comments on commit 715037a

Please sign in to comment.