Browse Source

fix: open editors for all failed scripts

+ inform the user explicitly in the notification
tophf 2 years ago
parent
commit
48c6df2425

+ 3 - 0
src/_locales/en/messages.yml

@@ -589,6 +589,9 @@ menuScriptEnabled:
 msgCheckingForUpdate:
   description: Message shown when a script is being checked for updates by version numbers.
   message: Checking for updates...
+msgOpenUpdateErrors:
+  description: Shown at the beginning of a notification (Chrome) or in its title (Firefox).
+  message: Error updating scripts. Click to open them.
 msgDateFormatInfo:
   description: Help text of the info icon in VM settings for the export file name.
   message: >-

+ 8 - 5
src/background/utils/db.js

@@ -376,14 +376,17 @@ function reportBadScripts(ids) {
   });
   console.error(`${title} ${toLog}`);
   if (unnotifiedIds.length) {
-    commands.Notification({ title, text: toNotify }, undefined, {
-      onClick() {
-        unnotifiedIds.forEach(id => commands.OpenEditor(id));
-      },
-    });
+    notifyToOpenScripts(title, toNotify, unnotifiedIds);
   }
 }
 
+export function notifyToOpenScripts(title, text, ids) {
+  // FF doesn't show notifications of type:'list' so we'll use `text` everywhere
+  commands.Notification({ title, text }, undefined, isClick => {
+    if (isClick) ids.forEach(id => commands.OpenEditor(id));
+  });
+}
+
 /**
  * @desc Get data for dashboard.
  * @return {Promise<{ scripts: VMScript[], cache: Object }>}

+ 16 - 13
src/background/utils/notifications.js

@@ -5,14 +5,15 @@ const openers = {};
 
 addPublicCommands({
   /** @return {Promise<string>} */
-  async Notification({ image, text, title }, src, bgExtras) {
+  async Notification({ image, text, title }, src, bgCallback) {
     const notificationId = await browser.notifications.create({
       type: 'basic',
       title: [title, IS_FIREFOX && i18n('extName')]::trueJoin(' - '), // Chrome already shows the name
       message: text,
       iconUrl: image || defaultImage,
     });
-    openers[notificationId] = bgExtras?.onClick || src.tab.id;
+    const op = bgCallback || src && [src.tab.id, src.frameId];
+    if (op) openers[notificationId] = op;
     return notificationId;
   },
   RemoveNotification(notificationId) {
@@ -21,19 +22,21 @@ addPublicCommands({
 });
 
 browser.notifications.onClicked.addListener((id) => {
-  const openerId = openers[id];
-  if (openerId >= 0) {
-    sendTabCmd(openerId, 'NotificationClick', id);
-  }
-  if (isFunction(openerId)) {
-    openerId();
-  }
+  notifyOpener(id, true);
 });
 
 browser.notifications.onClosed.addListener((id) => {
-  const openerId = openers[id];
+  notifyOpener(id, false);
   delete openers[id];
-  if (openerId >= 0) {
-    sendTabCmd(openerId, 'NotificationClose', id);
-  }
 });
+
+function notifyOpener(id, isClick) {
+  const op = openers[id];
+  if (isFunction(op)) {
+    op(isClick);
+  } else if (op) {
+    sendTabCmd(op[0], isClick ? 'NotificationClick' : 'NotificationClose', id, {
+      frameId: op[1],
+    });
+  }
+}

+ 10 - 28
src/background/utils/update.js

@@ -3,10 +3,10 @@ import {
   i18n, sendCmd, trueJoin,
 } from '@/common';
 import { METABLOCK_RE } from '@/common/consts';
-import { fetchResources, getScriptById, getScripts, parseScript } from './db';
+import { fetchResources, getScriptById, getScripts, notifyToOpenScripts, parseScript } from './db';
 import { parseMeta } from './script';
 import { getOption, setOption } from './options';
-import { addOwnCommands, commands } from './message';
+import { addOwnCommands } from './message';
 import { requestNewer } from './storage-fetch';
 
 const processes = {};
@@ -19,24 +19,19 @@ addOwnCommands({
   async CheckUpdate(id) {
     const scripts = id ? [getScriptById(id)] : getScripts();
     const results = await Promise.all(scripts.reduce(maybeCheckUpdate, []));
-    displayNotes(results.filter(r => r?.text));
+    const problems = results.filter(r => r?.text);
+    if (problems.length) {
+      notifyToOpenScripts(
+        i18n('msgOpenUpdateErrors'),
+        problems.map(p => `* ${p.text}\n`).join(''),
+        problems.map(p => p.script.props.id),
+      );
+    }
     if (!id) setOption('lastUpdate', Date.now());
     return results.reduce((num, r) => num + (r === true), 0);
   },
 });
 
-function displayNotes(notes) {
-  if (notes.length === 1) {
-    notify(notes[0]);
-  } else if (notes.length) {
-    notify({
-      // FF doesn't show notifications of type:'list' so we'll use `text` everywhere
-      text: notes.map(n => n.text).join('\n'),
-      onClick: () => commands.OpenEditor(''),
-    });
-  }
-}
-
 /**
  * @param {Promise[]} jobs
  * @param {VMScript} script
@@ -137,16 +132,3 @@ function canNotify(script) {
     : script.config.notifyUpdates ?? allowed;
 }
 
-function notify({
-  script,
-  text,
-  onClick = () => commands.OpenEditor(script.props.id),
-}) {
-  commands.Notification({
-    text,
-    // FF doesn't show the name of the extension in the title of the notification
-    title: IS_FIREFOX ? i18n('optionUpdate') : '',
-  }, undefined, {
-    onClick,
-  });
-}