mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 22:44:29 +01:00
Rewrite the Notification dropdown with Blazor (#5325)
* Rewrite the Notification dropdown with Blazor * Test fix --------- Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
@@ -4,51 +4,46 @@ using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Abstractions.Contracts;
|
||||
using BTCPayServer.Components.Notifications;
|
||||
using BTCPayServer.Data;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Newtonsoft.Json;
|
||||
using Org.BouncyCastle.Crypto.Generators;
|
||||
|
||||
namespace BTCPayServer.Services.Notifications
|
||||
{
|
||||
public class NotificationManager
|
||||
{
|
||||
private readonly ApplicationDbContextFactory _factory;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly EventAggregator _eventAggregator;
|
||||
private readonly Dictionary<string, INotificationHandler> _handlersByNotificationType;
|
||||
|
||||
public NotificationManager(ApplicationDbContextFactory factory, UserManager<ApplicationUser> userManager,
|
||||
public NotificationManager(ApplicationDbContextFactory factory,
|
||||
IMemoryCache memoryCache, IEnumerable<INotificationHandler> handlers, EventAggregator eventAggregator)
|
||||
{
|
||||
_factory = factory;
|
||||
_userManager = userManager;
|
||||
_memoryCache = memoryCache;
|
||||
_eventAggregator = eventAggregator;
|
||||
_handlersByNotificationType = handlers.ToDictionary(h => h.NotificationType);
|
||||
}
|
||||
|
||||
private const int _cacheExpiryMs = 5000;
|
||||
|
||||
public async Task<NotificationsViewModel> GetSummaryNotifications(ClaimsPrincipal user)
|
||||
public async Task<(List<NotificationViewModel> Items, int? Count)> GetSummaryNotifications(string userId, bool cachedOnly)
|
||||
{
|
||||
var userId = _userManager.GetUserId(user);
|
||||
var cacheKey = GetNotificationsCacheId(userId);
|
||||
|
||||
if (cachedOnly)
|
||||
return _memoryCache.Get<(List<NotificationViewModel> Items, int? Count)>(cacheKey);
|
||||
return await _memoryCache.GetOrCreateAsync(cacheKey, async entry =>
|
||||
{
|
||||
var resp = await GetNotifications(new NotificationsQuery
|
||||
var res = await GetNotifications(new NotificationsQuery
|
||||
{
|
||||
Seen = false,
|
||||
Skip = 0,
|
||||
Take = 5,
|
||||
UserId = userId
|
||||
});
|
||||
entry.SetAbsoluteExpiration(TimeSpan.FromMilliseconds(_cacheExpiryMs));
|
||||
var res = new NotificationsViewModel { Last5 = resp.Items, UnseenCount = resp.Count.Value };
|
||||
entry.Value = res;
|
||||
return res;
|
||||
});
|
||||
@@ -67,7 +62,7 @@ namespace BTCPayServer.Services.Notifications
|
||||
{
|
||||
return $"notifications-{userId}";
|
||||
}
|
||||
|
||||
public const int MaxUnseen = 100;
|
||||
public async Task<(List<NotificationViewModel> Items, int? Count)> GetNotifications(NotificationsQuery query)
|
||||
{
|
||||
await using var dbContext = _factory.CreateContext();
|
||||
@@ -80,6 +75,27 @@ namespace BTCPayServer.Services.Notifications
|
||||
{
|
||||
// Unseen notifications aren't likely to be too huge, so count should be fast
|
||||
count = await queryables.withoutPaging.CountAsync();
|
||||
if (count >= MaxUnseen)
|
||||
{
|
||||
// If we have too much unseen notifications, we don't want to show the exact count
|
||||
// because it would be too long to display, so we just show 99+
|
||||
// Then cleanup a bit the database by removing the oldest notifications, as it would be expensive to fetch every time
|
||||
if (count >= MaxUnseen + (MaxUnseen / 2))
|
||||
{
|
||||
nextBatch:
|
||||
var seenToRemove = await queryables.withoutPaging.OrderByDescending(data => data.Created).Skip(MaxUnseen).Take(1000).ToListAsync();
|
||||
if (seenToRemove.Count > 0)
|
||||
{
|
||||
foreach (var seen in seenToRemove)
|
||||
{
|
||||
seen.Seen = true;
|
||||
}
|
||||
await dbContext.SaveChangesAsync();
|
||||
goto nextBatch;
|
||||
}
|
||||
}
|
||||
count = MaxUnseen;
|
||||
}
|
||||
}
|
||||
return (Items: items, Count: count);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user