From 2b1676a4f795c13efbb0c5aebc75ce0fd9f5f733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Kaan=20K=C3=B6se?= Date: Mon, 20 Apr 2026 19:40:32 +0200 Subject: [PATCH] Dispose mail webviews when closing the shell --- .../Enums/ThreeButtonDialogResult.cs | 8 +++ .../Interfaces/IMailDialogService.cs | 6 ++ .../Translations/en_US/resources.json | 2 + Wino.Mail.ViewModels/ComposePageViewModel.cs | 26 +++++++-- Wino.Mail.WinUI/Services/DialogService.cs | 35 +++++++++++ Wino.Mail.WinUI/ShellWindow.xaml.cs | 58 ++++++++++++++++++- .../Views/Mail/MailListPage.xaml.cs | 6 -- 7 files changed, 129 insertions(+), 12 deletions(-) create mode 100644 Wino.Core.Domain/Enums/ThreeButtonDialogResult.cs diff --git a/Wino.Core.Domain/Enums/ThreeButtonDialogResult.cs b/Wino.Core.Domain/Enums/ThreeButtonDialogResult.cs new file mode 100644 index 00000000..ed45ee37 --- /dev/null +++ b/Wino.Core.Domain/Enums/ThreeButtonDialogResult.cs @@ -0,0 +1,8 @@ +namespace Wino.Core.Domain.Enums; + +public enum ThreeButtonDialogResult +{ + Primary, + Secondary, + Cancel +} diff --git a/Wino.Core.Domain/Interfaces/IMailDialogService.cs b/Wino.Core.Domain/Interfaces/IMailDialogService.cs index f08a0de3..0e070f15 100644 --- a/Wino.Core.Domain/Interfaces/IMailDialogService.cs +++ b/Wino.Core.Domain/Interfaces/IMailDialogService.cs @@ -19,6 +19,12 @@ public interface IMailDialogService : IDialogServiceBase { void ShowReadOnlyCalendarMessage(); Task ShowHardDeleteConfirmationAsync(); + Task ShowThreeButtonDialogAsync(string title, + string description, + string primaryButtonText, + string secondaryButtonText, + string cancelButtonText, + WinoCustomMessageDialogIcon? icon = null); Task HandleSystemFolderConfigurationDialogAsync(Guid accountId, IFolderService folderService); // Custom dialogs diff --git a/Wino.Core.Domain/Translations/en_US/resources.json b/Wino.Core.Domain/Translations/en_US/resources.json index bc824f55..3dfd9c1f 100644 --- a/Wino.Core.Domain/Translations/en_US/resources.json +++ b/Wino.Core.Domain/Translations/en_US/resources.json @@ -305,6 +305,8 @@ "DialogMessage_DeleteRecurringSeriesTitle": "Delete Recurring Series", "DialogMessage_DiscardDraftConfirmationMessage": "This draft will be discarded. Do you want to continue?", "DialogMessage_DiscardDraftConfirmationTitle": "Discard Draft", + "DialogMessage_CloseDraftWindowConfirmationMessage": "A draft is still open. Save it before closing the window?", + "DialogMessage_CloseDraftWindowConfirmationTitle": "Close Window", "DialogMessage_EmptySubjectConfirmation": "Missing Subject", "DialogMessage_EmptySubjectConfirmationMessage": "Message has no subject. Do you want to continue?", "DialogMessage_EnableStartupLaunchDeniedMessage": "You can enable startup launch from Settings -> App Preferences.", diff --git a/Wino.Mail.ViewModels/ComposePageViewModel.cs b/Wino.Mail.ViewModels/ComposePageViewModel.cs index 0ee9033a..b5c03f66 100644 --- a/Wino.Mail.ViewModels/ComposePageViewModel.cs +++ b/Wino.Mail.ViewModels/ComposePageViewModel.cs @@ -488,6 +488,12 @@ public partial class ComposePageViewModel : MailBaseViewModel, [RelayCommand(CanExecute = nameof(canSendMail))] private async Task DiscardAsync() + => await DiscardDraftAsync(); + + public Task SaveDraftAsync() + => UpdateMimeChangesAsync(); + + public async Task DiscardDraftAsync(bool requireConfirmation = true) { if (ComposingAccount == null) { @@ -495,14 +501,19 @@ public partial class ComposePageViewModel : MailBaseViewModel, return; } - var confirmation = await _dialogService.ShowConfirmationDialogAsync(Translator.DialogMessage_DiscardDraftConfirmationMessage, - Translator.DialogMessage_DiscardDraftConfirmationTitle, - Translator.Buttons_Yes); + var confirmation = !requireConfirmation || await _dialogService.ShowConfirmationDialogAsync(Translator.DialogMessage_DiscardDraftConfirmationMessage, + Translator.DialogMessage_DiscardDraftConfirmationTitle, + Translator.Buttons_Yes); - if (confirmation) + if (!confirmation) { - isUpdatingMimeBlocked = true; + return; + } + isUpdatingMimeBlocked = true; + + try + { // Don't send delete request for local drafts. Just delete the record and mime locally. if (CurrentMailDraftItem.MailCopy.IsLocalDraft) { @@ -514,6 +525,11 @@ public partial class ComposePageViewModel : MailBaseViewModel, await _worker.ExecuteAsync(deletePackage).ConfigureAwait(false); } } + catch + { + isUpdatingMimeBlocked = false; + throw; + } } //public override void OnNavigatedFrom(NavigationMode mode, object parameters) diff --git a/Wino.Mail.WinUI/Services/DialogService.cs b/Wino.Mail.WinUI/Services/DialogService.cs index cc05bc66..61cd9fe3 100644 --- a/Wino.Mail.WinUI/Services/DialogService.cs +++ b/Wino.Mail.WinUI/Services/DialogService.cs @@ -137,6 +137,41 @@ public class DialogService : DialogServiceBase, IMailDialogService WinoCustomMessageDialogIcon.Warning, Translator.Buttons_No); + public async Task ShowThreeButtonDialogAsync(string title, + string description, + string primaryButtonText, + string secondaryButtonText, + string cancelButtonText, + WinoCustomMessageDialogIcon? icon = null) + { + var informationContainer = new CustomMessageDialogInformationContainer( + title, + description, + icon ?? WinoCustomMessageDialogIcon.Information, + false); + + var dialog = new ContentDialog + { + Style = ApplicationResourceManager.GetResource