diff --git a/LehrerApp.Desktop/App.axaml.cs b/LehrerApp.Desktop/App.axaml.cs index aa8d80a..ea26c44 100644 --- a/LehrerApp.Desktop/App.axaml.cs +++ b/LehrerApp.Desktop/App.axaml.cs @@ -1,7 +1,9 @@ using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Styling; +using Avalonia.Threading; using LehrerApp.Core.Interfaces; using LehrerApp.Core.Models; using LehrerApp.Core.Services; @@ -38,32 +40,45 @@ public class App : Application if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - // Verschlüsselte Datenbank (13.3.4): Passwort abfragen, bevor die Datenbank - // (und damit BuildServices, das sie öffnet) angefasst wird. - if (AppBootstrapper.IsDbEncrypted()) - { - var promptVm = new DbPasswordPromptViewModel( - new DatabaseEncryptionService(), AppBootstrapper.ResolveDbPath()); - var promptWindow = new DbPasswordPromptWindow { DataContext = promptVm }; - promptVm.OnUnlocked = password => - { - AppBootstrapper.DbPassword = password; - StartMainApp(desktop, showImmediately: true); - promptWindow.Close(); - }; - desktop.MainWindow = promptWindow; - } - else - { - StartMainApp(desktop, showImmediately: false); - } + // Erst den Splashscreen anzeigen und die synchrone Initialisierung in den ersten + // Dispatcher-Durchlauf verschieben, damit das Ladebild vorher gezeichnet wird. + var splash = new SplashWindow(); + desktop.MainWindow = splash; + Dispatcher.UIThread.Post( + () => ContinueStartup(desktop, splash), + DispatcherPriority.Background); } base.OnFrameworkInitializationCompleted(); } + private static void ContinueStartup( + IClassicDesktopStyleApplicationLifetime desktop, SplashWindow splash) + { + // Verschlüsselte Datenbank (13.3.4): Passwort abfragen, bevor die Datenbank + // (und damit BuildServices, das sie öffnet) angefasst wird. + if (AppBootstrapper.IsDbEncrypted()) + { + var promptVm = new DbPasswordPromptViewModel( + new DatabaseEncryptionService(), AppBootstrapper.ResolveDbPath()); + var promptWindow = new DbPasswordPromptWindow { DataContext = promptVm }; + promptVm.OnUnlocked = password => + { + AppBootstrapper.DbPassword = password; + StartMainApp(desktop, splash); + promptWindow.Close(); + }; + desktop.MainWindow = promptWindow; + promptWindow.Show(); + splash.Close(); + return; + } + + StartMainApp(desktop, splash); + } + private static void StartMainApp( - IClassicDesktopStyleApplicationLifetime desktop, bool showImmediately) + IClassicDesktopStyleApplicationLifetime desktop, Window? windowToClose = null) { _serviceProvider = AppBootstrapper.BuildServices(); Services = _serviceProvider; @@ -96,7 +111,8 @@ public class App : Application if (Services.GetService() is { } syncEngine) main.EnableFinalSync(syncEngine); desktop.MainWindow = main; - if (showImmediately) main.Show(); + main.Show(); + windowToClose?.Close(); } /// Wechselt die Darstellung sofort, ohne Neustart (12.4) — Avalonia stylt den diff --git a/LehrerApp.Desktop/Assets/SplashScreen.png b/LehrerApp.Desktop/Assets/SplashScreen.png new file mode 100644 index 0000000..edfbcb8 Binary files /dev/null and b/LehrerApp.Desktop/Assets/SplashScreen.png differ diff --git a/LehrerApp.Desktop/Views/SplashWindow.axaml b/LehrerApp.Desktop/Views/SplashWindow.axaml new file mode 100644 index 0000000..4e5e58f --- /dev/null +++ b/LehrerApp.Desktop/Views/SplashWindow.axaml @@ -0,0 +1,14 @@ + + + diff --git a/LehrerApp.Desktop/Views/SplashWindow.axaml.cs b/LehrerApp.Desktop/Views/SplashWindow.axaml.cs new file mode 100644 index 0000000..3f46413 --- /dev/null +++ b/LehrerApp.Desktop/Views/SplashWindow.axaml.cs @@ -0,0 +1,8 @@ +using Avalonia.Controls; + +namespace LehrerApp.Desktop.Views; + +public partial class SplashWindow : Window +{ + public SplashWindow() => InitializeComponent(); +}