diff --git a/add-on/src/lib/ipfs-companion.js b/add-on/src/lib/ipfs-companion.js index 074db5d05..c1aa2f608 100644 --- a/add-on/src/lib/ipfs-companion.js +++ b/add-on/src/lib/ipfs-companion.js @@ -7,6 +7,7 @@ log.error = debug('ipfs-companion:main:error') const browser = require('webextension-polyfill') const toMultiaddr = require('uri-to-multiaddr') +const pMemoize = require('p-memoize') const { optionDefaults, storeMissingOptions, migrateOptions } = require('./options') const { initState, offlinePeerCount } = require('./state') const { createIpfsPathValidator } = require('./ipfs-path') @@ -526,9 +527,13 @@ module.exports = async function init () { badgeIcon = '/icons/ipfs-logo-off.svg' } try { - await browser.browserAction.setBadgeBackgroundColor({ color: badgeColor }) - await browser.browserAction.setBadgeText({ text: badgeText }) - await setBrowserActionIcon(badgeIcon) + const oldColor = colorArraytoHex(await browser.browserAction.getBadgeBackgroundColor({})) + if (badgeColor !== oldColor) { + await browser.browserAction.setBadgeBackgroundColor({ color: badgeColor }) + await setBrowserActionIcon(badgeIcon) + } + const oldText = await browser.browserAction.getBadgeText({}) + if (oldText !== badgeText) await browser.browserAction.setBadgeText({ text: badgeText }) } catch (error) { console.error('Unable to update browserAction badge due to error', error) } @@ -548,35 +553,53 @@ module.exports = async function init () { } } - function rasterIconDefinition (svgPath) { + // ColorArray [0,0,0,0] → Hex #000000 + // https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/ColorArray + function colorArraytoHex (colorArray) { + if (!colorArray) return '' + const colorAt = i => colorArray[i].toString(16).padStart(2, '0') + const r = colorAt(0) + const g = colorAt(1) + const b = colorAt(2) + return ('#' + r + g + b).toUpperCase() + } + + const rasterIconDefinition = pMemoize((svgPath) => { + const pngPath = (size) => { + // point at precomputed PNG file + const baseName = /\/icons\/(.+)\.svg/.exec(svgPath)[1] + return `/icons/png/${baseName}_${size}.png` + } // icon sizes to cover ranges from: // - https://bugs.chromium.org/p/chromium/issues/detail?id=647182 // - https://developer.chrome.com/extensions/manifest/icons - return { - path: { - 19: rasterIconPath(svgPath, 19), - 38: rasterIconPath(svgPath, 38), - 128: rasterIconPath(svgPath, 128) - } + const r19 = pngPath(19) + const r38 = pngPath(38) + const r128 = pngPath(128) + // return computed values to be cached by p-memoize + return { path: { 19: r19, 38: r38, 128: r128 } } + }) + + /* Alternative: raster images generated on the fly + const rasterIconDefinition = pMemoize((svgPath) => { + const rasterData = (size) => { + const icon = new Image() + icon.src = svgPath + const canvas = document.createElement('canvas') + const context = canvas.getContext('2d') + context.clearRect(0, 0, size, size) + context.drawImage(icon, 0, 0, size, size) + return context.getImageData(0, 0, size, size) } - } - - function rasterIconPath (iconPath, size) { - // point at precomputed PNG file - const baseName = /\/icons\/(.+)\.svg/.exec(iconPath)[1] - return `/icons/png/${baseName}_${size}.png` - } - - /* Easter-Egg: PoC that generates raster on the fly ;-) - function rasterIconData (iconPath, size) { - let icon = new Image() - icon.src = iconPath - let canvas = document.createElement('canvas') - let context = canvas.getContext('2d') - context.clearRect(0, 0, size, size) - context.drawImage(icon, 0, 0, size, size) - return context.getImageData(0, 0, size, size) - } + // icon sizes to cover ranges from: + // - https://bugs.chromium.org/p/chromium/issues/detail?id=647182 + // - https://developer.chrome.com/extensions/manifest/icons + const r19 = rasterData(19) + const r38 = rasterData(38) + const r128 = rasterData(128) + // return computed values to be cached by p-memoize + return { imageData: { 19: r19, 38: r38, 128: r128 } } + }) */ // OPTIONS diff --git a/package.json b/package.json index 8d8e2f97a..bb198f885 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,7 @@ "mime-types": "2.1.24", "multiaddr": "7.1.0", "multiaddr-to-uri": "5.0.0", + "p-memoize": "3.1.0", "p-queue": "6.1.1", "path-browserify": "1.0.0", "piggybacker": "2.0.0", diff --git a/yarn.lock b/yarn.lock index dbeb752c8..5fa3d736f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9643,7 +9643,7 @@ mem-storage-area@1.0.3: resolved "https://registry.yarnpkg.com/mem-storage-area/-/mem-storage-area-1.0.3.tgz#a8a9bc75eaf5ae69efe185fedd475fb731d14880" integrity sha512-UwDsIj6Fmml8NPiPp7QGJavwZVbXMFLvVDfshv3486KQHDcxOExr0od4YkUdJVWFlujZxtct59mEtsPvAQTOMQ== -mem@^4.0.0: +mem@^4.0.0, mem@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== @@ -11173,6 +11173,14 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" +p-memoize@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-memoize/-/p-memoize-3.1.0.tgz#ac7587983c9e530139f969ca7b41ef40e93659aa" + integrity sha512-e5tIvrsr7ydUUnxb534iQWtXxWgk/86IsH+H+nV4FHouIggBt4coXboKBt26o4lTu7JbEnGSeXdEsYR8BhAHFA== + dependencies: + mem "^4.3.0" + mimic-fn "^2.1.0" + p-queue@6.1.1, p-queue@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.1.1.tgz#eedbaf7335b4931ef857e2e58063fed461b97e80"