From 5c61de3ae96ca1e4c97f752962a6e2fbdbb4e3ce Mon Sep 17 00:00:00 2001 From: d11n Date: Tue, 21 Feb 2023 03:06:27 +0100 Subject: [PATCH] Different icons for notifications (#4632) * Different icons for notifications Closes #2510. * Fix version appendix for SVG use attributes * Fix SVGUse TagHelper * Update icons --- .../Contracts/INotificationHandler.cs | 2 + .../TagHelpers/SVGUse.cs | 11 +- .../Models/NotificationData.cs | 2 + BTCPayServer.Data/Data/NotificationData.cs | 1 - .../Components/Notifications/List.cshtml | 21 +++- .../GreenfieldNotificationsController.cs | 4 +- .../UIManageController.Notifications.cs | 10 +- .../ExternalPayoutTransactionNotification.cs | 3 +- .../Blobs/InvoiceEventNotification.cs | 6 +- .../Notifications/Blobs/JunkNotification.cs | 3 +- .../Blobs/NewVersionNotification.cs | 2 + .../Notifications/Blobs/PayoutNotification.cs | 13 +- .../Notifications/NotificationManager.cs | 11 +- .../UIManage/NotificationSettings.cshtml | 2 - .../Views/UIStorePullPayments/Payouts.cshtml | 2 +- BTCPayServer/wwwroot/img/icon-sprite.svg | 113 +++++++++--------- BTCPayServer/wwwroot/main/layout.css | 5 + .../wwwroot/main/themes/default-dark.css | 3 +- BTCPayServer/wwwroot/main/themes/default.css | 41 +------ .../v1/swagger.template.notifications.json | 8 ++ 20 files changed, 141 insertions(+), 122 deletions(-) diff --git a/BTCPayServer.Abstractions/Contracts/INotificationHandler.cs b/BTCPayServer.Abstractions/Contracts/INotificationHandler.cs index 0caaed572..49b92220b 100644 --- a/BTCPayServer.Abstractions/Contracts/INotificationHandler.cs +++ b/BTCPayServer.Abstractions/Contracts/INotificationHandler.cs @@ -19,6 +19,8 @@ namespace BTCPayServer.Abstractions.Contracts public class NotificationViewModel { public string Id { get; set; } + public string Identifier { get; set; } + public string Type { get; set; } public DateTimeOffset Created { get; set; } public string Body { get; set; } public string ActionLink { get; set; } diff --git a/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs b/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs index fecef0941..72c69dcc4 100644 --- a/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs +++ b/BTCPayServer.Abstractions/TagHelpers/SVGUse.cs @@ -23,10 +23,19 @@ public class SVGUse : UrlResolutionTagHelper2 { _fileVersionProvider = fileVersionProvider; } + public override void Process(TagHelperContext context, TagHelperOutput output) { var attr = output.Attributes["href"].Value.ToString(); - attr = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, attr); + var symbolIndex = attr!.IndexOf("#", StringComparison.InvariantCulture); + var start = attr.IndexOf("~", StringComparison.InvariantCulture) + 1; + var length = (symbolIndex != -1 ? symbolIndex : attr.Length) - start; + var filePath = attr.Substring(start, length); + if (!string.IsNullOrEmpty(filePath)) + { + var versioned = _fileVersionProvider.AddFileVersionToPath(ViewContext.HttpContext.Request.PathBase, filePath); + attr = attr.Replace(filePath, versioned); + } output.Attributes.SetAttribute("href", attr); base.Process(context, output); } diff --git a/BTCPayServer.Client/Models/NotificationData.cs b/BTCPayServer.Client/Models/NotificationData.cs index b74550f63..ef1014738 100644 --- a/BTCPayServer.Client/Models/NotificationData.cs +++ b/BTCPayServer.Client/Models/NotificationData.cs @@ -6,6 +6,8 @@ namespace BTCPayServer.Client.Models public class NotificationData { public string Id { get; set; } + public string Identifier { get; set; } + public string Type { get; set; } public string Body { get; set; } public bool Seen { get; set; } public Uri Link { get; set; } diff --git a/BTCPayServer.Data/Data/NotificationData.cs b/BTCPayServer.Data/Data/NotificationData.cs index c18020012..aa9d496b4 100644 --- a/BTCPayServer.Data/Data/NotificationData.cs +++ b/BTCPayServer.Data/Data/NotificationData.cs @@ -19,7 +19,6 @@ namespace BTCPayServer.Data public bool Seen { get; set; } public byte[] Blob { get; set; } - internal static void OnModelCreating(ModelBuilder builder) { builder.Entity() diff --git a/BTCPayServer/Components/Notifications/List.cshtml b/BTCPayServer/Components/Notifications/List.cshtml index b8dd9c3b9..2e1bcca55 100644 --- a/BTCPayServer/Components/Notifications/List.cshtml +++ b/BTCPayServer/Components/Notifications/List.cshtml @@ -1,12 +1,29 @@ @using BTCPayServer.Abstractions.Extensions @model BTCPayServer.Components.Notifications.NotificationsViewModel - +@functions { + private static string NotificationIcon(string type) + { + return type switch + { + "invoice_expired" => "notifications-invoice-failure", + "invoice_expiredpaidpartial" => "notifications-invoice-failure", + "invoice_failedtoconfirm" => "notifications-invoice-failure", + "invoice_confirmed" => "notifications-invoice-settled", + "invoice_paidafterexpiration" => "notifications-settled", + "external-payout-transaction" => "notifications-payout", + "payout_awaitingapproval" => "notifications-payout", + "payout_awaitingpayment" => "notifications-payout-approved", + "newversion" => "notifications-new-version", + _ => "note" + }; + } +}
@foreach (var n in Model.Last5) {
- +
diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs index d12fba6f9..bf85fa7f0 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldNotificationsController.cs @@ -98,9 +98,11 @@ namespace BTCPayServer.Controllers.Greenfield private NotificationData ToModel(NotificationViewModel entity) { - return new NotificationData() + return new NotificationData { Id = entity.Id, + Identifier = entity.Identifier, + Type = entity.Type, CreatedTime = entity.Created, Body = entity.Body, Seen = entity.Seen, diff --git a/BTCPayServer/Controllers/UIManageController.Notifications.cs b/BTCPayServer/Controllers/UIManageController.Notifications.cs index 829c17497..da39c3d52 100644 --- a/BTCPayServer/Controllers/UIManageController.Notifications.cs +++ b/BTCPayServer/Controllers/UIManageController.Notifications.cs @@ -19,17 +19,17 @@ namespace BTCPayServer.Controllers var user = await _userManager.GetUserAsync(User); if (user.DisabledNotifications == "all") { - return View(new NotificationSettingsViewModel() { All = true }); + return View(new NotificationSettingsViewModel { All = true }); } var disabledNotifications = - user.DisabledNotifications?.Split(';', StringSplitOptions.RemoveEmptyEntries)?.ToList() ?? + user.DisabledNotifications?.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(); var notifications = notificationHandlers.SelectMany(handler => handler.Meta.Select(tuple => new SelectListItem(tuple.name, tuple.identifier, disabledNotifications.Contains(tuple.identifier, StringComparer.InvariantCultureIgnoreCase)))) .ToList(); - return View(new NotificationSettingsViewModel() { DisabledNotifications = notifications }); + return View(new NotificationSettingsViewModel { DisabledNotifications = notifications }); } [HttpPost("/notifications/settings")] @@ -48,13 +48,13 @@ namespace BTCPayServer.Controllers { var disabled = vm.DisabledNotifications.Where(item => item.Selected).Select(item => item.Value) .ToArray(); - user.DisabledNotifications = disabled.Any() is true + user.DisabledNotifications = disabled.Any() ? string.Join(';', disabled) + ";" : string.Empty; } await _userManager.UpdateAsync(user); - TempData.SetStatusMessageModel(new StatusMessageModel() + TempData.SetStatusMessageModel(new StatusMessageModel { Message = "Updated successfully.", Severity = StatusMessageModel.StatusSeverity.Success diff --git a/BTCPayServer/Services/Notifications/Blobs/ExternalPayoutTransactionNotification.cs b/BTCPayServer/Services/Notifications/Blobs/ExternalPayoutTransactionNotification.cs index c2d9753b3..b1d58a252 100644 --- a/BTCPayServer/Services/Notifications/Blobs/ExternalPayoutTransactionNotification.cs +++ b/BTCPayServer/Services/Notifications/Blobs/ExternalPayoutTransactionNotification.cs @@ -2,7 +2,6 @@ using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Client.Models; using BTCPayServer.Configuration; using BTCPayServer.Controllers; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; namespace BTCPayServer.Services.Notifications.Blobs @@ -35,6 +34,8 @@ namespace BTCPayServer.Services.Notifications.Blobs protected override void FillViewModel(ExternalPayoutTransactionNotification notification, NotificationViewModel vm) { + vm.Identifier = notification.Identifier; + vm.Type = notification.NotificationType; vm.Body = "A payment that was made to an approved payout by an external wallet is waiting for your confirmation."; vm.ActionLink = _linkGenerator.GetPathByAction(nameof(UIStorePullPaymentsController.Payouts), diff --git a/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs b/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs index 7373002cb..2fe197a16 100644 --- a/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs +++ b/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs @@ -4,7 +4,7 @@ using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Configuration; using BTCPayServer.Controllers; using BTCPayServer.Events; -using BTCPayServer.Models.NotificationViewModels; +using ExchangeSharp; using Microsoft.AspNetCore.Routing; namespace BTCPayServer.Services.Notifications.Blobs @@ -52,6 +52,8 @@ namespace BTCPayServer.Services.Notifications.Blobs { vm.Body = $"{baseStr} {TextMapping[notification.Event]}"; } + vm.Identifier = notification.Identifier; + vm.Type = notification.NotificationType; vm.ActionLink = _linkGenerator.GetPathByAction(nameof(UIInvoiceController.Invoice), "UIInvoice", new { invoiceId = notification.InvoiceId }, _options.RootPath); @@ -75,7 +77,7 @@ namespace BTCPayServer.Services.Notifications.Blobs public string InvoiceId { get; set; } public string Event { get; set; } - public override string Identifier => $"{TYPE}_{Event}"; + public override string Identifier => Event is null ? TYPE : Event.ToStringLowerInvariant(); public override string NotificationType => TYPE; } } diff --git a/BTCPayServer/Services/Notifications/Blobs/JunkNotification.cs b/BTCPayServer/Services/Notifications/Blobs/JunkNotification.cs index 3dc894f23..3e1fbaa05 100644 --- a/BTCPayServer/Services/Notifications/Blobs/JunkNotification.cs +++ b/BTCPayServer/Services/Notifications/Blobs/JunkNotification.cs @@ -1,5 +1,4 @@ #if DEBUG -using System.Data; using BTCPayServer.Abstractions.Contracts; namespace BTCPayServer.Services.Notifications.Blobs @@ -20,7 +19,7 @@ namespace BTCPayServer.Services.Notifications.Blobs protected override void FillViewModel(JunkNotification notification, NotificationViewModel vm) { - vm.Body = $"All your junk r belong to us!"; + vm.Body = "All your junk r belong to us!"; } } diff --git a/BTCPayServer/Services/Notifications/Blobs/NewVersionNotification.cs b/BTCPayServer/Services/Notifications/Blobs/NewVersionNotification.cs index c6e15539d..d1522940d 100644 --- a/BTCPayServer/Services/Notifications/Blobs/NewVersionNotification.cs +++ b/BTCPayServer/Services/Notifications/Blobs/NewVersionNotification.cs @@ -19,6 +19,8 @@ namespace BTCPayServer.Services.Notifications.Blobs protected override void FillViewModel(NewVersionNotification notification, NotificationViewModel vm) { + vm.Identifier = notification.Identifier; + vm.Type = notification.NotificationType; vm.Body = $"New version {notification.Version} released!"; vm.ActionLink = $"https://github.com/btcpayserver/btcpayserver/releases/tag/v{notification.Version}"; } diff --git a/BTCPayServer/Services/Notifications/Blobs/PayoutNotification.cs b/BTCPayServer/Services/Notifications/Blobs/PayoutNotification.cs index 4b12fd11a..385f77064 100644 --- a/BTCPayServer/Services/Notifications/Blobs/PayoutNotification.cs +++ b/BTCPayServer/Services/Notifications/Blobs/PayoutNotification.cs @@ -3,8 +3,7 @@ using BTCPayServer.Abstractions.Contracts; using BTCPayServer.Client.Models; using BTCPayServer.Configuration; using BTCPayServer.Controllers; -using BTCPayServer.Data; -using BTCPayServer.Models.NotificationViewModels; +using ExchangeSharp; using Microsoft.AspNetCore.Routing; namespace BTCPayServer.Services.Notifications.Blobs @@ -35,10 +34,12 @@ namespace BTCPayServer.Services.Notifications.Blobs protected override void FillViewModel(PayoutNotification notification, NotificationViewModel vm) { + vm.Identifier = notification.Identifier; + vm.Type = notification.NotificationType; vm.Body = (notification.Status ?? PayoutState.AwaitingApproval) switch { - PayoutState.AwaitingApproval => $"A new payout is awaiting for approval", - PayoutState.AwaitingPayment => $"A new payout is approved and awaiting payment", + PayoutState.AwaitingApproval => "A new payout is awaiting for approval", + PayoutState.AwaitingPayment => "A new payout is approved and awaiting payment", _ => throw new ArgumentOutOfRangeException() }; vm.ActionLink = _linkGenerator.GetPathByAction(nameof(UIStorePullPaymentsController.Payouts), @@ -51,8 +52,8 @@ namespace BTCPayServer.Services.Notifications.Blobs public string StoreId { get; set; } public string PaymentMethod { get; set; } public string Currency { get; set; } - public PayoutState? State { get; set; } - public override string Identifier => TYPE; + public override string Identifier => Status is null ? TYPE : $"{TYPE}_{Status.ToStringLowerInvariant()}"; + public override string NotificationType => TYPE; public PayoutState? Status { get; set; } } diff --git a/BTCPayServer/Services/Notifications/NotificationManager.cs b/BTCPayServer/Services/Notifications/NotificationManager.cs index 0c4a0ba73..7f19c159b 100644 --- a/BTCPayServer/Services/Notifications/NotificationManager.cs +++ b/BTCPayServer/Services/Notifications/NotificationManager.cs @@ -40,7 +40,7 @@ namespace BTCPayServer.Services.Notifications return await _memoryCache.GetOrCreateAsync(cacheKey, async entry => { - var resp = await GetNotifications(new NotificationsQuery() + var resp = await GetNotifications(new NotificationsQuery { Seen = false, Skip = 0, @@ -119,7 +119,6 @@ namespace BTCPayServer.Services.Notifications return (queryable, queryable2); } - public async Task> ToggleSeen(NotificationsQuery notificationsQuery, bool? setSeen) { await using var dbContext = _factory.CreateContext(); @@ -156,7 +155,13 @@ namespace BTCPayServer.Services.Notifications if (handler is null) return null; var notification = JsonConvert.DeserializeObject(ZipUtils.Unzip(data.Blob), handler.NotificationBlobType); - var obj = new NotificationViewModel { Id = data.Id, Created = data.Created, Seen = data.Seen }; + var obj = new NotificationViewModel + { + Id = data.Id, + Type = data.NotificationType, + Created = data.Created, + Seen = data.Seen + }; handler.FillViewModel(notification, obj); return obj; } diff --git a/BTCPayServer/Views/UIManage/NotificationSettings.cshtml b/BTCPayServer/Views/UIManage/NotificationSettings.cshtml index 2af2a3d2e..3f643573b 100644 --- a/BTCPayServer/Views/UIManage/NotificationSettings.cshtml +++ b/BTCPayServer/Views/UIManage/NotificationSettings.cshtml @@ -1,6 +1,4 @@ -@using BTCPayServer.Abstractions.Contracts @model BTCPayServer.Controllers.UIManageController.NotificationSettingsViewModel -@inject IEnumerable NotificationHandlers @{ ViewData.SetActivePage(ManageNavPages.Notifications, "Notification Settings"); } diff --git a/BTCPayServer/Views/UIStorePullPayments/Payouts.cshtml b/BTCPayServer/Views/UIStorePullPayments/Payouts.cshtml index 23c2fec8d..a25c31153 100644 --- a/BTCPayServer/Views/UIStorePullPayments/Payouts.cshtml +++ b/BTCPayServer/Views/UIStorePullPayments/Payouts.cshtml @@ -100,7 +100,7 @@
-