Files
Wino-Mail/Wino.Core.WinUI/Services/NotificationBuilder.cs
T

257 lines
9.9 KiB
C#
Raw Normal View History

2024-04-18 01:44:37 +02:00
using System;
using System.Collections.Generic;
using System.IO;
2024-04-18 01:44:37 +02:00
using System.Linq;
using System.Threading.Tasks;
using CommunityToolkit.Mvvm.Messaging;
2025-09-29 11:16:14 +02:00
using Microsoft.Toolkit.Uwp.Notifications;
using Serilog;
2024-04-18 01:44:37 +02:00
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Wino.Core.Domain;
2024-11-10 23:28:25 +01:00
using Wino.Core.Domain.Entities.Mail;
2024-04-18 01:44:37 +02:00
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Messaging.UI;
2024-04-18 01:44:37 +02:00
2025-09-29 11:23:44 +02:00
namespace Wino.Core.WinUI.Services;
2025-02-16 11:54:23 +01:00
// TODO: Refactor this thing. It's garbage.
public class NotificationBuilder : INotificationBuilder
2024-04-18 01:44:37 +02:00
{
2025-02-16 11:54:23 +01:00
private readonly IUnderlyingThemeService _underlyingThemeService;
private readonly IAccountService _accountService;
private readonly IFolderService _folderService;
private readonly IMailService _mailService;
private readonly IThumbnailService _thumbnailService;
2025-02-16 11:54:23 +01:00
public NotificationBuilder(IUnderlyingThemeService underlyingThemeService,
IAccountService accountService,
IFolderService folderService,
IMailService mailService,
IThumbnailService thumbnailService)
2025-02-16 11:54:23 +01:00
{
_underlyingThemeService = underlyingThemeService;
_accountService = accountService;
_folderService = folderService;
_mailService = mailService;
_thumbnailService = thumbnailService;
WeakReferenceMessenger.Default.Register<MailReadStatusChanged>(this, (r, msg) =>
{
RemoveNotification(msg.UniqueId);
});
2025-02-16 11:54:23 +01:00
}
2024-04-18 01:44:37 +02:00
2025-10-03 15:46:38 +02:00
public async Task CreateNotificationsAsync(Guid inboxFolderId, IEnumerable<MailCopy> downloadedMailItems)
2024-04-18 01:44:37 +02:00
{
2025-02-16 11:54:23 +01:00
var mailCount = downloadedMailItems.Count();
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
try
2025-02-16 11:43:30 +01:00
{
2025-02-16 11:54:23 +01:00
// If there are more than 3 mails, just display 1 general toast.
if (mailCount > 3)
2025-02-16 11:43:30 +01:00
{
2025-02-16 11:54:23 +01:00
var builder = new ToastContentBuilder();
builder.SetToastScenario(ToastScenario.Default);
2025-02-16 11:54:23 +01:00
builder.AddText(Translator.Notifications_MultipleNotificationsTitle);
builder.AddText(string.Format(Translator.Notifications_MultipleNotificationsMessage, mailCount));
2025-02-16 11:54:23 +01:00
builder.AddButton(GetDismissButton());
builder.AddAudio(new ToastAudio()
2025-02-16 11:35:43 +01:00
{
2025-02-16 11:54:23 +01:00
Src = new Uri("ms-winsoundevent:Notification.Mail")
});
2025-02-16 11:54:23 +01:00
builder.Show();
}
else
{
2025-10-03 15:46:38 +02:00
var validItems = new List<MailCopy>();
2025-02-16 11:43:30 +01:00
2025-02-16 11:54:23 +01:00
// Fetch mails again to fill up assigned folder data and latest statuses.
// They've been marked as read by executing synchronizer tasks until inital sync finishes.
2025-02-16 11:43:30 +01:00
2025-02-16 11:54:23 +01:00
foreach (var item in downloadedMailItems)
{
var mailItem = await _mailService.GetSingleMailItemAsync(item.UniqueId);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
if (mailItem != null && mailItem.AssignedFolder != null)
2025-02-16 11:43:30 +01:00
{
2025-02-16 11:54:23 +01:00
validItems.Add(mailItem);
}
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
foreach (var mailItem in validItems)
{
if (mailItem.IsRead)
{
// Remove the notification for a specific mail if it exists
ToastNotificationManager.History.Remove(mailItem.UniqueId.ToString());
2025-02-16 11:54:23 +01:00
continue;
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
var builder = new ToastContentBuilder();
builder.SetToastScenario(ToastScenario.Default);
2024-04-18 01:44:37 +02:00
var avatarThumbnail = await _thumbnailService.GetThumbnailAsync(mailItem.FromAddress, awaitLoad: true);
if (!string.IsNullOrEmpty(avatarThumbnail))
2025-02-16 11:54:23 +01:00
{
var tempFile = await Windows.Storage.ApplicationData.Current.TemporaryFolder.CreateFileAsync($"{Guid.NewGuid()}.png", Windows.Storage.CreationCollisionOption.ReplaceExisting);
await using (var stream = await tempFile.OpenStreamForWriteAsync())
{
var bytes = Convert.FromBase64String(avatarThumbnail);
await stream.WriteAsync(bytes);
}
builder.AddAppLogoOverride(new Uri($"ms-appdata:///temp/{tempFile.Name}"), hintCrop: ToastGenericAppLogoCrop.Default);
2025-02-16 11:54:23 +01:00
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
// Override system notification timetamp with received date of the mail.
// It may create confusion for some users, but still it's the truth...
builder.AddCustomTimeStamp(mailItem.CreationDate.ToLocalTime());
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
builder.AddText(mailItem.FromName);
builder.AddText(mailItem.Subject);
builder.AddText(mailItem.PreviewText);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
builder.AddArgument(Constants.ToastMailUniqueIdKey, mailItem.UniqueId.ToString());
builder.AddArgument(Constants.ToastActionKey, MailOperation.Navigate);
2024-04-18 01:44:37 +02:00
builder.AddButton(GetMarkAsReadButton(mailItem.UniqueId));
2025-02-16 11:54:23 +01:00
builder.AddButton(GetDeleteButton(mailItem.UniqueId));
builder.AddButton(GetArchiveButton(mailItem.UniqueId));
2025-02-16 11:54:23 +01:00
builder.AddAudio(new ToastAudio()
{
Src = new Uri("ms-winsoundevent:Notification.Mail")
});
2025-02-16 11:35:43 +01:00
// Use UniqueId as tag to allow removal
builder.Show(toast => toast.Tag = mailItem.UniqueId.ToString());
2025-02-16 11:43:30 +01:00
}
2025-02-16 11:54:23 +01:00
await UpdateTaskbarIconBadgeAsync();
2025-02-16 11:43:30 +01:00
}
2024-04-18 01:44:37 +02:00
}
2025-02-16 11:54:23 +01:00
catch (Exception ex)
{
Log.Error(ex, "Failed to create notifications.");
}
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
private ToastButton GetDismissButton()
=> new ToastButton()
.SetDismissActivation()
.SetImageUri(new Uri("ms-appx:///Assets/NotificationIcons/dismiss.png"));
private static ToastButton GetArchiveButton(Guid mailUniqueId)
=> new ToastButton()
.SetContent(Translator.MailOperation_Archive)
.SetImageUri(new Uri("ms-appx:///Assets/NotificationIcons/archive.png"))
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
.AddArgument(Constants.ToastActionKey, MailOperation.Archive)
.SetBackgroundActivation();
2025-02-16 11:54:23 +01:00
private ToastButton GetDeleteButton(Guid mailUniqueId)
=> new ToastButton()
.SetContent(Translator.MailOperation_Delete)
.SetImageUri(new Uri("ms-appx:///Assets/NotificationIcons/delete.png"))
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
.AddArgument(Constants.ToastActionKey, MailOperation.SoftDelete)
.SetBackgroundActivation();
private static ToastButton GetMarkAsReadButton(Guid mailUniqueId)
2025-02-16 11:54:23 +01:00
=> new ToastButton()
.SetContent(Translator.MailOperation_MarkAsRead)
.SetImageUri(new System.Uri("ms-appx:///Assets/NotificationIcons/markread.png"))
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
.AddArgument(Constants.ToastActionKey, MailOperation.MarkAsRead)
.SetBackgroundActivation();
public async Task UpdateTaskbarIconBadgeAsync()
{
int totalUnreadCount = 0;
try
2024-04-18 01:44:37 +02:00
{
2025-02-16 11:54:23 +01:00
var badgeUpdater = BadgeUpdateManager.CreateBadgeUpdaterForApplication();
var accounts = await _accountService.GetAccountsAsync();
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
foreach (var account in accounts)
2024-04-18 01:44:37 +02:00
{
2025-02-16 11:54:23 +01:00
if (!account.Preferences.IsTaskbarBadgeEnabled) continue;
2025-02-16 11:54:23 +01:00
var accountInbox = await _folderService.GetSpecialFolderByAccountIdAsync(account.Id, SpecialFolderType.Inbox);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
if (accountInbox == null)
continue;
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
var inboxUnreadCount = await _folderService.GetFolderNotificationBadgeAsync(accountInbox.Id);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
totalUnreadCount += inboxUnreadCount;
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
if (totalUnreadCount > 0)
{
// Get the blank badge XML payload for a badge number
XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
// Set the value of the badge in the XML to our number
XmlElement badgeElement = badgeXml.SelectSingleNode("/badge") as XmlElement;
badgeElement.SetAttribute("value", totalUnreadCount.ToString());
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
// Create the badge notification
BadgeNotification badge = new BadgeNotification(badgeXml);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
// And update the badge
badgeUpdater.Update(badge);
2024-04-18 01:44:37 +02:00
}
2025-02-16 11:54:23 +01:00
else
badgeUpdater.Clear();
2025-02-16 11:35:43 +01:00
}
2025-02-16 11:54:23 +01:00
catch (Exception ex)
{
Log.Error(ex, "Error while updating taskbar badge.");
}
}
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
public async Task CreateTestNotificationAsync(string title, string message)
{
// with args test.
2025-10-03 15:46:38 +02:00
//await CreateNotificationsAsync(Guid.Parse("28c3c39b-7147-4de3-b209-949bd19eede6"), new List<IMailItem>()
//{
// new MailCopy()
// {
// Subject = "test subject",
// PreviewText = "preview html",
// CreationDate = DateTime.UtcNow,
// FromAddress = "bkaankose@outlook.com",
// Id = "AAkALgAAAAAAHYQDEapmEc2byACqAC-EWg0AnMdP0zg8wkS_Ib2Eeh80LAAGq91I3QAA",
// }
//});
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
//var builder = new ToastContentBuilder();
//builder.SetToastScenario(ToastScenario.Default);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
//builder.AddText(title);
//builder.AddText(message);
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
//builder.Show();
2024-04-18 01:44:37 +02:00
2025-02-16 11:54:23 +01:00
//await Task.CompletedTask;
2024-04-18 01:44:37 +02:00
}
public void RemoveNotification(Guid mailUniqueId)
{
try
{
ToastNotificationManager.History.Remove(mailUniqueId.ToString());
}
catch (Exception ex)
{
Log.Error(ex, $"Failed to remove notification for mail {mailUniqueId}");
}
}
2024-04-18 01:44:37 +02:00
}