From c93a53da512e3a51acb55961ba77ad922f3d8b19 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Sun, 19 Jul 2026 20:40:31 +0200 Subject: [PATCH] Add native OS notifications --- src/Decho/App.axaml.cs | 7 +++- src/Decho/Decho.csproj | 1 + src/Decho/Services/OsNotificationService.cs | 41 +++++++++++++++++++++ src/Decho/ViewModels/MainWindowViewModel.cs | 7 +++- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/Decho/Services/OsNotificationService.cs diff --git a/src/Decho/App.axaml.cs b/src/Decho/App.axaml.cs index 7895816..287ab0a 100644 --- a/src/Decho/App.axaml.cs +++ b/src/Decho/App.axaml.cs @@ -69,6 +69,10 @@ public partial class App : Application NotificationSoundService notificationService = new(ConfigManager.Load().Notifications); Locator.CurrentMutable.RegisterLazySingleton(() => notificationService); + OsNotificationService osNotificationService = new(); + osNotificationService.Initialize(); + Locator.CurrentMutable.RegisterLazySingleton(() => osNotificationService); + Locator.CurrentMutable.Register(() => new MainWindowViewModel( Locator.Current.GetService()!, @@ -76,6 +80,7 @@ public partial class App : Application Locator.Current.GetService()!, Locator.Current.GetService()!, Locator.Current.GetService()!, - Locator.Current.GetService()!)); + Locator.Current.GetService()!, + Locator.Current.GetService()!)); } } \ No newline at end of file diff --git a/src/Decho/Decho.csproj b/src/Decho/Decho.csproj index 932dc1f..a872461 100644 --- a/src/Decho/Decho.csproj +++ b/src/Decho/Decho.csproj @@ -25,6 +25,7 @@ + diff --git a/src/Decho/Services/OsNotificationService.cs b/src/Decho/Services/OsNotificationService.cs new file mode 100644 index 0000000..ea84dfb --- /dev/null +++ b/src/Decho/Services/OsNotificationService.cs @@ -0,0 +1,41 @@ +using OsNotifications; + +using Serilog; + +namespace Decho.Services; + +public sealed class OsNotificationService +{ + private bool _initialized; + + public void Initialize() + { + if (_initialized) return; + try + { + Notifications.SetGuiApplication(true); + _initialized = true; + } + catch (Exception ex) + { + Log.Warning(ex, "Failed to initialize OS notifications"); + } + } + + public void Show(string title, string? body = null) + { + if (!_initialized) return; + try + { + Notifications.ShowNotification(title, body ?? string.Empty); + } + catch (PlatformNotSupportedException ex) + { + Log.Warning(ex, "OS notifications not supported on this platform"); + } + catch (Exception ex) + { + Log.Warning(ex, "Failed to show OS notification"); + } + } +} \ No newline at end of file diff --git a/src/Decho/ViewModels/MainWindowViewModel.cs b/src/Decho/ViewModels/MainWindowViewModel.cs index 69d3e4f..771cf40 100644 --- a/src/Decho/ViewModels/MainWindowViewModel.cs +++ b/src/Decho/ViewModels/MainWindowViewModel.cs @@ -27,6 +27,7 @@ public sealed class MainWindowViewModel : ViewModelBase { private readonly CommandHandler _commandHandler; private readonly NotificationSoundService _notificationService; + private readonly OsNotificationService _osNotificationService; private Window? _mainWindow; public string Title { get; } = "Decho"; @@ -45,7 +46,7 @@ public sealed class MainWindowViewModel : ViewModelBase public ReactiveCommand AddServerCommand { get; } - public MainWindowViewModel(IConnectionService connectionService, IChannelService channelService, IUserService userService, IInviteService inviteService, CommandHandler commandHandler, NotificationSoundService notificationService) + public MainWindowViewModel(IConnectionService connectionService, IChannelService channelService, IUserService userService, IInviteService inviteService, CommandHandler commandHandler, NotificationSoundService notificationService, OsNotificationService osNotificationService) { ConnectionService = connectionService; ChannelService = channelService; @@ -53,6 +54,7 @@ public sealed class MainWindowViewModel : ViewModelBase InviteService = inviteService; _commandHandler = commandHandler; _notificationService = notificationService; + _osNotificationService = osNotificationService; Sidebar = new SidebarViewModel(); Chat = new ChatViewModel(); @@ -725,6 +727,9 @@ public sealed class MainWindowViewModel : ViewModelBase if (isMention) { _ = _notificationService.PlayAsync(); + string title = $"@{username} – {new Uri(serverUrl).Host}"; + string body = $"{message.Author.DisplayName} in #{message.ChannelName}: {message.Content}"; + _osNotificationService.Show(title, body); } };