diff --git a/TODO.md b/TODO.md index 31f62d6..223cb7f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,18 +1,5 @@ # TODO -## Quick Wins - -| Issue | Effort | -|-------|--------| -| Remove debug `console.log` in `options/main.js:174-175` | 1 min | -| Sync manifest versions (4.3.65 vs 4.3.66) | 1 min | -| Delete unused `TEMPLATE_FIELDSET` in `options/main.js:8` | 1 min | -| Delete dead `setCookie`/`getCookie` in `content-script/main.js:657-678` | 1 min | -| Fix `SEC_IN_WEEK` naming in `utils.js:69` (it's actually minutes) | 1 min | -| Move duplicated regexes to `shared/utils.js` | 5 min | -| Delete commented-out code blocks in `content-script/main.js` | 5 min | -| Add Page Visibility API to pause polling when tab is hidden | 10 min | - ## Code Quality - [ ] Auto-generate `idToShortId` map from `SECTIONS` instead of manual maintenance @@ -23,9 +10,9 @@ ## i18n / Localization Hardcoded English strings that break for non-English YouTube: -- `content-script/main.js:171` — `'for you'` comparison -- `content-script/main.js:211` — `'Streamed'` check -- `content-script/main.js:467-468` — `'All'`, `'Related'` chip names +- `content-script/main.js` — `'for you'` comparison +- `content-script/main.js` — `'Streamed'` check +- `content-script/main.js` — `'All'`, `'Related'` chip names ## Incomplete Features diff --git a/src/content-script/main.js b/src/content-script/main.js index 75822c6..4a6449a 100644 --- a/src/content-script/main.js +++ b/src/content-script/main.js @@ -10,12 +10,6 @@ const REDIRECT_URLS = { "redirect_to_library": 'https://www.youtube.com/feed/library', }; -const resultsPageRegex = new RegExp('.*://.*youtube\.com/results.*', 'i'); -const homepageRegex = new RegExp('.*://(www|m)\.youtube\.com(/)?$', 'i'); -const shortsRegex = new RegExp('.*://.*youtube\.com/shorts.*', 'i'); -const videoRegex = new RegExp('.*://.*youtube\.com/watch\\?v=.*', 'i'); -const channelRegex = new RegExp('.*://.*youtube\.com/(@|channel)', 'i'); -const subsRegex = new RegExp(/\/feed\/subscriptions$/, 'i'); // Dynamic settings variables const cache = {}; @@ -49,7 +43,7 @@ let theaterClicked = false, hyper = false; let onResultsPage = resultsPageRegex.test(url); let onHomepage = homepageRegex.test(url); let onShorts = shortsRegex.test(url); -let onVideo = videoRegex.test(url); +let onVideo = videoPageRegex.test(url); let onChannel = channelRegex.test(url); let onSubs = subsRegex.test(url); let settingsInit = false @@ -57,8 +51,6 @@ let settingsInit = false let dynamicIters = 0; let frameRequested = false; let isRunning = false; -// let lastRun = Date.now(); -// let counter = 0; let lastScheduleCheck; const scheduleInterval = 2_000; // 2 seconds let lastRedirect; @@ -113,8 +105,6 @@ document.addEventListener("DOMContentLoaded", e => handleNewPage()); // Dynamic settings (i.e. js instead of css) function runDynamicSettings() { if (isRunning) return; - // console.log('runDynamicSettings', Date.now() - lastRun); - // lastRun = Date.now(); isRunning = true; dynamicIters += 1; const on = cache['global_enable'] === true; @@ -340,16 +330,6 @@ function runDynamicSettings() { } } - // // Enable theater mode - // if (cache['enable_theater'] === true && !theaterClicked) { - // const theaterButton = qsa('button[title="Theater mode (t)"]')?.[0]; - // if (theaterButton && theaterButton.display !== 'none') { - // console.log('theaterButton.click();') - // theaterButton.click(); - // theaterClicked = true; - // } - // } - // Skip through ads if (cache['auto_skip_ads'] === true) { @@ -409,10 +389,6 @@ function runDynamicSettings() { } } - // if (cache['change_playback_speed']) { - // document.getElementsByTagName("video")[0].playbackRate = Number(cache['change_playback_speed']); - // } - // Hide all but the timestamped comments if (cache['remove_non_timestamp_comments']) { const timestamps = qsa('yt-formatted-string:not(.published-time-text).ytd-comment-renderer > a.yt-simple-endpoint[href^="/watch"]'); @@ -422,30 +398,6 @@ function runDynamicSettings() { }); } - // // Disable play on hover - // if (dynamicIters % 10 === 0) { - // const prefCookie = getCookie('PREF'); - // const prefObj = prefCookie?.split('&')?.reduce((acc, x) => { - // const [ key, value ] = x.split('='); - // acc[key] = value; - // return acc; - // }, {}); - // if (prefObj) { - // const f7 = prefObj['f7'] || '0'; - // const playOnHoverEnabled = f7[f7.length-1] === '0'; - - // if (cache['disable_play_on_hover'] && playOnHoverEnabled) { - // prefObj['f7'] = f7.substring(0, f7.length-1) + '1'; - // const newPref = Object.entries(prefObj).map(([key, value]) => `${key}=${value}`).join('&'); - // setCookie('PREF', newPref); - // } else if (!cache['disable_play_on_hover'] && !playOnHoverEnabled) { - // prefObj['f7'] = f7.substring(0, f7.length-1) + '0'; - // const newPref = Object.entries(prefObj).map(([key, value]) => `${key}=${value}`).join('&'); - // setCookie('PREF', newPref); - // } - // } - // } - // Show description if (cache['expand_description'] || cache['remove_comments']) { const expandButton = qsa('#description #expand.button'); @@ -577,11 +529,18 @@ function runDynamicSettings() { function requestRunDynamicSettings() { if (frameRequested || isRunning) return; + if (document.hidden) return; // Pause polling when tab is hidden frameRequested = true; - // setTimeout(() => runDynamicSettings(), 50); setTimeout(() => runDynamicSettings(), Math.min(100, 50 + 10 * dynamicIters)); } +// Resume polling when tab becomes visible +document.addEventListener('visibilitychange', () => { + if (!document.hidden) { + requestRunDynamicSettings(); + } +}); + function injectAnnouncementBanners() { if (!onHomepage) return; @@ -637,7 +596,7 @@ function handleNewPage() { onResultsPage = resultsPageRegex.test(url); onHomepage = homepageRegex.test(url); onShorts = shortsRegex.test(url); - onVideo = videoRegex.test(url); + onVideo = videoPageRegex.test(url); onChannel = channelRegex.test(url); onSubs = subsRegex.test(url); settingsInit = false; diff --git a/src/options/main.js b/src/options/main.js index 935940b..4212939 100644 --- a/src/options/main.js +++ b/src/options/main.js @@ -12,12 +12,6 @@ const LOCK_CODE_CONTAINER = document.getElementById('lock_code_container'); let openedTime = Date.now(); let currentUrl; -const resultsPageRegex = new RegExp('.*://.*youtube\\.com/results.*', 'i'); -const videoPageRegex = new RegExp('.*://(www|m)\\.youtube\\.com/watch\\?v=.*', 'i'); -const homepageRegex = new RegExp('.*://(www|m)\\.youtube\\.com/$', 'i'); -const channelRegex = new RegExp('.*://.*youtube\.com/(@|channel)', 'i'); -const shortsRegex = new RegExp('.*://.*youtube\.com/shorts.*', 'i'); -const subsRegex = new RegExp(/\/feed\/subscriptions$/, 'i'); document.addEventListener("DOMContentLoaded", () => { recordEvent('Page View: Options'); diff --git a/src/shared/utils.js b/src/shared/utils.js index 2191b5b..f9cd021 100644 --- a/src/shared/utils.js +++ b/src/shared/utils.js @@ -3,6 +3,14 @@ function uniq(array) { return Array.from(new Set(array)) } function qs(query, root=document) { return root.querySelector(query) } function qsa(query, root=document) { return Array.from(root.querySelectorAll(query)) } +/* YouTube URL Regexes */ +const resultsPageRegex = new RegExp('.*://.*youtube\\.com/results.*', 'i'); +const homepageRegex = new RegExp('.*://(www|m)\\.youtube\\.com(/)?$', 'i'); +const shortsRegex = new RegExp('.*://.*youtube\\.com/shorts.*', 'i'); +const videoPageRegex = new RegExp('.*://(www|m)\\.youtube\\.com/watch\\?v=.*', 'i'); +const channelRegex = new RegExp('.*://.*youtube\\.com/(@|channel)', 'i'); +const subsRegex = new RegExp(/\/feed\/subscriptions$/, 'i'); + /* Scheduling */ function timeIsValid(times) { @@ -77,7 +85,7 @@ function nextScheduleChange(times, days) { next = checkSchedule(times, days, testDate); } - if (i > SEC_IN_WEEK) return; + if (i >= MIN_IN_WEEK) return; return testDate; }