From 3e539e9e1c98a22e76b47a4d14094e1ce53e95c9 Mon Sep 17 00:00:00 2001 From: wanhose Date: Mon, 11 Nov 2024 12:35:54 +0100 Subject: [PATCH] fix(browser-extension): issue #166 --- .../src/scripts/background.js | 58 +++++++++---------- .../browser-extension/src/scripts/popup.js | 35 +++++------ 2 files changed, 44 insertions(+), 49 deletions(-) diff --git a/packages/browser-extension/src/scripts/background.js b/packages/browser-extension/src/scripts/background.js index 544017a..8324244 100644 --- a/packages/browser-extension/src/scripts/background.js +++ b/packages/browser-extension/src/scripts/background.js @@ -1,6 +1,5 @@ /** * @typedef {Object} ExtensionIssue - * @property {number} [expiresIn] * @property {string[]} [flags] * @property {string} [url] */ @@ -9,7 +8,6 @@ * @typedef {Object} ExtensionState * @property {ExtensionIssue} [issue] * @property {boolean} on - * @property {string} [updateAvailable] */ if (typeof browser === 'undefined') { @@ -84,7 +82,7 @@ const script = browser.scripting; * @description Default value for extension state * @type {ExtensionState} */ -const stateByDefault = { issue: { expiresIn: 0 }, on: true }; +const stateByDefault = { issue: undefined, on: true }; /** * @description The storage to use @@ -152,14 +150,26 @@ async function getTab() { * @returns {Promise} */ async function getState(hostname) { - const keys = [hostname, 'updateAvailable']; - const { [hostname]: state = stateByDefault, updateAvailable } = await storage.get(keys); + const { [hostname]: state = stateByDefault } = await storage.get(hostname); - if ((state.issue && Date.now() > state.issue.expiresIn) || !state.issue?.expiresIn) { - state.issue = await refreshIssue(hostname); + state.issue = await refreshIssue(hostname); + + return { ...stateByDefault, ...state }; +} + +/** + * @async + * @description Get latest version available for this extension + * @returns {Promise} + */ +async function getLatestVersion() { + try { + const { data } = await requestManager.fetch(`${apiUrl}/version/`); + + return data; + } catch { + return ''; } - - return { ...stateByDefault, ...state, updateAvailable }; } /** @@ -193,20 +203,7 @@ async function refreshIssue(hostname, attempt = 1) { if (attempt <= 3) { try { const { data = {} } = await requestManager.fetch(`${apiUrl}/issues/${hostname}/`); - - if (Object.keys(data).length === 0) { - await updateStore(hostname, { issue: { expiresIn: Date.now() + 8 * 60 * 60 * 1000 } }); - - return undefined; - } - - const issue = { - expiresIn: Date.now() + 4 * 60 * 60 * 1000, - flags: data.flags, - url: data.url, - }; - - await updateStore(hostname, { issue }); + await updateStore(hostname, { issue: { flags: data.flags, url: data.url } }); return data; } catch { @@ -301,6 +298,9 @@ browser.runtime.onMessage.addListener((message, sender, callback) => { callback(exclusionList); }); return true; + case 'GET_LATEST_VERSION': + getLatestVersion().then(callback); + return true; case 'GET_STATE': if (hostname) { getState(hostname).then(callback); @@ -366,15 +366,9 @@ browser.runtime.onInstalled.addListener((details) => { suppressLastError ); - if (details.reason === 'update') refreshData(); - storage.remove('updateAvailable'); -}); - -/** - * @description Listen to available updates - */ -browser.runtime.onUpdateAvailable.addListener((details) => { - storage.set({ updateAvailable: details.version }, suppressLastError); + if (details.reason === 'update') { + refreshData(); + } }); /** diff --git a/packages/browser-extension/src/scripts/popup.js b/packages/browser-extension/src/scripts/popup.js index 5d785c6..ee3ccbc 100644 --- a/packages/browser-extension/src/scripts/popup.js +++ b/packages/browser-extension/src/scripts/popup.js @@ -2,7 +2,6 @@ * @typedef {Object} ExtensionState * @property {ExtensionIssue} [issue] * @property {boolean} on - * @property {string} [updateAvailable] */ /** @@ -123,6 +122,17 @@ async function handleContentLoaded() { await updateDatabaseVersion(); const { exclusions } = (await dispatch({ hostname, type: 'GET_DATA' })) ?? {}; + const currentVersion = browser.runtime.getManifest().version; + const latestVersion = await dispatch({ type: 'GET_LATEST_VERSION' }); + const updateAvailable = currentVersion !== latestVersion; + + if (updateAvailable) { + const updateBanner = document.getElementById('update-banner'); + updateBanner.removeAttribute('aria-hidden'); + + const updateBannerUrl = document.getElementById('update-banner-url'); + updateBannerUrl.href += `/tag/${latestVersion}`; + } if (exclusions?.domains.some((x) => url.hostname.match(x.replaceAll(/\*/g, '[^ ]*')))) { const supportBanner = document.getElementById('support-banner'); @@ -130,6 +140,12 @@ async function handleContentLoaded() { return; } + const powerButtonElement = document.getElementById('power-option'); + powerButtonElement?.addEventListener('click', handlePowerToggle); + powerButtonElement?.removeAttribute('disabled'); + if (state.on) powerButtonElement?.setAttribute('data-value', 'on'); + else powerButtonElement?.setAttribute('data-value', 'off'); + if (state.issue?.url) { const issueBanner = document.getElementById('issue-banner'); issueBanner.removeAttribute('aria-hidden'); @@ -144,24 +160,9 @@ async function handleContentLoaded() { return; } - if (state.updateAvailable) { - const updateBanner = document.getElementById('update-banner'); - updateBanner.removeAttribute('aria-hidden'); - - const updateBannerUrl = document.getElementById('update-banner-url'); - updateBannerUrl.href += `/tag/${state.updateAvailable}`; - return; - } - const cancelButtonElement = document.getElementsByClassName('report-cancel-button')[0]; cancelButtonElement?.addEventListener('click', handleCancelClick); - const powerButtonElement = document.getElementById('power-option'); - powerButtonElement?.addEventListener('click', handlePowerToggle); - powerButtonElement?.removeAttribute('disabled'); - if (state.on) powerButtonElement?.setAttribute('data-value', 'on'); - else powerButtonElement?.setAttribute('data-value', 'off'); - const reasonInputElement = document.getElementById('report-input-reason'); reasonInputElement?.addEventListener('input', handleInputChange); reasonInputElement?.addEventListener('keydown', handleInputKeyDown); @@ -250,7 +251,7 @@ async function handleLinkRedirect(event) { * @returns {void} */ async function handlePowerToggle() { - const next = { on: !state.on }; + const next = { ...state, on: !state.on }; await dispatch({ hostname, state: next, type: 'UPDATE_STORE' }); await browser.tabs.reload(state.tabId, { bypassCache: true });