diff options
author | Ajay Ramachandran <[email protected]> | 2019-08-12 23:44:53 -0400 |
---|---|---|
committer | GitHub <[email protected]> | 2019-08-12 23:44:53 -0400 |
commit | 5347340c1c3cb75d8f2aa5e6e5e903997bd7bf83 (patch) | |
tree | 87d0c0a05ae8611f8a17b3623a26a0aef7775c30 | |
parent | 5916baf5ea415db2971a6871190473d102a1607e (diff) | |
parent | 524e443f4d0d4b4ddcd61800db38ba4750d99fc2 (diff) | |
download | SponsorBlock-5347340c1c3cb75d8f2aa5e6e5e903997bd7bf83.tar.gz SponsorBlock-5347340c1c3cb75d8f2aa5e6e5e903997bd7bf83.zip |
Merge pull request #107 from ajayyy/experimental-ajay1.0.34
Preview bar, downvote to hide sponsor, usernames
-rw-r--r-- | content.css | 18 | ||||
-rw-r--r-- | content.js | 34 | ||||
-rw-r--r-- | manifest.json | 3 | ||||
-rw-r--r-- | popup.html | 27 | ||||
-rw-r--r-- | popup.js | 74 | ||||
-rw-r--r-- | utils/previewBar.js | 86 |
6 files changed, 237 insertions, 5 deletions
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%; @@ -7,6 +7,9 @@ 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; @@ -19,6 +22,10 @@ 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 +109,7 @@ function messageListener(request, sender, sendResponse) { sendResponse({ found: sponsorDataFound, sponsorTimes: sponsorTimes, + hiddenSponsorTimes: hiddenSponsorTimes, UUIDs: UUIDs }); @@ -310,6 +318,10 @@ 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 + previewBar.set(sponsorTimes, [], v.duration); + getChannelID(); sponsorLookupRetries = 0; @@ -423,7 +435,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 +946,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 23204e4b..9d3208b8 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "name": "SponsorBlock for YouTube - Skip Sponsorships", "short_name": "SponsorBlock", - "version": "1.0.33", + "version": "1.0.34", "description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.", "content_scripts": [ { @@ -11,6 +11,7 @@ "all_frames": true, "js": [ "config.js", + "utils/previewBar.js", "utils.js", "content.js", "popup.js" @@ -114,6 +114,31 @@ </div> + <div id="setUsernameContainer" class="popupElement"> + <br/> + <br/> + + <button id="setUsernameButton" class="warningButton popupElement">Set Username</button> + </div> + + <div id="setUsername" class="popupElement" style="display: none"> + <br/> + + <h3>Set Username</h3> + + <div id="setUsernameStatusContainer" style="display: none"> + <h2 id="setUsernameStatus"></h2> + </div> + + + <input id="usernameInput" hint="Username"></input> + + <br/> + <br/> + + <button id="submitUsername" class="warningButton popupElement">Submit Username</button> + </div> + <div id="discordButtonContainer" class="popupElement" style="display: none"> <br/> @@ -121,7 +146,7 @@ <br/> - Come join the official discord server to give suggestions and feedback! + Come join the official discord server to give suggestions and feedback! <br/> @@ -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); @@ -384,7 +394,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"); @@ -988,11 +1005,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/utils/previewBar.js b/utils/previewBar.js new file mode 100644 index 00000000..95454e9d --- /dev/null +++ b/utils/previewBar.js @@ -0,0 +1,86 @@ +/* + This is based on code from VideoSegments. + https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd51f62a4e7fef4d4/segmentsbar/segmentsbar.js +*/ + +'use strict'; + +let barTypes = { + "undefined": { + color: "#00d400", + opacity: "0.5" + }, + "sponsor": { + color: "#00d400", + opacity: "0.5" + } +}; + +class PreviewBar { + constructor(parent) { + this.container = document.createElement('ul'); + this.container.id = 'previewbar'; + this.parent = parent; + this.bars = [] + + this.updatePosition(); + } + + updatePosition() { + //below the seek bar + // this.parent.insertAdjacentElement("afterEnd", this.container); + + //on the seek bar + this.parent.insertAdjacentElement("afterBegin", this.container); + } + + updateColor(segment, color, opacity) { + let bars = document.querySelectorAll('[data-vs-segment-type=' + segment + ']'); + for (let bar of bars) { + bar.style.backgroundColor = color; + bar.style.opacity = opacity; + } + } + + set(timestamps, types, duration) { + while (this.container.firstChild) { + this.container.removeChild(this.container.firstChild); + } + + if (!timestamps || !types) { + return; + } + + // to avoid rounding error resulting in width more than 100% + duration = Math.floor(duration * 100) / 100; + let width; + for (let i = 0; i < timestamps.length; i++) { + width = (timestamps[i][1] - timestamps[i][0]) / duration * 100; + width = Math.floor(width * 100) / 100; + + let bar = this.createBar(); + bar.setAttribute('data-vs-segment-type', types[i]); + + bar.style.backgroundColor = barTypes[types[i]].color; + bar.style.opacity = barTypes[types[i]].opacity; + bar.style.width = width + '%'; + bar.style.left = (timestamps[i][0] / duration * 100) + "%"; + bar.style.position = "absolute" + + this.container.insertAdjacentElement('beforeEnd', bar); + this.bars[i] = bar; + } + } + + createBar() { + let bar = document.createElement('li'); + bar.classList.add('previewbar'); + bar.innerHTML = ' '; + return bar; + } + + remove() { + this.container.remove(); + this.container = undefined; + } +}
\ No newline at end of file |