using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Threading; namespace Lumi.Companion.App; public partial class App : Application { private TrayIcon? _trayIcon; private MainWindow? _mainWindow; public override void Initialize() => AvaloniaXamlLoader.Load(this); public override void OnFrameworkInitializationCompleted() { if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown; var paths = CompanionPaths.ForCurrentUser(); var settings = new CompanionSettingsStore(paths.SettingsPath); var runtime = new CompanionRuntime(paths, settings); _mainWindow = new MainWindow(runtime, settings); desktop.MainWindow = _mainWindow; ConfigureTray(desktop, runtime); runtime.UpdateRestartRequested += async () => { _mainWindow.AllowExit(); _trayIcon?.Dispose(); await runtime.DisposeAsync(); desktop.Shutdown(); }; Program.InstanceCoordinator!.ActivationRequested += () => Dispatcher.UIThread.Post(ShowMainWindow); if (!Program.LaunchInBackground) _mainWindow.Show(); _ = runtime.InitializeAsync(); } base.OnFrameworkInitializationCompleted(); } private void ConfigureTray(IClassicDesktopStyleApplicationLifetime desktop, CompanionRuntime runtime) { var open = new NativeMenuItem("Open Lumi Companion"); var test = new NativeMenuItem("Run transcription test"); var health = new NativeMenuItem("Health: Starting") { IsEnabled = false }; var update = new NativeMenuItem("Updates: Checking…") { IsEnabled = false }; var web = new NativeMenuItem("Open Lumi WebUI"); var quit = new NativeMenuItem("Quit"); open.Click += (_, _) => ShowMainWindow(); test.Click += async (_, _) => { ShowMainWindow(); _mainWindow?.ShowPage(CompanionPage.Test); await runtime.RunTestAsync(); }; web.Click += (_, _) => runtime.OpenLumiWebUi(); update.Click += (_, _) => { ShowMainWindow(); _mainWindow?.ShowPage(CompanionPage.Overview); }; quit.Click += async (_, _) => { if (runtime.State.RequiresQuitConfirmation) ShowMainWindow(); if (_mainWindow is null || !await _mainWindow.ConfirmQuitAsync()) return; _mainWindow.AllowExit(); _trayIcon?.Dispose(); await runtime.DisposeAsync(); desktop.Shutdown(); }; _trayIcon = new TrayIcon { Icon = LumiIconFactory.Create(TrayHealth.Ready), ToolTipText = "Lumi Companion — starting", IsVisible = true, Menu = new NativeMenu { Items = { open, test, web, health, update, new NativeMenuItemSeparator(), quit } } }; _trayIcon.Clicked += (_, _) => ShowMainWindow(); TrayIcon.SetIcons(this, new TrayIcons { _trayIcon }); runtime.StateChanged += state => Dispatcher.UIThread.Post(() => { if (_trayIcon is null) return; _trayIcon.Icon = LumiIconFactory.Create(state.Health); _trayIcon.ToolTipText = state.UpdateAvailable ? $"Lumi Companion — update {state.AvailableVersion} available" : $"Lumi Companion — {state.Summary}"; health.Header = $"Health: {state.Summary}"; update.Header = state.UpdateAvailable ? $"Update available: {state.AvailableVersion}" : "Updates: Current"; update.IsEnabled = state.UpdateAvailable; test.Header = state.TestRunning ? "Transcription test running…" : "Run transcription test"; test.IsEnabled = !state.TestRunning; }); } private void ShowMainWindow() { if (_mainWindow is null) return; _mainWindow.Show(); _mainWindow.WindowState = WindowState.Normal; _mainWindow.Activate(); } }