New startup window.
This commit is contained in:
+141
-11
@@ -21,14 +21,17 @@ using Wino.Core.Domain.Enums;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
using Wino.Core.Domain.Models.Calendar;
|
||||
using Wino.Core.Domain.Models.MailItem;
|
||||
using Wino.Core.Domain.Models.Navigation;
|
||||
using Wino.Core.Domain.Models.Synchronization;
|
||||
using Wino.Core.Domain.Models.Updates;
|
||||
using Wino.Mail.Services;
|
||||
using Wino.Mail.ViewModels;
|
||||
using Wino.Mail.WinUI.Activation;
|
||||
using Wino.Mail.WinUI.Interfaces;
|
||||
using Wino.Mail.WinUI.Models;
|
||||
using Wino.Mail.WinUI.Services;
|
||||
using Wino.Messaging.Client.Accounts;
|
||||
using Wino.Messaging.Client.Navigation;
|
||||
using Wino.Messaging.Server;
|
||||
using Wino.Messaging.UI;
|
||||
using Wino.Services;
|
||||
@@ -37,13 +40,16 @@ namespace Wino.Mail.WinUI;
|
||||
|
||||
public partial class App : WinoApplication,
|
||||
IRecipient<NewMailSynchronizationRequested>,
|
||||
IRecipient<NewCalendarSynchronizationRequested>
|
||||
IRecipient<NewCalendarSynchronizationRequested>,
|
||||
IRecipient<AccountCreatedMessage>,
|
||||
IRecipient<GetStartedFromWelcomeRequested>
|
||||
{
|
||||
private const int InboxSyncsPerFullSync = 20;
|
||||
private const string ToggleDefaultModeLaunchArgument = "--mode=toggle-default";
|
||||
private ISynchronizationManager? _synchronizationManager;
|
||||
private IPreferencesService? _preferencesService;
|
||||
private IAccountService? _accountService;
|
||||
private bool _windowManagerConfigured;
|
||||
private CancellationTokenSource? _autoSynchronizationLoopCts;
|
||||
private readonly SemaphoreSlim _autoSynchronizationSemaphore = new(1, 1);
|
||||
private readonly Dictionary<Guid, int> _inboxSyncCounters = [];
|
||||
@@ -58,6 +64,52 @@ public partial class App : WinoApplication,
|
||||
RegisterRecipients();
|
||||
}
|
||||
|
||||
private void EnsureWindowManagerConfigured()
|
||||
{
|
||||
if (_windowManagerConfigured)
|
||||
return;
|
||||
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
windowManager.ActiveWindowChanged -= OnActiveWindowChanged;
|
||||
windowManager.ActiveWindowChanged += OnActiveWindowChanged;
|
||||
windowManager.WindowRemoved -= OnManagedWindowRemoved;
|
||||
windowManager.WindowRemoved += OnManagedWindowRemoved;
|
||||
|
||||
var nativeAppService = Services.GetRequiredService<INativeAppService>();
|
||||
nativeAppService.GetCoreWindowHwnd = () =>
|
||||
{
|
||||
var window = windowManager.ActiveWindow
|
||||
?? windowManager.GetWindow(WinoWindowKind.Shell)
|
||||
?? windowManager.GetWindow(WinoWindowKind.Welcome)
|
||||
?? MainWindow;
|
||||
|
||||
return window == null
|
||||
? IntPtr.Zero
|
||||
: WinRT.Interop.WindowNative.GetWindowHandle(window);
|
||||
};
|
||||
|
||||
_windowManagerConfigured = true;
|
||||
}
|
||||
|
||||
private void OnActiveWindowChanged(object? sender, WindowEx? window)
|
||||
{
|
||||
if (window == null)
|
||||
return;
|
||||
|
||||
MainWindow = window;
|
||||
InitializeNavigationDispatcher();
|
||||
}
|
||||
|
||||
private void OnManagedWindowRemoved(object? sender, WindowEx window)
|
||||
{
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
MainWindow = windowManager.ActiveWindow
|
||||
?? windowManager.GetWindow(WinoWindowKind.Shell)
|
||||
?? windowManager.GetWindow(WinoWindowKind.Welcome);
|
||||
|
||||
InitializeNavigationDispatcher();
|
||||
}
|
||||
|
||||
public bool IsNotificationActivation(out AppNotificationActivatedEventArgs args)
|
||||
{
|
||||
var activationArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
@@ -93,6 +145,7 @@ public partial class App : WinoApplication,
|
||||
services.AddTransient(typeof(MailRenderingPageViewModel));
|
||||
services.AddTransient(typeof(AccountManagementViewModel));
|
||||
services.AddTransient(typeof(WelcomePageViewModel));
|
||||
services.AddTransient(typeof(WelcomePageV2ViewModel));
|
||||
|
||||
services.AddTransient(typeof(ComposePageViewModel));
|
||||
services.AddTransient(typeof(IdlePageViewModel));
|
||||
@@ -153,11 +206,22 @@ public partial class App : WinoApplication,
|
||||
_synchronizationManager = Services.GetRequiredService<ISynchronizationManager>();
|
||||
_preferencesService = Services.GetRequiredService<IPreferencesService>();
|
||||
_accountService = Services.GetRequiredService<IAccountService>();
|
||||
EnsureWindowManagerConfigured();
|
||||
|
||||
var hasAnyAccount = (await _accountService.GetAccountsAsync()).Any();
|
||||
if (!IsStartupTaskLaunch() && !hasAnyAccount)
|
||||
{
|
||||
CreateWelcomeWindow();
|
||||
await NewThemeService.InitializeAsync();
|
||||
MainWindow?.Activate();
|
||||
LogActivation("Welcome window created and activated.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether the new version requires a migration before starting sync.
|
||||
var updateManager = Services.GetRequiredService<IUpdateManager>();
|
||||
var updateNotes = await updateManager.GetLatestUpdateNotesAsync();
|
||||
bool hasPendingMigration = updateNotes.HasMigrations && updateManager.HasPendingMigrations();
|
||||
bool hasPendingMigration = updateNotes.HasPendingMigrations && updateManager.HasPendingMigrations();
|
||||
|
||||
_preferencesService.PreferenceChanged -= PreferencesServiceChanged;
|
||||
_preferencesService.PreferenceChanged += PreferencesServiceChanged;
|
||||
@@ -462,10 +526,19 @@ public partial class App : WinoApplication,
|
||||
// Initialize theme service after window is created.
|
||||
await NewThemeService.InitializeAsync();
|
||||
|
||||
MainWindow?.Activate();
|
||||
if (MainWindow != null)
|
||||
Services.GetRequiredService<IWinoWindowManager>().ActivateWindow(MainWindow);
|
||||
|
||||
LogActivation("Window created and activated.");
|
||||
}
|
||||
|
||||
public Task OpenManageAccountsFromWelcomeAsync()
|
||||
{
|
||||
Services.GetRequiredService<INavigationService>()
|
||||
.Navigate(WinoPage.ManageAccountsPage, null, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.DrillIn);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the main window without activating it.
|
||||
/// Used for both normal launch and startup task launch (tray only).
|
||||
@@ -474,15 +547,15 @@ public partial class App : WinoApplication,
|
||||
{
|
||||
LogActivation("Creating main window.");
|
||||
|
||||
MainWindow = new ShellWindow();
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
MainWindow = windowManager.CreateWindow(WinoWindowKind.Shell, () => new ShellWindow());
|
||||
InitializeNavigationDispatcher();
|
||||
|
||||
var nativeAppService = Services.GetRequiredService<INativeAppService>();
|
||||
nativeAppService.GetCoreWindowHwnd = () => WinRT.Interop.WindowNative.GetWindowHandle(MainWindow);
|
||||
|
||||
if (MainWindow is not IWinoShellWindow shellWindow)
|
||||
throw new ArgumentException("MainWindow must implement IWinoShellWindow");
|
||||
|
||||
windowManager.SetPrimaryNavigationFrame(WinoWindowKind.Shell, shellWindow.GetMainFrame());
|
||||
|
||||
var activationArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
|
||||
if (activationArgs.Kind == ExtendedActivationKind.Launch &&
|
||||
@@ -508,6 +581,21 @@ public partial class App : WinoApplication,
|
||||
shellWindow.HandleAppActivation(args?.Arguments, GetCurrentLaunchTileId(), Environment.CommandLine);
|
||||
}
|
||||
|
||||
private void CreateWelcomeWindow()
|
||||
{
|
||||
LogActivation("Creating welcome window.");
|
||||
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
MainWindow = windowManager.CreateWindow(WinoWindowKind.Welcome, () => new WelcomeWindow());
|
||||
if (MainWindow is WelcomeWindow welcomeWindow)
|
||||
windowManager.SetPrimaryNavigationFrame(WinoWindowKind.Welcome, welcomeWindow.GetRootFrame());
|
||||
|
||||
InitializeNavigationDispatcher();
|
||||
|
||||
Services.GetRequiredService<INavigationService>()
|
||||
.Navigate(WinoPage.WelcomePageV2, null, NavigationReferenceFrame.ShellFrame, NavigationTransitionType.None);
|
||||
}
|
||||
|
||||
private void InitializeNavigationDispatcher()
|
||||
{
|
||||
if (MainWindow == null)
|
||||
@@ -521,18 +609,25 @@ public partial class App : WinoApplication,
|
||||
|
||||
private void EnsureMainWindowVisibleAndForeground()
|
||||
{
|
||||
if (MainWindow == null)
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
var currentWindow = windowManager.ActiveWindow
|
||||
?? windowManager.GetWindow(WinoWindowKind.Shell)
|
||||
?? windowManager.GetWindow(WinoWindowKind.Welcome)
|
||||
?? MainWindow;
|
||||
|
||||
if (currentWindow == null)
|
||||
return;
|
||||
|
||||
MainWindow.Show();
|
||||
MainWindow.BringToFront();
|
||||
MainWindow.Activate();
|
||||
MainWindow = currentWindow;
|
||||
windowManager.ActivateWindow(currentWindow);
|
||||
}
|
||||
|
||||
private void RegisterRecipients()
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register<NewMailSynchronizationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<NewCalendarSynchronizationRequested>(this);
|
||||
WeakReferenceMessenger.Default.Register<AccountCreatedMessage>(this);
|
||||
WeakReferenceMessenger.Default.Register<GetStartedFromWelcomeRequested>(this);
|
||||
}
|
||||
|
||||
public async void Receive(NewMailSynchronizationRequested message)
|
||||
@@ -585,6 +680,41 @@ public partial class App : WinoApplication,
|
||||
}
|
||||
}
|
||||
|
||||
public void Receive(AccountCreatedMessage message)
|
||||
{
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
|
||||
// Only transition when the account was created from the WelcomeWindow.
|
||||
if (windowManager.GetWindow(WinoWindowKind.Welcome) == null)
|
||||
return;
|
||||
|
||||
MainWindow?.DispatcherQueue?.TryEnqueue(async () =>
|
||||
{
|
||||
// Create and activate ShellWindow — ActiveWindowChanged fires and rebinds the dispatcher.
|
||||
CreateWindow(null);
|
||||
windowManager.HideWindow(WinoWindowKind.Welcome);
|
||||
await NewThemeService.ApplyThemeToActiveWindowAsync();
|
||||
MainWindow?.Activate();
|
||||
RestartAutoSynchronizationLoop();
|
||||
});
|
||||
}
|
||||
|
||||
public void Receive(GetStartedFromWelcomeRequested message)
|
||||
{
|
||||
var windowManager = Services.GetRequiredService<IWinoWindowManager>();
|
||||
|
||||
if (windowManager.GetWindow(WinoWindowKind.Welcome) == null)
|
||||
return;
|
||||
|
||||
MainWindow?.DispatcherQueue?.TryEnqueue(async () =>
|
||||
{
|
||||
CreateWindow(null);
|
||||
windowManager.HideWindow(WinoWindowKind.Welcome);
|
||||
await NewThemeService.ApplyThemeToActiveWindowAsync();
|
||||
MainWindow?.Activate();
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetSynchronizationFailureMessage(MailSynchronizationType synchronizationType, string? exceptionMessage)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(exceptionMessage))
|
||||
|
||||
Reference in New Issue
Block a user