Custom print dialog and better message registrations

This commit is contained in:
Burak Kaan Köse
2025-10-21 01:27:29 +02:00
parent 4191b7314f
commit 057edb5488
27 changed files with 656 additions and 760 deletions
+8 -3
View File
@@ -15,7 +15,7 @@ namespace Wino.Mail.WinUI;
public partial class App : WinoApplication, IRecipient<NewMailSynchronizationRequested>
{
private ISynchronizationManager _synchronizationManager;
private ISynchronizationManager? _synchronizationManager;
public App()
{
@@ -23,7 +23,7 @@ public partial class App : WinoApplication, IRecipient<NewMailSynchronizationReq
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
RegisterRecipients();
}
#region Dependency Injection
@@ -114,8 +114,13 @@ public partial class App : WinoApplication, IRecipient<NewMailSynchronizationReq
MainWindow.Activate();
}
private void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
}
public void Receive(NewMailSynchronizationRequested message)
{
_synchronizationManager.SynchronizeMailAsync(message.Options);
_synchronizationManager?.SynchronizeMailAsync(message.Options);
}
}
+47 -11
View File
@@ -9,6 +9,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Navigation;
using Windows.Foundation;
using Wino.Core.Domain;
using Wino.Core.Domain.Entities.Mail;
@@ -20,6 +21,7 @@ using Wino.Core.Domain.Models.Navigation;
using Wino.Core.WinUI;
using Wino.Core.WinUI.Controls;
using Wino.Extensions;
using Wino.Mail.ViewModels.Data;
using Wino.MenuFlyouts;
using Wino.MenuFlyouts.Context;
using Wino.Messaging.Client.Accounts;
@@ -37,13 +39,27 @@ public sealed partial class AppShell : AppShellAbstract,
IRecipient<InfoBarMessageRequested>
{
[GeneratedDependencyProperty]
public partial UIElement TopShellContent { get; set; }
public partial UIElement? TopShellContent { get; set; }
public AppShell() : base()
{
InitializeComponent();
}
public Frame GetShellFrame() => ShellFrame;
//protected override void OnNavigatedTo(NavigationEventArgs e)
//{
// base.OnNavigatedTo(e);
// WeakReferenceMessenger.Default.Register<InfoBarMessageRequested>(this);
// WeakReferenceMessenger.Default.Register<AccountMenuItemExtended>(this);
// WeakReferenceMessenger.Default.Register<CreateNewMailWithMultipleAccountsRequested>(this);
// WeakReferenceMessenger.Default.Register<NavigateMailFolderEvent>(this);
//}
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
}
private async void ItemDroppedOnFolder(object sender, DragEventArgs e)
{
@@ -66,14 +82,14 @@ public sealed partial class AppShell : AppShellAbstract,
foreach (var item in dragPackage.DraggingMails)
{
//if (item is MailItemViewModel singleMailItemViewModel)
//{
// mailCopies.Add(singleMailItemViewModel.MailCopy);
//}
//else if (item is ThreadMailItemViewModel threadViewModel)
//{
// mailCopies.AddRange(threadViewModel.GetMailCopies());
//}
if (item is MailItemViewModel singleMailItemViewModel)
{
mailCopies.Add(singleMailItemViewModel.MailCopy);
}
else if (item is ThreadMailItemViewModel threadViewModel)
{
mailCopies.AddRange(threadViewModel.ThreadEmails.Select(a => a.MailCopy));
}
}
await ViewModel.PerformMoveOperationAsync(mailCopies, draggingFolder);
@@ -114,7 +130,7 @@ public sealed partial class AppShell : AppShellAbstract,
// Check whether the moving item's account has at least one same as the target folder's account.
var draggedAccountIds = folderMenuItem.HandlingFolders.Select(a => a.MailAccountId);
if (!dragPackage.DraggingMails.Any(a => draggedAccountIds.Contains(a.AssignedAccount.Id))) return false;
if (!dragPackage.DraggingMails.Cast<MailCopy>().Any(a => draggedAccountIds.Contains(a.AssignedAccount.Id))) return false;
return true;
}
@@ -320,4 +336,24 @@ public sealed partial class AppShell : AppShellAbstract,
ShellFrame.Margin = new Thickness(0);
}
}
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Register<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Register<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Register<NavigateMailFolderEvent>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<InfoBarMessageRequested>(this);
WeakReferenceMessenger.Default.Unregister<AccountMenuItemExtended>(this);
WeakReferenceMessenger.Default.Unregister<CreateNewMailWithMultipleAccountsRequested>(this);
WeakReferenceMessenger.Default.Unregister<NavigateMailFolderEvent>(this);
}
}
@@ -103,9 +103,19 @@ public sealed partial class NewImapSetupDialog : ContentDialog,
public void StartImapConnectionSetup(MailAccount account) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), account, new DrillInNavigationTransitionInfo());
public void StartImapConnectionSetup(AccountCreationDialogResult accountCreationDialogResult) => ImapFrame.Navigate(typeof(WelcomeImapSetupPage), accountCreationDialogResult, new DrillInNavigationTransitionInfo());
private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args) => WeakReferenceMessenger.Default.UnregisterAll(this);
private void ImapSetupDialogClosed(ContentDialog sender, ContentDialogClosedEventArgs args)
{
WeakReferenceMessenger.Default.Unregister<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Unregister<ImapSetupDismissRequested>(this);
}
private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args) => WeakReferenceMessenger.Default.RegisterAll(this);
private void ImapSetupDialogOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
{
WeakReferenceMessenger.Default.Register<ImapSetupNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupBackNavigationRequested>(this);
WeakReferenceMessenger.Default.Register<ImapSetupDismissRequested>(this);
}
// Don't hide the dialog unless dismiss is requested from the inner pages specifically.
private void OnDialogClosing(ContentDialog sender, ContentDialogClosingEventArgs args) => args.Cancel = !isDismissRequested;
+16 -3
View File
@@ -15,7 +15,7 @@ using WinUIEx;
namespace Wino.Mail.WinUI;
public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient<ApplicationThemeChanged>
public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient<ApplicationThemeChanged>, IRecipient<TitleBarShellContentUpdated>
{
public IStatePersistanceService StatePersistanceService { get; } = WinoApplication.Current.Services.GetService<IStatePersistanceService>() ?? throw new Exception("StatePersistanceService not registered in DI container.");
public IPreferencesService PreferencesService { get; } = WinoApplication.Current.Services.GetService<IPreferencesService>() ?? throw new Exception("PreferencesService not registered in DI container.");
@@ -23,8 +23,7 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
public ShellWindow()
{
WeakReferenceMessenger.Default.Register<TitleBarShellContentUpdated>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
RegisterRecipients();
InitializeComponent();
@@ -177,10 +176,24 @@ public sealed partial class ShellWindow : WindowEx, IWinoShellWindow, IRecipient
// Clean up system tray
_systemTrayService?.Dispose();
UnregisterRecipients();
// Close the window
this.Close();
// Exit the application
Application.Current.Exit();
}
private void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<TitleBarShellContentUpdated>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
}
private void UnregisterRecipients()
{
WeakReferenceMessenger.Default.Unregister<TitleBarShellContentUpdated>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
}
}
+16 -10
View File
@@ -57,22 +57,12 @@ public sealed partial class MailListPage : MailListPageAbstract,
{
WeakReferenceMessenger.Default.Send(new ActiveMailFolderChangedEvent(folderNavigationArgs.BaseFolderMenuItem, folderNavigationArgs.FolderInitLoadAwaitTask));
}
WeakReferenceMessenger.Default.Register<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Register<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Register<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Register<DisposeRenderingFrameRequested>(this);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
WeakReferenceMessenger.Default.Unregister<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Unregister<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Unregister<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Unregister<DisposeRenderingFrameRequested>(this);
// Dispose all WinoListView items.
// MailListView.Dispose();
@@ -455,6 +445,22 @@ public sealed partial class MailListPage : MailListPageAbstract,
ViewModel.NavigationService.Navigate(WinoPage.IdlePage, null, NavigationReferenceFrame.RenderingFrame, NavigationTransitionType.DrillIn);
}
protected override void RegisterRecipients()
{
WeakReferenceMessenger.Default.Register<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Register<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Register<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Register<DisposeRenderingFrameRequested>(this);
}
protected override void UnregisterRecipients()
{
WeakReferenceMessenger.Default.Unregister<ClearMailSelectionsRequested>(this);
WeakReferenceMessenger.Default.Unregister<ActiveMailItemChangedEvent>(this);
WeakReferenceMessenger.Default.Unregister<SelectMailItemContainerEvent>(this);
WeakReferenceMessenger.Default.Unregister<DisposeRenderingFrameRequested>(this);
}
private void PageSizeChanged(object sender, SizeChangedEventArgs e)
{
ViewModel.MaxMailListLength = e.NewSize.Width - RENDERING_COLUMN_MIN_WIDTH;
+37 -19
View File
@@ -11,7 +11,9 @@ using Microsoft.UI.Xaml.Navigation;
using Microsoft.Web.WebView2.Core;
using Windows.System;
using Wino.Core.Domain;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.Printing;
using Wino.Core.WinUI.Extensions;
using Wino.Mail.ViewModels.Data;
using Wino.Mail.WinUI;
@@ -43,7 +45,7 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00FFFFFF");
Environment.SetEnvironmentVariable("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "--enable-features=OverlayScrollbar,msOverlayScrollbarWinStyle,msOverlayScrollbarWinStyleAnimation,msWebView2CodeCache");
ViewModel.ShowPrintUIAction = ShowPrintUI;
ViewModel.DirectPrintFuncAsync = DirectPrintAsync;
ViewModel.SaveHTMLasPDFFunc = new Func<string, Task<bool>>((path) =>
{
@@ -51,19 +53,25 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
});
}
private async void ShowPrintUI()
private async Task<PrintingResult> DirectPrintAsync(WebView2PrintSettingsModel settings)
{
if (Chromium.CoreWebView2 == null) return;
if (Chromium.CoreWebView2 == null) return PrintingResult.Failed;
// TODO: Footer still shows wino.mail/html, there is no way to change it currently.
// TODO: ShowPrintUI - System doesn't open.
// TODO: ShowPrintUI - System doesn't open.
try
{
var nativeSettings = settings.ToCoreWebView2PrintSettings(Chromium.CoreWebView2.Environment);
var res = await Chromium.CoreWebView2.PrintAsync(nativeSettings);
// Set the document title before printing. This title will be used in the print dialog and header.
await Chromium.CoreWebView2.ExecuteScriptAsync($"document.title = '{ViewModel.Subject}';");
var settings = Chromium.CoreWebView2.Environment.CreatePrintSettings();
Chromium.CoreWebView2?.ShowPrintUI(CoreWebView2PrintDialogKind.System);
return res switch
{
CoreWebView2PrintStatus.Succeeded => PrintingResult.Submitted,
_ => PrintingResult.Failed,
};
}
catch (Exception)
{
return PrintingResult.Failed;
}
}
public override async void OnEditorThemeChanged()
@@ -138,10 +146,6 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
{
base.OnNavigatedFrom(e);
WeakReferenceMessenger.Default.Unregister<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Unregister<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
// Disposing the page.
// Make sure the WebView2 is disposed properly.
@@ -171,10 +175,6 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
{
base.OnNavigatedTo(e);
WeakReferenceMessenger.Default.Register<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Register<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
var anim = ConnectedAnimationService.GetForCurrentView().GetAnimation("WebViewConnectedAnimation");
anim?.TryStart(Chromium);
@@ -297,4 +297,22 @@ public sealed partial class MailRenderingPage : MailRenderingPageAbstract,
hyperlinkButton.ContextFlyout.ShowAt(hyperlinkButton);
}
}
protected override void RegisterRecipients()
{
base.RegisterRecipients();
WeakReferenceMessenger.Default.Register<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Register<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Register<ApplicationThemeChanged>(this);
}
protected override void UnregisterRecipients()
{
base.UnregisterRecipients();
WeakReferenceMessenger.Default.Unregister<HtmlRenderingRequested>(this);
WeakReferenceMessenger.Default.Unregister<CancelRenderingContentRequested>(this);
WeakReferenceMessenger.Default.Unregister<ApplicationThemeChanged>(this);
}
}