diff --git a/Wino.Core.Domain/Interfaces/INotificationBuilder.cs b/Wino.Core.Domain/Interfaces/INotificationBuilder.cs index 50528ab2..86961ad7 100644 --- a/Wino.Core.Domain/Interfaces/INotificationBuilder.cs +++ b/Wino.Core.Domain/Interfaces/INotificationBuilder.cs @@ -22,4 +22,9 @@ public interface INotificationBuilder /// Creates test notification for test purposes. /// Task CreateTestNotificationAsync(string title, string message); + + /// + /// Removes the toast notification for a specific mail by unique id. + /// + void RemoveNotification(Guid mailUniqueId); } diff --git a/Wino.Core.UWP/Services/NotificationBuilder.cs b/Wino.Core.UWP/Services/NotificationBuilder.cs index 6770c297..722979c3 100644 --- a/Wino.Core.UWP/Services/NotificationBuilder.cs +++ b/Wino.Core.UWP/Services/NotificationBuilder.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.WinUI.Notifications; using Serilog; using Windows.Data.Xml.Dom; @@ -11,7 +13,7 @@ using Wino.Core.Domain.Entities.Mail; using Wino.Core.Domain.Enums; using Wino.Core.Domain.Interfaces; using Wino.Core.Domain.Models.MailItem; -using System.IO; +using Wino.Messaging.UI; namespace Wino.Core.UWP.Services; @@ -36,6 +38,11 @@ public class NotificationBuilder : INotificationBuilder _folderService = folderService; _mailService = mailService; _thumbnailService = thumbnailService; + + WeakReferenceMessenger.Default.Register(this, (r, msg) => + { + RemoveNotification(msg.UniqueId); + }); } public async Task CreateNotificationsAsync(Guid inboxFolderId, IEnumerable downloadedMailItems) @@ -81,7 +88,11 @@ public class NotificationBuilder : INotificationBuilder foreach (var mailItem in validItems) { if (mailItem.IsRead) + { + // Remove the notification for a specific mail if it exists + ToastNotificationManager.History.Remove(mailItem.UniqueId.ToString()); continue; + } var builder = new ToastContentBuilder(); builder.SetToastScenario(ToastScenario.Default); @@ -117,7 +128,8 @@ public class NotificationBuilder : INotificationBuilder Src = new Uri("ms-winsoundevent:Notification.Mail") }); - builder.Show(); + // Use UniqueId as tag to allow removal + builder.Show(toast => toast.Tag = mailItem.UniqueId.ToString()); } await UpdateTaskbarIconBadgeAsync(); @@ -230,4 +242,16 @@ public class NotificationBuilder : INotificationBuilder //await Task.CompletedTask; } + + public void RemoveNotification(Guid mailUniqueId) + { + try + { + ToastNotificationManager.History.Remove(mailUniqueId.ToString()); + } + catch (Exception ex) + { + Log.Error(ex, $"Failed to remove notification for mail {mailUniqueId}"); + } + } } diff --git a/Wino.Messages/UI/MailReadStatusChanged.cs b/Wino.Messages/UI/MailReadStatusChanged.cs new file mode 100644 index 00000000..0653ca71 --- /dev/null +++ b/Wino.Messages/UI/MailReadStatusChanged.cs @@ -0,0 +1,5 @@ +using System; + +namespace Wino.Messaging.UI; + +public record MailReadStatusChanged(Guid UniqueId); diff --git a/Wino.Services/MailService.cs b/Wino.Services/MailService.cs index 6de9fe22..c060d23e 100644 --- a/Wino.Services/MailService.cs +++ b/Wino.Services/MailService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using CommunityToolkit.Mvvm.Messaging; using MimeKit; using Serilog; using SqlKata; @@ -584,6 +585,10 @@ public class MailService : BaseDatabaseService, IMailService if (item.IsRead == isRead) return false; item.IsRead = isRead; + if (isRead && item.UniqueId != Guid.Empty) + { + WeakReferenceMessenger.Default.Send(new MailReadStatusChanged(item.UniqueId)); + } return true; });