Ajout du système de notifications : service, configuration et persistance des notifications introduits. Mise à jour de l'UI pour afficher et gérer les notifications Syncshell.

This commit is contained in:
2025-11-02 13:48:11 +01:00
parent 7a391e6253
commit 699678f641
10 changed files with 240 additions and 31 deletions

View File

@@ -2,29 +2,45 @@ using System;
using System.Collections.Generic;
using System.Linq;
using MareSynchronos.Services.Mediator;
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Configurations;
using MareSynchronos.MareConfiguration.Models;
namespace MareSynchronos.Services.Notifications;
public enum NotificationCategory
{
AutoDetect,
Syncshell,
}
public sealed record NotificationEntry(NotificationCategory Category, string Id, string Title, string? Description, DateTime CreatedAt)
{
public static NotificationEntry AutoDetect(string uid, string displayName)
=> new(NotificationCategory.AutoDetect, uid, displayName, "Nouvelle demande d'appairage via AutoDetect.", DateTime.UtcNow);
public static NotificationEntry SyncshellPublic(string gid, string aliasOrGid)
=> new(NotificationCategory.Syncshell, gid, $"Syncshell publique: {aliasOrGid}", "La Syncshell est désormais visible via AutoDetect.", DateTime.UtcNow);
public static NotificationEntry SyncshellNotPublic(string gid, string aliasOrGid)
=> new(NotificationCategory.Syncshell, gid, $"Syncshell non publique: {aliasOrGid}", "La Syncshell n'est plus visible via AutoDetect.", DateTime.UtcNow);
}
public sealed class NotificationTracker
{
private const int MaxStored = 100;
private readonly MareMediator _mediator;
private readonly NotificationsConfigService _configService;
private readonly Dictionary<(NotificationCategory Category, string Id), NotificationEntry> _entries = new();
private readonly object _lock = new();
public NotificationTracker(MareMediator mediator)
public NotificationTracker(MareMediator mediator, NotificationsConfigService configService)
{
_mediator = mediator;
_configService = configService;
LoadPersisted();
PublishState();
}
public void Upsert(NotificationEntry entry)
@@ -32,6 +48,8 @@ public sealed class NotificationTracker
lock (_lock)
{
_entries[(entry.Category, entry.Id)] = entry;
TrimIfNecessary_NoLock();
Persist_NoLock();
}
PublishState();
}
@@ -41,6 +59,7 @@ public sealed class NotificationTracker
lock (_lock)
{
_entries.Remove((category, id));
Persist_NoLock();
}
PublishState();
}
@@ -70,4 +89,56 @@ public sealed class NotificationTracker
{
_mediator.Publish(new NotificationStateChanged(Count));
}
private void LoadPersisted()
{
try
{
var list = _configService.Current.Notifications ?? new List<StoredNotification>();
foreach (var s in list)
{
if (!Enum.TryParse<NotificationCategory>(s.Category, out var cat)) continue;
var entry = new NotificationEntry(cat, s.Id, s.Title, s.Description, s.CreatedAtUtc);
_entries[(entry.Category, entry.Id)] = entry;
}
TrimIfNecessary_NoLock();
}
catch
{
// ignore load errors, start empty
}
}
private void Persist_NoLock()
{
try
{
var stored = _entries.Values
.OrderBy(e => e.CreatedAt)
.Select(e => new StoredNotification
{
Category = e.Category.ToString(),
Id = e.Id,
Title = e.Title,
Description = e.Description,
CreatedAtUtc = e.CreatedAt
})
.ToList();
_configService.Current.Notifications = stored;
_configService.Save();
}
catch
{
// ignore persistence errors
}
}
private void TrimIfNecessary_NoLock()
{
if (_entries.Count <= MaxStored) return;
foreach (var kv in _entries.Values.OrderByDescending(v => v.CreatedAt).Skip(MaxStored).ToList())
{
_entries.Remove((kv.Category, kv.Id));
}
}
}