Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30c6437160 | ||
|
|
e8ff6171eb | ||
|
|
b7764fc634 | ||
|
|
9913e99a6a | ||
|
|
c91c08a17f | ||
|
|
86bffeb96c | ||
|
|
c580a7dc7c | ||
|
|
22df50e3fe | ||
|
|
6d32b88490 | ||
|
|
95dee05e92 | ||
|
|
21220bf2d3 | ||
|
|
180260088d | ||
|
|
4c380aa1bf | ||
|
|
1040868ebb | ||
|
|
b7a35f0823 | ||
|
|
baefc59954 | ||
|
|
14121af900 | ||
|
|
52ec50a132 | ||
|
|
f162d6b8dd | ||
|
|
2d00cfffdf | ||
|
|
a7a4642920 | ||
|
|
91f0b65d06 | ||
|
|
4cc44258e8 | ||
|
|
4bb6cd0dcf | ||
|
|
b319729da8 | ||
|
|
888a03a708 | ||
|
|
e452e02bda | ||
|
|
01b61f6192 |
2
.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
content-config.js
|
||||
config.js
|
||||
ignored
|
||||
@@ -1,9 +1,9 @@
|
||||

|
||||
<br/><sub>Logo by [@munadikieh](https://github.com/munadikieh)</sub>
|
||||
|
||||
# SponsorBlocker
|
||||
# SponsorBlock
|
||||
|
||||
SponsorBlocker is an extension that will skip over sponsored segments of YouTube videos. SponsorBlocker is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
|
||||
SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.
|
||||
|
||||
# Server
|
||||
|
||||
@@ -29,4 +29,6 @@ None at the moment
|
||||
|
||||
# Credit
|
||||
|
||||
Some i 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>
|
||||
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>
|
||||
|
||||
102
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);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
//this file is loaded along iwth content.js
|
||||
//this file sets the server to connect to, and is gitignored
|
||||
var serverAddress = "http://localhost";
|
||||
80
content.css
@@ -1,8 +1,20 @@
|
||||
.playerButtonImage {
|
||||
height: 60%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.playerButton {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sponsorSkipObject {
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
}
|
||||
|
||||
#sponsorSkipLogo {
|
||||
.sponsorSkipLogo {
|
||||
height: 64px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -11,7 +23,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 +36,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 +56,7 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#sponsorSkipInfo {
|
||||
.sponsorSkipInfo {
|
||||
font-size: 10px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
@@ -42,6 +68,8 @@
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
#sponsorTimesThanksForVotingInfoText {
|
||||
@@ -49,6 +77,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 +96,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;
|
||||
|
||||
387
content.js
@@ -21,6 +21,9 @@ var v;
|
||||
//the last time looked at (used to see if this time is in the interval)
|
||||
var lastTime;
|
||||
|
||||
//the last time skipped to
|
||||
var lastTimeSkippedTo = -1;
|
||||
|
||||
//the last time in the video a sponsor was skipped
|
||||
//used for the go back button
|
||||
var lastSponsorTimeSkipped = null;
|
||||
@@ -36,7 +39,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 +62,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 +77,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 +100,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;
|
||||
}
|
||||
@@ -114,58 +120,75 @@ function videoIDChange(id) {
|
||||
|
||||
function sponsorsLookup(id) {
|
||||
v = document.querySelector('video') // Youtube video player
|
||||
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
|
||||
//see if any sponsor start time was just passed
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//the sponsor time is in between these times, skip it
|
||||
//if the time difference is more than 1 second, than the there was probably a skip in time,
|
||||
// and it's not due to playback
|
||||
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
//see if any sponsor start time was just passed
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
//the sponsor time is in between these times, skip it
|
||||
//if the time difference is more than 1 second, than the there was probably a skip in time,
|
||||
// and it's not due to playback
|
||||
//also check if the last time skipped to is not too close to now, to make sure not to get too many
|
||||
// sponsor times in a row (from one troll)
|
||||
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime &&
|
||||
(lastTimeSkippedTo == -1 || Math.abs(v.currentTime - lastTimeSkippedTo) > 1)) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
lastTimeSkippedTo = sponsorTimes[i][1];
|
||||
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
lastSponsorTimeSkippedUUID = UUIDs[i];
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
|
||||
let currentUUID = UUIDs[i];
|
||||
lastSponsorTimeSkippedUUID = currentUUID;
|
||||
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
openSkipNotice();
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
openSkipNotice();
|
||||
|
||||
setTimeout(closeSkipNotice, 7000);
|
||||
}
|
||||
setTimeout(() => closeSkipNotice(currentUUID), 7000);
|
||||
|
||||
lastTime = v.currentTime;
|
||||
//send telemetry that a this sponsor was skipped happened
|
||||
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,17 +201,13 @@ function addPlayerControlsButton() {
|
||||
|
||||
let startSponsorButton = document.createElement("button");
|
||||
startSponsorButton.id = "startSponsorButton";
|
||||
startSponsorButton.className = "ytp-button";
|
||||
startSponsorButton.className = "ytp-button playerButton";
|
||||
startSponsorButton.setAttribute("title", "Sponsor Starts Now");
|
||||
startSponsorButton.addEventListener("click", startSponsorClicked);
|
||||
|
||||
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 = "playerButtonImage";
|
||||
startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
@@ -201,6 +220,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 +229,7 @@ function updateVisibilityOfPlayerControlsButton() {
|
||||
removePlayerControlsButton();
|
||||
} else {
|
||||
addPlayerControlsButton();
|
||||
addSubmitButton();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,16 +243,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 playerButton";
|
||||
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 = "playerButtonImage";
|
||||
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 +302,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 +364,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 +396,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 +425,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 +523,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);
|
||||
|
||||
61
firefox_manifest.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "SponsorBlock - YouTube Sponsorship Blocker",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.1",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"https://*.youtube.com/*"
|
||||
],
|
||||
"js": [
|
||||
"config.js",
|
||||
"content.js"
|
||||
],
|
||||
"css": [
|
||||
"content.css",
|
||||
"./libs/Source+Sans+Pro.css"
|
||||
]
|
||||
}
|
||||
],
|
||||
"web_accessible_resources": [
|
||||
"icons/LogoSponsorBlocker256px.png",
|
||||
"icons/IconSponsorBlocker256px.png",
|
||||
"icons/PlayerStartIconSponsorBlocker256px.png",
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"browser_action": {
|
||||
"default_title": "SponsorBlock",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"background": {
|
||||
"scripts":[
|
||||
"config.js",
|
||||
"background.js"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/IconSponsorBlocker16px.png",
|
||||
"32": "icons/IconSponsorBlocker32px.png",
|
||||
"64": "icons/LogoSponsorBlocker64px.png",
|
||||
"128": "icons/LogoSponsorBlocker128px.png",
|
||||
"256": "icons/LogoSponsorBlocker256px.png"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "sponsorBlocker@ajay.app",
|
||||
"strict_min_version": "57.0"
|
||||
}
|
||||
},
|
||||
"manifest_version": 2
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.3 KiB |
BIN
icons/PlayerUploadFailedIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
icons/PlayerUploadIconSponsorBlocker256px.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"name": "YTSponsorSkip",
|
||||
"version": "1.0",
|
||||
"description": "Skip youtube video sponsors.",
|
||||
"name": "SponsorBlock - YouTube Sponsorship Blocker",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.1",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
@@ -22,13 +23,16 @@
|
||||
"icons/IconSponsorBlocker256px.png",
|
||||
"icons/PlayerStartIconSponsorBlocker256px.png",
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"notifications"
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"browser_action": {
|
||||
"default_title": "SponsorBlock",
|
||||
|
||||
13
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;
|
||||
|
||||
55
popup.html
@@ -24,8 +24,44 @@
|
||||
<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>
|
||||
<span id=sponsorTimesContributionsContainer style="display: none">
|
||||
So far, you've submitted
|
||||
<span id="sponsorTimesContributionsDisplay">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesContributionsDisplayEndWord">
|
||||
sponsors.
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<span id=sponsorTimesViewsContainer style="display: none">
|
||||
You have saved people from
|
||||
<span id="sponsorTimesViewsDisplay">
|
||||
0
|
||||
</span>
|
||||
<span id="sponsorTimesViewsDisplayEndWord">
|
||||
sponsor segments.
|
||||
</span>
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Click the button below when the sponsorship starts and ends to record and
|
||||
@@ -48,8 +84,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">
|
||||
@@ -75,5 +121,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
|
||||
<!-- Scripts that need to load after the html -->
|
||||
<script src="config.js"></script>
|
||||
<script src="popup.js"></script>
|
||||
</html>
|
||||
219
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,52 @@ 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 sponsorTimesContributionsContainer = document.getElementById("sponsorTimesContributionsContainer");
|
||||
let sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
|
||||
let sponsorTimesContributionsDisplayEndWord = document.getElementById("sponsorTimesContributionsDisplayEndWord");
|
||||
|
||||
if (result.sponsorTimesContributed > 1) {
|
||||
sponsorTimesContributionsDisplayEndWord.innerText = "sponsors."
|
||||
} else {
|
||||
sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
|
||||
}
|
||||
sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
|
||||
sponsorTimesContributionsContainer.style.display = "unset";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
let userID = result.userID;
|
||||
if (userID != undefined) {
|
||||
//there are probably some views on these submissions then
|
||||
//get the amount of views from the sponsors submitted
|
||||
sendRequestToServer("GET", "/api/getViewsForUser?userID=" + userID, function(xmlhttp) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
let viewCount = JSON.parse(xmlhttp.responseText).viewCount;
|
||||
|
||||
if (viewCount != 0) {
|
||||
let sponsorTimesViewsContainer = document.getElementById("sponsorTimesViewsContainer");
|
||||
let sponsorTimesViewsDisplay = document.getElementById("sponsorTimesViewsDisplay");
|
||||
let sponsorTimesViewsDisplayEndWord = document.getElementById("sponsorTimesViewsDisplayEndWord");
|
||||
|
||||
if (viewCount > 1) {
|
||||
sponsorTimesViewsDisplayEndWord.innerText = "sponsor segments."
|
||||
} else {
|
||||
sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
|
||||
}
|
||||
sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
sponsorTimesViewsContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -54,7 +101,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 +186,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 +211,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 +287,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 +305,7 @@ function clearTimes() {
|
||||
sponsorTimes = [];
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
@@ -217,18 +316,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 +365,7 @@ function showNoticeAgain() {
|
||||
}
|
||||
|
||||
function hideVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": true});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -260,7 +382,7 @@ function hideVideoPlayerControls() {
|
||||
}
|
||||
|
||||
function showVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": false});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -292,13 +414,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 +438,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);
|
||||
@@ -328,6 +498,25 @@ function getFormattedTime(seconds) {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||