mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-06 11:37:02 +03:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
180260088d | ||
|
|
4c380aa1bf | ||
|
|
1040868ebb | ||
|
|
b7a35f0823 | ||
|
|
baefc59954 | ||
|
|
14121af900 | ||
|
|
52ec50a132 | ||
|
|
f162d6b8dd | ||
|
|
2d00cfffdf | ||
|
|
a7a4642920 | ||
|
|
91f0b65d06 | ||
|
|
4cc44258e8 | ||
|
|
4bb6cd0dcf | ||
|
|
b319729da8 | ||
|
|
888a03a708 | ||
|
|
e452e02bda | ||
|
|
01b61f6192 | ||
|
|
7bfc223cac | ||
|
|
255f049c96 | ||
|
|
987b7b036c | ||
|
|
6cd01108f4 | ||
|
|
f3cc497bd6 | ||
|
|
762039e2f6 | ||
|
|
a1d51656c5 |
12
README.md
12
README.md
@@ -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
|
||||
|
||||
@@ -21,8 +21,14 @@ This project is partially based off of [this experimental extension](https://git
|
||||
|
||||
# Chrome extension
|
||||
|
||||
It will be on the chrome webstore soon once I get some more UI features in, such as an icon. For now, you can load this project as an unpacked extension. Make sure to rename the `content-config.js.example` file to `content-config.js` before installing.
|
||||
It will be on the chrome webstore soon once I get some more UI features in, such as an icon. For now, you can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
||||
|
||||
# Firefox extension
|
||||
|
||||
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>
|
||||
|
||||
100
background.js
100
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);
|
||||
@@ -39,6 +38,11 @@ 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, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
}
|
||||
@@ -49,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;
|
||||
@@ -75,28 +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 submitTimes(videoID) {
|
||||
function submitVote(type, UUID, callback) {
|
||||
getUserID(function(userID) {
|
||||
//publish this vote
|
||||
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, 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', 'http://localhost/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});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -106,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) {
|
||||
@@ -130,10 +176,11 @@ function videoIDChange(currentVideoID) {
|
||||
function getUserID(callback) {
|
||||
if (userID != null) {
|
||||
callback(userID);
|
||||
return;
|
||||
}
|
||||
|
||||
//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;
|
||||
@@ -143,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 +1,3 @@
|
||||
//this file is loaded along iwth content.js
|
||||
//this file sets the server to connect to, and is gitignored
|
||||
var serverAddresss = "https://sponsor.ajay.app";
|
||||
var serverAddress = "http://localhost";
|
||||
3
config.js.example
Normal file
3
config.js.example
Normal file
@@ -0,0 +1,3 @@
|
||||
//this file is loaded along iwth content.js
|
||||
//this file sets the server to connect to, and is gitignored
|
||||
var serverAddress = "https://sponsor.ajay.app";
|
||||
118
content.css
118
content.css
@@ -1,8 +1,16 @@
|
||||
.playerButton {
|
||||
height: 60%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.sponsorSkipObject {
|
||||
font-family: 'Source Sans Pro', sans-serif;
|
||||
}
|
||||
|
||||
#sponsorSkipLogo {
|
||||
.sponsorSkipLogo {
|
||||
height: 64px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -11,27 +19,113 @@
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#sponsorSkipNotice {
|
||||
min-height: 125px;
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.sponsorSkipNotice {
|
||||
min-height: 165px;
|
||||
min-width: 400px;
|
||||
background-color: rgba(255, 217, 217, 0.8);
|
||||
position: absolute;
|
||||
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;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
#sponsorSkipInfo {
|
||||
.sponsorSkipInfo {
|
||||
font-size: 10px;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
#sponsorTimesThanksForVotingText {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
#sponsorTimesThanksForVotingInfoText {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.sponsorTimesInfoMessage {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.voteButton {
|
||||
height: 32px;
|
||||
margin-right: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.voteButton:hover {
|
||||
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 {
|
||||
@@ -54,6 +148,12 @@
|
||||
.sponsorSkipButton:hover {
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
|
||||
.sponsorSkipButton:focus {
|
||||
outline: none;
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
|
||||
.sponsorSkipButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
@@ -79,6 +179,12 @@
|
||||
.sponsorSkipDontShowButton:hover {
|
||||
background-color:#bc3315;
|
||||
}
|
||||
|
||||
.sponsorSkipDontShowButton:focus {
|
||||
outline: none;
|
||||
background-color:#bc3315;
|
||||
}
|
||||
|
||||
.sponsorSkipDontShowButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
|
||||
391
content.js
391
content.js
@@ -11,8 +11,9 @@ if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
//was sponsor data found when doing SponsorsLookup
|
||||
var sponsorDataFound = false;
|
||||
|
||||
//the actual sponsorTimes if loaded
|
||||
//the actual sponsorTimes if loaded and UUIDs associated with them
|
||||
var sponsorTimes = undefined;
|
||||
var UUIDs = undefined;
|
||||
|
||||
//the video
|
||||
var v;
|
||||
@@ -23,6 +24,8 @@ var lastTime;
|
||||
//the last time in the video a sponsor was skipped
|
||||
//used for the go back button
|
||||
var lastSponsorTimeSkipped = null;
|
||||
//used for ratings
|
||||
var lastSponsorTimeSkippedUUID = null;
|
||||
|
||||
//if showing the start sponsor button or the end sponsor button on the player
|
||||
var showingStartSponsor = true;
|
||||
@@ -33,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;
|
||||
@@ -56,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
|
||||
})
|
||||
}
|
||||
|
||||
@@ -70,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") {
|
||||
@@ -93,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;
|
||||
}
|
||||
@@ -114,58 +120,77 @@ function sponsorsLookup(id) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
//check database for sponsor times
|
||||
xmlhttp.open('GET', serverAddresss + "/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;
|
||||
// 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
|
||||
sponsorTimes.forEach(function (sponsorTime, index) { // Foreach Sponsor in video
|
||||
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 && sponsorTime[0] >= lastTime && sponsorTime[0] <= v.currentTime) {
|
||||
if (Math.abs(v.currentTime - lastTime) < 1 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTime[1];
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
|
||||
lastSponsorTimeSkipped = sponsorTime[0];
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
//Adds a sponsorship starts button to the player controls
|
||||
function addPlayerControlsButton() {
|
||||
if (document.getElementById("startSponsorButton") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
let startSponsorButton = document.createElement("button");
|
||||
startSponsorButton.id = "startSponsorButton";
|
||||
startSponsorButton.className = "ytp-button";
|
||||
@@ -174,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
|
||||
@@ -191,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
|
||||
@@ -199,6 +221,7 @@ function updateVisibilityOfPlayerControlsButton() {
|
||||
removePlayerControlsButton();
|
||||
} else {
|
||||
addPlayerControlsButton();
|
||||
addSubmitButton();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,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) {
|
||||
@@ -229,42 +294,77 @@ 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.innerText = "This message will disapear in 7 seconds";
|
||||
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" + lastSponsorTimeSkippedUUID;
|
||||
voteButtonsContainer.setAttribute("align", "center");
|
||||
|
||||
let upvoteButton = document.createElement("img");
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + lastSponsorTimeSkippedUUID;
|
||||
upvoteButton.className = "sponsorSkipObject voteButton";
|
||||
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
|
||||
upvoteButton.addEventListener("click", () => vote(1, UUID));
|
||||
|
||||
let downvoteButton = document.createElement("img");
|
||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + lastSponsorTimeSkippedUUID;
|
||||
downvoteButton.className = "sponsorSkipObject 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(upvoteButton);
|
||||
voteButtonsContainer.appendChild(downvoteButton);
|
||||
|
||||
let buttonContainer = document.createElement("div");
|
||||
buttonContainer.setAttribute("align", "center");
|
||||
|
||||
let goBackButton = document.createElement("button");
|
||||
goBackButton.innerText = "Go back";
|
||||
goBackButton.className = "sponsorSkipObject";
|
||||
goBackButton.className = "sponsorSkipButton";
|
||||
goBackButton.addEventListener("click", goBackToPreviousTime);
|
||||
goBackButton.addEventListener("click", () => goBackToPreviousTime(UUID));
|
||||
|
||||
let hideButton = document.createElement("button");
|
||||
hideButton.innerText = "Dismiss";
|
||||
hideButton.className = "sponsorSkipObject";
|
||||
hideButton.className = "sponsorSkipButton";
|
||||
hideButton.addEventListener("click", closeSkipNotice);
|
||||
hideButton.addEventListener("click", () => closeSkipNotice(UUID));
|
||||
|
||||
let dontShowAgainButton = document.createElement("button");
|
||||
dontShowAgainButton.innerText = "Don't Show This Again";
|
||||
dontShowAgainButton.className = "sponsorSkipObject";
|
||||
dontShowAgainButton.className = "sponsorSkipDontShowButton";
|
||||
dontShowAgainButton.addEventListener("click", dontShowNoticeAgain);
|
||||
|
||||
@@ -277,6 +377,7 @@ function openSkipNotice(){
|
||||
noticeElement.appendChild(logoElement);
|
||||
noticeElement.appendChild(noticeMessage);
|
||||
noticeElement.appendChild(noticeInfo);
|
||||
noticeElement.appendChild(voteButtonsContainer);
|
||||
noticeElement.appendChild(buttonContainer);
|
||||
|
||||
let referenceNode = document.getElementById("info");
|
||||
@@ -287,20 +388,118 @@ function openSkipNotice(){
|
||||
referenceNode.prepend(noticeElement);
|
||||
}
|
||||
|
||||
//Closes the notice that tells the user that a sponsor was just skipped
|
||||
function closeSkipNotice(){
|
||||
let notice = document.getElementById("sponsorSkipNotice");
|
||||
function afterDownvote(UUID) {
|
||||
//change text to say thanks for voting
|
||||
//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 = "sponsorTimesThanksForVotingText";
|
||||
thanksForVotingText.innerText = "Thanks for voting!"
|
||||
|
||||
//add extra info for voting
|
||||
let thanksForVotingInfoText = document.createElement("p");
|
||||
thanksForVotingInfoText.id = "sponsorTimesThanksForVotingInfoText";
|
||||
thanksForVotingInfoText.innerText = "Hit go back to get to where you came from."
|
||||
|
||||
//add element to div
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText);
|
||||
}
|
||||
|
||||
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: 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 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() {
|
||||
@@ -316,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);
|
||||
|
||||
BIN
icons/PlayerUploadFailedIconSponsorBlocker256px.png
Normal file
BIN
icons/PlayerUploadFailedIconSponsorBlocker256px.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
icons/PlayerUploadIconSponsorBlocker256px.png
Normal file
BIN
icons/PlayerUploadIconSponsorBlocker256px.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
icons/downvote.png
Normal file
BIN
icons/downvote.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
BIN
icons/upvote.png
Normal file
BIN
icons/upvote.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
98
icons/upvote.svg
Normal file
98
icons/upvote.svg
Normal file
@@ -0,0 +1,98 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 478.2 478.2"
|
||||
style="enable-background:new 0 0 478.2 478.2;"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="upvote.svg"
|
||||
inkscape:export-filename="C:\_Projects\_____SponsorSkip\icons\upvote.png"
|
||||
inkscape:export-xdpi="52.797993"
|
||||
inkscape:export-ydpi="52.797993"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
|
||||
id="metadata41"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs39" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1001"
|
||||
id="namedview37"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.98703469"
|
||||
inkscape:cx="264.34466"
|
||||
inkscape:cy="180.78075"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Capa_1" />
|
||||
<g
|
||||
id="g4">
|
||||
<path
|
||||
d="M457.575,325.1c9.8-12.5,14.5-25.9,13.9-39.7c-0.6-15.2-7.4-27.1-13-34.4c6.5-16.2,9-41.7-12.7-61.5 c-15.9-14.5-42.9-21-80.3-19.2c-26.3,1.2-48.3,6.1-49.2,6.3h-0.1c-5,0.9-10.3,2-15.7,3.2c-0.4-6.4,0.7-22.3,12.5-58.1 c14-42.6,13.2-75.2-2.6-97c-16.6-22.9-43.1-24.7-50.9-24.7c-7.5,0-14.4,3.1-19.3,8.8c-11.1,12.9-9.8,36.7-8.4,47.7 c-13.2,35.4-50.2,122.2-81.5,146.3c-0.6,0.4-1.1,0.9-1.6,1.4c-9.2,9.7-15.4,20.2-19.6,29.4c-5.9-3.2-12.6-5-19.8-5h-61 c-23,0-41.6,18.7-41.6,41.6v162.5c0,23,18.7,41.6,41.6,41.6h61c8.9,0,17.2-2.8,24-7.6l23.5,2.8c3.6,0.5,67.6,8.6,133.3,7.3 c11.9,0.9,23.1,1.4,33.5,1.4c17.9,0,33.5-1.4,46.5-4.2c30.6-6.5,51.5-19.5,62.1-38.6c8.1-14.6,8.1-29.1,6.8-38.3 c19.9-18,23.4-37.9,22.7-51.9C461.275,337.1,459.475,330.2,457.575,325.1z M48.275,447.3c-8.1,0-14.6-6.6-14.6-14.6V270.1 c0-8.1,6.6-14.6,14.6-14.6h61c8.1,0,14.6,6.6,14.6,14.6v162.5c0,8.1-6.6,14.6-14.6,14.6h-61V447.3z M431.975,313.4 c-4.2,4.4-5,11.1-1.8,16.3c0,0.1,4.1,7.1,4.6,16.7c0.7,13.1-5.6,24.7-18.8,34.6c-4.7,3.6-6.6,9.8-4.6,15.4c0,0.1,4.3,13.3-2.7,25.8 c-6.7,12-21.6,20.6-44.2,25.4c-18.1,3.9-42.7,4.6-72.9,2.2c-0.4,0-0.9,0-1.4,0c-64.3,1.4-129.3-7-130-7.1h-0.1l-10.1-1.2 c0.6-2.8,0.9-5.8,0.9-8.8V270.1c0-4.3-0.7-8.5-1.9-12.4c1.8-6.7,6.8-21.6,18.6-34.3c44.9-35.6,88.8-155.7,90.7-160.9 c0.8-2.1,1-4.4,0.6-6.7c-1.7-11.2-1.1-24.9,1.3-29c5.3,0.1,19.6,1.6,28.2,13.5c10.2,14.1,9.8,39.3-1.2,72.7 c-16.8,50.9-18.2,77.7-4.9,89.5c6.6,5.9,15.4,6.2,21.8,3.9c6.1-1.4,11.9-2.6,17.4-3.5c0.4-0.1,0.9-0.2,1.3-0.3 c30.7-6.7,85.7-10.8,104.8,6.6c16.2,14.8,4.7,34.4,3.4,36.5c-3.7,5.6-2.6,12.9,2.4,17.4c0.1,0.1,10.6,10,11.1,23.3 C444.875,295.3,440.675,304.4,431.975,313.4z"
|
||||
id="path2" />
|
||||
</g>
|
||||
<g
|
||||
id="g6">
|
||||
</g>
|
||||
<g
|
||||
id="g8">
|
||||
</g>
|
||||
<g
|
||||
id="g10">
|
||||
</g>
|
||||
<g
|
||||
id="g12">
|
||||
</g>
|
||||
<g
|
||||
id="g14">
|
||||
</g>
|
||||
<g
|
||||
id="g16">
|
||||
</g>
|
||||
<g
|
||||
id="g18">
|
||||
</g>
|
||||
<g
|
||||
id="g20">
|
||||
</g>
|
||||
<g
|
||||
id="g22">
|
||||
</g>
|
||||
<g
|
||||
id="g24">
|
||||
</g>
|
||||
<g
|
||||
id="g26">
|
||||
</g>
|
||||
<g
|
||||
id="g28">
|
||||
</g>
|
||||
<g
|
||||
id="g30">
|
||||
</g>
|
||||
<g
|
||||
id="g32">
|
||||
</g>
|
||||
<g
|
||||
id="g34">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
@@ -8,7 +8,7 @@
|
||||
"https://*.youtube.com/*"
|
||||
],
|
||||
"js": [
|
||||
"content-config.js",
|
||||
"config.js",
|
||||
"content.js"
|
||||
],
|
||||
"css": [
|
||||
@@ -21,7 +21,11 @@
|
||||
"icons/LogoSponsorBlocker256px.png",
|
||||
"icons/IconSponsorBlocker256px.png",
|
||||
"icons/PlayerStartIconSponsorBlocker256px.png",
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png"
|
||||
"icons/PlayerStopIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
@@ -33,7 +37,10 @@
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"background": {
|
||||
"scripts":["background.js"]
|
||||
"scripts":[
|
||||
"config.js",
|
||||
"background.js"
|
||||
]
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/IconSponsorBlocker16px.png",
|
||||
|
||||
29
popup.css
29
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;
|
||||
@@ -29,6 +42,10 @@ body {
|
||||
.greenButton:hover {
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
.greenButton:focus {
|
||||
outline: none;
|
||||
background-color:#bf2a2a;
|
||||
}
|
||||
.greenButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
@@ -54,6 +71,10 @@ body {
|
||||
.dangerButton:hover {
|
||||
background-color:#bc3315;
|
||||
}
|
||||
.dangerButton:focus {
|
||||
outline: none;
|
||||
background-color:#bc3315;
|
||||
}
|
||||
.dangerButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
@@ -79,6 +100,10 @@ body {
|
||||
.warningButton:hover {
|
||||
background-color:#bc8215;
|
||||
}
|
||||
.warningButton:focus {
|
||||
outline: none;
|
||||
background-color:#bc8215;
|
||||
}
|
||||
.warningButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
@@ -100,6 +125,10 @@ body {
|
||||
.smallButton:hover {
|
||||
background-color:#fa9806;
|
||||
}
|
||||
.smallButton:focus {
|
||||
outline: none;
|
||||
background-color:#fa9806;
|
||||
}
|
||||
.smallButton:active {
|
||||
position:relative;
|
||||
top:1px;
|
||||
|
||||
34
popup.html
34
popup.html
@@ -24,8 +24,26 @@
|
||||
<div id="downloadedSponsorMessageTimes">
|
||||
|
||||
</div>
|
||||
|
||||
<h2>Record the times of a sponsorship</h2>
|
||||
|
||||
<br/>
|
||||
|
||||
<button id="reportAnIssue" class="dangerButton">Vote On A Sponsor Time</button>
|
||||
|
||||
<div id="issueReporterContainer" style="display: none">
|
||||
|
||||
<h3 style="margin-top: 0px">Vote On A Sponsor Time</h3>
|
||||
|
||||
<div id="issueReporterTimeButtons">
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 class="recordingSubtitle">Record the times of a sponsorship</h2>
|
||||
|
||||
<p id="sponsorTimesContributionsDisplay" style="display: none">
|
||||
So far, you've submitted no sponsor times.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Click the button below when the sponsorship starts and ends to record and
|
||||
@@ -48,8 +66,18 @@
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<div id="submitTimesContainer" style="display: none">
|
||||
<button id="submitTimes" class="smallButton">Submit Times</button>
|
||||
|
||||
<div id="submitTimesInfoMessageContainer" style="display: none">
|
||||
<h3 id="submitTimesInfoMessage">
|
||||
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<button id="submitTimes" style="display: none" class="smallButton">Submit Times</button>
|
||||
</div>
|
||||
|
||||
<div id="optionsButtonContainer">
|
||||
|
||||
168
popup.js
168
popup.js
@@ -6,6 +6,7 @@ document.getElementById("showNoticeAgain").addEventListener("click", showNoticeA
|
||||
document.getElementById("hideVideoPlayerControls").addEventListener("click", hideVideoPlayerControls);
|
||||
document.getElementById("showVideoPlayerControls").addEventListener("click", showVideoPlayerControls);
|
||||
document.getElementById("optionsButton").addEventListener("click", openOptions);
|
||||
document.getElementById("reportAnIssue").addEventListener("click", reportAnIssue);
|
||||
|
||||
//if true, the button now selects the end time
|
||||
var startTimeChosen = false;
|
||||
@@ -21,7 +22,7 @@ var isYouTubeTab = false;
|
||||
|
||||
//if the don't show notice again variable is true, an option to
|
||||
// disable should be available
|
||||
chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
|
||||
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
|
||||
document.getElementById("showNoticeAgain").style.display = "unset";
|
||||
@@ -29,7 +30,7 @@ chrome.storage.local.get(["dontShowNoticeAgain"], function(result) {
|
||||
});
|
||||
|
||||
//show proper video player controls option
|
||||
chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
|
||||
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
|
||||
let hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "none";
|
||||
@@ -37,6 +38,20 @@ chrome.storage.local.get(["hideVideoPlayerControls"], function(result) {
|
||||
}
|
||||
});
|
||||
|
||||
//get the amount of times this user has contributed and display it to thank them
|
||||
chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
if (result.sponsorTimesContributed != undefined) {
|
||||
let sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
|
||||
|
||||
if (result.sponsorTimesContributed > 1) {
|
||||
sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor times.";
|
||||
} else {
|
||||
sponsorTimesContributionsDisplay.innerText = "So far, you've submitted " + result.sponsorTimesContributed + " sponsor time.";
|
||||
}
|
||||
sponsorTimesContributionsDisplay.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
@@ -54,7 +69,7 @@ function loadTabData(tabs) {
|
||||
|
||||
//load video times for this video
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimesStorage = result[sponsorTimeKey];
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||
@@ -139,7 +154,7 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = request.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
@@ -164,6 +179,56 @@ function displayDownloadedSponsorTimes(request) {
|
||||
if (request.sponsorTimes != undefined) {
|
||||
//set it to the message
|
||||
document.getElementById("downloadedSponsorMessageTimes").innerHTML = getSponsorTimesMessage(request.sponsorTimes);
|
||||
|
||||
//add them as buttons to the issue reporting container
|
||||
let container = document.getElementById("issueReporterTimeButtons");
|
||||
for (let i = 0; i < request.sponsorTimes.length; i++) {
|
||||
let sponsorTimeButton = document.createElement("button");
|
||||
sponsorTimeButton.className = "warningButton";
|
||||
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]);
|
||||
|
||||
let votingButtons = document.createElement("div");
|
||||
|
||||
let UUID = request.UUIDs[i];
|
||||
|
||||
//thumbs up and down buttons
|
||||
let voteButtonsContainer = document.createElement("div");
|
||||
voteButtonsContainer.id = "sponsorTimesVoteButtonsContainer" + UUID;
|
||||
voteButtonsContainer.setAttribute("align", "center");
|
||||
voteButtonsContainer.style.display = "none"
|
||||
|
||||
let upvoteButton = document.createElement("img");
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
|
||||
upvoteButton.className = "voteButton";
|
||||
upvoteButton.src = chrome.extension.getURL("icons/upvote.png");
|
||||
upvoteButton.addEventListener("click", () => vote(1, UUID));
|
||||
|
||||
let downvoteButton = document.createElement("img");
|
||||
downvoteButton.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
|
||||
downvoteButton.className = "voteButton";
|
||||
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
|
||||
downvoteButton.addEventListener("click", () => vote(0, UUID));
|
||||
|
||||
//add thumbs up and down buttons to the container
|
||||
voteButtonsContainer.appendChild(document.createElement("br"));
|
||||
voteButtonsContainer.appendChild(document.createElement("br"));
|
||||
voteButtonsContainer.appendChild(upvoteButton);
|
||||
voteButtonsContainer.appendChild(downvoteButton);
|
||||
|
||||
//add click listener to open up vote panel
|
||||
sponsorTimeButton.addEventListener("click", function() {
|
||||
voteButtonsContainer.style.display = "unset";
|
||||
});
|
||||
|
||||
container.appendChild(sponsorTimeButton);
|
||||
container.appendChild(voteButtonsContainer);
|
||||
|
||||
//if it is not the last iteration
|
||||
if (i != request.sponsorTimes.length - 1) {
|
||||
container.appendChild(document.createElement("br"));
|
||||
container.appendChild(document.createElement("br"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,14 +255,16 @@ function getSponsorTimesMessage(sponsorTimes) {
|
||||
}
|
||||
|
||||
function clearTimes() {
|
||||
//check if the player controls should be toggled
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
//send new sponsor time state to tab
|
||||
if (sponsorTimes.length > 0) {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "toggleStartSponsorButton"
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -206,7 +273,7 @@ function clearTimes() {
|
||||
sponsorTimes = [];
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes});
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
displaySponsorTimes();
|
||||
|
||||
@@ -217,18 +284,41 @@ function clearTimes() {
|
||||
}
|
||||
|
||||
function submitTimes() {
|
||||
//make info message say loading
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "Loading...";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
|
||||
if (sponsorTimes.length > 0) {
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitTimes",
|
||||
videoID: currentVideoID
|
||||
}, function(request) {
|
||||
clearTimes();
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
if (response.statusCode == 200) {
|
||||
//hide loading message
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "none";
|
||||
|
||||
clearTimes();
|
||||
} else if(response.statusCode == 400) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "Server said this request was invalid";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else if(response.statusCode == 429) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "You have submitted too many sponsor times for this one video, are you sure there are this many?";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else if(response.statusCode == 409) {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "This has already been submitted before";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
} else {
|
||||
document.getElementById("submitTimesInfoMessage").innerText = "There was an error submitting your sponsor times, please try again later";
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function showNoticeAgain() {
|
||||
chrome.storage.local.set({"dontShowNoticeAgain": false});
|
||||
chrome.storage.sync.set({"dontShowNoticeAgain": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -243,7 +333,7 @@ function showNoticeAgain() {
|
||||
}
|
||||
|
||||
function hideVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": true});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -260,7 +350,7 @@ function hideVideoPlayerControls() {
|
||||
}
|
||||
|
||||
function showVideoPlayerControls() {
|
||||
chrome.storage.local.set({"hideVideoPlayerControls": false});
|
||||
chrome.storage.sync.set({"hideVideoPlayerControls": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
@@ -292,13 +382,15 @@ function resetStartTimeChosen() {
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now";
|
||||
}
|
||||
|
||||
//hides and shows the submit times button when needed
|
||||
function showSubmitTimesIfNecessary() {
|
||||
//check if an end time has been specified for the latest sponsor time
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) {
|
||||
//show submit times button
|
||||
document.getElementById("submitTimes").style.display = "unset";
|
||||
document.getElementById("submitTimesContainer").style.display = "unset";
|
||||
} else {
|
||||
document.getElementById("submitTimes").style.display = "none";
|
||||
//hide submit times button
|
||||
document.getElementById("submitTimesContainer").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +406,52 @@ function displayNoVideo() {
|
||||
"If you know this is a YouTube tab, close this popup and open it again.";
|
||||
}
|
||||
|
||||
function reportAnIssue() {
|
||||
document.getElementById("issueReporterContainer").style.display = "unset";
|
||||
document.getElementById("reportAnIssue").style.display = "none";
|
||||
}
|
||||
|
||||
function addVoteMessage(message, UUID) {
|
||||
let container = document.getElementById("sponsorTimesVoteButtonsContainer" + UUID);
|
||||
//remove all children
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
|
||||
let thanksForVotingText = document.createElement("h2");
|
||||
thanksForVotingText.innerText = message;
|
||||
//there are already breaks there
|
||||
thanksForVotingText.style.marginBottom = "0px";
|
||||
|
||||
container.appendChild(thanksForVotingText);
|
||||
}
|
||||
|
||||
function vote(type, UUID) {
|
||||
//add loading info
|
||||
addVoteMessage("Loading...", UUID)
|
||||
|
||||
//send the vote message to the tab
|
||||
chrome.runtime.sendMessage({
|
||||
message: "submitVote",
|
||||
type: type,
|
||||
UUID: UUID
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
//see if it was a success or failure
|
||||
if (response.successType == 1) {
|
||||
//success
|
||||
addVoteMessage("Thanks for voting!", UUID)
|
||||
} else if (response.successType == 0) {
|
||||
//failure: duplicate vote
|
||||
addVoteMessage("You have already voted this way before.", UUID)
|
||||
} else if (response.successType == -1) {
|
||||
//failure: duplicate vote
|
||||
addVoteMessage("A connection error has occured.", UUID)
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes:seconds
|
||||
function getFormattedTime(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
|
||||
Reference in New Issue
Block a user