diff --git a/SB.js b/SB.js new file mode 100644 index 00000000..eb6c489f --- /dev/null +++ b/SB.js @@ -0,0 +1,175 @@ +SB = {}; + +// Function setup + +Map.prototype.toJSON = function() { + return Array.from(this.entries()); +}; + +class MapIO { + constructor(id) { + this.id = id; + this.map = SB.localConfig[this.id]; + } + + set(key, value) { + this.map.set(key, value); + + SB.config.handler.set(undefined, this.id, encodeStoredItem(this.map)); + + return this.map; + } + + get(key) { + return this.map.get(key); + } + + has(key) { + return this.map.has(key); + } + + deleteProperty(key) { + if (this.map.has(key)) { + this.map.delete(key); + return true; + } else { + return false; + } + } + + size() { + return this.map.size; + } + + delete(key) { + this.map.delete(key); + + SB.config.handler.set(undefined, this.id, encodeStoredItem(this.map)); + } +} + +/** + * A Map cannot be stored in the chrome storage. + * This data will be encoded into an array instead as specified by the toJSON function. + * + * @param {*} data + */ +function encodeStoredItem(data) { + if(!(data instanceof Map)) return data; + return JSON.stringify(data); +} + +/** + * A Map cannot be stored in the chrome storage. + * This data will be decoded from the array it is stored in + * + * @param {*} data + */ +function decodeStoredItem(data) { + if(typeof data !== "string") return data; + + try { + let str = JSON.parse(data); + + if(!Array.isArray(str)) return data; + return new Map(str); + } catch(e) { + + // If all else fails, return the data + return data; + } +} + +function configProxy() { + chrome.storage.onChanged.addListener((changes, namespace) => { + for (key in changes) { + SB.localConfig[key] = decodeStoredItem(changes[key].newValue); + } + }); + + var handler = { + set: function(obj, prop, value) { + SB.localConfig[prop] = value; + + chrome.storage.sync.set({ + [prop]: encodeStoredItem(value) + }); + }, + get: function(obj, prop) { + let data = SB.localConfig[prop]; + if(data instanceof Map) data = new MapIO(prop); + + return obj[prop] || data; + } + + }; + + return new Proxy({handler}, handler); +} + +function fetchConfig() { + return new Promise((resolve, reject) => { + chrome.storage.sync.get(null, function(items) { + SB.localConfig = items; // Data is ready + resolve(); + }); + }); +} + +function migrateOldFormats() { // Convert sponsorTimes format + for (key in SB.localConfig) { + if (key.startsWith("sponsorTimes") && key !== "sponsorTimes" && key !== "sponsorTimesContributed") { + SB.config.sponsorTimes.set(key.substr(12), SB.config[key]); + delete SB.config[key]; + } + } +} + +async function setupConfig() { + await fetchConfig(); + addDefaults(); + convertJSON(); + SB.config = configProxy(); + migrateOldFormats(); +} + +SB.defaults = { + "sponsorTimes": new Map(), + "startSponsorKeybind": ";", + "submitKeybind": "'", + "minutesSaved": 0, + "skipCount": 0, + "sponsorTimesContributed": 0, + "disableSkipping": false, + "disableAutoSkip": false, + "trackViewCount": true, + "dontShowNotice": false, + "hideVideoPlayerControls": false, + "hideInfoButtonPlayerControls": false, + "hideDeleteButtonPlayerControls": false, + "hideDiscordLaunches": 0, + "hideDiscordLink": false +} + +// Reset config +function resetConfig() { + SB.config = SB.defaults; +}; + +function convertJSON() { + Object.keys(SB.defaults).forEach(key => { + SB.localConfig[key] = decodeStoredItem(SB.localConfig[key], key); + }); +} + +// Add defaults +function addDefaults() { + Object.keys(SB.defaults).forEach(key => { + if(!SB.localConfig.hasOwnProperty(key)) { + SB.localConfig[key] = SB.defaults[key]; + } + }); +}; + +// Sync config +setupConfig(); diff --git a/background.js b/background.js index f2759f1f..409e59af 100644 --- a/background.js +++ b/background.js @@ -4,7 +4,9 @@ chrome.tabs.onUpdated.addListener(function(tabId) { }, () => void chrome.runtime.lastError ); // Suppress error on Firefox }); -chrome.runtime.onMessage.addListener(function (request, sender, callback) { +chrome.runtime.onMessage.addListener(async function (request, sender, callback) { + await wait(() => SB.config !== undefined); + switch(request.message) { case "submitTimes": submitTimes(request.videoID, callback); @@ -15,11 +17,12 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) { addSponsorTime(request.time, request.videoID, callback); //this allows the callback to be called later - return true; + return true; + case "getSponsorTimes": getSponsorTimes(request.videoID, function(sponsorTimes) { callback({ - sponsorTimes: sponsorTimes + sponsorTimes: sponsorTimes }) }); @@ -43,37 +46,31 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) { //add help page on install chrome.runtime.onInstalled.addListener(function (object) { setTimeout(function() { - chrome.storage.sync.get(["userID"], function(result) { - const userID = result.userID; + const userID = SB.config.userID; - // If there is no userID, then it is the first install. - if (!userID){ - //open up the install page - chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")}); + // If there is no userID, then it is the first install. + if (!userID){ + //open up the install page + chrome.tabs.create({url: chrome.extension.getURL("/help/index_en.html")}); - //generate a userID - const newUserID = generateUserID(); - //save this UUID - chrome.storage.sync.set({ - "userID": newUserID - }); - } - }); + //generate a userID + const newUserID = generateUserID(); + //save this UUID + SB.config.userID = newUserID; + } }, 1500); }); //gets the sponsor times from memory function getSponsorTimes(videoID, callback) { let sponsorTimes = []; - let sponsorTimeKey = "sponsorTimes" + videoID; - chrome.storage.sync.get([sponsorTimeKey], function(result) { - let sponsorTimesStorage = result[sponsorTimeKey]; - if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) { - sponsorTimes = sponsorTimesStorage; - } - - callback(sponsorTimes) - }); + let sponsorTimesStorage = SB.config.sponsorTimes.get(videoID); + + if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) { + sponsorTimes = sponsorTimesStorage; + } + + callback(sponsorTimes); } function addSponsorTime(time, videoID, callback) { @@ -91,21 +88,18 @@ function addSponsorTime(time, videoID, callback) { } //save this info - let sponsorTimeKey = "sponsorTimes" + videoID; - chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, callback); + SB.config.sponsorTimes.set(videoID, sponsorTimes); + callback(); }); } function submitVote(type, UUID, callback) { - chrome.storage.sync.get(["userID"], function(result) { - let userID = result.userID; + let userID = SB.config.userID; if (userID == undefined || userID === "undefined") { //generate one userID = generateUserID(); - chrome.storage.sync.set({ - "userID": userID - }); + SB.config.userID = userID; } //publish this vote @@ -128,74 +122,62 @@ function submitVote(type, UUID, callback) { }); } }) - }) } -function submitTimes(videoID, callback) { +async function submitTimes(videoID, callback) { //get the video times from storage - let sponsorTimeKey = 'sponsorTimes' + videoID; - chrome.storage.sync.get([sponsorTimeKey, "userID"], async function(result) { - let sponsorTimes = result[sponsorTimeKey]; - let userID = result.userID; - - if (sponsorTimes != undefined && sponsorTimes.length > 0) { - let durationResult = await new Promise((resolve, reject) => { - chrome.tabs.query({ - active: true, - currentWindow: true - }, function(tabs) { - chrome.tabs.sendMessage(tabs[0].id, { - message: "getVideoDuration" - }, (response) => resolve(response)); - }); + let sponsorTimes = SB.config.sponsorTimes.get(videoID); + let userID = SB.config.userID; + + if (sponsorTimes != undefined && sponsorTimes.length > 0) { + let durationResult = await new Promise((resolve, reject) => { + chrome.tabs.query({ + active: true, + currentWindow: true + }, function(tabs) { + chrome.tabs.sendMessage(tabs[0].id, { + message: "getVideoDuration" + }, (response) => resolve(response)); }); + }); - //check if a sponsor exceeds the duration of the video - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i][1] > durationResult.duration) { - sponsorTimes[i][1] = durationResult.duration; - } - } - - //submit these times - for (let i = 0; i < sponsorTimes.length; i++) { - //to prevent it from happeneing twice - let increasedContributionAmount = false; - - //submit the sponsorTime - sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1] - + "&userID=" + userID, function(xmlhttp, error) { - if (xmlhttp.readyState == 4 && !error) { - callback({ - statusCode: xmlhttp.status - }); - - if (xmlhttp.status == 200) { - //add these to the storage log - chrome.storage.sync.get(["sponsorTimesContributed"], function(result) { - let currentContributionAmount = 0; - if (result.sponsorTimesContributed != undefined) { - //current contribution amount is known - currentContributionAmount = result.sponsorTimesContributed; - } - - //save the amount contributed - if (!increasedContributionAmount) { - increasedContributionAmount = true; - - chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length}); - } - }); - } - } else if (error) { - callback({ - statusCode: -1 - }); - } - }); + //check if a sponsor exceeds the duration of the video + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i][1] > durationResult.duration) { + sponsorTimes[i][1] = durationResult.duration; } } - }); + + //submit these times + for (let i = 0; i < sponsorTimes.length; i++) { + //to prevent it from happeneing twice + let increasedContributionAmount = false; + + //submit the sponsorTime + sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1] + + "&userID=" + userID, function(xmlhttp, error) { + if (xmlhttp.readyState == 4 && !error) { + callback({ + statusCode: xmlhttp.status + }); + + if (xmlhttp.status == 200) { + //add these to the storage log + currentContributionAmount = SB.config.sponsorTimesContributed; + //save the amount contributed + if (!increasedContributionAmount) { + increasedContributionAmount = true; + SB.config.sponsorTimesContributed = currentContributionAmount + sponsorTimes.length; + } + } + } else if (error) { + callback({ + statusCode: -1 + }); + } + }); + } + } } function sendRequestToServer(type, address, callback) { @@ -215,4 +197,4 @@ function sendRequestToServer(type, address, callback) { //submit this request xmlhttp.send(); -} \ No newline at end of file +} diff --git a/content.js b/content.js index 0a829e51..175bcb6c 100644 --- a/content.js +++ b/content.js @@ -58,11 +58,6 @@ var lastSponsorTimeSkippedUUID = null; //if showing the start sponsor button or the end sponsor button on the player var showingStartSponsor = true; -//should the video controls buttons be added -var hideVideoPlayerControls = false; -var hideInfoButtonPlayerControls = false; -var hideDeleteButtonPlayerControls = false; - //the sponsor times being prepared to be submitted var sponsorTimesSubmitting = []; @@ -70,54 +65,6 @@ var sponsorTimesSubmitting = []; //this is used to close the popup on YouTube when the other popup opens var popupInitialised = false; -//should skips happen at all -var disableSkipping = false; -chrome.storage.sync.get(["disableSkipping"], function(result) { - let disableSkippingStorage = result.disableSkipping; - if (disableSkippingStorage != undefined) { - disableSkipping = disableSkippingStorage; - } -}); - -//should skips be manual -var disableAutoSkip = false; -chrome.storage.sync.get(["disableAutoSkip"], function(result) { - let disableAutoSkipStorage = result.disableAutoSkip; - if (disableAutoSkipStorage != undefined) { - disableAutoSkip = disableAutoSkipStorage; - } -}); - -//should view counts be tracked -var trackViewCount = false; -chrome.storage.sync.get(["trackViewCount"], function(result) { - let trackViewCountStorage = result.trackViewCount; - if (trackViewCountStorage != undefined) { - trackViewCount = trackViewCountStorage; - } else { - trackViewCount = true; - } -}); - -//if the notice should not be shown -//happens when the user click's the "Don't show notice again" button -//option renamed when new notice was made -var dontShowNotice = false; -chrome.storage.sync.get(["dontShowNotice"], function(result) { - let dontShowNoticeAgain = result.dontShowNotice; - if (dontShowNoticeAgain != undefined) { - dontShowNotice = dontShowNoticeAgain; - } -}); -//load the legacy option to hide the notice -var dontShowNoticeOld = false; -chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) { - let dontShowNoticeAgain = result.dontShowNoticeAgain; - if (dontShowNoticeAgain != undefined) { - dontShowNoticeOld = dontShowNoticeAgain; - } -}); - //get messages from the background script and the popup chrome.runtime.onMessage.addListener(messageListener); @@ -126,7 +73,6 @@ function messageListener(request, sender, sendResponse) { switch(request.message){ case "update": videoIDChange(getYouTubeVideoID(document.URL)); - break; case "sponsorStart": sponsorMessageStarted(sendResponse); @@ -191,35 +137,35 @@ function messageListener(request, sender, sendResponse) { break; case "dontShowNotice": - dontShowNotice = false; + SB.config.dontShowNotice = true; break; case "changeStartSponsorButton": changeStartSponsorButton(request.showStartSponsor, request.uploadButtonVisible); break; + case "showNoticeAgain": - dontShowNotice = false; - + SB.config.dontShowNotice = true; break; + case "changeVideoPlayerControlsVisibility": - hideVideoPlayerControls = request.value; + SB.config.hideVideoPlayerControls = request.value; updateVisibilityOfPlayerControlsButton(); break; case "changeInfoButtonPlayerControlsVisibility": - hideInfoButtonPlayerControls = request.value; + SB.config.hideInfoButtonPlayerControls = request.value; updateVisibilityOfPlayerControlsButton(); break; case "changeDeleteButtonPlayerControlsVisibility": - hideDeleteButtonPlayerControls = request.value; + SB.config.hideDeleteButtonPlayerControls = request.value; updateVisibilityOfPlayerControlsButton(); break; case "trackViewCount": - trackViewCount = request.value; - + SB.config.trackViewCount = request.value; break; } } @@ -231,19 +177,9 @@ document.onkeydown = async function(e){ let video = document.getElementById("movie_player"); - let startSponsorKey = await new Promise((resolve, reject) => { - chrome.storage.sync.get(["startSponsorKeybind"], (result) => resolve(result)); - }); - let submitKey = await new Promise((resolve, reject) => { - chrome.storage.sync.get(["submitKeybind"], (result) => resolve(result)); - }); + let startSponsorKey = SB.config.startSponsorKeybind; - if (startSponsorKey.startSponsorKeybind === undefined) { - startSponsorKey.startSponsorKeybind = ";" - } - if (submitKey.submitKeybind === undefined) { - submitKey.submitKeybind = "'" - } + let submitKey = SB.config.submitKeybind; //is the video in focus, otherwise they could be typing a comment if (document.activeElement === video) { @@ -302,21 +238,17 @@ function videoIDChange(id) { //warn them if they had unsubmitted times if (previousVideoID != null) { //get the sponsor times from storage - let sponsorTimeKey = 'sponsorTimes' + previousVideoID; - chrome.storage.sync.get([sponsorTimeKey], function(result) { - let sponsorTimes = result[sponsorTimeKey]; + let sponsorTimes = SB.config.sponsorTimes.get(previousVideoID); + if (sponsorTimes != undefined && sponsorTimes.length > 0) { + //warn them that they have unsubmitted sponsor times + chrome.runtime.sendMessage({ + message: "alertPrevious", + previousVideoID: previousVideoID + }) + } - if (sponsorTimes != undefined && sponsorTimes.length > 0) { - //warn them that they have unsubmitted sponsor times - chrome.runtime.sendMessage({ - message: "alertPrevious", - previousVideoID: previousVideoID - }) - } - - //set the previous video id to the currentID - previousVideoID = id; - }); + //set the previous video id to the currentID + previousVideoID = id; } else { //set the previous id now, don't wait for chrome.storage.get previousVideoID = id; @@ -358,30 +290,8 @@ function videoIDChange(id) { } }); }); - - //see if video controls buttons should be added - chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) { - if (result.hideVideoPlayerControls != undefined) { - hideVideoPlayerControls = result.hideVideoPlayerControls; - } - - updateVisibilityOfPlayerControlsButton(); - }); - chrome.storage.sync.get(["hideInfoButtonPlayerControls"], function(result) { - if (result.hideInfoButtonPlayerControls != undefined) { - hideInfoButtonPlayerControls = result.hideInfoButtonPlayerControls; - } - - updateVisibilityOfPlayerControlsButton(); - }); - chrome.storage.sync.get(["hideDeleteButtonPlayerControls"], function(result) { - if (result.hideDeleteButtonPlayerControls != undefined) { - hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls; - } - - updateVisibilityOfPlayerControlsButton(false); - }); - + updateVisibilityOfPlayerControlsButton(); + updateVisibilityOfPlayerControlsButton(false); } function sponsorsLookup(id, channelIDPromise) { @@ -463,7 +373,7 @@ function sponsorsLookup(id, channelIDPromise) { }); //add the event to run on the videos "ontimeupdate" - if (!disableSkipping) { + if (!SB.config.disableSkipping) { v.ontimeupdate = function () { sponsorCheck(); }; @@ -542,20 +452,18 @@ function getChannelID() { //checks if this channel is whitelisted, should be done only after the channelID has been loaded function whitelistCheck() { //see if this is a whitelisted channel - chrome.storage.sync.get(["whitelistedChannels"], function(result) { - let whitelistedChannels = result.whitelistedChannels; + let whitelistedChannels = SB.config.whitelistedChannels; console.log(channelURL) if (whitelistedChannels != undefined && whitelistedChannels.includes(channelURL)) { channelWhitelisted = true; } - }); } //video skipping function sponsorCheck() { - if (disableSkipping) { + if (SB.config.disableSkipping) { // Make sure this isn't called again v.ontimeupdate = null; return; @@ -621,7 +529,7 @@ function checkIfTimeToSkip(currentVideoTime, startTime, endTime) { //skip fromt he start time to the end time for a certain index sponsor time function skipToTime(v, index, sponsorTimes, openNotice) { - if (!disableAutoSkip) { + if (!SB.config.disableAutoSkip) { v.currentTime = sponsorTimes[index][1]; } @@ -632,42 +540,23 @@ function skipToTime(v, index, sponsorTimes, openNotice) { if (openNotice) { //send out the message saying that a sponsor message was skipped - if (!dontShowNotice) { - let skipNotice = new SkipNotice(this, currentUUID, disableAutoSkip); - - if (dontShowNoticeOld) { - //show why this notice is showing - skipNotice.addNoticeInfoMessage(chrome.i18n.getMessage("noticeUpdate"), chrome.i18n.getMessage("noticeUpdate2")); - - //remove this setting - chrome.storage.sync.remove(["dontShowNoticeAgain"]); - dontShowNoticeOld = false; - } - + if (!SB.config.dontShowNotice) { + let skipNotice = new SkipNotice(this, currentUUID, SB.config.disableAutoSkip); //auto-upvote this sponsor - if (trackViewCount && !disableAutoSkip) { + if (SB.config.trackViewCount && !SB.config.disableAutoSkip) { vote(1, currentUUID, null); } } } //send telemetry that a this sponsor was skipped - if (trackViewCount && !sponsorSkipped[index]) { + if (SB.config.trackViewCount && !sponsorSkipped[index]) { sendRequestToServer("POST", "/api/viewedVideoSponsorTime?UUID=" + currentUUID); - if (!disableAutoSkip) { + if (!SB.config.disableAutoSkip) { // Count this as a skip - chrome.storage.sync.get(["minutesSaved"], function(result) { - if (result.minutesSaved === undefined) result.minutesSaved = 0; - - chrome.storage.sync.set({"minutesSaved": result.minutesSaved + (sponsorTimes[index][1] - sponsorTimes[index][0]) / 60 }); - }); - chrome.storage.sync.get(["skipCount"], function(result) { - if (result.skipCount === undefined) result.skipCount = 0; - - chrome.storage.sync.set({"skipCount": result.skipCount + 1 }); - }); - + SB.config.minutesSaved = SB.config.minutesSaved + (sponsorTimes[index][1] - sponsorTimes[index][0]) / 60; + SB.config.skipCount = SB.config.skipCount + 1; sponsorSkipped[index] = true; } } @@ -744,14 +633,14 @@ async function updateVisibilityOfPlayerControlsButton() { await createButtons(); - if (hideVideoPlayerControls) { + if (SB.config.hideDeleteButtonPlayerControls) { removePlayerControlsButton(); } //don't show the info button on embeds - if (hideInfoButtonPlayerControls || document.URL.includes("/embed/")) { + if (SB.config.hideInfoButtonPlayerControls || document.URL.includes("/embed/")) { document.getElementById("infoButton").style.display = "none"; } - if (hideDeleteButtonPlayerControls) { + if (SB.config.hideDeleteButtonPlayerControls) { document.getElementById("deleteButton").style.display = "none"; } } @@ -803,7 +692,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) { await wait(isSubmitButtonLoaded); //if it isn't visible, there is no data - let shouldHide = (uploadButtonVisible && !hideDeleteButtonPlayerControls) ? "unset" : "none" + let shouldHide = (uploadButtonVisible && !SB.config.hideDeleteButtonPlayerControls) ? "unset" : "none" document.getElementById("deleteButton").style.display = shouldHide; if (showStartSponsor) { @@ -811,7 +700,7 @@ async function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) { document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png"); document.getElementById("startSponsorButton").setAttribute("title", chrome.i18n.getMessage("sponsorStart")); - if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !hideInfoButtonPlayerControls) { + if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible && !SB.config.hideInfoButtonPlayerControls) { document.getElementById("submitButton").style.display = "unset"; } else if (!uploadButtonVisible) { //disable submit button @@ -906,28 +795,24 @@ function clearSponsorTimes() { let currentVideoID = sponsorVideoID; - let sponsorTimeKey = 'sponsorTimes' + currentVideoID; - chrome.storage.sync.get([sponsorTimeKey], function(result) { - let sponsorTimes = result[sponsorTimeKey]; + let sponsorTimes = SB.config.sponsorTimes.get(currentVideoID); - if (sponsorTimes != undefined && sponsorTimes.length > 0) { - let confirmMessage = chrome.i18n.getMessage("clearThis") + getSponsorTimesMessage(sponsorTimes); - confirmMessage += chrome.i18n.getMessage("confirmMSG") - if(!confirm(confirmMessage)) return; + if (sponsorTimes != undefined && sponsorTimes.length > 0) { + let confirmMessage = chrome.i18n.getMessage("clearThis") + getSponsorTimesMessage(sponsorTimes); + confirmMessage += chrome.i18n.getMessage("confirmMSG") + if(!confirm(confirmMessage)) return; - //clear the sponsor times - let sponsorTimeKey = "sponsorTimes" + currentVideoID; - chrome.storage.sync.set({[sponsorTimeKey]: []}); + //clear the sponsor times + SB.config.sponsorTimes.delete(currentVideoID); - //clear sponsor times submitting - sponsorTimesSubmitting = []; + //clear sponsor times submitting + sponsorTimesSubmitting = []; - updatePreviewBar(); + updatePreviewBar(); - //set buttons to be correct - changeStartSponsorButton(true, false); - } - }); + //set buttons to be correct + changeStartSponsorButton(true, false); + } } //if skipNotice is null, it will not affect the UI @@ -949,17 +834,12 @@ function vote(type, UUID, skipNotice) { sponsorSkipped[sponsorIndex] = false; } - // Count this as a skip - chrome.storage.sync.get(["minutesSaved"], function(result) { - if (result.minutesSaved === undefined) result.minutesSaved = 0; + // Count this as a skip + SB.config.minutesSaved = SB.config.minutesSaved + factor * (sponsorTimes[sponsorIndex][1] - sponsorTimes[sponsorIndex][0]) / 60; + + SB.config.skipCount = 0; - chrome.storage.sync.set({"minutesSaved": result.minutesSaved + factor * (sponsorTimes[sponsorIndex][1] - sponsorTimes[sponsorIndex][0]) / 60 }); - }); - chrome.storage.sync.get(["skipCount"], function(result) { - if (result.skipCount === undefined) result.skipCount = 0; - - chrome.storage.sync.set({"skipCount": result.skipCount + factor * 1 }); - }); + SB.config.skipCount = SB.config.skipCount + factor * 1; } chrome.runtime.sendMessage({ @@ -997,10 +877,7 @@ function closeAllSkipNotices(){ } function dontShowNoticeAgain() { - chrome.storage.sync.set({"dontShowNotice": true}); - - dontShowNotice = true; - + SB.config.dontShowNotice = true; closeAllSkipNotices(); } @@ -1027,30 +904,27 @@ function submitSponsorTimes() { let currentVideoID = sponsorVideoID; - let sponsorTimeKey = 'sponsorTimes' + currentVideoID; - chrome.storage.sync.get([sponsorTimeKey], function(result) { - let sponsorTimes = result[sponsorTimeKey]; + let sponsorTimes = SB.config.sponsorTimes.get(currentVideoID); - if (sponsorTimes != undefined && sponsorTimes.length > 0) { - //check if a sponsor exceeds the duration of the video - for (let i = 0; i < sponsorTimes.length; i++) { - if (sponsorTimes[i][1] > v.duration) { - sponsorTimes[i][1] = v.duration; - } + if (sponsorTimes != undefined && sponsorTimes.length > 0) { + //check if a sponsor exceeds the duration of the video + for (let i = 0; i < sponsorTimes.length; i++) { + if (sponsorTimes[i][1] > v.duration) { + sponsorTimes[i][1] = v.duration; } - //update sponsorTimes - chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}); - - //update sponsorTimesSubmitting - sponsorTimesSubmitting = sponsorTimes; - - let confirmMessage = chrome.i18n.getMessage("submitCheck") + "\n\n" + getSponsorTimesMessage(sponsorTimes) - + "\n\n" + chrome.i18n.getMessage("confirmMSG") + "\n\n" + chrome.i18n.getMessage("guildlinesSummary"); - if(!confirm(confirmMessage)) return; - - sendSubmitMessage(); } - }); + //update sponsorTimes + SB.config.sponsorTimes.set(currentVideoID, sponsorTimes); + + //update sponsorTimesSubmitting + sponsorTimesSubmitting = sponsorTimes; + + let confirmMessage = chrome.i18n.getMessage("submitCheck") + "\n\n" + getSponsorTimesMessage(sponsorTimes) + + "\n\n" + chrome.i18n.getMessage("confirmMSG") + "\n\n" + chrome.i18n.getMessage("guildlinesSummary"); + if(!confirm(confirmMessage)) return; + + sendSubmitMessage(); + } } @@ -1085,8 +959,7 @@ function sendSubmitMessage(){ submitButton.addEventListener("animationend", animationEndListener); //clear the sponsor times - let sponsorTimeKey = "sponsorTimes" + currentVideoID; - chrome.storage.sync.set({[sponsorTimeKey]: []}); + SB.config.sponsorTimes.delete(currentVideoID); //add submissions to current sponsors list sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting); diff --git a/manifest.json b/manifest.json index aea51e65..f87d2d31 100644 --- a/manifest.json +++ b/manifest.json @@ -6,6 +6,7 @@ "description": "__MSG_Description__", "content_scripts": [ { + "run_at": "document_start", "matches": [ "https://*.youtube.com/*", "https://www.youtube-nocookie.com/embed/*" @@ -13,6 +14,7 @@ "all_frames": true, "js": [ "config.js", + "SB.js", "utils/previewBar.js", "utils/skipNotice.js", "utils.js", @@ -52,6 +54,7 @@ }, "background": { "scripts":[ + "SB.js", "utils.js", "config.js", "background.js" diff --git a/options/options.html b/options/options.html index 45983d58..2e01e997 100644 --- a/options/options.html +++ b/options/options.html @@ -4,6 +4,7 @@ + diff --git a/options/options.js b/options/options.js index d1fef77b..14ed32ad 100644 --- a/options/options.js +++ b/options/options.js @@ -3,38 +3,33 @@ window.addEventListener('DOMContentLoaded', init); async function init() { localizeHtmlPage(); + await wait(() => SB.config !== undefined); + // Set all of the toggle options to the correct option let optionsContainer = document.getElementById("options"); let optionsElements = optionsContainer.children; - // How many checks are left to be done - let checksLeft = 0; - for (let i = 0; i < optionsElements.length; i++) { switch (optionsElements[i].getAttribute("option-type")) { case "toggle": let option = optionsElements[i].getAttribute("sync-option"); - chrome.storage.sync.get([option], function(result) { - let optionResult = result[option]; - if (optionResult != undefined) { - let checkbox = optionsElements[i].querySelector("input"); - checkbox.checked = optionResult; - let reverse = optionsElements[i].getAttribute("toggle-type") === "reverse"; + let optionResult = SB.config[option]; - if (reverse) { - optionsElements[i].querySelector("input").checked = !optionResult; - } + let checkbox = optionsElements[i].querySelector("input"); + let reverse = optionsElements[i].getAttribute("toggle-type") === "reverse"; - checkbox.addEventListener("click", () =>{ - setOptionValue(option, reverse ? !checkbox.checked : checkbox.checked) - }); + if (optionResult != undefined) { + checkbox.checked = optionResult; + + if (reverse) { + optionsElements[i].querySelector("input").checked = !optionResult; } + } - checksLeft--; + checkbox.addEventListener("click", () =>{ + SB.config[option] = reverse ? !checkbox.checked : checkbox.checked; }); - - checksLeft++; break; case "text-change": let button = optionsElements[i].querySelector(".trigger-button"); @@ -49,8 +44,6 @@ async function init() { } } - await wait(() => checksLeft == 0, 1000, 50); - optionsContainer.classList.remove("hidden"); optionsContainer.classList.add("animated"); } @@ -68,21 +61,19 @@ function activateKeybindChange(element) { let option = element.getAttribute("sync-option"); - chrome.storage.sync.get([option], function(result) { - let currentlySet = result[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : ""; - - let status = element.querySelector(".option-hidden-section > .keybind-status"); - status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet; - - if (result[option] !== null) { - let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key"); - statusKey.innerText = result[option]; - } + let currentlySet = SB.config[option] !== null ? chrome.i18n.getMessage("keybindCurrentlySet") : ""; - element.querySelector(".option-hidden-section").classList.remove("hidden"); - - document.addEventListener("keydown", (e) => keybindKeyPressed(element, e), {once: true}); - }); + let status = element.querySelector(".option-hidden-section > .keybind-status"); + status.innerText = chrome.i18n.getMessage("keybindDescription") + currentlySet; + + if (SB.config[option] !== null) { + let statusKey = element.querySelector(".option-hidden-section > .keybind-status-key"); + statusKey.innerText = SB.config[option]; + } + + element.querySelector(".option-hidden-section").classList.remove("hidden"); + + document.addEventListener("keydown", (e) => keybindKeyPressed(element, e), {once: true}); } /** @@ -97,7 +88,7 @@ function keybindKeyPressed(element, e) { let option = element.getAttribute("sync-option"); - chrome.storage.sync.set({[option]: key}); + SB.config[option] = key; let status = element.querySelector(".option-hidden-section > .keybind-status"); status.innerText = chrome.i18n.getMessage("keybindDescriptionComplete"); @@ -123,23 +114,11 @@ function activateTextChange(element) { let textBox = element.querySelector(".option-text-box"); let option = element.getAttribute("sync-option"); + + textBox.value = SB.config[option]; - chrome.storage.sync.get([option], function(result) { - textBox.value = result[option]; + let setButton = element.querySelector(".text-change-set"); + setButton.addEventListener("click", () => {SB.config[option] = textBox.value}); - let setButton = element.querySelector(".text-change-set"); - setButton.addEventListener("click", () => setOptionValue(option, textBox.value)); - - element.querySelector(".option-hidden-section").classList.remove("hidden"); - }); + element.querySelector(".option-hidden-section").classList.remove("hidden"); } - -/** - * Called when an option has been changed. - * - * @param {string} option - * @param {*} value - */ -function setOptionValue(option, value) { - chrome.storage.sync.set({[option]: value}); -} \ No newline at end of file diff --git a/popup.html b/popup.html index 6d453871..624b8b55 100644 --- a/popup.html +++ b/popup.html @@ -1,6 +1,7 @@