diff --git a/background.js b/background.js index c5927143..e531869d 100644 --- a/background.js +++ b/background.js @@ -5,38 +5,39 @@ chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { }); chrome.runtime.onMessage.addListener(function (request, sender, callback) { - if (request.message == "submitTimes") { - submitTimes(request.videoID, callback); - - //this allows the callback to be called later by the submitTimes function - return true; - } else if (request.message == "addSponsorTime") { - addSponsorTime(request.time, request.videoID, callback); - - //this allows the callback to be called later - return true; - } else if (request.message == "getSponsorTimes") { - getSponsorTimes(request.videoID, function(sponsorTimes) { - callback({ - sponsorTimes: sponsorTimes - }) - }); - - //this allows the callback to be called later - return true; - } else if (request.message == "submitVote") { - submitVote(request.type, request.UUID, callback); - - //this allows the callback to be called later - return true; - } else if (request.message == "alertPrevious") { - chrome.notifications.create("stillThere" + Math.random(), { - type: "basic", - title: chrome.i18n.getMessage("wantToSubmit") + request.previousVideoID + "?", - message: chrome.i18n.getMessage("leftTimes"), - iconUrl: "./icons/LogoSponsorBlocker256px.png" - }); - } + switch(request.message) { + case "submitTimes": + submitTimes(request.videoID, callback); + + //this allows the callback to be called later by the submitTimes function + return true; + case "addSponsorTime": + addSponsorTime(request.time, request.videoID, callback); + + //this allows the callback to be called later + return true; + case "getSponsorTimes": + getSponsorTimes(request.videoID, function(sponsorTimes) { + callback({ + sponsorTimes: sponsorTimes + }) + }); + + //this allows the callback to be called later + return true; + case "submitVote": + submitVote(request.type, request.UUID, callback); + + //this allows the callback to be called later + return true; + case "alertPrevious": + chrome.notifications.create("stillThere" + Math.random(), { + type: "basic", + title: "Do you want to submit the sponsor times for video id " + request.previousVideoID + "?", + message: "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted).", + iconUrl: "./icons/LogoSponsorBlocker256px.png" + }); + } }); //add help page on install diff --git a/content.css b/content.css index 1d118fcf..c05f2f16 100644 --- a/content.css +++ b/content.css @@ -1,3 +1,21 @@ +#previewbar { + overflow: visible; + padding: 0; + margin: 0; + position: absolute; + width: 100%; + pointer-events: none; + + height: 100%; + transform: scaleY(0.6) translateY(-30%) translateY(1.5px); + z-index: 40; +} + +.previewbar { + display: inline-block; + height: 100%; +} + .popup { z-index: 10; width: 100%; diff --git a/content.js b/content.js index 5d433620..eb3b254b 100644 --- a/content.js +++ b/content.js @@ -7,18 +7,27 @@ var UUIDs = null; //what video id are these sponsors for var sponsorVideoID = null; +//these are sponsors that have been downvoted +var hiddenSponsorTimes = []; + //the time this video is starting at when first played, if not zero var youtubeVideoStartTime = null; //the video var v; +var listenerAdded; + //the channel this video is about var channelURL; //is this channel whitelised from getting sponsors skipped var channelWhitelisted = false; +// create preview bar +let progressBar = document.getElementsByClassName("ytp-progress-bar-container")[0] || document.getElementsByClassName("no-model cue-range-markers")[0]; +var previewBar = new PreviewBar(progressBar); + if(id = getYouTubeVideoID(document.URL)){ // Direct Links videoIDChange(id); } @@ -102,6 +111,7 @@ function messageListener(request, sender, sendResponse) { sendResponse({ found: sponsorDataFound, sponsorTimes: sponsorTimes, + hiddenSponsorTimes: hiddenSponsorTimes, UUIDs: UUIDs }); @@ -233,6 +243,9 @@ function videoIDChange(id) { sponsorVideoID = id; sponsorLookupRetries = 0; + //empty the preview bar + previewBar.set([], [], 0); + //see if there is a video start time youtubeVideoStartTime = getYouTubeVideoStartTime(document.URL); @@ -310,6 +323,17 @@ function sponsorsLookup(id) { sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes; UUIDs = JSON.parse(xmlhttp.responseText).UUIDs; + //update the preview bar + //leave the type blank for now until categories are added + console.log(v.duration) + if (isNaN(v.duration)) { + //wait until it is loaded + v.addEventListener('durationchange', updatePreviewBar); + } else { + //set it now + updatePreviewBar(); + } + getChannelID(); sponsorLookupRetries = 0; @@ -330,7 +354,7 @@ function sponsorsLookup(id) { }); sponsorLookupRetries = 0; - } else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 15) { + } else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90) { //some error occurred, try again in a second setTimeout(() => sponsorsLookup(id), 1000); @@ -344,6 +368,13 @@ function sponsorsLookup(id) { }; } +function updatePreviewBar() { + previewBar.set(sponsorTimes, [], v.duration); + + //the listener is only needed once + v.removeEventListener('durationchange', updatePreviewBar); +} + function getChannelID() { //get channel id let channelContainers = document.querySelectorAll("#owner-name"); @@ -423,7 +454,7 @@ function checkSponsorTime(sponsorTimes, index, openNotice) { lastTime = v.currentTime - 0.0001; } - if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0])) { + if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0]) && !hiddenSponsorTimes.includes(index)) { //skip it skipToTime(v, index, sponsorTimes, openNotice); @@ -934,6 +965,26 @@ function afterDownvote(UUID) { //add element to div document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText); document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText); + + //remove this sponsor from the sponsors looked up + //find which one it is + for (let i = 0; i < sponsorTimes.length; i++) { + if (UUIDs[i] == UUID) { + //this one is the one to hide + + //add this as a hidden sponsorTime + hiddenSponsorTimes.push(i); + + let sponsorTimesLeft = sponsorTimes.slice(); + for (let j = 0; j < hiddenSponsorTimes.length; j++) { + //remove this sponsor time + sponsorTimesLeft.splice(hiddenSponsorTimes[j], 1); + } + + //update the preview + previewBar.set(sponsorTimesLeft, [], v.duration); + } + } } function addLoadingInfo(message, UUID) { diff --git a/manifest.json b/manifest.json index c121f6ef..b2ea0914 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_fullName__", "short_name": "__MSG_Name__", - "version": "1.0.33", + "version": "1.0.35", "default_locale": "en", "description": "__MSG_Description__", "content_scripts": [ @@ -12,6 +12,7 @@ "all_frames": true, "js": [ "config.js", + "utils/previewBar.js", "utils.js", "content.js", "popup.js" diff --git a/popup.js b/popup.js index 209763e1..76d7dba8 100644 --- a/popup.js +++ b/popup.js @@ -54,6 +54,14 @@ function runThePopup() { // submitTimesInfoMessage "submitTimesInfoMessageContainer", "submitTimesInfoMessage", + // Username + "setUsernameContainer", + "setUsernameButton", + "setUsernameStatusContainer", + "setUsernameStatus", + "setUsername", + "usernameInput", + "submitUsername", // More "submissionSection", "mainControls", @@ -78,6 +86,8 @@ function runThePopup() { SB.showDeleteButtonPlayerControls.addEventListener("click", showDeleteButtonPlayerControls); SB.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking); SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking); + SB.setUsernameButton.addEventListener("click", setUsernameButton); + SB.submitUsername.addEventListener("click", submitUsername); SB.optionsButton.addEventListener("click", openOptions); SB.reportAnIssue.addEventListener("click", reportAnIssue); SB.hideDiscordButton.addEventListener("click", hideDiscordButton); @@ -374,7 +384,14 @@ function runThePopup() { for (let i = 0; i < request.sponsorTimes.length; i++) { let sponsorTimeButton = document.createElement("button"); sponsorTimeButton.className = "warningButton popupElement"; - sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]); + + let extraInfo = ""; + if (request.hiddenSponsorTimes.includes(i)) { + //this one is hidden + extraInfo = " (hidden)"; + } + + sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]) + extraInfo; let votingButtons = document.createElement("div"); @@ -973,11 +990,64 @@ function runThePopup() { } } - //make the options div visisble + //make the options div visible function openOptions() { document.getElementById("optionsButtonContainer").style.display = "none"; document.getElementById("options").style.display = "unset"; } + + //make the options username setting option visible + function setUsernameButton() { + //get the userID + chrome.storage.sync.get(["userID"], function(result) { + //get username from the server + sendRequestToServer("GET", "/api/getUsername?userID=" + result.userID, function (xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + SB.usernameInput.value = JSON.parse(xmlhttp.responseText).userName; + + SB.submitUsername.style.display = "unset"; + SB.usernameInput.style.display = "unset"; + + SB.setUsernameContainer.style.display = "none"; + SB.setUsername.style.display = "unset"; + } else { + SB.setUsername.style.display = "unset"; + SB.submitUsername.style.display = "none"; + SB.usernameInput.style.display = "none"; + + SB.setUsernameStatus.innerText = "Couldn't connect to server. Error code: " + xmlhttp.status; + } + }); + }); + } + + //submit the new username + function submitUsername() { + //add loading indicator + SB.setUsernameStatusContainer.style.display = "unset"; + SB.setUsernameStatus.innerText = "Loading..."; + + //get the userID + chrome.storage.sync.get(["userID"], function(result) { + sendRequestToServer("POST", "/api/setUsername?userID=" + result.userID + "&username=" + SB.usernameInput.value, function (xmlhttp, error) { + if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { + //submitted + SB.submitUsername.style.display = "none"; + SB.usernameInput.style.display = "none"; + + SB.setUsernameStatus.innerText = "Success!"; + } else if (xmlhttp.readyState == 4 && xmlhttp.status == 400) { + SB.setUsernameStatus.innerText = "Bad Request"; + } else { + SB.setUsernameStatus.innerText = getErrorMessage(EN_US, xmlhttp.status); + } + }); + }); + + + SB.setUsernameContainer.style.display = "none"; + SB.setUsername.style.display = "unset"; + } //this is not a YouTube video page function displayNoVideo() { diff --git a/popup_en.html b/popup_en.html index 82c2d66c..0c829494 100644 --- a/popup_en.html +++ b/popup_en.html @@ -114,6 +114,31 @@ +