From c570aff66df2c5e868b9ff55ebb9f6310241a94d Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 3 Nov 2023 09:00:39 -0700 Subject: [PATCH 1/3] Revert "delay buildChannelButton to account for UI refresh on YT" This reverts commit aaa04a43b5eaf14f8763390a2f6065c0ac87d8dc. --- .eslintrc.js | 1 - extension/script.js | 36 +++++++++++++++--------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ccc033b..72398fc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,6 @@ module.exports = { }, env: { browser: true, - es6: true, }, globals: { browser: 'readonly', diff --git a/extension/script.js b/extension/script.js index 72451a5..32bb357 100644 --- a/extension/script.js +++ b/extension/script.js @@ -124,13 +124,13 @@ function isElementVisible(element) { function ensureTALinks() { let channelContainerNodes = getChannelContainers(); + for (let channelContainer of channelContainerNodes) { channelContainer = adjustOwner(channelContainer); if (channelContainer.hasTA) continue; + let channelButton = buildChannelButton(channelContainer); + channelContainer.appendChild(channelButton); channelContainer.hasTA = true; - buildChannelButton(channelContainer).then(channelButton => { - channelContainer.appendChild(channelButton); - }); } let titleContainerNodes = getTitleContainers(); @@ -150,25 +150,19 @@ function adjustOwner(channelContainer) { } function buildChannelButton(channelContainer) { - return new Promise(resolve => { - let buttonDiv; - let channelSubButton; - let spacer; - let channelDownloadButton; + let channelHandle = getChannelHandle(channelContainer); + let buttonDiv = buildChannelButtonDiv(); - // Delayed execution for interface to refresh - setTimeout(() => { - const channelHandle = getChannelHandle(channelContainer); - buttonDiv = buildChannelButtonDiv(); - channelSubButton = buildChannelSubButton(channelHandle); - spacer = buildSpacer(); - channelDownloadButton = buildChannelDownloadButton(); - buttonDiv.appendChild(channelSubButton); - buttonDiv.appendChild(spacer); - buttonDiv.appendChild(channelDownloadButton); - resolve(buttonDiv); - }, 2000); - }); + let channelSubButton = buildChannelSubButton(channelHandle); + buttonDiv.appendChild(channelSubButton); + + let spacer = buildSpacer(); + buttonDiv.appendChild(spacer); + + let channelDownloadButton = buildChannelDownloadButton(); + buttonDiv.appendChild(channelDownloadButton); + + return buttonDiv; } function getChannelHandle(channelContainer) { From 72c94fbe99681f21e05b02a9eb7508327ac4e184 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 3 Nov 2023 09:02:35 -0700 Subject: [PATCH 2/3] 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(); } }); From ee6db2595fce1c5c2487c148072ca259d93c8f33 Mon Sep 17 00:00:00 2001 From: Kevin Gibbons Date: Fri, 3 Nov 2023 09:03:06 -0700 Subject: [PATCH 3/3] restore .eslintrc.js --- .eslintrc.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintrc.js b/.eslintrc.js index 5d3c880..cd14b64 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,6 +6,7 @@ module.exports = { }, env: { browser: true, + es6: true, }, globals: { browser: 'readonly',