Skip to content

Commit 08d523f

Browse files
committed
added a default handler
1 parent 7ff7914 commit 08d523f

File tree

2 files changed

+43
-22
lines changed

2 files changed

+43
-22
lines changed

App/Services/UserNotifier.cs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Threading;
55
using System.Threading.Tasks;
6+
using Coder.Desktop.App.Views;
67
using Microsoft.Extensions.Logging;
78
using Microsoft.Windows.AppNotifications;
89
using Microsoft.Windows.AppNotifications.Builder;
@@ -20,17 +21,26 @@ public interface IUserNotifier : INotificationHandler, IAsyncDisposable
2021
public void UnregisterHandler(string name);
2122

2223
public Task ShowErrorNotification(string title, string message, CancellationToken ct = default);
23-
public Task ShowActionNotification(string title, string message, string handlerName, IDictionary<string, string>? args = null, CancellationToken ct = default);
24+
public Task ShowActionNotification(string title, string message, string? handlerName, IDictionary<string, string>? args = null, CancellationToken ct = default);
2425
}
2526

26-
public class UserNotifier(ILogger<UserNotifier> logger, IDispatcherQueueManager dispatcherQueueManager) : IUserNotifier
27+
public class UserNotifier : IUserNotifier
2728
{
2829
private const string CoderNotificationHandler = "CoderNotificationHandler";
2930

3031
private readonly AppNotificationManager _notificationManager = AppNotificationManager.Default;
32+
private readonly ILogger<UserNotifier> _logger;
33+
private readonly IDispatcherQueueManager _dispatcherQueueManager;
3134

3235
private ConcurrentDictionary<string, INotificationHandler> Handlers { get; } = new();
3336

37+
public UserNotifier(ILogger<UserNotifier> logger, IDispatcherQueueManager dispatcherQueueManager)
38+
{
39+
_logger = logger;
40+
_dispatcherQueueManager = dispatcherQueueManager;
41+
Handlers.TryAdd(nameof(DefaultNotificationHandler), new DefaultNotificationHandler());
42+
}
43+
3444
public ValueTask DisposeAsync()
3545
{
3646
return ValueTask.CompletedTask;
@@ -61,10 +71,18 @@ public Task ShowErrorNotification(string title, string message, CancellationToke
6171
return Task.CompletedTask;
6272
}
6373

64-
public Task ShowActionNotification(string title, string message, string handlerName, IDictionary<string, string>? args = null, CancellationToken ct = default)
74+
public Task ShowActionNotification(string title, string message, string? handlerName, IDictionary<string, string>? args = null, CancellationToken ct = default)
6575
{
66-
if (!Handlers.TryGetValue(handlerName, out _))
67-
throw new InvalidOperationException($"No action handler with the name '{handlerName}' is registered.");
76+
if (handlerName == null)
77+
{
78+
// Use default handler if no handler name is provided
79+
handlerName = nameof(DefaultNotificationHandler);
80+
}
81+
else
82+
{
83+
if (!Handlers.TryGetValue(handlerName, out _))
84+
throw new InvalidOperationException($"No action handler with the name '{handlerName}' is registered. Use null for default");
85+
}
6886

6987
var builder = new AppNotificationBuilder()
7088
.AddText(title)
@@ -90,20 +108,32 @@ public void HandleNotificationActivation(IDictionary<string, string> args)
90108

91109
if (!Handlers.TryGetValue(handlerName, out var handler))
92110
{
93-
logger.LogWarning("no action handler '{HandlerName}' found for notification activation, ignoring", handlerName);
111+
_logger.LogWarning("no action handler '{HandlerName}' found for notification activation, ignoring", handlerName);
94112
return;
95113
}
96114

97-
dispatcherQueueManager.RunInUiThread(() =>
115+
_dispatcherQueueManager.RunInUiThread(() =>
98116
{
99117
try
100118
{
101119
handler.HandleNotificationActivation(args);
102120
}
103121
catch (Exception ex)
104122
{
105-
logger.LogWarning(ex, "could not handle activation for notification with handler '{HandlerName}", handlerName);
123+
_logger.LogWarning(ex, "could not handle activation for notification with handler '{HandlerName}", handlerName);
106124
}
107125
});
108126
}
109127
}
128+
129+
public class DefaultNotificationHandler : INotificationHandler
130+
{
131+
public void HandleNotificationActivation(IDictionary<string, string> _)
132+
{
133+
var app = (App)Microsoft.UI.Xaml.Application.Current;
134+
if (app != null && app.TrayWindow != null)
135+
{
136+
app.TrayWindow.Tray_Open();
137+
}
138+
}
139+
}

App/Views/TrayWindow.xaml.cs

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
namespace Coder.Desktop.App.Views;
2525

26-
public sealed partial class TrayWindow : Window, INotificationHandler
26+
public sealed partial class TrayWindow : Window
2727
{
2828
private const int WIDTH = 300;
2929

@@ -38,8 +38,6 @@ public sealed partial class TrayWindow : Window, INotificationHandler
3838
private VpnLifecycle prevVpnLifecycle = VpnLifecycle.Stopped;
3939
private RpcLifecycle prevRpcLifecycle = RpcLifecycle.Disconnected;
4040

41-
private NativeApi.POINT? _lastActivatePosition;
42-
4341
private readonly IRpcController _rpcController;
4442
private readonly ICredentialManager _credentialManager;
4543
private readonly ISyncSessionController _syncSessionController;
@@ -69,7 +67,6 @@ public TrayWindow(
6967
_mainPage = mainPage;
7068

7169
InitializeComponent();
72-
_userNotifier.RegisterHandler("TrayWindow", this);
7370
AppWindow.Hide();
7471
Activated += Window_Activated;
7572
RootFrame.SizeChanged += RootFrame_SizeChanged;
@@ -158,7 +155,7 @@ private void NotifyUser(RpcModel rpcModel)
158155
{
159156
// This method is called when the state changes, but we don't want to notify
160157
// the user if the state hasn't changed.
161-
var isRpcLifecycleChanged = rpcModel.RpcLifecycle != RpcLifecycle.Connecting && prevRpcLifecycle != rpcModel.RpcLifecycle;
158+
var isRpcLifecycleChanged = rpcModel.RpcLifecycle == RpcLifecycle.Disconnected && prevRpcLifecycle != rpcModel.RpcLifecycle;
162159
var isVpnLifecycleChanged = (rpcModel.VpnLifecycle == VpnLifecycle.Started || rpcModel.VpnLifecycle == VpnLifecycle.Stopped) && prevVpnLifecycle != rpcModel.VpnLifecycle;
163160

164161
if (!isRpcLifecycleChanged && !isVpnLifecycleChanged)
@@ -170,8 +167,7 @@ private void NotifyUser(RpcModel rpcModel)
170167
if (isRpcLifecycleChanged)
171168
message += rpcModel.RpcLifecycle switch
172169
{
173-
RpcLifecycle.Connected => "Connected to Coder vpn service.",
174-
RpcLifecycle.Disconnected => "Disconnected from Coder vpn service.",
170+
RpcLifecycle.Disconnected => "Disconnected from Coder background service.",
175171
_ => "" // This will never be hit.
176172
};
177173

@@ -196,7 +192,7 @@ private void NotifyUser(RpcModel rpcModel)
196192
}
197193

198194
// Trigger notification
199-
_userNotifier.ShowActionNotification(message, string.Empty, nameof(TrayWindow), null, CancellationToken.None);
195+
_userNotifier.ShowActionNotification(message, string.Empty, null, null, CancellationToken.None);
200196
}
201197

202198
private void RpcController_StateChanged(object? _, RpcModel model)
@@ -355,7 +351,7 @@ private void Window_Activated(object sender, WindowActivatedEventArgs e)
355351
}
356352

357353
[RelayCommand]
358-
private void Tray_Open()
354+
public void Tray_Open()
359355
{
360356
MoveResizeAndActivate();
361357
}
@@ -374,11 +370,6 @@ private void Tray_Exit()
374370
_ = ((App)Application.Current).ExitApplication();
375371
}
376372

377-
public void HandleNotificationActivation(IDictionary<string, string> args)
378-
{
379-
Tray_Open();
380-
}
381-
382373
public static class NativeApi
383374
{
384375
[DllImport("dwmapi.dll")]

0 commit comments

Comments
 (0)