Use attribute to map notifcations to their string

This commit is contained in:
nicolas.dorier
2020-06-15 17:05:12 +09:00
parent 9070b475ea
commit 7cdfa7d4c5
8 changed files with 49 additions and 15 deletions

View File

@@ -47,7 +47,7 @@ namespace BTCPayServer.Controllers
.OrderByDescending(a => a.Created) .OrderByDescending(a => a.Created)
.Skip(skip).Take(count) .Skip(skip).Take(count)
.Where(a => a.ApplicationUserId == userId) .Where(a => a.ApplicationUserId == userId)
.Select(a => a.ViewModel()) .Select(a => a.ToViewModel())
.ToList(), .ToList(),
Total = _db.Notifications.Where(a => a.ApplicationUserId == userId).Count() Total = _db.Notifications.Where(a => a.ApplicationUserId == userId).Count()
}; };

View File

@@ -30,22 +30,26 @@ namespace BTCPayServer.Models.NotificationViewModels
public static class NotificationViewModelExt public static class NotificationViewModelExt
{ {
public static NotificationViewModel ViewModel(this NotificationData data) static Dictionary<string, Type> _NotificationTypes;
static NotificationViewModelExt()
{ {
var baseType = typeof(BaseNotification); _NotificationTypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Select(t => (t, NotificationType: t.GetCustomAttribute<NotificationAttribute>()?.NotificationType))
.Where(t => t.NotificationType is string)
.ToDictionary(o => o.NotificationType, o => o.t);
}
var fullTypeName = baseType.FullName.Replace(nameof(BaseNotification), data.NotificationType, StringComparison.OrdinalIgnoreCase); public static NotificationViewModel ToViewModel(this NotificationData data)
var parsedType = baseType.Assembly.GetType(fullTypeName); {
var casted = (BaseNotification)JsonConvert.DeserializeObject(ZipUtils.Unzip(data.Blob), _NotificationTypes[data.NotificationType]);
var casted = (BaseNotification)JsonConvert.DeserializeObject(ZipUtils.Unzip(data.Blob), parsedType);
var obj = new NotificationViewModel var obj = new NotificationViewModel
{ {
Id = data.Id, Id = data.Id,
Created = data.Created, Created = data.Created,
Seen = data.Seen Seen = data.Seen
}; };
casted.FillViewModel(obj);
casted.FillViewModel(ref obj);
return obj; return obj;
} }

View File

@@ -10,6 +10,6 @@ namespace BTCPayServer.Services.Notifications.Blobs
// IndexViewModel.cs#32 // IndexViewModel.cs#32
public abstract class BaseNotification public abstract class BaseNotification
{ {
public abstract void FillViewModel(ref NotificationViewModel data); public abstract void FillViewModel(NotificationViewModel data);
} }
} }

View File

@@ -4,9 +4,9 @@ using Newtonsoft.Json;
namespace BTCPayServer.Services.Notifications.Blobs namespace BTCPayServer.Services.Notifications.Blobs
{ {
[Notification("newversion")]
internal class NewVersionNotification : BaseNotification internal class NewVersionNotification : BaseNotification
{ {
internal override string NotificationType => "NewVersionNotification";
public NewVersionNotification() public NewVersionNotification()
{ {
@@ -17,7 +17,7 @@ namespace BTCPayServer.Services.Notifications.Blobs
} }
public string Version { get; set; } public string Version { get; set; }
public override void FillViewModel(ref NotificationViewModel vm) public override void FillViewModel(NotificationViewModel vm)
{ {
vm.Body = $"New version {Version} released!"; vm.Body = $"New version {Version} released!";
vm.ActionLink = $"https://github.com/btcpayserver/btcpayserver/releases/tag/v{Version}"; vm.ActionLink = $"https://github.com/btcpayserver/btcpayserver/releases/tag/v{Version}";

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BTCPayServer.Services.Notifications.Blobs
{
[AttributeUsage(AttributeTargets.Class)]
public class NotificationAttribute : Attribute
{
public NotificationAttribute(string notificationType)
{
NotificationType = notificationType;
}
public string NotificationType { get; }
}
}

View File

@@ -55,7 +55,7 @@ namespace BTCPayServer.Services.Notifications
.Where(a => a.ApplicationUserId == userId && !a.Seen) .Where(a => a.ApplicationUserId == userId && !a.Seen)
.OrderByDescending(a => a.Created) .OrderByDescending(a => a.Created)
.Take(5) .Take(5)
.Select(a => a.ViewModel()) .Select(a => a.ToViewModel())
.ToList(); .ToList();
} }
catch (System.IO.InvalidDataException) catch (System.IO.InvalidDataException)

View File

@@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events; using BTCPayServer.Events;
@@ -24,6 +26,10 @@ namespace BTCPayServer.Services.Notifications
public async Task SendNotification(NotificationScope scope, BaseNotification notification) public async Task SendNotification(NotificationScope scope, BaseNotification notification)
{ {
if (scope == null)
throw new ArgumentNullException(nameof(scope));
if (notification == null)
throw new ArgumentNullException(nameof(notification));
var users = await GetUsers(scope); var users = await GetUsers(scope);
using (var db = _contextFactory.CreateContext()) using (var db = _contextFactory.CreateContext())
{ {
@@ -35,7 +41,7 @@ namespace BTCPayServer.Services.Notifications
Id = Guid.NewGuid().ToString(), Id = Guid.NewGuid().ToString(),
Created = DateTimeOffset.UtcNow, Created = DateTimeOffset.UtcNow,
ApplicationUserId = uid, ApplicationUserId = uid,
NotificationType = notification.NotificationType, NotificationType = GetNotificationTypeString(notification.GetType()),
Blob = ZipUtils.Zip(obj), Blob = ZipUtils.Zip(obj),
Seen = false Seen = false
}; };
@@ -46,6 +52,14 @@ namespace BTCPayServer.Services.Notifications
} }
} }
private string GetNotificationTypeString(Type type)
{
var str = type.GetCustomAttribute<NotificationAttribute>()?.NotificationType;
if (str is null)
throw new NotSupportedException($"{type} is not a notification");
return str;
}
private async Task<string[]> GetUsers(NotificationScope scope) private async Task<string[]> GetUsers(NotificationScope scope)
{ {
if (scope is AdminScope) if (scope is AdminScope)

View File

@@ -2,7 +2,6 @@
@inject BTCPayServer.HostedServices.CssThemeManager themeManager @inject BTCPayServer.HostedServices.CssThemeManager themeManager
@{ @{
ViewData["Title"] = "Log in"; ViewData["Title"] = "Log in";
Layout = "_LayoutWelcome";
} }
@if (TempData.HasStatusMessage()) @if (TempData.HasStatusMessage())
{ {