Skip to content

Commit 3d1320c

Browse files
committed
feat: add notification tap stream
1 parent 63ad498 commit 3d1320c

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed

lib/js_notifications_web.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class JsNotificationsWeb extends JsNotificationsPlatform {
2323

2424
StreamController<NotificationActionResult>? _dismissStream;
2525
StreamController<NotificationActionResult>? _actionStream;
26+
StreamController<NotificationActionResult>? _tapStream;
2627

2728
static String _scopeUrl = defaultScope;
2829

@@ -37,11 +38,16 @@ class JsNotificationsWeb extends JsNotificationsPlatform {
3738

3839
void _setup() {
3940
serviceWorkerManager = ServiceWorkerManager(
41+
onNotificationTap: _onNotificationTap,
4042
onNotificationAction: _onNotificationAction,
4143
onNotificationDismiss: (t) => _onNotificationDismiss,
4244
scopeUrl: _scopeUrl);
4345
}
4446

47+
void _onNotificationTap(NotificationActionResult e) {
48+
_tapStream?.add(e);
49+
}
50+
4551
void _onNotificationAction(NotificationActionResult e) {
4652
_actionStream?.add(e);
4753
}
@@ -146,4 +152,10 @@ class JsNotificationsWeb extends JsNotificationsPlatform {
146152
_dismissStream ??= StreamController<NotificationActionResult>.broadcast();
147153
return _dismissStream!.stream;
148154
}
155+
156+
@override
157+
Stream<NotificationActionResult> get tapStream {
158+
_tapStream ??= StreamController<NotificationActionResult>.broadcast();
159+
return _tapStream!.stream;
160+
}
149161
}

lib/managers/service_worker_manager.dart

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ class ServiceWorkerManager {
1919

2020
late final String _scope;
2121

22-
ServiceWorkerManager({this.onNotificationAction, this.onNotificationDismiss, required String scopeUrl}){
22+
ServiceWorkerManager({this.onNotificationTap, this.onNotificationAction, this.onNotificationDismiss, required String scopeUrl}){
2323
_scope = scopeUrl;
2424
_notificationApi = interop.NotificationsAPI.instance;
2525
_setupServiceWorker();
2626
}
2727

2828
Consumer<NotificationActionResult>? onNotificationAction;
2929
Consumer<NotificationActionResult>? onNotificationDismiss;
30+
Consumer<NotificationActionResult>? onNotificationTap;
3031

3132
html.ServiceWorkerContainer? _webServiceWorkerContainerDelegate;
3233

@@ -162,12 +163,30 @@ class ServiceWorkerManager {
162163
void _onServiceWorkerContainerMessageEvent(html.MessageEvent event) {
163164
printDebug("Service worker container message event: $event", tag);
164165
final map = Map<String, dynamic>.from(event.data);
165-
final action = NotificationActionResult.fromJson(map);
166+
final result = NotificationActionResult.fromJson(map);
166167
final type = map["type"];
167168
if(type == SWEvents.click) {
168-
onNotificationAction?.call(action);
169+
/// Custom notification event, not part of the standard Notification API.
170+
/// Used to describe clicking on a notification.
171+
/// This may be confused with an empty notification action event.
172+
/// Sample:
173+
/// ```js
174+
/// notification.actions = [
175+
/// { action: "", title: "Open Window" },
176+
/// { action: "click", title: "Clicked me" },
177+
/// ];
178+
/// ```
179+
///
180+
/// The above action with title "Open Window" will be considered a tap action as the service worker does not
181+
/// distinguish between a normal notification click and a notification action with an empty action string
182+
/// (see "Open Window" action above).
183+
if(result.action == null || result.action!.isEmpty) {
184+
onNotificationTap?.call(result);
185+
} else {
186+
onNotificationAction?.call(result);
187+
}
169188
} else if (type == SWEvents.close) {
170-
onNotificationDismiss?.call(action);
189+
onNotificationDismiss?.call(result);
171190
} else {
172191
throw Exception("Unknown NotificationActionResult type $type");
173192
}

lib/method_channel/js_notifications_method_channel.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class MethodChannelJsNotifications extends JsNotificationsPlatform {
6868
@override
6969
Stream<NotificationActionResult> get dismissStream => throw UnimplementedError();
7070

71+
@override
72+
Stream<NotificationActionResult> get tapStream => throw UnimplementedError();
73+
7174
@override
7275
set scopeUrl(String value) {
7376
// TODO: implement scopeUrl

lib/platform_interface/js_notifications_platform_interface.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,7 @@ abstract class JsNotificationsPlatform extends PlatformInterface {
8383

8484
/// Stream broadcasting notification close events with associated data
8585
Stream<NotificationActionResult> get dismissStream;
86+
87+
/// Stream broadcasting notification tap events with associated data
88+
Stream<NotificationActionResult> get tapStream;
8689
}

test/js_notifications_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ class MockJsNotificationsPlatform
6666
// TODO: implement notificationClose
6767
Stream<NotificationActionResult> get dismissStream => throw UnimplementedError();
6868

69+
@override
70+
// TODO: implement notificationTap
71+
Stream<NotificationActionResult> get tapStream => throw UnimplementedError();
72+
6973
@override
7074
set scopeUrl(String value) {
7175
// TODO: implement scopeUrl

0 commit comments

Comments
 (0)