Fix AppNotification multi-entry notifications
This commit is contained in:
@@ -5,10 +5,10 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using CommunityToolkit.WinUI.Notifications;
|
using Microsoft.Windows.AppNotifications;
|
||||||
|
using Microsoft.Windows.AppNotifications.Builder;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using Windows.Data.Xml.Dom;
|
using Windows.Data.Xml.Dom;
|
||||||
using Windows.Storage;
|
|
||||||
using Windows.UI.Notifications;
|
using Windows.UI.Notifications;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Entities.Calendar;
|
using Wino.Core.Domain.Entities.Calendar;
|
||||||
@@ -72,16 +72,13 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
|
|
||||||
if (mailCount > 3)
|
if (mailCount > 3)
|
||||||
{
|
{
|
||||||
var builder = new ToastContentBuilder()
|
var builder = CreateBuilder();
|
||||||
.AddText(Translator.Notifications_MultipleNotificationsTitle)
|
builder.AddText(Translator.Notifications_MultipleNotificationsTitle);
|
||||||
.AddText(string.Format(Translator.Notifications_MultipleNotificationsMessage, mailCount))
|
builder.AddText(string.Format(Translator.Notifications_MultipleNotificationsMessage, mailCount));
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail)
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
.AddAudio(new ToastAudio
|
builder.SetAudioUri(new Uri("ms-winsoundevent:Notification.Mail"));
|
||||||
{
|
|
||||||
Src = new Uri("ms-winsoundevent:Notification.Mail")
|
|
||||||
});
|
|
||||||
|
|
||||||
ShowToast(builder, ToastTargetApp.Mail);
|
ShowNotification(builder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -149,10 +146,7 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ToastNotificationManager.History.Remove(
|
AppNotificationManager.Default.RemoveByTagAsync(mailUniqueId.ToString()).AsTask().GetAwaiter().GetResult();
|
||||||
mailUniqueId.ToString(),
|
|
||||||
null,
|
|
||||||
AppEntryConstants.GetAppUserModelId(WinoApplicationMode.Mail));
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
@@ -165,38 +159,37 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
|
|
||||||
public void CreateAttentionRequiredNotification(MailAccount account)
|
public void CreateAttentionRequiredNotification(MailAccount account)
|
||||||
{
|
{
|
||||||
var builder = new ToastContentBuilder()
|
var builder = CreateBuilder();
|
||||||
.AddText(Translator.Exception_AccountNeedsAttention_Title)
|
builder.AddText(Translator.Exception_AccountNeedsAttention_Title);
|
||||||
.AddText(string.Format(Translator.Exception_AccountNeedsAttention_Message, account.Name))
|
builder.AddText(string.Format(Translator.Exception_AccountNeedsAttention_Message, account.Name));
|
||||||
|
builder.AddArgument(Constants.ToastMailAccountIdKey, account.Id.ToString());
|
||||||
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
builder.AddButton(new AppNotificationButton(Translator.Buttons_FixAccount)
|
||||||
.AddArgument(Constants.ToastMailAccountIdKey, account.Id.ToString())
|
.AddArgument(Constants.ToastMailAccountIdKey, account.Id.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail)
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail));
|
||||||
.AddButton(new ToastButton()
|
|
||||||
.SetContent(Translator.Buttons_FixAccount)
|
|
||||||
.AddArgument(Constants.ToastMailAccountIdKey, account.Id.ToString())
|
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail));
|
|
||||||
|
|
||||||
ShowToast(builder, ToastTargetApp.Mail);
|
ShowNotification(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateWebView2RuntimeMissingNotification()
|
public void CreateWebView2RuntimeMissingNotification()
|
||||||
{
|
{
|
||||||
var builder = new ToastContentBuilder()
|
var builder = CreateBuilder();
|
||||||
.AddText(Translator.Exception_WebView2RuntimeMissing_Title)
|
builder.AddText(Translator.Exception_WebView2RuntimeMissing_Title);
|
||||||
.AddText(Translator.Exception_WebView2RuntimeMissing_Message)
|
builder.AddText(Translator.Exception_WebView2RuntimeMissing_Message);
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
|
||||||
ShowToast(builder, ToastTargetApp.Mail);
|
ShowNotification(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateStoreUpdateNotification()
|
public void CreateStoreUpdateNotification()
|
||||||
{
|
{
|
||||||
var builder = new ToastContentBuilder()
|
var builder = CreateBuilder();
|
||||||
.AddText(Translator.Notifications_StoreUpdateAvailableTitle)
|
builder.AddText(Translator.Notifications_StoreUpdateAvailableTitle);
|
||||||
.AddText(Translator.Notifications_StoreUpdateAvailableMessage)
|
builder.AddText(Translator.Notifications_StoreUpdateAvailableMessage);
|
||||||
.AddArgument(Constants.ToastStoreUpdateActionKey, Constants.ToastStoreUpdateActionInstall)
|
builder.AddArgument(Constants.ToastStoreUpdateActionKey, Constants.ToastStoreUpdateActionInstall);
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
|
||||||
ShowToast(builder, ToastTargetApp.Mail, "store-update-available");
|
ShowNotification(builder, "store-update-available");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task CreateCalendarReminderNotificationAsync(CalendarItem calendarItem, long reminderDurationInSeconds)
|
public Task CreateCalendarReminderNotificationAsync(CalendarItem calendarItem, long reminderDurationInSeconds)
|
||||||
@@ -204,8 +197,7 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
if (calendarItem == null)
|
if (calendarItem == null)
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
||||||
var builder = new ToastContentBuilder()
|
var builder = CreateBuilder(AppNotificationScenario.Reminder);
|
||||||
.SetToastScenario(ToastScenario.Reminder);
|
|
||||||
var localStart = calendarItem.GetLocalStartDate();
|
var localStart = calendarItem.GetLocalStartDate();
|
||||||
var reminderContext = GetCalendarReminderContext(localStart, DateTime.Now);
|
var reminderContext = GetCalendarReminderContext(localStart, DateTime.Now);
|
||||||
|
|
||||||
@@ -218,10 +210,7 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
builder.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarNavigateAction);
|
builder.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarNavigateAction);
|
||||||
builder.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString());
|
builder.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString());
|
||||||
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar);
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar);
|
||||||
builder.AddAudio(new ToastAudio
|
builder.SetAudioUri(new Uri("ms-winsoundevent:Notification.Reminder"));
|
||||||
{
|
|
||||||
Src = new Uri("ms-winsoundevent:Notification.Reminder")
|
|
||||||
});
|
|
||||||
|
|
||||||
var allowedSnoozeMinutes = CalendarReminderSnoozeOptions.GetAllowedSnoozeMinutes(
|
var allowedSnoozeMinutes = CalendarReminderSnoozeOptions.GetAllowedSnoozeMinutes(
|
||||||
reminderDurationInSeconds,
|
reminderDurationInSeconds,
|
||||||
@@ -234,52 +223,45 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
? preferredSnoozeMinutes
|
? preferredSnoozeMinutes
|
||||||
: allowedSnoozeMinutes[0];
|
: allowedSnoozeMinutes[0];
|
||||||
|
|
||||||
var selectionBox = new ToastSelectionBox(Constants.ToastCalendarSnoozeDurationInputId)
|
var selectionBox = new AppNotificationComboBox(Constants.ToastCalendarSnoozeDurationInputId)
|
||||||
{
|
.SetSelectedItem(defaultSnoozeMinutes.ToString());
|
||||||
DefaultSelectionBoxItemId = defaultSnoozeMinutes.ToString()
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (var snoozeMinutes in allowedSnoozeMinutes)
|
foreach (var snoozeMinutes in allowedSnoozeMinutes)
|
||||||
{
|
{
|
||||||
selectionBox.Items.Add(new ToastSelectionBoxItem(
|
selectionBox.AddItem(
|
||||||
snoozeMinutes.ToString(),
|
snoozeMinutes.ToString(),
|
||||||
string.Format(Translator.CalendarReminder_SnoozeMinutesOption, snoozeMinutes)));
|
string.Format(Translator.CalendarReminder_SnoozeMinutesOption, snoozeMinutes));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AddToastInput(selectionBox);
|
builder.AddComboBox(selectionBox);
|
||||||
builder.AddButton(new ToastButton()
|
builder.AddButton(new AppNotificationButton(Translator.CalendarReminder_SnoozeAction)
|
||||||
.SetContent(Translator.CalendarReminder_SnoozeAction)
|
.SetIcon(GetNotificationIconUri("calendar-snooze"))
|
||||||
.SetImageUri(GetNotificationIconUri("calendar-snooze"))
|
|
||||||
.SetBackgroundActivation()
|
|
||||||
.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarSnoozeAction)
|
.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarSnoozeAction)
|
||||||
.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString())
|
.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar));
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar));
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AddButton(new ToastButton()
|
builder.AddButton(new AppNotificationButton(Translator.Buttons_Open)
|
||||||
.SetContent(Translator.Buttons_Open)
|
|
||||||
.SetBackgroundActivation()
|
|
||||||
.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarNavigateAction)
|
.AddArgument(Constants.ToastCalendarActionKey, Constants.ToastCalendarNavigateAction)
|
||||||
.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString())
|
.AddArgument(Constants.ToastCalendarItemIdKey, calendarItem.Id.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar));
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar));
|
||||||
|
|
||||||
if (Uri.TryCreate(calendarItem.HtmlLink, UriKind.Absolute, out var joinUri))
|
if (Uri.TryCreate(calendarItem.HtmlLink, UriKind.Absolute, out var joinUri))
|
||||||
{
|
{
|
||||||
builder.AddButton(new ToastButton()
|
builder.AddButton(new AppNotificationButton(Translator.CalendarEventDetails_JoinOnline)
|
||||||
.SetContent(Translator.CalendarEventDetails_JoinOnline)
|
.SetIcon(GetNotificationIconUri("calendar-join"))
|
||||||
.SetImageUri(GetNotificationIconUri("calendar-join"))
|
.SetInvokeUri(joinUri));
|
||||||
.SetProtocolActivation(joinUri));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tag = $"calendar-reminder-{calendarItem.Id:N}-{reminderDurationInSeconds}";
|
var tag = $"calendar-reminder-{calendarItem.Id:N}-{reminderDurationInSeconds}";
|
||||||
ShowToast(builder, ToastTargetApp.Calendar, tag);
|
ShowNotification(builder, tag);
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CreateSingleNotificationAsync(MailCopy mailItem)
|
private async Task CreateSingleNotificationAsync(MailCopy mailItem)
|
||||||
{
|
{
|
||||||
var builder = new ToastContentBuilder();
|
var builder = CreateBuilder();
|
||||||
|
|
||||||
var avatarThumbnail = await _thumbnailService.GetThumbnailAsync(mailItem.FromAddress, awaitLoad: true);
|
var avatarThumbnail = await _thumbnailService.GetThumbnailAsync(mailItem.FromAddress, awaitLoad: true);
|
||||||
if (!string.IsNullOrEmpty(avatarThumbnail))
|
if (!string.IsNullOrEmpty(avatarThumbnail))
|
||||||
@@ -294,25 +276,22 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
await stream.WriteAsync(bytes);
|
await stream.WriteAsync(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AddAppLogoOverride(new Uri($"ms-appdata:///temp/{tempFile.Name}"), ToastGenericAppLogoCrop.Default);
|
builder.SetAppLogoOverride(new Uri($"ms-appdata:///temp/{tempFile.Name}"), AppNotificationImageCrop.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.AddCustomTimeStamp(mailItem.CreationDate.ToLocalTime());
|
builder.SetTimeStamp(mailItem.CreationDate.ToLocalTime());
|
||||||
builder.AddText(mailItem.FromName);
|
builder.AddText(mailItem.FromName);
|
||||||
builder.AddText(mailItem.Subject);
|
builder.AddText(mailItem.Subject);
|
||||||
builder.AddText(mailItem.PreviewText);
|
builder.AddText(mailItem.PreviewText);
|
||||||
builder.AddArgument(Constants.ToastMailUniqueIdKey, mailItem.UniqueId.ToString());
|
builder.AddArgument(Constants.ToastMailUniqueIdKey, mailItem.UniqueId.ToString());
|
||||||
builder.AddArgument(Constants.ToastActionKey, MailOperation.Navigate);
|
builder.AddArgument(Constants.ToastActionKey, MailOperation.Navigate.ToString());
|
||||||
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
builder.AddButton(GetMarkAsReadButton(mailItem.UniqueId));
|
builder.AddButton(GetMarkAsReadButton(mailItem.UniqueId));
|
||||||
builder.AddButton(GetDeleteButton(mailItem.UniqueId));
|
builder.AddButton(GetDeleteButton(mailItem.UniqueId));
|
||||||
builder.AddButton(GetArchiveButton(mailItem.UniqueId));
|
builder.AddButton(GetArchiveButton(mailItem.UniqueId));
|
||||||
builder.AddAudio(new ToastAudio
|
builder.SetAudioUri(new Uri("ms-winsoundevent:Notification.Mail"));
|
||||||
{
|
|
||||||
Src = new Uri("ms-winsoundevent:Notification.Mail")
|
|
||||||
});
|
|
||||||
|
|
||||||
ShowToast(builder, ToastTargetApp.Mail, mailItem.UniqueId.ToString());
|
ShowNotification(builder, mailItem.UniqueId.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateBadge(string applicationId, int? badgeCount)
|
private void UpdateBadge(string applicationId, int? badgeCount)
|
||||||
@@ -366,55 +345,42 @@ public class NotificationBuilder : INotificationBuilder
|
|||||||
return string.Format(Translator.CalendarReminder_StartedMinutesAgo, minutesAgo);
|
return string.Format(Translator.CalendarReminder_StartedMinutesAgo, minutesAgo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ToastButton GetArchiveButton(Guid mailUniqueId)
|
private AppNotificationButton GetArchiveButton(Guid mailUniqueId)
|
||||||
=> new ToastButton()
|
=> new AppNotificationButton(Translator.MailOperation_Archive)
|
||||||
.SetContent(Translator.MailOperation_Archive)
|
.SetIcon(GetNotificationIconUri("mail-archive"))
|
||||||
.SetImageUri(GetNotificationIconUri("mail-archive"))
|
|
||||||
.SetBackgroundActivation()
|
|
||||||
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
||||||
.AddArgument(Constants.ToastActionKey, MailOperation.Archive)
|
.AddArgument(Constants.ToastActionKey, MailOperation.Archive.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
|
||||||
private ToastButton GetDeleteButton(Guid mailUniqueId)
|
private AppNotificationButton GetDeleteButton(Guid mailUniqueId)
|
||||||
=> new ToastButton()
|
=> new AppNotificationButton(Translator.MailOperation_Delete)
|
||||||
.SetContent(Translator.MailOperation_Delete)
|
.SetIcon(GetNotificationIconUri("mail-delete"))
|
||||||
.SetImageUri(GetNotificationIconUri("mail-delete"))
|
|
||||||
.SetBackgroundActivation()
|
|
||||||
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
||||||
.AddArgument(Constants.ToastActionKey, MailOperation.SoftDelete)
|
.AddArgument(Constants.ToastActionKey, MailOperation.SoftDelete.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
|
||||||
private ToastButton GetMarkAsReadButton(Guid mailUniqueId)
|
private AppNotificationButton GetMarkAsReadButton(Guid mailUniqueId)
|
||||||
=> new ToastButton()
|
=> new AppNotificationButton(Translator.MailOperation_MarkAsRead)
|
||||||
.SetContent(Translator.MailOperation_MarkAsRead)
|
.SetIcon(GetNotificationIconUri("mail-markread"))
|
||||||
.SetImageUri(GetNotificationIconUri("mail-markread"))
|
|
||||||
.SetBackgroundActivation()
|
|
||||||
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
|
||||||
.AddArgument(Constants.ToastActionKey, MailOperation.MarkAsRead)
|
.AddArgument(Constants.ToastActionKey, MailOperation.MarkAsRead.ToString())
|
||||||
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
|
||||||
|
|
||||||
private static void ShowToast(ToastContentBuilder builder, ToastTargetApp targetApp, string? tag = null)
|
private static AppNotificationBuilder CreateBuilder(AppNotificationScenario scenario = AppNotificationScenario.Default)
|
||||||
|
=> new AppNotificationBuilder().SetScenario(scenario);
|
||||||
|
|
||||||
|
private static void ShowNotification(AppNotificationBuilder builder, string? tag = null)
|
||||||
{
|
{
|
||||||
var toastNotification = new ToastNotification(builder.GetToastContent().GetXml());
|
var notification = builder.BuildNotification();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(tag))
|
if (!string.IsNullOrWhiteSpace(tag))
|
||||||
{
|
{
|
||||||
toastNotification.Tag = tag;
|
notification.Tag = tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToastNotificationManager
|
AppNotificationManager.Default.Show(notification);
|
||||||
.CreateToastNotifier(AppEntryConstants.GetAppUserModelId(targetApp == ToastTargetApp.Calendar
|
|
||||||
? WinoApplicationMode.Calendar
|
|
||||||
: WinoApplicationMode.Mail))
|
|
||||||
.Show(toastNotification);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Uri GetNotificationIconUri(string iconName)
|
private static Uri GetNotificationIconUri(string iconName)
|
||||||
=> new($"{NotificationIconRootUri}{iconName}.png");
|
=> new($"{NotificationIconRootUri}{iconName}.png");
|
||||||
|
|
||||||
private enum ToastTargetApp
|
|
||||||
{
|
|
||||||
Mail,
|
|
||||||
Calendar
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,6 @@
|
|||||||
<PackageReference Include="CommunityToolkit.Diagnostics" />
|
<PackageReference Include="CommunityToolkit.Diagnostics" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" />
|
<PackageReference Include="CommunityToolkit.Mvvm" />
|
||||||
<PackageReference Include="CommunityToolkit.Labs.WinUI.DependencyPropertyGenerator" />
|
<PackageReference Include="CommunityToolkit.Labs.WinUI.DependencyPropertyGenerator" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" />
|
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
|
<PackageReference Include="CommunityToolkit.WinUI.Animations" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" />
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" />
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" />
|
||||||
|
|||||||
Reference in New Issue
Block a user