From 273f9d532c36564cff5cabb0edb8b779078ef661 Mon Sep 17 00:00:00 2001 From: Corey Kaliszewski Date: Tue, 8 Nov 2022 01:46:27 -0500 Subject: [PATCH] Added option to automatically click skip intro button Changed options page to dark theme Added sync for options --- src/content_script.js | 167 +++++++++++++++++++++++++++++++++++------- src/img/introSkip.svg | 113 ++++++++++++++++++++++++++++ src/manifest.json | 5 +- src/options.html | 117 +++++++++++++++++++++-------- src/options.js | 18 ++++- 5 files changed, 363 insertions(+), 57 deletions(-) create mode 100644 src/img/introSkip.svg diff --git a/src/content_script.js b/src/content_script.js index 54f402c..62dcf8c 100755 --- a/src/content_script.js +++ b/src/content_script.js @@ -3,7 +3,70 @@ "use strict"; // todo: fix this -let enhanceotronAudioCtx, compressor, source, compressorActive, libraryType; +let enhanceotronAudioCtx, compressor, libraryType; +let introObserver = new MutationObserver((mutationsList) => { + for (let mutation of mutationsList) { + if (mutation.addedNodes.length <= 0 || !mutation.addedNodes[0] || mutation.addedNodes[0].innerText !== "SKIP INTRO") continue; + + // Intro button shows up early sometimes so wait 2 seconds before clicking it + setTimeout(() => { mutation.addedNodes[0].firstChild.click() }, 2000); + return; + } +}); + +const enhanceotronOptions = { + _skipIntroEnabled: false, + _audioCompressorEnabled: false, + _source: null, + + // Skip Intro getter/setter + get SkipIntroEnabled() { + return this._skipIntroEnabled; + }, + set SkipIntroEnabled(value) { + this._skipIntroEnabled = value; + + if (value) { + introObserver.observe(document.getElementById('plex'), { + childList: true, + attributes: false, + subtree: true + }); + } else { + introObserver.disconnect(); + } + }, + + // Audio Compressor getter/setter + get AudioCompressorEnabled() { + return this._audioCompressorEnabled; + }, + set AudioCompressorEnabled(value) { + this._audioCompressorEnabled = value; + audioCompressorChange(); + }, + + // Source getter/setter + get Source() { + return this._source; + }, + set Source(value) { + this._source = value; + if(value) setTimeout(function () { audioCompressorChange(); }, 500); + } +}; + +const audioCompressorChange = function () { + if (enhanceotronOptions.Source && enhanceotronOptions.AudioCompressorEnabled) { + enhanceotronOptions.Source.disconnect(enhanceotronAudioCtx.destination); + enhanceotronOptions.Source.connect(compressor); + compressor.connect(enhanceotronAudioCtx.destination); + } else if (enhanceotronOptions.Source && !enhanceotronOptions.AudioCompressorEnabled) { + enhanceotronOptions.Source.disconnect(compressor); + compressor.disconnect(enhanceotronAudioCtx.destination); + enhanceotronOptions.Source.connect(enhanceotronAudioCtx.destination); + } +} // TRAILERS // @@ -228,11 +291,9 @@ function createZoomElem() { function createCompressor() { let compressorBtn = document.createElement('button'); compressorBtn.setAttribute("id","enhanceotron-compressor"); - //compressorBtn.setAttribute('data-active', 'false'); compressorBtn.setAttribute('title', 'Volume Compressor'); - //compressorBtn.style.marginLeft = "10px"; - compressorBtn.style.opacity = compressorActive ? "1" : "0.5"; + compressorBtn.style.opacity = enhanceotronOptions.AudioCompressorEnabled ? "1" : "0.5"; compressorBtn.style.marginLeft = "5px"; compressorBtn.style.fontSize = "18px"; @@ -261,22 +322,10 @@ function createCompressor() { compressorBtn.appendChild(compressorIcon); compressorBtn.onclick = function () { - //const active = compressorBtn.getAttribute('data-active'); - if (source && !compressorActive) { - //compressorBtn.setAttribute('data-active', 'true'); - compressorActive = true - compressorBtn.style.opacity = "1"; - source.disconnect(enhanceotronAudioCtx.destination); - source.connect(compressor); - compressor.connect(enhanceotronAudioCtx.destination); - } else if (source && compressorActive) { - //compressorBtn.setAttribute('data-active', 'false'); - compressorActive = false - compressorBtn.style.opacity = "0.5"; - source.disconnect(compressor); - compressor.disconnect(enhanceotronAudioCtx.destination); - source.connect(enhanceotronAudioCtx.destination); - } + enhanceotronOptions.AudioCompressorEnabled = !enhanceotronOptions.AudioCompressorEnabled; + compressorBtn.style.opacity = enhanceotronOptions.AudioCompressorEnabled ? "1" : "0.5"; + chrome.storage.sync.set({ audioCompressor: enhanceotronOptions.AudioCompressorEnabled }); + } const rightControls = document.querySelector('[class*="PlayerControls-buttonGroupRight-"]'); @@ -286,6 +335,54 @@ function createCompressor() { } } +// SKIP INTRO // + +function createSkipIntro() { + + let skipIntroButton = document.createElement('button'); + + skipIntroButton.setAttribute("id", "enhanceotron-skipIntro"); + skipIntroButton.setAttribute("title", "Automatically Skip Intros (Requires Plex Pass)"); + + skipIntroButton.style.opacity = enhanceotronOptions.SkipIntroEnabled ? "1" : ".5"; + skipIntroButton.style.marginLeft = "5px"; + skipIntroButton.style.fontSize = "18px"; + skipIntroButton.style.height = "30px"; + skipIntroButton.style.width = "30px"; + skipIntroButton.style.background = "none"; + skipIntroButton.style.border = "0"; + skipIntroButton.style.cursor = "pointer"; + skipIntroButton.style.outline = "none"; + skipIntroButton.style.padding = "0"; + skipIntroButton.style.textDecoration = "none"; + skipIntroButton.style.touchAction = "manipulation"; + skipIntroButton.style.transition = "color .2s"; + skipIntroButton.style.userSelect = "none"; + + let skipIntroIcon = document.createElement("img"); + skipIntroIcon.src = chrome.runtime.getURL("img/introSkip.svg"); + + skipIntroIcon.style.height = "1.2em"; + skipIntroIcon.style.width = "1.2em"; + skipIntroIcon.style.position = "relative"; + skipIntroIcon.style.top = "-2px"; + skipIntroIcon.style.verticalAlign = "middle"; + + skipIntroButton.appendChild(skipIntroIcon); + + skipIntroButton.onclick = function () { + enhanceotronOptions.SkipIntroEnabled = !enhanceotronOptions.SkipIntroEnabled; + skipIntroButton.style.opacity = enhanceotronOptions.SkipIntroEnabled ? "1" : ".5"; + chrome.storage.sync.set({ skipIntro: enhanceotronOptions.SkipIntroEnabled }); + } + + const rightControls = document.querySelector('[class*="PlayerControls-buttonGroupRight-"]'); + + if (rightControls) { + rightControls.insertBefore(skipIntroButton, rightControls.lastChild); + } +} + document.arrive('video[class*="HTMLMedia-mediaElement-"]', function() { //const videoElem = document.querySelector('.HTMLMedia-mediaElement-2XwlNN'); const videoElem = document.querySelector('video[class*="HTMLMedia-mediaElement-"]'); @@ -300,8 +397,8 @@ document.arrive('video[class*="HTMLMedia-mediaElement-"]', function() { const AudioContext = window.AudioContext || window.webkitAudioContext; enhanceotronAudioCtx = new AudioContext(); - if (!source) { - source = enhanceotronAudioCtx.createMediaElementSource(videoElem); + if (!enhanceotronOptions.Source) { + enhanceotronOptions.Source = enhanceotronAudioCtx.createMediaElementSource(videoElem); } compressor = enhanceotronAudioCtx.createDynamicsCompressor(); @@ -311,7 +408,7 @@ document.arrive('video[class*="HTMLMedia-mediaElement-"]', function() { compressor.threshold.value = -50; compressor.knee.value = 12; - source.connect(enhanceotronAudioCtx.destination); + enhanceotronOptions.Source.connect(enhanceotronAudioCtx.destination); } }); }); @@ -328,7 +425,17 @@ document.arrive("button[data-qa-id='volumeButton']", function() { } if (!document.getElementById('enhanceotron-compressor')) { - createCompressor(); + chrome.storage.sync.get(['audioCompressor'], function (result) { + enhanceotronOptions.AudioCompressorEnabled = result.audioCompressor; + createCompressor(); + }); + } + + if (!document.getElementById('enhanceotron-skipIntro')) { + chrome.storage.sync.get(['skipIntro'], function (result) { + enhanceotronOptions.SkipIntroEnabled = result.skipIntro; + createSkipIntro(); + }); } }); @@ -343,6 +450,16 @@ document.arrive("button[data-testid='volumeButton']", function() { } if (!document.getElementById('enhanceotron-compressor')) { - createCompressor(); + chrome.storage.sync.get(['audioCompressor'], function (result) { + enhanceotronOptions.AudioCompressorEnabled = result.audioCompressor; + createCompressor(); + }); + } + + if (!document.getElementById('enhanceotron-skipIntro')) { + chrome.storage.sync.get(['skipIntro'], function (result) { + enhanceotronOptions.SkipIntroEnabled = result.skipIntro; + createSkipIntro(); + }); } }); diff --git a/src/img/introSkip.svg b/src/img/introSkip.svg new file mode 100644 index 0000000..4b9866f --- /dev/null +++ b/src/img/introSkip.svg @@ -0,0 +1,113 @@ + + + + diff --git a/src/manifest.json b/src/manifest.json index 1cae3b3..7ecb0b4 100755 --- a/src/manifest.json +++ b/src/manifest.json @@ -9,7 +9,8 @@ "*://app.plex.tv/*", "*://localhost/*", "*://127.0.0.1/*", - "activeTab" + "activeTab", + "storage" ], "optional_permissions": [ "" @@ -28,5 +29,5 @@ "48": "img/icon48.png", "128": "img/icon128.png" }, - "web_accessible_resources": ["img/icon219.svg", "img/compress.svg"] + "web_accessible_resources": [ "img/icon219.svg", "img/compress.svg", "img/introSkip.svg" ] } diff --git a/src/options.html b/src/options.html index 716688f..215f953 100644 --- a/src/options.html +++ b/src/options.html @@ -1,37 +1,96 @@ + + + Enhance-O-Tron Settings - - - - - - - - + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/src/options.js b/src/options.js index 3144e32..615c104 100644 --- a/src/options.js +++ b/src/options.js @@ -32,7 +32,7 @@ function saveOptions(e) { chrome.permissions.request({ origins: [url] - }, function(granted) { + }, (granted) => { if (granted) { chrome.tabs.reload(tabId); window.close(); @@ -42,7 +42,23 @@ function saveOptions(e) { }); } +function removeDomain(e) { + e.preventDefault(); + + chrome.permissions.remove({ + origins: [url] + }, (removed) => { + if (removed) { + document.getElementById("enabled").style.display = "none"; + document.getElementById("disabled").style.display = "block"; + } else { + document.getElementById("removeError").style.display = "block"; + } + }) +} + chrome.tabs.query({ active: true, currentWindow: true }, getUrl); document.getElementById('option-no').addEventListener("click", function() {window.close();}); document.getElementById('option-yes').addEventListener("click", saveOptions); +document.getElementById('option-remove').addEventListener("click", removeDomain);