From 72c94fbe99681f21e05b02a9eb7508327ac4e184 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 3 Nov 2023 09:02:35 -0700 Subject: [PATCH] better logic for updating the subscribe button on page navigation --- .eslintrc.js | 2 ++ extension/script.js | 66 +++++++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 72398fc..5d3c880 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,5 +17,7 @@ module.exports = { eqeqeq: ['error', 'always', { null: 'ignore' }], curly: ['error', 'multi-line'], 'no-var': 'error', + 'no-func-assign': 'off', + 'no-inner-declarations': 'off', }, }; diff --git a/extension/script.js b/extension/script.js index 32bb357..484d378 100644 --- a/extension/script.js +++ b/extension/script.js @@ -126,8 +126,8 @@ function ensureTALinks() { let channelContainerNodes = getChannelContainers(); for (let channelContainer of channelContainerNodes) { - channelContainer = adjustOwner(channelContainer); if (channelContainer.hasTA) continue; + channelContainer = adjustOwner(channelContainer); let channelButton = buildChannelButton(channelContainer); channelContainer.appendChild(channelButton); channelContainer.hasTA = true; @@ -143,6 +143,7 @@ function ensureTALinks() { titleContainer.hasTA = true; } } +ensureTALinks = throttled(ensureTALinks, 700); // fix positioning of #owner div to fit new button function adjustOwner(channelContainer) { @@ -151,16 +152,42 @@ function adjustOwner(channelContainer) { function buildChannelButton(channelContainer) { let channelHandle = getChannelHandle(channelContainer); + channelContainer.taDerivedHandle = channelHandle; + let buttonDiv = buildChannelButtonDiv(); let channelSubButton = buildChannelSubButton(channelHandle); buttonDiv.appendChild(channelSubButton); + channelContainer.taSubButton = channelSubButton; let spacer = buildSpacer(); buttonDiv.appendChild(spacer); let channelDownloadButton = buildChannelDownloadButton(); buttonDiv.appendChild(channelDownloadButton); + channelContainer.taDownloadButton = channelDownloadButton; + + if (!channelContainer.taObserver) { + function updateButtonsIfNecessary() { + let newHandle = getChannelHandle(channelContainer); + if (channelContainer.taDerivedHandle === newHandle) return; + console.log(`updating handle from ${channelContainer.taDerivedHandle} to ${newHandle}`); + channelContainer.taDerivedHandle = newHandle; + let channelSubButton = buildChannelSubButton(newHandle); + channelContainer.taSubButton.replaceWith(channelSubButton); + channelContainer.taSubButton = channelSubButton; + + let channelDownloadButton = buildChannelDownloadButton(); + channelContainer.taDownloadButton.replaceWith(channelDownloadButton); + channelContainer.taDownloadButton = channelDownloadButton; + } + channelContainer.taObserver = new MutationObserver(throttled(updateButtonsIfNecessary, 100)); + channelContainer.taObserver.observe(channelContainer, { + attributes: true, + childList: true, + subtree: true, + }); + } return buttonDiv; } @@ -230,10 +257,10 @@ function checkChannelSubscribed(channelSubButton) { console.log('Unknown state'); } } - function handleError() { + function handleError(e) { buttonError(channelSubButton); channelSubButton.innerText = 'Error'; - console.log('error'); + console.error('error', e); } let channelHandle = channelSubButton.dataset.id; @@ -389,10 +416,11 @@ function checkVideoExists(taButton) { } taButton.isChecked = true; } - function handleError() { + function handleError(e) { buttonError(taButton); let videoId = taButton.dataset.id; console.log(`error: failed to get info from TA for video ${videoId}`); + console.error(e); } let videoId = taButton.dataset.id; @@ -449,9 +477,8 @@ function sendUrl(url, action, button) { } } - function handleError(error) { - console.log('error'); - console.log(JSON.stringify(error)); + function handleError(e) { + console.log('error', e); buttonError(button); } @@ -484,15 +511,20 @@ function cleanButtons() { } let oldHref = document.location.href; -let throttleBlock; -const throttle = (callback, time) => { - if (throttleBlock) return; - throttleBlock = true; - setTimeout(() => { - callback(); - throttleBlock = false; - }, time); -}; + +function throttled(callback, time) { + let throttleBlock = false; + let lastArgs; + return (...args) => { + lastArgs = args; + if (throttleBlock) return; + throttleBlock = true; + setTimeout(() => { + throttleBlock = false; + callback(...lastArgs); + }, time); + }; +} let observer = new MutationObserver(list => { const currentHref = document.location.href; @@ -501,7 +533,7 @@ let observer = new MutationObserver(list => { oldHref = currentHref; } if (list.some(i => i.type === 'childList' && i.addedNodes.length > 0)) { - throttle(ensureTALinks, 700); + ensureTALinks(); } });