From 8321cee418ced2c7219a8062d8583ca739b3ca16 Mon Sep 17 00:00:00 2001 From: Barry Pollard Date: Fri, 21 Jul 2023 18:47:20 +0100 Subject: [PATCH] Option to disable badge animation (#141) * Option to disable badge animation * Update README * Review feedback * Update comments based on review feedback --- README.md | 2 +- service_worker.js | 29 +++++++++++++++++++++++++++++ src/options/options.html | 5 +++++ src/options/options.js | 6 +++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 100ff14..13ca3b6 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ The badge has a number of states: * One or more metrics needs improvement - amber square * One or more metrics poor - red triangle -If one or more metrics are failing, the badge will animate the values of these metrics. +If one or more metrics are failing, the badge will animate the values of these metrics (this animation can be turned off in the options screen). ### Detailed drill-down diff --git a/service_worker.js b/service_worker.js index e8bc4ec..ab1413f 100755 --- a/service_worker.js +++ b/service_worker.js @@ -19,6 +19,16 @@ const CLS_THRESHOLD = 0.1; const FCP_THRESHOLD = 1800; const TTFB_THRESHOLD = 800; +// Get the optionsNoBadgeAnimation value +// Actual default is false but lets set to true initially in case sync storage +// is slow so users don't experience any animation initially. +let optionsNoBadgeAnimation = true; +chrome.storage.sync.get({ + optionsNoBadgeAnimation: false +}, ({noBadgeAnimation}) => { + optionsNoBadgeAnimation = noBadgeAnimation; +}); + /** * Hash the URL and return a numeric hash as a String to be used as the key * @param {String} str @@ -235,6 +245,7 @@ let globalAnimationId = 0; /** @type {Map} */ const animationsByTabId = new Map(); + /** * Animate badges between pass/fail -> each failing metric. * We track each animation by tabId so that we can handle "cancellation" of the animation on new information. @@ -249,8 +260,18 @@ async function animateBadges(request, tabId) { const delay = 2000; // First badge overall perf badgeOverallPerf(request.passesAllThresholds, tabId); + // If perf is poor, animate the sequence if (request.passesAllThresholds === 'POOR') { + + // However, if user has turned this off, then leave it off. + // Note: if optionsNoBadgeAnimation is flipped, it won't start (or stop) + // animating immediately until a status change or page reload to avoid + // having to check continually. This is similar to HUD and console.logs + // not appearing immediately. + return; + } + await wait(delay); if (animationsByTabId.get(tabId) !== animationId) return; badgeMetric('lcp', request.metrics.lcp.value, tabId); @@ -287,3 +308,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { sendResponse({tabId: sender.tab.id}); } }); + +// Listen for changes to noBadgeAnimation option +function logStorageChange(changes, area) { + if (area === 'sync' && 'noBadgeAnimation' in changes) { + optionsNoBadgeAnimation = changes.noBadgeAnimation.newValue; + } +} +chrome.storage.onChanged.addListener(logStorageChange); diff --git a/src/options/options.html b/src/options/options.html index 6be1fe2..ae9ed86 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -32,6 +32,11 @@ Compare local experiences to phone field data +
+
diff --git a/src/options/options.js b/src/options/options.js index 32dcf17..44f1c59 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -1,5 +1,6 @@ const optionsOverlayNode = document.getElementById('overlay'); const optionsConsoleLoggingNode = document.getElementById('consoleLogging'); +const optionsNoBadgeAnimation = document.getElementById('noBadgeAnimation'); const optionsUserTimingNode = document.getElementById('userTiming'); const optionsPreferPhoneFieldNode = document.getElementById('preferPhoneField'); const optionsSaveBtn = document.getElementById('save'); @@ -14,6 +15,7 @@ function saveOptions() { debug: optionsConsoleLoggingNode.checked, userTiming: optionsUserTimingNode.checked, preferPhoneField: optionsPreferPhoneFieldNode.checked, + noBadgeAnimation: optionsNoBadgeAnimation.checked, }, () => { // Update status to let user know options were saved. optionsStatus.textContent = 'Options saved.'; @@ -33,11 +35,13 @@ function restoreOptions() { debug: false, userTiming: false, preferPhoneField: false, - }, ({enableOverlay, debug, userTiming, preferPhoneField}) => { + noBadgeAnimation: false, + }, ({enableOverlay, debug, userTiming, preferPhoneField, noBadgeAnimation}) => { optionsOverlayNode.checked = enableOverlay; optionsConsoleLoggingNode.checked = debug; optionsUserTimingNode.checked = userTiming; optionsPreferPhoneFieldNode.checked = preferPhoneField; + optionsNoBadgeAnimation.checked = noBadgeAnimation; }); } document.addEventListener('DOMContentLoaded', restoreOptions);