Merge pull request #3 from ajayyy/experimental

Error messages and usability improvements
This commit is contained in:
Ajay Ramachandran 2019-07-22 19:27:04 -04:00 committed by GitHub
commit 180260088d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 627 additions and 119 deletions

View file

@ -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>

View file

@ -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);

View file

@ -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;
}
#sponsorSkipMessage {
/* if two are very close to eachother */
.secondSkipNotice {
margin-left: 500px;
transition: margin-left 0.2s;
}
.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;

View file

@ -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);
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
sponsorDataFound = 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;
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;
// 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);
//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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -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"
],

View file

@ -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;

View file

@ -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">

168
popup.js
View file

@ -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);