Web Support
Adds web support. The plan is as follows, taken from https://github.com/MaikuB/flutter_local_notifications/issues/481#issuecomment-2473307972:
Basic functionality
- [x] Get a web version of the plugin to register on launch
- [x] Show a notification with
show() - [x] List all notifications using
getActiveNotifications() - [x] Cancel notifications using
cancel()andcancelAll() - [x]
periodicallyShowandperiodicallyShowWithDurationwould throwUnsupportedError - [x]
pendingNotificationRequestwould return an empty list
Advanced Functionality
- [x] Support all customizations options offered by
web.NotificationOptions - [x] Register a custom service worker that can listen for notification clicks
- [x] Call handler when a notification is clicked in the foreground
- [x] Support
getNotificationAppLaunchDetails()from terminated state
PR Cleanup
- [x] Document everything (ie, re-enable lint)
- [x] Add web-specific examples to the example app
- [x] Write tests where applicable (I didn't find any good spots)
Custom service workers
Of course, getNotificationAppLaunchDetails and setting any handlers would require the ability to customize the service worker. That appears to be blocked on flutter/flutter#145828, we can also register a new service worker at runtime:
let flutter_sw = await navigator.serviceWorker.getRegistration();
if (flutter_sw != null) flutter_sw.unregister();
let plugin_sw = await navigator.serviceWorker.register("/flutter_local_notifications_sw.js");
Where our custom service worker can start off as simple as
function _handleNotif(event) {
console.log(`Clicked: ${event}`);
clients.openWindow(`/?id=${event.notification.tag`);
}
self.addEventListener("notificationclick", _handleNotif);
It evolved more throughout the PR, but that's the gist
@MaikuB I'll once again put in my request to disable the always_specify_types and lines_longer_than_80_chars lints, as they cause a lot of headache when trying to write readable code here. Disabling them now won't require changing old code, but will allow cleaner code going forward, and there may be a fair amount of code since this is a big feature. I'll also point out again that always_specify_types contradicts Effective Dart and there are even replacements such as omit_obvious_local_variable_types and specify_nonobvious_local_variabletypes. As for line lengths, the new formatter will allow custom line lengths, for which I find 100 is a reasonable limit, especially with variable names as long as WebFlutterLocalNotificationsPlugin.
Love this test feedback!
Failed to load ".../flutter_local_notification_test.dart": Instance of 'VmServiceDisappearedException'
Hi @Levi-Lesches, I would like to know how I can install this alpha version inside my project. Can you please write a simple procedure on how to use it? Thanks so much
Look into git dependencies in your pubspec, and set the URL to my repo and ref to my branch
Look into git dependencies in your pubspec, and set the URL to my repo and ref to my branch
thanks so much. Is there an example on how to show a basic notification (title and subtitle) like on the other platforms? I cannot find a simple example in your code.
It's been a while since I've touched this PR, but show() should work. Are you able to run the example app on chrome?
Hello @Levi-Lesches is there an update or ETA to have basic functionality merged?
I hear your calls! Foreground callbacks are now supported!
await plugin.initialize(
initializationSettings,
// same as other platforms, but now it'll work on web too!
onDidReceiveNotificationResponse: myHandler,
);
Oh, but this commit also adds a new package to the mix, which is unpublished, so you'll need to clone this whole repository and use path overrides for flutter_local_notifications_web
Launch details are also now supported!
// Same as every other platform!
final launchDetails = await plugin.getNotificationAppLaunchDetails();
If a notification is tapped when your tab is closed, it will be re-opened with a bunch of query parameters. Calling this function will read them and clear them so the user doesn't see them for too long.
I'm going to clean up the PR now. Here's what I did not add:
- background handlers: when a tab is closed, it is terminated. Browser tabs don't really have a standard suspended state as far as I know, and the code I wrote will just treat them as terminated and open a new tab
- scheduled notifications: The browser just doesn't offer the same flexibility as an app here, so I don't think this is reasonably possible.
- The Periodic Background Sync API looked promising, but
- permission is granted when the browser "trusts" you, and there's no way to request it
- the interval parameter is just a suggestion, and the browser will decide when to run your code based on how often the user interacts with your page. Being a few seconds or even minutes off is acceptable for this package, but this is too unreliable
- Not supported by Firefox or Safari
- The Periodic Background Sync API looked promising, but
@MaikuB I'm ready for a review!
There a handful of lints that are coming up from the master branch that aren't related to this PR. I opened https://github.com/MaikuB/flutter_local_notifications/pull/2687 for those
I couldn't really think of a great way to unit test this since it's so close to the actual JS layer and there's barely any plain Dart, so I just did the usual in making the really detailed examples. Let me know if you have a specific test case in mind.
I also didn't touch changelogs because I see you have a lot of PRs open and didn't want to conflict. This release is non-breaking though!
I added snippets in the web-only README, and made some light changes to the main README, but I want to save my main documentation effort for #2477 and adding a web guide to that PR
Thanks I'll take a look when I can do so. Regarding changelogs, that is something I can deal as part of resolving merge conflicts. With that in mind, if your wanted to, you can add details under "vNext" to represent next release. This is optional though