3
3
using System . Collections . Generic ;
4
4
using System . Threading ;
5
5
using System . Threading . Tasks ;
6
+ using Coder . Desktop . App . Views ;
6
7
using Microsoft . Extensions . Logging ;
7
8
using Microsoft . Windows . AppNotifications ;
8
9
using Microsoft . Windows . AppNotifications . Builder ;
@@ -20,17 +21,40 @@ public interface IUserNotifier : INotificationHandler, IAsyncDisposable
20
21
public void UnregisterHandler ( string name ) ;
21
22
22
23
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
+ /// <summary>
25
+ /// This method allows to display a Windows-native notification with an action defined in
26
+ /// <paramref name="handlerName"/> and provided <paramref name="args"/>.
27
+ /// </summary>
28
+ /// <param name="title">Title of the notification.</param>
29
+ /// <param name="message">Message to be displayed in the notification body.</param>
30
+ /// <param name="handlerName">Handler should be e.g. <c>nameof(Handler)</c> where <c>Handler</c>
31
+ /// implements <see cref="Coder.Desktop.App.Services.INotificationHandler" />.
32
+ /// If handler is <c>null</c> the action will open Coder Desktop.</param>
33
+ /// <param name="args">Arguments to be provided to the handler when executing the action.</param>
34
+ public Task ShowActionNotification ( string title , string message , string ? handlerName , IDictionary < string , string > ? args = null , CancellationToken ct = default ) ;
24
35
}
25
36
26
- public class UserNotifier ( ILogger < UserNotifier > logger , IDispatcherQueueManager dispatcherQueueManager ) : IUserNotifier
37
+ public class UserNotifier : IUserNotifier
27
38
{
28
39
private const string CoderNotificationHandler = "CoderNotificationHandler" ;
40
+ private const string DefaultNotificationHandler = "DefaultNotificationHandler" ;
29
41
30
42
private readonly AppNotificationManager _notificationManager = AppNotificationManager . Default ;
43
+ private readonly ILogger < UserNotifier > _logger ;
44
+ private readonly IDispatcherQueueManager _dispatcherQueueManager ;
31
45
32
46
private ConcurrentDictionary < string , INotificationHandler > Handlers { get ; } = new ( ) ;
33
47
48
+ public UserNotifier ( ILogger < UserNotifier > logger , IDispatcherQueueManager dispatcherQueueManager ,
49
+ INotificationHandler notificationHandler )
50
+ {
51
+ _logger = logger ;
52
+ _dispatcherQueueManager = dispatcherQueueManager ;
53
+ var defaultHandlerAdded = Handlers . TryAdd ( DefaultNotificationHandler , notificationHandler ) ;
54
+ if ( ! defaultHandlerAdded )
55
+ throw new Exception ( $ "UserNotifier failed to be initialized with { nameof ( DefaultNotificationHandler ) } ") ;
56
+ }
57
+
34
58
public ValueTask DisposeAsync ( )
35
59
{
36
60
return ValueTask . CompletedTask ;
@@ -50,6 +74,8 @@ public void RegisterHandler(string name, INotificationHandler handler)
50
74
51
75
public void UnregisterHandler ( string name )
52
76
{
77
+ if ( name == nameof ( DefaultNotificationHandler ) )
78
+ throw new InvalidOperationException ( $ "You cannot remove '{ name } '.") ;
53
79
if ( ! Handlers . TryRemove ( name , out _ ) )
54
80
throw new InvalidOperationException ( $ "No handler with the name '{ name } ' is registered.") ;
55
81
}
@@ -61,8 +87,11 @@ public Task ShowErrorNotification(string title, string message, CancellationToke
61
87
return Task . CompletedTask ;
62
88
}
63
89
64
- public Task ShowActionNotification ( string title , string message , string handlerName , IDictionary < string , string > ? args = null , CancellationToken ct = default )
90
+ public Task ShowActionNotification ( string title , string message , string ? handlerName , IDictionary < string , string > ? args = null , CancellationToken ct = default )
65
91
{
92
+ if ( handlerName == null )
93
+ handlerName = nameof ( DefaultNotificationHandler ) ; // Use default handler if no handler name is provided
94
+
66
95
if ( ! Handlers . TryGetValue ( handlerName , out _ ) )
67
96
throw new InvalidOperationException ( $ "No action handler with the name '{ handlerName } ' is registered.") ;
68
97
@@ -90,19 +119,19 @@ public void HandleNotificationActivation(IDictionary<string, string> args)
90
119
91
120
if ( ! Handlers . TryGetValue ( handlerName , out var handler ) )
92
121
{
93
- logger . LogWarning ( "no action handler '{HandlerName}' found for notification activation, ignoring" , handlerName ) ;
122
+ _logger . LogWarning ( "no action handler '{HandlerName}' found for notification activation, ignoring" , handlerName ) ;
94
123
return ;
95
124
}
96
125
97
- dispatcherQueueManager . RunInUiThread ( ( ) =>
126
+ _dispatcherQueueManager . RunInUiThread ( ( ) =>
98
127
{
99
128
try
100
129
{
101
130
handler . HandleNotificationActivation ( args ) ;
102
131
}
103
132
catch ( Exception ex )
104
133
{
105
- logger . LogWarning ( ex , "could not handle activation for notification with handler '{HandlerName}" , handlerName ) ;
134
+ _logger . LogWarning ( ex , "could not handle activation for notification with handler '{HandlerName}" , handlerName ) ;
106
135
}
107
136
} ) ;
108
137
}
0 commit comments