aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2019-07-22 19:27:04 -0400
committerGitHub <[email protected]>2019-07-22 19:27:04 -0400
commit180260088d2ad9af62950928263a3f238aa70d58 (patch)
treec9ae0d37a3c14cc17082338757c4317ad3a2f0c1
parentf162d6b8dd1d736762d8ee3369f34b436681045f (diff)
parent4c380aa1bf8a35d7be596927d187e5a55c863707 (diff)
downloadSponsorBlock-180260088d2ad9af62950928263a3f238aa70d58.tar.gz
SponsorBlock-180260088d2ad9af62950928263a3f238aa70d58.zip
Merge pull request #3 from ajayyy/experimentalv0.3
Error messages and usability improvements
-rw-r--r--README.md2
-rw-r--r--background.js102
-rw-r--r--content.css76
-rw-r--r--content.js355
-rw-r--r--icons/PlayerUploadFailedIconSponsorBlocker256px.pngbin0 -> 11695 bytes
-rw-r--r--icons/PlayerUploadIconSponsorBlocker256px.pngbin0 -> 11934 bytes
-rw-r--r--manifest.json2
-rw-r--r--popup.css13
-rw-r--r--popup.html34
-rw-r--r--popup.js168
10 files changed, 630 insertions, 122 deletions
diff --git a/README.md b/README.md
index fb6fe43e..89aa4c8e 100644
--- a/README.md
+++ b/README.md
@@ -29,4 +29,6 @@ None at the moment
# Credit
+The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) is used to grab the time the video was published.
+
Some icons made by <a href="https://www.flaticon.com/authors/gregor-cresnar" title="Gregor Cresnar">Gregor Cresnar</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a> and are licensed by <a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons BY 3.0" target="_blank">CC 3.0 BY</a>
diff --git a/background.js b/background.js
index c619bcbb..07743435 100644
--- a/background.js
+++ b/background.js
@@ -21,11 +21,10 @@ chrome.tabs.onUpdated.addListener( // On tab update
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
if (request.message == "submitTimes") {
- submitTimes(request.videoID);
+ submitTimes(request.videoID, callback);
- callback({
- success: true
- });
+ //this allows the callback to be called later by the submitTimes function
+ return true;
} else if (request.message == "ytvideoid") {
if (previousVideoID != request.videoID) {
videoIDChange(request.videoID);
@@ -42,7 +41,10 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//this allows the callback to be called later
return true;
} else if (request.message == "submitVote") {
- submitVote(request.type, request.UUID)
+ submitVote(request.type, request.UUID, callback);
+
+ //this allows the callback to be called later
+ return true;
}
});
@@ -51,7 +53,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
function getSponsorTimes(videoID, callback) {
let sponsorTimes = [];
let sponsorTimeKey = "sponsorTimes" + videoID;
- chrome.storage.local.get([sponsorTimeKey], function(result) {
+ chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimesStorage = result[sponsorTimeKey];
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
sponsorTimes = sponsorTimesStorage;
@@ -77,41 +79,70 @@ function addSponsorTime(time) {
//save this info
let sponsorTimeKey = "sponsorTimes" + previousVideoID;
- chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
+ chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
});
}
-function submitVote(type, UUID) {
- let xmlhttp = new XMLHttpRequest();
-
+function submitVote(type, UUID, callback) {
getUserID(function(userID) {
//publish this vote
- console.log(serverAddress + "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type);
- xmlhttp.open('GET', serverAddress + "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, true);
-
- //submit this vote
- xmlhttp.send();
+ sendRequestToServer('GET', "/api/voteOnSponsorTime?UUID=" + UUID + "&userID=" + userID + "&type=" + type, function(xmlhttp, error) {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ callback({
+ successType: 1
+ });
+ } else if (xmlhttp.readyState == 4 && xmlhttp.status == 405) {
+ //duplicate vote
+ callback({
+ successType: 0
+ });
+ } else if (error) {
+ //error while connect
+ callback({
+ successType: -1
+ });
+ }
+ })
})
}
-function submitTimes(videoID) {
+function submitTimes(videoID, callback) {
//get the video times from storage
let sponsorTimeKey = 'sponsorTimes' + videoID;
- chrome.storage.local.get([sponsorTimeKey], function(result) {
+ chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//submit these times
for (let i = 0; i < sponsorTimes.length; i++) {
- let xmlhttp = new XMLHttpRequest();
-
- let userIDStorage = getUserID(function(userIDStorage) {
+ getUserID(function(userIDStorage) {
//submit the sponsorTime
- xmlhttp.open('GET', serverAddress + "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
- + "&userID=" + userIDStorage, true);
- xmlhttp.send();
+ sendRequestToServer('GET', "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
+ + "&userID=" + userIDStorage, function(xmlhttp, error) {
+ if (xmlhttp.readyState == 4 && !error) {
+ callback({
+ statusCode: xmlhttp.status
+ });
+ } else if (error) {
+ callback({
+ statusCode: -1
+ });
+ }
+ });
});
}
+
+ //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
+ chrome.storage.sync.set({"sponsorTimesContributed": currentContributionAmount + sponsorTimes.length});
+ });
}
});
}
@@ -121,7 +152,7 @@ function videoIDChange(currentVideoID) {
if (previousVideoID != null) {
//get the sponsor times from storage
let sponsorTimeKey = 'sponsorTimes' + previousVideoID;
- chrome.storage.local.get([sponsorTimeKey], function(result) {
+ chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimes = result[sponsorTimeKey];
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
@@ -149,7 +180,7 @@ function getUserID(callback) {
}
//if it is not cached yet, grab it from storage
- chrome.storage.local.get(["userID"], function(result) {
+ chrome.storage.sync.get(["userID"], function(result) {
let userIDStorage = result.userID;
if (userIDStorage != undefined) {
userID = userIDStorage;
@@ -159,13 +190,32 @@ function getUserID(callback) {
userID = generateUUID();
//save this UUID
- chrome.storage.local.set({"userID": userID});
+ chrome.storage.sync.set({"userID": userID});
callback(userID);
}
});
}
+function sendRequestToServer(type, address, callback) {
+ let xmlhttp = new XMLHttpRequest();
+
+ xmlhttp.open(type, serverAddress + address, true);
+
+ if (callback != undefined) {
+ xmlhttp.onreadystatechange = function () {
+ callback(xmlhttp, false);
+ };
+
+ xmlhttp.onerror = function(ev) {
+ callback(xmlhttp, true);
+ };
+ }
+
+ //submit this request
+ xmlhttp.send();
+}
+
function getYouTubeVideoID(url) { // Return video id or false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
diff --git a/content.css b/content.css
index 1a85c3ac..6126768a 100644
--- a/content.css
+++ b/content.css
@@ -1,8 +1,16 @@
+.playerButton {
+ height: 60%;
+ top: 0;
+ bottom: 0;
+ display: block;
+ margin: auto;
+}
+
.sponsorSkipObject {
font-family: 'Source Sans Pro', sans-serif;
}
-#sponsorSkipLogo {
+.sponsorSkipLogo {
height: 64px;
position: absolute;
top: 0;
@@ -11,7 +19,12 @@
margin-left: 10px;
}
-#sponsorSkipNotice {
+@keyframes fadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+.sponsorSkipNotice {
min-height: 165px;
min-width: 400px;
background-color: rgba(255, 217, 217, 0.8);
@@ -19,9 +32,18 @@
z-index: 1;
border: 3px solid rgba(0, 0, 0, 0.8);
margin-top: -50px;
+
+ animation: fadeIn 0.5s;
+}
+
+/* if two are very close to eachother */
+.secondSkipNotice {
+ margin-left: 500px;
+
+ transition: margin-left 0.2s;
}
-#sponsorSkipMessage {
+.sponsorSkipMessage {
font-size: 18px;
color: #000000;
text-align: center;
@@ -30,7 +52,7 @@
margin-top: 4px;
}
-#sponsorSkipInfo {
+.sponsorSkipInfo {
font-size: 10px;
color: #000000;
text-align: center;
@@ -42,6 +64,8 @@
font-weight: bold;
color: #000000;
text-align: center;
+ margin-top: 0px;
+ margin-bottom: 0px;
}
#sponsorTimesThanksForVotingInfoText {
@@ -49,6 +73,14 @@
font-weight: bold;
color: #000000;
text-align: center;
+ margin-top: 0px;
+}
+
+.sponsorTimesInfoMessage {
+ font-size: 15px;
+ font-weight: bold;
+ color: #000000;
+ text-align: center;
}
.voteButton {
@@ -60,6 +92,42 @@
filter: brightness(80%);
}
+.submitButton {
+ background-color:#ec1c1c;
+ -moz-border-radius:28px;
+ -webkit-border-radius:28px;
+ border-radius:28px;
+ border:1px solid #d31919;
+ display:inline-block;
+ cursor:pointer;
+ color:#ffffff;
+ font-size:14px;
+ padding:4px 15px;
+ text-decoration:none;
+ text-shadow:0px 0px 0px #662727;
+
+ margin-top: 5px;
+ margin-right: 15px;
+}
+.submitButton:hover {
+ background-color:#bf2a2a;
+}
+
+.submitButton:focus {
+ outline: none;
+ background-color:#bf2a2a;
+}
+
+.submitButton:active {
+ position:relative;
+ top:1px;
+}
+
+@keyframes rotate {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
.sponsorSkipButton {
background-color:#ec1c1c;
-moz-border-radius:28px;
diff --git a/content.js b/content.js
index 91e217f6..1fdccecc 100644
--- a/content.js
+++ b/content.js
@@ -36,7 +36,7 @@ var hideVideoPlayerControls = false;
//if the notice should not be shown
//happens when the user click's the "Don't show notice again" button
var dontShowNotice = false;
-chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
+chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
let dontShowNoticeAgain = result.dontShowNoticeAgain;
if (dontShowNoticeAgain != undefined) {
dontShowNotice = dontShowNoticeAgain;
@@ -59,7 +59,8 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
//send the sponsor times along with if it's found
sendResponse({
found: sponsorDataFound,
- sponsorTimes: sponsorTimes
+ sponsorTimes: sponsorTimes,
+ UUIDs: UUIDs
})
}
@@ -73,8 +74,8 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
dontShowNotice = false;
}
- if (request.message == "toggleStartSponsorButton") {
- toggleStartSponsorButton();
+ if (request.message == "changeStartSponsorButton") {
+ changeStartSponsorButton(request.showStartSponsor, request.uploadButtonVisible);
}
if (request.message == "changeVideoPlayerControlsVisibility") {
@@ -96,14 +97,16 @@ function videoIDChange(id) {
}, function(response) {
if (response != undefined) {
let sponsorTimes = response.sponsorTimes;
- if (sponsorTimes != undefined && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
+ if (sponsorTimes != undefined && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length >= 2) {
+ document.getElementById("submitButton").style.display = "unset";
+ } else if (sponsorTimes != undefined && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
toggleStartSponsorButton();
}
}
});
//see if video control buttons should be added
- chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
+ chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
if (result.hideVideoPlayerControls != undefined) {
hideVideoPlayerControls = result.hideVideoPlayerControls;
}
@@ -117,24 +120,34 @@ function sponsorsLookup(id) {
let xmlhttp = new XMLHttpRequest();
//check database for sponsor times
- xmlhttp.open('GET', serverAddress + "/api/getVideoSponsorTimes?videoID=" + id, true);
-
- xmlhttp.onreadystatechange = function () {
- if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
- sponsorDataFound = true;
-
- sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
- UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
-
- // If the sponsor data exists, add the event to run on the videos "ontimeupdate"
- v.ontimeupdate = function () {
- sponsorCheck(sponsorTimes);
- };
- } else {
- sponsorDataFound = false;
- }
- };
- xmlhttp.send(null);
+ sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ sponsorDataFound = true;
+
+ sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
+ UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
+
+ // If the sponsor data exists, add the event to run on the videos "ontimeupdate"
+ v.ontimeupdate = function () {
+ sponsorCheck(sponsorTimes);
+ };
+ } else if (xmlhttp.readyState == 4) {
+ sponsorDataFound = false;
+
+ //check if this video was uploaded recently
+ //use the invidious api to get the time published
+ sendRequestToCustomServer('GET', "https://invidio.us/api/v1/videos/" + id, function(xmlhttp, error) {
+ if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
+ let unixTimePublished = JSON.parse(xmlhttp.responseText).published;
+
+ //if less than 3 days old
+ if ((Date.now() / 1000) - unixTimePublished < 259200) {
+ setTimeout(() => sponsorsLookup(id), 10000);
+ }
+ }
+ });
+ }
+ });
}
function sponsorCheck(sponsorTimes) { // Video skipping
@@ -148,24 +161,26 @@ function sponsorCheck(sponsorTimes) { // Video skipping
v.currentTime = sponsorTimes[i][1];
lastSponsorTimeSkipped = sponsorTimes[i][0];
- lastSponsorTimeSkippedUUID = UUIDs[i];
+
+ let currentUUID = UUIDs[i];
+ lastSponsorTimeSkippedUUID = currentUUID;
//send out the message saying that a sponsor message was skipped
openSkipNotice();
- setTimeout(closeSkipNotice, 7000);
+ setTimeout(() => closeSkipNotice(currentUUID), 7000);
}
lastTime = v.currentTime;
}
}
-function goBackToPreviousTime() {
- if (lastSponsorTimeSkipped != null) {
+function goBackToPreviousTime(UUID) {
+ if (sponsorTimes != undefined) {
//add a tiny bit of time to make sure it is not skipped again
- v.currentTime = lastSponsorTimeSkipped + 0.001;
+ v.currentTime = sponsorTimes[UUIDs.indexOf(UUID)][0] + 0.001;
- closeSkipNotice();
+ closeSkipNotice(UUID);
}
}
@@ -184,11 +199,7 @@ function addPlayerControlsButton() {
let startSponsorImage = document.createElement("img");
startSponsorImage.id = "startSponsorImage";
- startSponsorImage.style.height = "60%";
- startSponsorImage.style.top = "0";
- startSponsorImage.style.bottom = "0";
- startSponsorImage.style.display = "block";
- startSponsorImage.style.margin = "auto";
+ startSponsorImage.className = "playerButton";
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
//add the image to the button
@@ -201,6 +212,7 @@ function addPlayerControlsButton() {
function removePlayerControlsButton() {
document.getElementById("startSponsorButton").style.display = "none";
+ document.getElementById("submitButton").style.display = "none";
}
//adds or removes the player controls button to what it should be
@@ -209,6 +221,7 @@ function updateVisibilityOfPlayerControlsButton() {
removePlayerControlsButton();
} else {
addPlayerControlsButton();
+ addSubmitButton();
}
}
@@ -222,16 +235,58 @@ function startSponsorClicked() {
});
}
-function toggleStartSponsorButton() {
- if (showingStartSponsor) {
- showingStartSponsor = false;
- document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
- } else {
+function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
+ if (showStartSponsor) {
showingStartSponsor = true;
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
+
+ if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible) {
+ document.getElementById("submitButton").style.display = "unset";
+ } else if (!uploadButtonVisible) {
+ //disable submit button
+ document.getElementById("submitButton").style.display = "none";
+ }
+ } else {
+ showingStartSponsor = false;
+ document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
+
+ //disable submit button
+ document.getElementById("submitButton").style.display = "none";
}
}
+function toggleStartSponsorButton() {
+ changeStartSponsorButton(!showingStartSponsor, true);
+}
+
+//shows the submit button on the video player
+function addSubmitButton() {
+ if (document.getElementById("submitButton") != null) {
+ //it's already added
+ return;
+ }
+
+ //make a submit button
+ let submitButton = document.createElement("button");
+ submitButton.id = "submitButton";
+ submitButton.className = "ytp-button";
+ submitButton.setAttribute("title", "Submit Sponsor Times");
+ submitButton.addEventListener("click", submitSponsorTimes);
+ //hide it at the start
+ submitButton.style.display = "none";
+
+ let submitImage = document.createElement("img");
+ submitImage.id = "submitButtonImage";
+ submitImage.className = "playerButton";
+ submitImage.src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
+
+ //add the image to the button
+ submitButton.appendChild(submitImage);
+
+ let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
+ referenceNode.prepend(submitButton);
+}
+
//Opens the notice that tells the user that a sponsor was just skipped
function openSkipNotice(){
if (dontShowNotice) {
@@ -239,40 +294,57 @@ function openSkipNotice(){
return;
}
+ let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
+
+ if (amountOfPreviousNotices > 0) {
+ //already exists
+
+ let previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
+ previousNotice.classList.add("secondSkipNotice")
+ }
+
+ let UUID = lastSponsorTimeSkippedUUID;
+
let noticeElement = document.createElement("div");
- noticeElement.id = "sponsorSkipNotice";
- noticeElement.className = "sponsorSkipObject";
+ //what sponsor time this is about
+ noticeElement.id = "sponsorSkipNotice" + lastSponsorTimeSkippedUUID;
+ noticeElement.classList.add("sponsorSkipObject");
+ noticeElement.classList.add("sponsorSkipNotice");
+ noticeElement.style.zIndex = 1 + amountOfPreviousNotices;
let logoElement = document.createElement("img");
- logoElement.id = "sponsorSkipLogo";
+ logoElement.id = "sponsorSkipLogo" + lastSponsorTimeSkippedUUID;
+ logoElement.className = "sponsorSkipLogo";
logoElement.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
let noticeMessage = document.createElement("div");
- noticeMessage.id = "sponsorSkipMessage";
- noticeMessage.className = "sponsorSkipObject";
+ noticeMessage.id = "sponsorSkipMessage" + lastSponsorTimeSkippedUUID;
+ noticeMessage.classList.add("sponsorSkipMessage");
+ noticeMessage.classList.add("sponsorSkipObject");
noticeMessage.innerText = "Hey, you just skipped a sponsor!";
let noticeInfo = document.createElement("p");
- noticeInfo.id = "sponsorSkipInfo";
- noticeInfo.className = "sponsorSkipObject";
+ noticeInfo.id = "sponsorSkipInfo" + lastSponsorTimeSkippedUUID;
+ noticeInfo.classList.add("sponsorSkipInfo");
+ noticeInfo.classList.add("sponsorSkipObject");
noticeInfo.innerText = "This message will disapear in 7 seconds";
//thumbs up and down buttons
let voteButtonsContainer = document.createElement("div");
- voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer";
+ voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + lastSponsorTimeSkippedUUID;
voteButtonsContainer.setAttribute("align", "center");
let upvoteButton = document.createElement("img");
- upvoteButton.id = "sponsorTimesUpvoteButtonsContainer"
+ upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + lastSponsorTimeSkippedUUID;
upvoteButton.className = "sponsorSkipObject voteButton";
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
- upvoteButton.addEventListener("click", upvote);
+ upvoteButton.addEventListener("click", () => vote(1, UUID));
let downvoteButton = document.createElement("img");
- downvoteButton.id = "sponsorTimesDownvoteButtonsContainer"
+ downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + lastSponsorTimeSkippedUUID;
downvoteButton.className = "sponsorSkipObject voteButton";
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
- downvoteButton.addEventListener("click", downvote);
+ downvoteButton.addEventListener("click", () => vote(0, UUID));
//add thumbs up and down buttons to the container
voteButtonsContainer.appendChild(upvoteButton);
@@ -284,12 +356,12 @@ function openSkipNotice(){
let goBackButton = document.createElement("button");
goBackButton.innerText = "Go back";
goBackButton.className = "sponsorSkipButton";
- goBackButton.addEventListener("click", goBackToPreviousTime);
+ goBackButton.addEventListener("click", () => goBackToPreviousTime(UUID));
let hideButton = document.createElement("button");
hideButton.innerText = "Dismiss";
hideButton.className = "sponsorSkipButton";
- hideButton.addEventListener("click", closeSkipNotice);
+ hideButton.addEventListener("click", () => closeSkipNotice(UUID));
let dontShowAgainButton = document.createElement("button");
dontShowAgainButton.innerText = "Don't Show This Again";
@@ -316,19 +388,23 @@ function openSkipNotice(){
referenceNode.prepend(noticeElement);
}
-function upvote() {
- vote(1);
-
- closeSkipNotice();
-}
-
-function downvote() {
- vote(0);
-
+function afterDownvote(UUID) {
//change text to say thanks for voting
//remove buttons
- document.getElementById("sponsorTimesVoteButtonsContainer").removeChild(document.getElementById("sponsorTimesUpvoteButtonsContainer"));
- document.getElementById("sponsorTimesVoteButtonsContainer").removeChild(document.getElementById("sponsorTimesDownvoteButtonsContainer"));
+ let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
+ let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
+ if (upvoteButton != null) {
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
+ }
+ if (downvoteButton != null) {
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
+ }
+
+ let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
+ if (previousInfoMessage != null) {
+ //remove it
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
+ }
//add thanks for voting text
let thanksForVotingText = document.createElement("p");
@@ -341,32 +417,89 @@ function downvote() {
thanksForVotingInfoText.innerText = "Hit go back to get to where you came from."
//add element to div
- document.getElementById("sponsorTimesVoteButtonsContainer").appendChild(thanksForVotingText);
- document.getElementById("sponsorTimesVoteButtonsContainer").appendChild(thanksForVotingInfoText);
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText);
}
-function vote(type) {
+function addLoadingInfo(message, UUID) {
+ //change text to say thanks for message
+ //remove buttons
+ let upvoteButton = document.getElementById("sponsorTimesUpvoteButtonsContainer" + UUID);
+ let downvoteButton = document.getElementById("sponsorTimesDownvoteButtonsContainer" + UUID);
+ if (upvoteButton != null) {
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(upvoteButton);
+ }
+ if (downvoteButton != null) {
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(downvoteButton);
+ }
+
+ let previousInfoMessage = document.getElementById("sponsorTimesInfoMessage" + UUID);
+ if (previousInfoMessage != null) {
+ //remove it
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).removeChild(previousInfoMessage);
+ }
+
+ //add thanks for voting text
+ let thanksForVotingText = document.createElement("p");
+ thanksForVotingText.id = "sponsorTimesInfoMessage" + UUID;
+ thanksForVotingText.className = "sponsorTimesInfoMessage";
+ thanksForVotingText.innerText = message;
+
+ //add element to div
+ document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
+}
+
+function vote(type, UUID) {
+ //add loading info
+ addLoadingInfo("Loading...", UUID)
+
chrome.runtime.sendMessage({
message: "submitVote",
type: type,
- UUID: lastSponsorTimeSkippedUUID
+ UUID: UUID
+ }, function(response) {
+ if (response != undefined) {
+ //see if it was a success or failure
+ if (response.successType == 1) {
+ //success
+ if (type == 0) {
+ afterDownvote(UUID);
+ } else if (type == 1) {
+ closeSkipNotice(UUID);
+ }
+ } else if (response.successType == 0) {
+ //failure: duplicate vote
+ addLoadingInfo("It seems you've already voted before", UUID)
+ } else if (response.successType == -1) {
+ //failure: duplicate vote
+ addLoadingInfo("A connection error has occured.", UUID)
+ }
+ }
});
}
-//Closes the notice that tells the user that a sponsor was just skipped
-function closeSkipNotice(){
- let notice = document.getElementById("sponsorSkipNotice");
+//Closes the notice that tells the user that a sponsor was just skipped for this UUID
+function closeSkipNotice(UUID){
+ let notice = document.getElementById("sponsorSkipNotice" + UUID);
if (notice != null) {
notice.remove();
}
}
+//Closes all notices that tell the user that a sponsor was just skipped
+function closeAllSkipNotices(){
+ let notices = document.getElementsByClassName("sponsorSkipNotice");
+ for (let i = 0; i < notices.length; i++) {
+ notices[i].remove();
+ }
+}
+
function dontShowNoticeAgain() {
- chrome.storage.local.set({"dontShowNoticeAgain": true});
+ chrome.storage.sync.set({"dontShowNoticeAgain": true});
dontShowNotice = true;
- closeSkipNotice();
+ closeAllSkipNotices();
}
function sponsorMessageStarted() {
@@ -382,6 +515,80 @@ function sponsorMessageStarted() {
toggleStartSponsorButton();
}
+function submitSponsorTimes() {
+ //add loading animation
+ document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
+ document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
+
+ let currentVideoID = getYouTubeVideoID(document.URL);
+
+ chrome.runtime.sendMessage({
+ message: "submitTimes",
+ videoID: currentVideoID
+ }, function(response) {
+ if (response != undefined) {
+ if (response.statusCode == 200) {
+ //hide loading message
+ let submitButton = document.getElementById("submitButton");
+ //finish this animation
+ submitButton.style.animation = "rotate 1s";
+ //when the animation is over, hide the button
+ submitButton.addEventListener("animationend", function() {
+ submitButton.style.animation = "unset";
+ submitButton.style.display = "none";
+ });
+
+ //clear the sponsor times
+ let sponsorTimeKey = "sponsorTimes" + currentVideoID;
+ chrome.storage.sync.set({[sponsorTimeKey]: []});
+ } else {
+ //for a more detailed error message, they should check the popup
+ //show that the upload failed
+ document.getElementById("submitButton").style.animation = "unset";
+ document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadFailedIconSponsorBlocker256px.png");
+ }
+ }
+ });
+}
+
+function sendRequestToServer(type, address, callback) {
+ let xmlhttp = new XMLHttpRequest();
+
+ xmlhttp.open(type, serverAddress + address, true);
+
+ if (callback != undefined) {
+ xmlhttp.onreadystatechange = function () {
+ callback(xmlhttp, false);
+ };
+
+ xmlhttp.onerror = function(ev) {
+ callback(xmlhttp, true);
+ };
+ }
+
+ //submit this request
+ xmlhttp.send();
+}
+
+function sendRequestToCustomServer(type, fullAddress, callback) {
+ let xmlhttp = new XMLHttpRequest();
+
+ xmlhttp.open(type, fullAddress, true);
+
+ if (callback != undefined) {
+ xmlhttp.onreadystatechange = function () {
+ callback(xmlhttp, false);
+ };
+
+ xmlhttp.onerror = function(ev) {
+ callback(xmlhttp, true);
+ };
+ }
+
+ //submit this request
+ xmlhttp.send();
+}
+
function getYouTubeVideoID(url) { // Returns with video id else returns false
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
diff --git a/icons/PlayerUploadFailedIconSponsorBlocker256px.png b/icons/PlayerUploadFailedIconSponsorBlocker256px.png
new file mode 100644
index 00000000..57c80838
--- /dev/null
+++ b/icons/PlayerUploadFailedIconSponsorBlocker256px.png
Binary files differ
diff --git a/icons/PlayerUploadIconSponsorBlocker256px.png b/icons/PlayerUploadIconSponsorBlocker256px.png
new file mode 100644
index 00000000..5be42678
--- /dev/null
+++ b/icons/PlayerUploadIconSponsorBlocker256px.png
Binary files differ
diff --git a/manifest.json b/manifest.json
index c742d16d..f0a4ba7b 100644
--- a/manifest.json
+++ b/manifest.json
@@ -22,6 +22,8 @@
"icons/IconSponsorBlocker256px.png",
"icons/PlayerStartIconSponsorBlocker256px.png",
"icons/PlayerStopIconSponsorBlocker256px.png",
+ "icons/PlayerUploadIconSponsorBlocker256px.png",
+ "icons/PlayerUploadFailedIconSponsorBlocker256px.png",
"icons/upvote.png",
"icons/downvote.png"
],
diff --git a/popup.css b/popup.css
index 64ae0a17..ec2f1d59 100644
--- a/popup.css
+++ b/popup.css
@@ -12,6 +12,19 @@ body {
background-color: #ffd9d9;
}
+.recordingSubtitle {
+ margin-bottom: 10px;
+}
+
+.voteButton {
+ height: 32px;
+ margin-right: 15px;
+ cursor: pointer;
+}
+.voteButton:hover {
+ filter: brightness(80%);
+}
+
.greenButton {
background-color:#ec1c1c;
-moz-border-radius:28px;
diff --git a/popup.html b/popup.html
index 79b7adde..b180d788 100644
--- a/popup.html
+++ b/popup.html
@@ -24,8 +24,26 @@
<div id="downloadedSponsorMessageTimes">
</div>
-
- <h2>Record the times of a sponsorship</h2>
+
+ <br/>
+
+ <button id="reportAnIssue" class="dangerButton">Vote On A Sponsor Time</button>
+
+ <div id="issueReporterContainer" style="display: none">
+
+ <h3 style="margin-top: 0px">Vote On A Sponsor Time</h3>
+
+ <div id="issueReporterTimeButtons">
+
+ </div>
+
+ </div>
+
+ <h2 class="recordingSubtitle">Record the times of a sponsorship</h2>
+
+ <p id="sponsorTimesContributionsDisplay" style="display: none">
+ So far, you've submitted no sponsor times.
+ </p>
<p>
Click the button below when the sponsorship starts and ends to record and
@@ -48,8 +66,18 @@
<br/>
<br/>
+
+ <div id="submitTimesContainer" style="display: none">
+ <button id="submitTimes" class="smallButton">Submit Times</button>
+
+ <div id="submitTimesInfoMessageContainer" style="display: none">
+ <h3 id="submitTimesInfoMessage">
+
+ </h3>
+ </div>
+
+ </div>
- <button id="submitTimes" style="display: none" class="smallButton">Submit Times</button>
</div>
<div id="optionsButtonContainer">
diff --git a/popup.js b/popup.js
index d5b984f0..36f6e2d2 100644
--- a/popup.js
+++ b/popup.js
@@ -6,6 +6,7 @@ document.getElementById("showNoticeAgain").addEventListener("click", showNoticeA
document.getElementById("hideVideoPlayerControls").addEventListener("click", hideVideoPlayerControls);
document.getElementById("showVideoPlayerControls").addEventListener("click", showVideoPlayerControls);
document.getElementById("optionsButton").addEventListener("click", openOptions);
+document.getElementById("reportAnIssue").addEventListener("click", reportAnIssue);
//if true, the button now selects the end time
var startTimeChosen = false;
@@ -21,7 +22,7 @@ var isYouTubeTab = false;
//if the don't show notice again variable is true, an option to
// disable should be available
-chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
+chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
let dontShowNoticeAgain = result.dontShowNoticeAgain;
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
document.getElementById("showNoticeAgain").style.display = "unset";
@@ -29,7 +30,7 @@ chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
});
//show proper video player controls option
-chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
+chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
let hideVideoPlayerControls = result.hideVideoPlayerControls;
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
document.getElementById("hideVideoPlayerControls").style.display = "none";
@@ -37,6 +38,20 @@ chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
}
});
+//get the amount of times this user has contributed and display it to thank them
+chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
+ if (result.sponsorTimesContributed != undefined) {
+ let sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
+
+ if (result.sponsorTimesContributed > 1) {
+ sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor times.";
+ } else {
+ sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor time.";
+ }
+ sponsorTimesContributionsDisplay.style.display = "unset";
+ }
+});
+
chrome.tabs.query({
active: true,
currentWindow: true
@@ -54,7 +69,7 @@ function loadTabData(tabs) {
//load video times for this video
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
- chrome.storage.local.get([sponsorTimeKey], function(result) {
+ chrome.storage.sync.get([sponsorTimeKey], function(result) {
let sponsorTimesStorage = result[sponsorTimeKey];
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
@@ -139,7 +154,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = request.time;
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
- chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
+ chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
updateStartTimeChosen();
@@ -164,6 +179,56 @@ function displayDownloadedSponsorTimes(request) {
if (request.sponsorTimes != undefined) {
//set it to the message
document.getElementById("downloadedSponsorMessageTimes").innerHTML = getSponsorTimesMessage(request.sponsorTimes);
+
+ //add them as buttons to the issue reporting container
+ let container = document.getElementById("issueReporterTimeButtons");
+ for (let i = 0; i < request.sponsorTimes.length; i++) {
+ let sponsorTimeButton = document.createElement("button");
+ sponsorTimeButton.className = "warningButton";
+ sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]);
+
+ let votingButtons = document.createElement("div");
+
+ let UUID = request.UUIDs[i];
+
+ //thumbs up and down buttons
+ let voteButtonsContainer = document.createElement("div");
+ voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
+ voteButtonsContainer.setAttribute("align", "center");
+ voteButtonsContainer.style.display = "none"
+
+ let upvoteButton = document.createElement("img");
+ upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
+ upvoteButton.className = "voteButton";
+ upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
+ upvoteButton.addEventListener("click", () => vote(1, UUID));
+
+ let downvoteButton = document.createElement("img");
+ downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
+ downvoteButton.className = "voteButton";
+ downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
+ downvoteButton.addEventListener("click", () => vote(0, UUID));
+
+ //add thumbs up and down buttons to the container
+ voteButtonsContainer.appendChild(document.createElement("br"));
+ voteButtonsContainer.appendChild(document.createElement("br"));
+ voteButtonsContainer.appendChild(upvoteButton);
+ voteButtonsContainer.appendChild(downvoteButton);
+
+ //add click listener to open up vote panel
+ sponsorTimeButton.addEventListener("click", function() {
+ voteButtonsContainer.style.display = "unset";
+ });
+
+ container.appendChild(sponsorTimeButton);
+ container.appendChild(voteButtonsContainer);
+
+ //if it is not the last iteration
+ if (i != request.sponsorTimes.length - 1) {
+ container.appendChild(document.createElement("br"));
+ container.appendChild(document.createElement("br"));
+ }
+ }
}
}
@@ -190,14 +255,16 @@ function getSponsorTimesMessage(sponsorTimes) {
}
function clearTimes() {
- //check if the player controls should be toggled
- if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
+ //send new sponsor time state to tab
+ if (sponsorTimes.length > 0) {
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {
- message: "toggleStartSponsorButton"
+ message: "changeStartSponsorButton",
+ showStartSponsor: true,
+ uploadButtonVisible: false
});
});
}
@@ -206,7 +273,7 @@ function clearTimes() {
sponsorTimes = [];
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
- chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
+ chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
displaySponsorTimes();
@@ -217,18 +284,41 @@ function clearTimes() {
}
function submitTimes() {
+ //make info message say loading
+ document.getElementById("submitTimesInfoMessage").innerText = "Loading...";
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
+
if (sponsorTimes.length > 0) {
chrome.runtime.sendMessage({
message: "submitTimes",
videoID: currentVideoID
- }, function(request) {
- clearTimes();
+ }, function(response) {
+ if (response != undefined) {
+ if (response.statusCode == 200) {
+ //hide loading message
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "none";
+
+ clearTimes();
+ } else if(response.statusCode == 400) {
+ document.getElementById("submitTimesInfoMessage").innerText = "Server said this request was invalid";
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
+ } else if(response.statusCode == 429) {
+ document.getElementById("submitTimesInfoMessage").innerText = "You have submitted too many sponsor times for this one video, are you sure there are this many?";
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
+ } else if(response.statusCode == 409) {
+ document.getElementById("submitTimesInfoMessage").innerText = "This has already been submitted before";
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
+ } else {
+ document.getElementById("submitTimesInfoMessage").innerText = "There was an error submitting your sponsor times, please try again later";
+ document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
+ }
+ }
});
}
}
function showNoticeAgain() {
- chrome.storage.local.set({"dontShowNoticeAgain": false});
+ chrome.storage.sync.set({"dontShowNoticeAgain": false});
chrome.tabs.query({
active: true,
@@ -243,7 +333,7 @@ function showNoticeAgain() {
}
function hideVideoPlayerControls() {
- chrome.storage.local.set({"hideVideoPlayerControls": true});
+ chrome.storage.sync.set({"hideVideoPlayerControls": true});
chrome.tabs.query({
active: true,
@@ -260,7 +350,7 @@ function hideVideoPlayerControls() {
}
function showVideoPlayerControls() {
- chrome.storage.local.set({"hideVideoPlayerControls": false});
+ chrome.storage.sync.set({"hideVideoPlayerControls": false});
chrome.tabs.query({
active: true,
@@ -292,13 +382,15 @@ function resetStartTimeChosen() {
document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now";
}
+//hides and shows the submit times button when needed
function showSubmitTimesIfNecessary() {
//check if an end time has been specified for the latest sponsor time
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) {
//show submit times button
- document.getElementById("submitTimes").style.display = "unset";
+ document.getElementById("submitTimesContainer").style.display = "unset";
} else {
- document.getElementById("submitTimes").style.display = "none";
+ //hide submit times button
+ document.getElementById("submitTimesContainer").style.display = "none";
}
}
@@ -314,6 +406,52 @@ function displayNoVideo() {
"If you know this is a YouTube tab, close this popup and open it again.";
}
+function reportAnIssue() {
+ document.getElementById("issueReporterContainer").style.display = "unset";
+ document.getElementById("reportAnIssue").style.display = "none";
+}
+
+function addVoteMessage(message, UUID) {
+ let container = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID);
+ //remove all children
+ while (container.firstChild) {
+ container.removeChild(container.firstChild);
+ }
+
+ let thanksForVotingText = document.createElement("h2");
+ thanksForVotingText.innerText = message;
+ //there are already breaks there
+ thanksForVotingText.style.marginBottom = "0px";
+
+ container.appendChild(thanksForVotingText);
+}
+
+function vote(type, UUID) {
+ //add loading info
+ addVoteMessage("Loading...", UUID)
+
+ //send the vote message to the tab
+ chrome.runtime.sendMessage({
+ message: "submitVote",
+ type: type,
+ UUID: UUID
+ }, function(response) {
+ if (response != undefined) {
+ //see if it was a success or failure
+ if (response.successType == 1) {
+ //success
+ addVoteMessage("Thanks for voting!", UUID)
+ } else if (response.successType == 0) {
+ //failure: duplicate vote
+ addVoteMessage("You have already voted this way before.", UUID)
+ } else if (response.successType == -1) {
+ //failure: duplicate vote
+ addVoteMessage("A connection error has occured.", UUID)
+ }
+ }
+ });
+}
+
//converts time in seconds to minutes:seconds
function getFormattedTime(seconds) {
let minutes = Math.floor(seconds / 60);