Files

140 lines
4.6 KiB
C#
Raw Permalink Normal View History

using System.Windows;
using System.Windows.Controls;
using EngineeringSync.TrayApp.Services;
using EngineeringSync.TrayApp.ViewModels;
using EngineeringSync.TrayApp.Views;
using H.NotifyIcon;
namespace EngineeringSync.TrayApp;
public partial class App : Application
{
private TaskbarIcon? _trayIcon;
private SignalRService? _signalR;
private ApiClient? _apiClient;
private PendingChangesWindow? _pendingChangesWindow;
private PendingChangesViewModel? _pendingChangesViewModel;
protected override async void OnStartup(StartupEventArgs e)
{
try
{
base.OnStartup(e);
_apiClient = new ApiClient(new System.Net.Http.HttpClient());
_signalR = new SignalRService();
// TaskbarIcon aus XAML-Resource laden (wird dadurch korrekt im Shell registriert)
_trayIcon = (TaskbarIcon)FindResource("TrayIcon");
_trayIcon.ContextMenu = BuildContextMenu();
// ForceCreate() aufrufen, um sicherzustellen dass das Icon im System Tray erscheint
_trayIcon.ForceCreate(enablesEfficiencyMode: false);
_signalR.ChangeNotificationReceived += OnChangeNotificationReceived;
_signalR.ChangeNotificationReceived += OnPendingChangesWindowNotification;
try { await _signalR.ConnectAsync(); }
catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[TrayApp] SignalR Connect Fehler: {ex}"); }
}
catch (Exception ex)
{
// Debug-Fehlerbehandlung für Icon-Initialisierung
MessageBox.Show(
$"Fehler bei der Initialisierung des Tray Icons:\n\n{ex.Message}\n\n{ex.StackTrace}",
"EngineeringSync Startup Error",
MessageBoxButton.OK,
MessageBoxImage.Error);
throw;
}
}
private ContextMenu BuildContextMenu()
{
var menu = new ContextMenu();
var showChanges = new MenuItem { Header = "Änderungen anzeigen" };
showChanges.Click += (_, _) => OpenChangesWindow();
menu.Items.Add(showChanges);
var showProjects = new MenuItem { Header = "Projekte verwalten" };
showProjects.Click += (_, _) => OpenProjectsWindow();
menu.Items.Add(showProjects);
menu.Items.Add(new Separator());
var exit = new MenuItem { Header = "Beenden" };
exit.Click += (_, _) => ExitApp();
menu.Items.Add(exit);
return menu;
}
private void OpenChangesWindow()
{
// Fenster beim ersten Mal erstellen
if (_pendingChangesWindow is null)
{
_pendingChangesViewModel = new PendingChangesViewModel(_apiClient!);
_pendingChangesWindow = new PendingChangesWindow(_pendingChangesViewModel);
}
// Fenster anzeigen/aktivieren
_pendingChangesWindow.Show();
_pendingChangesWindow.Activate();
_ = _pendingChangesViewModel!.LoadProjectsCommand.ExecuteAsync(null);
}
private void OpenProjectsWindow()
{
var existing = Windows.OfType<ProjectManagementWindow>().FirstOrDefault();
if (existing is not null) { existing.Activate(); return; }
var vm = new ProjectManagementViewModel(_apiClient!);
var window = new ProjectManagementWindow(vm);
window.Show();
_ = vm.LoadCommand.ExecuteAsync(null);
}
private void OnChangeNotificationReceived(Guid projectId, string projectName, int count)
{
Dispatcher.Invoke(() =>
{
_trayIcon?.ShowNotification(
title: "Neue Engineering-Daten",
message: $"Projekt \"{projectName}\": {count} ausstehende Änderung(en).");
});
}
private void OnPendingChangesWindowNotification(Guid projectId, string projectName, int count)
{
// Handler für PendingChangesWindow: nur aktualisieren wenn Fenster sichtbar ist
if (_pendingChangesWindow?.IsVisible == true && _pendingChangesViewModel is not null)
{
Dispatcher.Invoke(() => _ = _pendingChangesViewModel.LoadChangesCommand.ExecuteAsync(null));
}
}
private async void ExitApp()
{
if (_signalR is not null)
{
await _signalR.DisposeAsync();
_signalR = null;
}
_trayIcon?.Dispose();
Shutdown();
}
protected override async void OnExit(ExitEventArgs e)
{
if (_signalR is not null)
{
await _signalR.DisposeAsync();
_signalR = null;
}
_trayIcon?.Dispose();
base.OnExit(e);
}
}