diff --git a/AGENTS.md b/AGENTS.md
index b32a6ef6..4b451cce 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -150,6 +150,8 @@ private string searchQuery = string.Empty;
- For dependency properties in WinUI code, always prefer `[GeneratedDependencyProperty]` from CommunityToolkit over manual `DependencyProperty.Register(...)` declarations.
- When a `[RelayCommand]` needs enable/disable logic, prefer the command's `CanExecute` over binding `Button.IsEnabled` in XAML; use `[NotifyCanExecuteChangedFor]` on dependent properties and call `NotifyCanExecuteChanged()` explicitly when non-generated state affects the command.
- In ViewModels, update all UI-bound properties/collections via `ExecuteUIThread(...)` (especially after awaited calls and any use of `ConfigureAwait(false)`).
+- `ConfigureAwait(false)` continues execution on a background thread. Any UI-bound property change, `INotifyPropertyChanged` notification, collection mutation, or similar UI-facing state update after that point must be marshaled back with `ExecuteUIThread(...)` or the appropriate dispatcher call, otherwise the app can crash.
+- Messenger messages are raised from a background thread by default, while UI control event handlers such as `Button.Click` start on the UI thread. Be deliberate when combining dispatcher usage with `ConfigureAwait(false)` so post-await UI updates always return to the UI thread.
- ViewModels should only handle UI interaction/state and delegate business logic to services; account-management work belongs in `WinoAccountProfileService`, and preferences import/export/apply logic belongs in `PreferencesService`.
- In `EventDetailsPageViewModel.LoadAttendeesAsync`, never mutate `CurrentEvent.Attendees` outside `ExecuteUIThread(...)`.
- Never create pure C# controls or controls that heavily manipulate UI structure from `.cs` files. Define controls in XAML and keep UI composition in XAML.
diff --git a/Wino.Core.Domain/Constants.cs b/Wino.Core.Domain/Constants.cs
index e57f7696..dd1af841 100644
--- a/Wino.Core.Domain/Constants.cs
+++ b/Wino.Core.Domain/Constants.cs
@@ -24,6 +24,7 @@ public static class Constants
public const string ToastModeKey = nameof(ToastModeKey);
public const string ToastModeMail = nameof(ToastModeMail);
public const string ToastModeCalendar = nameof(ToastModeCalendar);
+ public const string ToastDismissActionKey = nameof(ToastDismissActionKey);
public const string ToastStoreUpdateActionKey = nameof(ToastStoreUpdateActionKey);
public const string ToastStoreUpdateActionInstall = nameof(ToastStoreUpdateActionInstall);
public const string ClientLogFile = "Client_.log";
diff --git a/Wino.Core.Domain/Enums/WinoPage.cs b/Wino.Core.Domain/Enums/WinoPage.cs
index 5a23c97c..8f8e79bc 100644
--- a/Wino.Core.Domain/Enums/WinoPage.cs
+++ b/Wino.Core.Domain/Enums/WinoPage.cs
@@ -19,6 +19,7 @@ public enum WinoPage
AboutPage,
PersonalizationPage,
MessageListPage,
+ MailNotificationSettingsPage,
MailListPage,
ReadComposePanePage,
AppPreferencesPage,
diff --git a/Wino.Core.Domain/Interfaces/IPreferencesService.cs b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
index c9f58ba3..cde1ca06 100644
--- a/Wino.Core.Domain/Interfaces/IPreferencesService.cs
+++ b/Wino.Core.Domain/Interfaces/IPreferencesService.cs
@@ -192,6 +192,16 @@ public interface IPreferencesService : INotifyPropertyChanged
///
Guid? StartupEntityId { get; set; }
+ ///
+ /// Setting: First action button displayed on mail toast notifications.
+ ///
+ MailOperation FirstMailNotificationAction { get; set; }
+
+ ///
+ /// Setting: Second action button displayed on mail toast notifications.
+ ///
+ MailOperation SecondMailNotificationAction { get; set; }
+
///
diff --git a/Wino.Core.Domain/Models/Settings/SettingsNavigationItemInfo.cs b/Wino.Core.Domain/Models/Settings/SettingsNavigationItemInfo.cs
index 4a3581e4..274ce538 100644
--- a/Wino.Core.Domain/Models/Settings/SettingsNavigationItemInfo.cs
+++ b/Wino.Core.Domain/Models/Settings/SettingsNavigationItemInfo.cs
@@ -68,6 +68,11 @@ public static class SettingsNavigationInfoProvider
Translator.SettingsMessageList_Description,
"\uE8C4",
searchKeywords: Translator.SettingsSearch_MessageList_Keywords),
+ new(WinoPage.MailNotificationSettingsPage,
+ Translator.SettingsMailNotifications_Title,
+ Translator.SettingsMailNotifications_Description,
+ "\uE7F4",
+ searchKeywords: Translator.SettingsSearch_MailNotifications_Keywords),
new(WinoPage.ReadComposePanePage,
Translator.SettingsReadComposePane_Title,
Translator.SettingsReadComposePane_Description,
@@ -149,6 +154,7 @@ public static class SettingsNavigationInfoProvider
WinoPage.PersonalizationPage => Translator.SettingsPersonalization_Title,
WinoPage.AboutPage => Translator.SettingsAbout_Title,
WinoPage.MessageListPage => Translator.SettingsMessageList_Title,
+ WinoPage.MailNotificationSettingsPage => Translator.SettingsMailNotifications_Title,
WinoPage.ReadComposePanePage => Translator.SettingsReadComposePane_Title,
WinoPage.AppPreferencesPage => Translator.SettingsAppPreferences_Title,
WinoPage.CalendarSettingsPage => Translator.CalendarSettings_Preferences_Title,
diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json
index b1fd54b5..fe103b57 100644
--- a/Wino.Core.Domain/Translations/en_US/resources.json
+++ b/Wino.Core.Domain/Translations/en_US/resources.json
@@ -84,6 +84,7 @@
"Buttons_Delete": "Delete",
"Buttons_Deny": "Deny",
"Buttons_Discard": "Discard",
+ "Buttons_Dismiss": "Dismiss",
"Buttons_Edit": "Edit",
"Buttons_EnableImageRendering": "Enable",
"Buttons_Multiselect": "Select Multiple",
@@ -910,6 +911,14 @@
"SettingsMarkAsRead_WhenSelected": "When selected",
"SettingsMessageList_Description": "Change how your messages should be organized in mail list.",
"SettingsMessageList_Title": "Message List",
+ "SettingsMailNotifications_Title": "Notifications",
+ "SettingsMailNotifications_Description": "Notification settings and preferences for mails.",
+ "SettingsMailNotifications_Actions_Title": "App notification actions.",
+ "SettingsMailNotifications_Actions_Description": "Customize the button behaviors on the notifications as you like.",
+ "SettingsMailNotifications_FirstAction_Title": "First notification action",
+ "SettingsMailNotifications_FirstAction_Description": "Choose the first button shown on mail notifications.",
+ "SettingsMailNotifications_SecondAction_Title": "Second notification action",
+ "SettingsMailNotifications_SecondAction_Description": "Choose the second button shown on mail notifications.",
"SettingsNoAccountSetupMessage": "You didn't setup any accounts yet.",
"SettingsNotifications_Description": "Turn on or off notifications for this account.",
"SettingsNotifications_Title": "Notifications",
@@ -946,6 +955,7 @@
"SettingsSearch_About_Keywords": "about;version;website;privacy;github;donate;store;support",
"SettingsSearch_KeyboardShortcuts_Keywords": "shortcut;shortcuts;hotkey;hotkeys;keyboard;keys",
"SettingsSearch_MessageList_Keywords": "message;messages;list;threading;threads;avatar;preview;sender",
+ "SettingsSearch_MailNotifications_Keywords": "mail;notification;notifications;toast;action;actions;reply;reply all;forward;archive;delete;junk;read",
"SettingsSearch_ReadComposePane_Keywords": "reader;compose;composer;font;fonts;external content;display;reading",
"SettingsSearch_SignatureAndEncryption_Keywords": "signature;signatures;encryption;certificate;certificates;s mime;smime;security",
"SettingsSearch_Storage_Keywords": "storage;cache;caching;mime;disk;space;cleanup;clean up;local data",
diff --git a/Wino.Mail.ViewModels/MailNotificationSettingsPageViewModel.cs b/Wino.Mail.ViewModels/MailNotificationSettingsPageViewModel.cs
new file mode 100644
index 00000000..19032544
--- /dev/null
+++ b/Wino.Mail.ViewModels/MailNotificationSettingsPageViewModel.cs
@@ -0,0 +1,135 @@
+using System.Collections.ObjectModel;
+using System.Linq;
+using CommunityToolkit.Mvvm.ComponentModel;
+using Wino.Core.Domain.Enums;
+using Wino.Core.Domain.Interfaces;
+using Wino.Core.Domain;
+
+namespace Wino.Mail.ViewModels;
+
+public partial class MailNotificationSettingsPageViewModel : MailBaseViewModel
+{
+ private static readonly MailOperation[] SupportedMailNotificationActions =
+ [
+ MailOperation.MarkAsRead,
+ MailOperation.SoftDelete,
+ MailOperation.MoveToJunk,
+ MailOperation.Archive,
+ MailOperation.Reply,
+ MailOperation.ReplyAll,
+ MailOperation.Forward
+ ];
+
+ private readonly IPreferencesService _preferencesService;
+ private bool _isUpdatingSelection;
+ private bool _isLoaded;
+
+ public ObservableCollection AvailableNotificationActions { get; } = [];
+
+ [ObservableProperty]
+ public partial MailNotificationActionOption SelectedFirstAction { get; set; }
+
+ [ObservableProperty]
+ public partial MailNotificationActionOption SelectedSecondAction { get; set; }
+
+ public MailNotificationSettingsPageViewModel(IPreferencesService preferencesService)
+ {
+ _preferencesService = preferencesService;
+
+ foreach (var action in SupportedMailNotificationActions)
+ {
+ AvailableNotificationActions.Add(new MailNotificationActionOption(action, GetOperationDisplayText(action)));
+ }
+
+ InitializeSelections();
+ _isLoaded = true;
+ }
+
+ partial void OnSelectedFirstActionChanged(MailNotificationActionOption value)
+ {
+ if (!_isLoaded || _isUpdatingSelection || value == null)
+ return;
+
+ EnsureDistinctSelections(changedSelection: value, isFirstSelection: true);
+ _preferencesService.FirstMailNotificationAction = value.Operation;
+ }
+
+ partial void OnSelectedSecondActionChanged(MailNotificationActionOption value)
+ {
+ if (!_isLoaded || _isUpdatingSelection || value == null)
+ return;
+
+ EnsureDistinctSelections(changedSelection: value, isFirstSelection: false);
+ _preferencesService.SecondMailNotificationAction = value.Operation;
+ }
+
+ private void InitializeSelections()
+ {
+ var firstAction = ResolveSupportedAction(_preferencesService.FirstMailNotificationAction, MailOperation.MarkAsRead);
+ var secondAction = ResolveSupportedAction(_preferencesService.SecondMailNotificationAction, MailOperation.SoftDelete);
+
+ if (secondAction == firstAction)
+ {
+ secondAction = GetFallbackDistinctAction(firstAction);
+ }
+
+ SelectedFirstAction = GetOption(firstAction);
+ SelectedSecondAction = GetOption(secondAction);
+
+ _preferencesService.FirstMailNotificationAction = firstAction;
+ _preferencesService.SecondMailNotificationAction = secondAction;
+ }
+
+ private void EnsureDistinctSelections(MailNotificationActionOption changedSelection, bool isFirstSelection)
+ {
+ var otherSelection = isFirstSelection ? SelectedSecondAction : SelectedFirstAction;
+ if (otherSelection?.Operation != changedSelection.Operation)
+ return;
+
+ _isUpdatingSelection = true;
+
+ var fallbackAction = GetFallbackDistinctAction(changedSelection.Operation);
+ var fallbackOption = GetOption(fallbackAction);
+
+ if (isFirstSelection)
+ {
+ SelectedSecondAction = fallbackOption;
+ _preferencesService.SecondMailNotificationAction = fallbackAction;
+ }
+ else
+ {
+ SelectedFirstAction = fallbackOption;
+ _preferencesService.FirstMailNotificationAction = fallbackAction;
+ }
+
+ _isUpdatingSelection = false;
+ }
+
+ private MailNotificationActionOption GetOption(MailOperation action)
+ => AvailableNotificationActions.First(option => option.Operation == action);
+
+ private static MailOperation ResolveSupportedAction(MailOperation action, MailOperation fallbackAction)
+ => SupportedMailNotificationActions.Contains(action) ? action : fallbackAction;
+
+ private static MailOperation GetFallbackDistinctAction(MailOperation excludedAction)
+ => SupportedMailNotificationActions.First(action => action != excludedAction);
+
+ private static string GetOperationDisplayText(MailOperation action)
+ => action switch
+ {
+ MailOperation.MarkAsRead => Translator.MailOperation_MarkAsRead,
+ MailOperation.SoftDelete => Translator.MailOperation_Delete,
+ MailOperation.MoveToJunk => Translator.MailOperation_MarkAsJunk,
+ MailOperation.Archive => Translator.MailOperation_Archive,
+ MailOperation.Reply => Translator.MailOperation_Reply,
+ MailOperation.ReplyAll => Translator.MailOperation_ReplyAll,
+ MailOperation.Forward => Translator.MailOperation_Forward,
+ _ => action.ToString()
+ };
+}
+
+public sealed class MailNotificationActionOption(MailOperation operation, string displayText)
+{
+ public MailOperation Operation { get; } = operation;
+ public string DisplayText { get; } = displayText;
+}
diff --git a/Wino.Mail.WinUI/Activation/ToastActivationResolver.cs b/Wino.Mail.WinUI/Activation/ToastActivationResolver.cs
index bbbf829d..e3cb7426 100644
--- a/Wino.Mail.WinUI/Activation/ToastActivationResolver.cs
+++ b/Wino.Mail.WinUI/Activation/ToastActivationResolver.cs
@@ -41,9 +41,14 @@ internal static class ToastActivationResolver
return calendarAction == Constants.ToastCalendarNavigateAction;
}
+ if (toastArguments.TryGetValue(Constants.ToastDismissActionKey, out string _))
+ {
+ return false;
+ }
+
if (toastArguments.TryGetValue(Constants.ToastActionKey, out MailOperation mailAction))
{
- return mailAction == MailOperation.Navigate;
+ return mailAction is MailOperation.Navigate or MailOperation.Reply or MailOperation.ReplyAll or MailOperation.Forward;
}
return true;
@@ -52,5 +57,6 @@ internal static class ToastActivationResolver
private static bool ContainsKnownToastKey(NotificationArguments toastArguments)
=> toastArguments.TryGetValue(Constants.ToastStoreUpdateActionKey, out string _) ||
toastArguments.TryGetValue(Constants.ToastCalendarActionKey, out string _) ||
+ toastArguments.TryGetValue(Constants.ToastDismissActionKey, out string _) ||
toastArguments.TryGetValue(Constants.ToastActionKey, out string _);
}
diff --git a/Wino.Mail.WinUI/App.xaml.cs b/Wino.Mail.WinUI/App.xaml.cs
index b3b7189a..893990b5 100644
--- a/Wino.Mail.WinUI/App.xaml.cs
+++ b/Wino.Mail.WinUI/App.xaml.cs
@@ -358,6 +358,7 @@ public partial class App : WinoApplication,
services.AddTransient(typeof(AccountDetailsPageViewModel));
services.AddTransient(typeof(SignatureManagementPageViewModel));
services.AddTransient(typeof(MessageListPageViewModel));
+ services.AddTransient(typeof(MailNotificationSettingsPageViewModel));
services.AddTransient(typeof(ReadComposePanePageViewModel));
services.AddTransient(typeof(MergedAccountDetailsPageViewModel));
services.AddTransient(typeof(AppPreferencesPageViewModel));
@@ -599,6 +600,12 @@ public partial class App : WinoApplication,
return;
}
+ if (toastArguments.TryGetValue(Constants.ToastDismissActionKey, out string _))
+ {
+ LogActivation("Handling notification dismiss action.");
+ return;
+ }
+
// Check calendar reminder toast activation first.
if (toastArguments.TryGetValue(Constants.ToastCalendarActionKey, out string calendarAction) &&
toastArguments.TryGetValue(Constants.ToastCalendarItemIdKey, out string calendarItemIdString) &&
@@ -632,6 +639,10 @@ public partial class App : WinoApplication,
// User clicked notification - create window if needed and navigate.
await HandleToastNavigationAsync(mailItemUniqueId);
}
+ else if (IsComposeToastAction(action))
+ {
+ await HandleToastComposeActionAsync(action, mailItemUniqueId);
+ }
else
{
// User clicked action button (Mark as Read, Delete, etc.)
@@ -985,6 +996,87 @@ public partial class App : WinoApplication,
}
}
+ private async Task HandleToastComposeActionAsync(MailOperation action, Guid mailItemUniqueId)
+ {
+ LogActivation($"Handling compose toast action: {action} for mail {mailItemUniqueId}");
+
+ var mailService = Services.GetRequiredService();
+ var folderService = Services.GetRequiredService();
+ var mimeFileService = Services.GetRequiredService();
+ var navigationService = Services.GetRequiredService();
+ var requestDelegator = Services.GetRequiredService();
+ var mailShellViewModel = Services.GetRequiredService();
+
+ var mailItem = await mailService.GetSingleMailItemAsync(mailItemUniqueId);
+ if (mailItem == null)
+ {
+ LogActivation($"Compose toast mail item was not found for {mailItemUniqueId}.");
+ return;
+ }
+
+ var account = await mailService.GetMailAccountByUniqueIdAsync(mailItemUniqueId) ?? mailItem.AssignedAccount;
+ if (account == null)
+ {
+ LogActivation($"Compose toast account was not found for {mailItemUniqueId}.");
+ return;
+ }
+
+ var draftFolder = await folderService.GetSpecialFolderByAccountIdAsync(account.Id, SpecialFolderType.Draft);
+ if (draftFolder == null)
+ {
+ LogActivation($"Compose toast draft folder is missing for account {account.Id}.");
+ return;
+ }
+
+ var mimeInformation = await mimeFileService.GetMimeMessageInformationAsync(mailItem.FileId, account.Id);
+ if (mimeInformation?.MimeMessage == null)
+ {
+ LogActivation($"Compose toast MIME payload was not found for mail {mailItemUniqueId}.");
+ return;
+ }
+
+ await EnsureShellWindowAsync(WinoApplicationMode.Mail, activateWindow: true);
+ navigationService.ChangeApplicationMode(WinoApplicationMode.Mail);
+
+ if (mailShellViewModel.MenuItems.TryGetAccountMenuItem(account.Id, out IAccountMenuItem accountMenuItem))
+ {
+ await mailShellViewModel.ChangeLoadedAccountAsync(accountMenuItem, navigateInbox: false);
+ }
+
+ if (mailShellViewModel.MenuItems.TryGetSpecialFolderMenuItem(account.Id, SpecialFolderType.Draft, out var draftFolderMenuItem))
+ {
+ await mailShellViewModel.NavigateFolderAsync(draftFolderMenuItem);
+ }
+
+ var draftOptions = new DraftCreationOptions
+ {
+ Reason = action switch
+ {
+ MailOperation.Reply => DraftCreationReason.Reply,
+ MailOperation.ReplyAll => DraftCreationReason.ReplyAll,
+ MailOperation.Forward => DraftCreationReason.Forward,
+ _ => DraftCreationReason.Empty
+ },
+ ReferencedMessage = new ReferencedMessage
+ {
+ MimeMessage = mimeInformation.MimeMessage,
+ MailCopy = mailItem
+ }
+ };
+
+ var (draftMailCopy, draftBase64MimeMessage) = await mailService.CreateDraftAsync(account.Id, draftOptions);
+ var draftPreparationRequest = new DraftPreparationRequest(account, draftMailCopy, draftBase64MimeMessage, draftOptions.Reason, mailItem);
+
+ await requestDelegator.ExecuteAsync(draftPreparationRequest);
+ navigationService.Navigate(WinoPage.ComposePage,
+ new MailItemViewModel(draftMailCopy),
+ NavigationReferenceFrame.RenderingFrame,
+ NavigationTransitionType.DrillIn);
+ }
+
+ private static bool IsComposeToastAction(MailOperation action)
+ => action is MailOperation.Reply or MailOperation.ReplyAll or MailOperation.Forward;
+
///
/// Creates the main window and activates it.
///
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-forward.png
new file mode 100644
index 00000000..38c3e00a
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-junk.png
new file mode 100644
index 00000000..098634b9
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-reply.png
new file mode 100644
index 00000000..6366658c
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-replyall.png
new file mode 100644
index 00000000..aa9644ad
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-100/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-forward.png
new file mode 100644
index 00000000..7b5f2532
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-junk.png
new file mode 100644
index 00000000..7532e7c6
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-reply.png
new file mode 100644
index 00000000..c96bb76b
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-replyall.png
new file mode 100644
index 00000000..3029bcaa
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-125/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-forward.png
new file mode 100644
index 00000000..7431c7c8
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-junk.png
new file mode 100644
index 00000000..f1156562
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-reply.png
new file mode 100644
index 00000000..50fb6bf7
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-replyall.png
new file mode 100644
index 00000000..5875c1c3
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-150/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-forward.png
new file mode 100644
index 00000000..ced855f6
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-junk.png
new file mode 100644
index 00000000..ca265c3f
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-reply.png
new file mode 100644
index 00000000..972a9bf1
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-replyall.png
new file mode 100644
index 00000000..2a94da2b
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-200/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-forward.png
new file mode 100644
index 00000000..81125184
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-junk.png
new file mode 100644
index 00000000..ab1ec9eb
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-reply.png
new file mode 100644
index 00000000..22b30d41
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-replyall.png
new file mode 100644
index 00000000..86b55939
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-dark/scale-400/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-forward.png
new file mode 100644
index 00000000..48d584f3
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-junk.png
new file mode 100644
index 00000000..6ec71bc7
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-reply.png
new file mode 100644
index 00000000..3212d6eb
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-replyall.png
new file mode 100644
index 00000000..4eec5a28
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-100/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-forward.png
new file mode 100644
index 00000000..9b6f9bc0
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-junk.png
new file mode 100644
index 00000000..6bdb71c4
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-reply.png
new file mode 100644
index 00000000..8babc787
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-replyall.png
new file mode 100644
index 00000000..b93039b4
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-125/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-forward.png
new file mode 100644
index 00000000..a10134b0
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-junk.png
new file mode 100644
index 00000000..90f992af
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-reply.png
new file mode 100644
index 00000000..f8ff82d1
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-replyall.png
new file mode 100644
index 00000000..e73efc66
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-150/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-forward.png
new file mode 100644
index 00000000..0abf2501
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-junk.png
new file mode 100644
index 00000000..7f32d4bc
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-reply.png
new file mode 100644
index 00000000..502d0055
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-replyall.png
new file mode 100644
index 00000000..9ed846f8
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-200/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-forward.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-forward.png
new file mode 100644
index 00000000..5279390a
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-forward.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-junk.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-junk.png
new file mode 100644
index 00000000..e0c791b4
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-junk.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-reply.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-reply.png
new file mode 100644
index 00000000..fad78de3
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-reply.png differ
diff --git a/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-replyall.png b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-replyall.png
new file mode 100644
index 00000000..2887def3
Binary files /dev/null and b/Wino.Mail.WinUI/Assets/NotificationIcons/theme-light/scale-400/mail-replyall.png differ
diff --git a/Wino.Mail.WinUI/Services/NavigationService.cs b/Wino.Mail.WinUI/Services/NavigationService.cs
index cdf45cca..233df6e3 100644
--- a/Wino.Mail.WinUI/Services/NavigationService.cs
+++ b/Wino.Mail.WinUI/Services/NavigationService.cs
@@ -79,6 +79,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.AboutPage,
WinoPage.PersonalizationPage,
WinoPage.MessageListPage,
+ WinoPage.MailNotificationSettingsPage,
WinoPage.ReadComposePanePage,
WinoPage.AppPreferencesPage,
WinoPage.AliasManagementPage,
@@ -142,6 +143,7 @@ public class NavigationService : NavigationServiceBase, INavigationService
WinoPage.AboutPage => typeof(AboutPage),
WinoPage.PersonalizationPage => typeof(PersonalizationPage),
WinoPage.MessageListPage => typeof(MessageListPage),
+ WinoPage.MailNotificationSettingsPage => typeof(MailNotificationSettingsPage),
WinoPage.ReadComposePanePage => typeof(ReadComposePanePage),
WinoPage.MailRenderingPage => typeof(MailRenderingPage),
WinoPage.ComposePage => typeof(ComposePage),
diff --git a/Wino.Mail.WinUI/Services/NotificationBuilder.cs b/Wino.Mail.WinUI/Services/NotificationBuilder.cs
index 3a134f50..63813f09 100644
--- a/Wino.Mail.WinUI/Services/NotificationBuilder.cs
+++ b/Wino.Mail.WinUI/Services/NotificationBuilder.cs
@@ -17,6 +17,7 @@ using Wino.Core.Domain.Entities.Shared;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Extensions;
using Wino.Core.Domain.Interfaces;
+using Wino.Helpers;
using Wino.Mail.WinUI.Activation;
using Wino.Messaging.UI;
@@ -26,6 +27,16 @@ public class NotificationBuilder : INotificationBuilder
{
private const string NotificationIconRootUri = "ms-appx:///Assets/NotificationIcons/";
private static int _calendarTaskbarBadgeCount;
+ private static readonly MailOperation[] SupportedMailNotificationActions =
+ [
+ MailOperation.MarkAsRead,
+ MailOperation.SoftDelete,
+ MailOperation.MoveToJunk,
+ MailOperation.Archive,
+ MailOperation.Reply,
+ MailOperation.ReplyAll,
+ MailOperation.Forward
+ ];
private readonly IAccountService _accountService;
private readonly IFolderService _folderService;
@@ -76,6 +87,7 @@ public class NotificationBuilder : INotificationBuilder
builder.AddText(Translator.Notifications_MultipleNotificationsTitle);
builder.AddText(string.Format(Translator.Notifications_MultipleNotificationsMessage, mailCount));
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
+ builder.AddButton(CreateDismissButton());
builder.SetAudioUri(new Uri("ms-winsoundevent:Notification.Mail"));
ShowNotification(builder);
@@ -167,6 +179,7 @@ public class NotificationBuilder : INotificationBuilder
builder.AddButton(new AppNotificationButton(Translator.Buttons_FixAccount)
.AddArgument(Constants.ToastMailAccountIdKey, account.Id.ToString())
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail));
+ builder.AddButton(CreateDismissButton());
ShowNotification(builder);
}
@@ -177,6 +190,7 @@ public class NotificationBuilder : INotificationBuilder
builder.AddText(Translator.Exception_WebView2RuntimeMissing_Title);
builder.AddText(Translator.Exception_WebView2RuntimeMissing_Message);
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
+ builder.AddButton(CreateDismissButton());
ShowNotification(builder);
}
@@ -188,6 +202,7 @@ public class NotificationBuilder : INotificationBuilder
builder.AddText(Translator.Notifications_StoreUpdateAvailableMessage);
builder.AddArgument(Constants.ToastStoreUpdateActionKey, Constants.ToastStoreUpdateActionInstall);
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
+ builder.AddButton(CreateDismissButton());
ShowNotification(builder, "store-update-available");
}
@@ -255,6 +270,8 @@ public class NotificationBuilder : INotificationBuilder
.AddArgument(Constants.ToastModeKey, Constants.ToastModeCalendar));
}
+ builder.AddButton(CreateDismissButton());
+
var tag = $"calendar-reminder-{calendarItem.Id:N}-{reminderDurationInSeconds}";
ShowNotification(builder, tag);
@@ -288,9 +305,11 @@ public class NotificationBuilder : INotificationBuilder
builder.AddArgument(Constants.ToastMailUniqueIdKey, mailItem.UniqueId.ToString());
builder.AddArgument(Constants.ToastActionKey, MailOperation.Navigate.ToString());
builder.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
- builder.AddButton(GetMarkAsReadButton(mailItem.UniqueId));
- builder.AddButton(GetDeleteButton(mailItem.UniqueId));
- builder.AddButton(GetArchiveButton(mailItem.UniqueId));
+
+ var (firstAction, secondAction) = GetConfiguredMailNotificationActions();
+ builder.AddButton(CreateMailNotificationActionButton(firstAction, mailItem.UniqueId));
+ builder.AddButton(CreateMailNotificationActionButton(secondAction, mailItem.UniqueId));
+ builder.AddButton(CreateDismissButton());
builder.SetAudioUri(new Uri("ms-winsoundevent:Notification.Mail"));
ShowNotification(builder, mailItem.UniqueId.ToString());
@@ -347,26 +366,55 @@ public class NotificationBuilder : INotificationBuilder
return string.Format(Translator.CalendarReminder_StartedMinutesAgo, minutesAgo);
}
- private AppNotificationButton GetArchiveButton(Guid mailUniqueId)
- => new AppNotificationButton(Translator.MailOperation_Archive)
- .SetIcon(GetNotificationIconUri("mail-archive"))
+ private (MailOperation FirstAction, MailOperation SecondAction) GetConfiguredMailNotificationActions()
+ {
+ var firstAction = ResolveMailNotificationAction(_preferencesService.FirstMailNotificationAction, MailOperation.MarkAsRead);
+ var secondAction = ResolveMailNotificationAction(_preferencesService.SecondMailNotificationAction, MailOperation.SoftDelete);
+
+ if (secondAction == firstAction)
+ {
+ secondAction = SupportedMailNotificationActions.First(action => action != firstAction);
+ }
+
+ return (firstAction, secondAction);
+ }
+
+ private static MailOperation ResolveMailNotificationAction(MailOperation configuredAction, MailOperation fallbackAction)
+ => SupportedMailNotificationActions.Contains(configuredAction) ? configuredAction : fallbackAction;
+
+ private AppNotificationButton CreateMailNotificationActionButton(MailOperation action, Guid mailUniqueId)
+ {
+ var button = new AppNotificationButton(XamlHelpers.GetOperationString(action))
.AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
- .AddArgument(Constants.ToastActionKey, MailOperation.Archive.ToString())
+ .AddArgument(Constants.ToastActionKey, action.ToString())
.AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
- private AppNotificationButton GetDeleteButton(Guid mailUniqueId)
- => new AppNotificationButton(Translator.MailOperation_Delete)
- .SetIcon(GetNotificationIconUri("mail-delete"))
- .AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
- .AddArgument(Constants.ToastActionKey, MailOperation.SoftDelete.ToString())
- .AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
+ var iconUri = GetMailActionIconUri(action);
+ if (iconUri != null)
+ {
+ button.SetIcon(iconUri);
+ }
- private AppNotificationButton GetMarkAsReadButton(Guid mailUniqueId)
- => new AppNotificationButton(Translator.MailOperation_MarkAsRead)
- .SetIcon(GetNotificationIconUri("mail-markread"))
- .AddArgument(Constants.ToastMailUniqueIdKey, mailUniqueId.ToString())
- .AddArgument(Constants.ToastActionKey, MailOperation.MarkAsRead.ToString())
- .AddArgument(Constants.ToastModeKey, Constants.ToastModeMail);
+ return button;
+ }
+
+ private static Uri? GetMailActionIconUri(MailOperation action)
+ => action switch
+ {
+ MailOperation.Archive => GetNotificationIconUri("mail-archive"),
+ MailOperation.SoftDelete => GetNotificationIconUri("mail-delete"),
+ MailOperation.MarkAsRead => GetNotificationIconUri("mail-markread"),
+ MailOperation.MoveToJunk => GetNotificationIconUri("mail-junk"),
+ MailOperation.Reply => GetNotificationIconUri("mail-reply"),
+ MailOperation.ReplyAll => GetNotificationIconUri("mail-replyall"),
+ MailOperation.Forward => GetNotificationIconUri("mail-forward"),
+ _ => null
+ };
+
+ private static AppNotificationButton CreateDismissButton()
+ => new AppNotificationButton(Translator.Buttons_Dismiss)
+ .SetIcon(GetNotificationIconUri("dismiss"))
+ .AddArgument(Constants.ToastDismissActionKey, bool.TrueString);
private static AppNotificationBuilder CreateBuilder(AppNotificationScenario scenario = AppNotificationScenario.Default)
=> new AppNotificationBuilder().SetScenario(scenario);
diff --git a/Wino.Mail.WinUI/Services/PreferencesService.cs b/Wino.Mail.WinUI/Services/PreferencesService.cs
index cc1ed9bf..d7d3feb3 100644
--- a/Wino.Mail.WinUI/Services/PreferencesService.cs
+++ b/Wino.Mail.WinUI/Services/PreferencesService.cs
@@ -237,6 +237,18 @@ public class PreferencesService(IConfigurationService configurationService) : Ob
set => SaveProperty(propertyName: nameof(StartupEntityId), value);
}
+ public MailOperation FirstMailNotificationAction
+ {
+ get => _configurationService.Get(nameof(FirstMailNotificationAction), MailOperation.MarkAsRead);
+ set => SetPropertyAndSave(nameof(FirstMailNotificationAction), value);
+ }
+
+ public MailOperation SecondMailNotificationAction
+ {
+ get => _configurationService.Get(nameof(SecondMailNotificationAction), MailOperation.SoftDelete);
+ set => SetPropertyAndSave(nameof(SecondMailNotificationAction), value);
+ }
+
public AppLanguage CurrentLanguage
{
get => _configurationService.Get(nameof(CurrentLanguage), TranslationService.DefaultAppLanguage);
diff --git a/Wino.Mail.WinUI/Views/Abstract/MailNotificationSettingsPageAbstract.cs b/Wino.Mail.WinUI/Views/Abstract/MailNotificationSettingsPageAbstract.cs
new file mode 100644
index 00000000..132714e3
--- /dev/null
+++ b/Wino.Mail.WinUI/Views/Abstract/MailNotificationSettingsPageAbstract.cs
@@ -0,0 +1,5 @@
+using Wino.Mail.ViewModels;
+
+namespace Wino.Views.Abstract;
+
+public abstract class MailNotificationSettingsPageAbstract : SettingsPageBase { }
diff --git a/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml b/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml
new file mode 100644
index 00000000..034d5582
--- /dev/null
+++ b/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml.cs b/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml.cs
new file mode 100644
index 00000000..bb160fe5
--- /dev/null
+++ b/Wino.Mail.WinUI/Views/Settings/MailNotificationSettingsPage.xaml.cs
@@ -0,0 +1,11 @@
+using Wino.Views.Abstract;
+
+namespace Wino.Views.Settings;
+
+public sealed partial class MailNotificationSettingsPage : MailNotificationSettingsPageAbstract
+{
+ public MailNotificationSettingsPage()
+ {
+ InitializeComponent();
+ }
+}