Hey guys,
I have a pattern I’ve been using on a few projects and I just wanted to share
Quite often I want to notify a user if something has happened when the browser window is in the background. For my use case, the js Notification API is perfect. This is what I do;
in app.js;
let Hooks = {}
function sendNotification(title, message) {
if(Notification.permission === "granted") {
try {
new Notification(title, {body: message, requireInteraction: false});
} catch (e) {
console.debug("notifcation error: " + e)
}
}
}
Hooks.Notification = {
mounted(){
if(Notification.permission === "default") {
Notification.requestPermission();
}
this.handleEvent("notification", ({title, message}) => sendNotification(title, message));
}
}
Note that this will ask the user for the notification on mount, which might not be what you want. You could easily have a button that pushes to the client with an event that asks for notification.
To hook it in your need to add the hooks to your liveSocket call like;
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: Hooks})
then on your live view;
<div id="notification" phx-hook="Notification"></div>
And finally in your live view supporting code eg a handle info callback;
{:noreply, push_event(socket, "notification", %{title: title, message: message})}
There are lots of enhancements you can do like only send these notifications if the browser is in the background eg. watch for phx-window-blur and phx-window-focus events and set some state so you know when it’s in the background. You could also enhance it by using a service worker and sending the notifcations via gcm/apns but that was an overkill for my use case.
Overall it’s been a nice pattern - I love when i’m uploading a file or processing some work and get a notification when it’s complete.
Cheers,
Anko