Skip to content
Extraits de code Groupes Projets
web_push_notifications.js 3,78 ko
Newer Older
  • Learn to ignore specific revisions
  • const handlePush = (event) => {
      const options = event.data.json();
    
      options.body = options.data.nsfw || options.data.content;
      options.image = options.image || undefined; // Null results in a network request (404)
      options.timestamp = options.timestamp && new Date(options.timestamp);
    
      const expandAction = options.data.actions.find(action => action.todo === 'expand');
    
      if (expandAction) {
        options.actions = [expandAction];
        options.hiddenActions = options.data.actions.filter(action => action !== expandAction);
    
        options.data.hiddenImage = options.image;
        options.image = undefined;
      } else {
        options.actions = options.data.actions;
      }
    
      event.waitUntil(self.registration.showNotification(options.title, options));
    };
    
    const cloneNotification = (notification) => {
      const clone = {  };
    
      for(var k in notification) {
        clone[k] = notification[k];
      }
    
      return clone;
    };
    
    const expandNotification = (notification) => {
      const nextNotification = cloneNotification(notification);
    
      nextNotification.body = notification.data.content;
      nextNotification.image = notification.data.hiddenImage;
      nextNotification.actions = notification.data.actions.filter(action => action.todo !== 'expand');
    
      return self.registration.showNotification(nextNotification.title, nextNotification);
    };
    
    const makeRequest = (notification, action) =>
      fetch(action.action, {
        headers: {
          'Authorization': `Bearer ${notification.data.access_token}`,
          'Content-Type': 'application/json',
        },
        method: action.method,
        credentials: 'include',
      });
    
    
    const findBestClient = clients => {
      const focusedClient = clients.find(client => client.focused);
      const visibleClient = clients.find(client => client.visibilityState === 'visible');
    
      return focusedClient || visibleClient || clients[0];
    };
    
    
    const openUrl = url =>
      self.clients.matchAll({ type: 'window' }).then(clientList => {
    
        if (clientList.length !== 0) {
          const webClients = clientList.filter(client => /\/web\//.test(client.url));
    
          if (webClients.length !== 0) {
            const client = findBestClient(webClients);
    
            const { pathname } = new URL(url);
    
            if (pathname.startsWith('/web/')) {
              return client.focus().then(client => client.postMessage({
                type: 'navigate',
                path: pathname.slice('/web/'.length - 1),
              }));
            }
          } else if ('navigate' in clientList[0]) { // Chrome 42-48 does not support navigate
            const client = findBestClient(clientList);
    
            return client.navigate(url).then(client => client.focus());
          }
    
    
        return self.clients.openWindow(url);
    
    const removeActionFromNotification = (notification, action) => {
      const actions = notification.actions.filter(act => act.action !== action.action);
    
      const nextNotification = cloneNotification(notification);
    
      nextNotification.actions = actions;
    
      return self.registration.showNotification(nextNotification.title, nextNotification);
    };
    
    const handleNotificationClick = (event) => {
      const reactToNotificationClick = new Promise((resolve, reject) => {
        if (event.action) {
          const action = event.notification.data.actions.find(({ action }) => action === event.action);
    
          if (action.todo === 'expand') {
            resolve(expandNotification(event.notification));
          } else if (action.todo === 'request') {
            resolve(makeRequest(event.notification, action)
              .then(() => removeActionFromNotification(event.notification, action)));
          } else {
            reject(`Unknown action: ${action.todo}`);
          }
        } else {
          event.notification.close();
    
          resolve(openUrl(event.notification.data.url));
    
        }
      });
    
      event.waitUntil(reactToNotificationClick);
    };
    
    self.addEventListener('push', handlePush);
    self.addEventListener('notificationclick', handleNotificationClick);