about summary refs log tree commit diff
path: root/app/javascript/mastodon/service_worker
diff options
context:
space:
mode:
authorSorin Davidoi <sorin.davidoi@gmail.com>2017-07-18 00:19:17 +0200
committerEugen Rochko <eugen@zeonfederated.com>2017-07-18 00:19:17 +0200
commit719ab720a7286c4968f1b42e1be385f5580de13e (patch)
treea000cec72a61b73753c5aa6d1b9ff0fa64014de7 /app/javascript/mastodon/service_worker
parentb11ac88692ad7a8765b0b15e6d7a882d171ffe81 (diff)
feat(push-notifications): Open link in current tab if possible (#4228)
* fix(push-notification): Open link in current tab if possible

* feat(sw): Skip waiting and claim clients
Diffstat (limited to 'app/javascript/mastodon/service_worker')
-rw-r--r--app/javascript/mastodon/service_worker/entry.js9
-rw-r--r--app/javascript/mastodon/service_worker/web_push_notifications.js20
2 files changed, 28 insertions, 1 deletions
diff --git a/app/javascript/mastodon/service_worker/entry.js b/app/javascript/mastodon/service_worker/entry.js
index 364b67066..eea4cfc3c 100644
--- a/app/javascript/mastodon/service_worker/entry.js
+++ b/app/javascript/mastodon/service_worker/entry.js
@@ -1 +1,10 @@
 import './web_push_notifications';
+
+// Cause a new version of a registered Service Worker to replace an existing one
+// that is already installed, and replace the currently active worker on open pages.
+self.addEventListener('install', function(event) {
+  event.waitUntil(self.skipWaiting());
+});
+self.addEventListener('activate', function(event) {
+  event.waitUntil(self.clients.claim());
+});
diff --git a/app/javascript/mastodon/service_worker/web_push_notifications.js b/app/javascript/mastodon/service_worker/web_push_notifications.js
index 1708aa9f7..4a8a57767 100644
--- a/app/javascript/mastodon/service_worker/web_push_notifications.js
+++ b/app/javascript/mastodon/service_worker/web_push_notifications.js
@@ -50,6 +50,24 @@ const makeRequest = (notification, action) =>
     credentials: 'include',
   });
 
+const openUrl = url =>
+  self.clients.matchAll({ type: 'window' }).then(clientList => {
+    if (clientList.length !== 0 && 'navigate' in clientList[0]) { // Chrome 42-48 does not support navigate
+      const webClients = clientList
+        .filter(client => /\/web\//.test(client.url))
+        .sort(client => client !== 'visible');
+
+      const visibleClient = clientList.find(client => client.visibilityState === 'visible');
+      const focusedClient = clientList.find(client => client.focused);
+
+      const client = webClients[0] || visibleClient || focusedClient || clientList[0];
+
+      return client.navigate(url).then(client => client.focus());
+    } else {
+      return self.clients.openWindow(url);
+    }
+  });
+
 const removeActionFromNotification = (notification, action) => {
   const actions = notification.actions.filter(act => act.action !== action.action);
 
@@ -75,7 +93,7 @@ const handleNotificationClick = (event) => {
       }
     } else {
       event.notification.close();
-      resolve(self.clients.openWindow(event.notification.data.url));
+      resolve(openUrl(event.notification.data.url));
     }
   });