aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2019-08-12 23:44:53 -0400
committerGitHub <[email protected]>2019-08-12 23:44:53 -0400
commit5347340c1c3cb75d8f2aa5e6e5e903997bd7bf83 (patch)
tree87d0c0a05ae8611f8a17b3623a26a0aef7775c30
parent5916baf5ea415db2971a6871190473d102a1607e (diff)
parent524e443f4d0d4b4ddcd61800db38ba4750d99fc2 (diff)
downloadSponsorBlock-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.css18
-rw-r--r--content.js34
-rw-r--r--manifest.json3
-rw-r--r--popup.html27
-rw-r--r--popup.js74
-rw-r--r--utils/previewBar.js86
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%;
diff --git a/content.js b/content.js
index 3ee26aeb..0a181560 100644
--- a/content.js
+++ b/content.js
@@ -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"
diff --git a/popup.html b/popup.html
index 82c2d66c..0c829494 100644
--- a/popup.html
+++ b/popup.html
@@ -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/>
diff --git a/popup.js b/popup.js
index 71587889..309d5eeb 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);
@@ -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 = '&nbsp;';
+ return bar;
+ }
+
+ remove() {
+ this.container.remove();
+ this.container = undefined;
+ }
+} \ No newline at end of file