mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-07 03:57:09 +03:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3e4121a21 | ||
|
|
a75ea50098 | ||
|
|
6b6e74b5a0 | ||
|
|
d6c5dbaff1 | ||
|
|
a66804064a | ||
|
|
919f9f56bd | ||
|
|
bd614e250b | ||
|
|
6275c2d62c | ||
|
|
feea7aa51d | ||
|
|
16263d463f | ||
|
|
6673272e14 | ||
|
|
6358ba2e11 | ||
|
|
2415784eee | ||
|
|
acb3c67629 | ||
|
|
622b2ea158 | ||
|
|
7a9af6cbcf | ||
|
|
51a389284d | ||
|
|
2ff70f1511 | ||
|
|
ff9badf2e9 | ||
|
|
aefc880486 | ||
|
|
e749456719 | ||
|
|
a2312a10be | ||
|
|
b0090a3334 | ||
|
|
7100831956 | ||
|
|
30c1b2d919 | ||
|
|
3ec6caee9d | ||
|
|
7f505a52ca | ||
|
|
84b8e59b39 | ||
|
|
808dfe42ce | ||
|
|
600365d998 | ||
|
|
569699cbc1 | ||
|
|
08cb324125 | ||
|
|
504f0b0ede | ||
|
|
00877fb087 | ||
|
|
d654d8934b | ||
|
|
97e202dbd0 | ||
|
|
64be41b008 | ||
|
|
b3684a8730 | ||
|
|
45f0d65f69 | ||
|
|
5436a1651e | ||
|
|
33fe63084b | ||
|
|
8f47513c98 | ||
|
|
7a17cc2b0a | ||
|
|
c7cb845d8a | ||
|
|
250c75a78f | ||
|
|
a86e55ac67 | ||
|
|
30f2f638fe | ||
|
|
725ab783e3 | ||
|
|
30e3222177 | ||
|
|
d9789c20d6 | ||
|
|
c8114e2d7e | ||
|
|
c7da0f0c65 | ||
|
|
0f561d4a5a | ||
|
|
55c7529731 |
14
README.md
14
README.md
@@ -5,6 +5,12 @@
|
||||
|
||||
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.
|
||||
|
||||
# Available for Chrome and Firefox
|
||||
|
||||
Chrome: https://chrome.google.com/webstore/detail/ajjollijmimolcncegpgkbilohbhjnhi
|
||||
|
||||
Firefox: https://addons.mozilla.org/addon/sponsorblock/
|
||||
|
||||
# Server
|
||||
|
||||
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
|
||||
@@ -19,13 +25,9 @@ Hopefully this project can be combined with projects like [this](https://github.
|
||||
|
||||
This project is partially based off of [this experimental extension](https://github.com/OfficialNoob/YTSponsorSkip). That extension has the basic video skipping functionality.
|
||||
|
||||
# Chrome extension
|
||||
# Build Yourself
|
||||
|
||||
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
|
||||
You can load this project as an unpacked extension. Make sure to rename the `config.js.example` file to `config.js` before installing.
|
||||
|
||||
# Credit
|
||||
|
||||
|
||||
@@ -3,34 +3,40 @@ var previousVideoID = null
|
||||
//the id of this user, randomly generated once per install
|
||||
var userID = null;
|
||||
|
||||
chrome.tabs.onUpdated.addListener( // On tab update
|
||||
function(tabId, changeInfo, tab) {
|
||||
if (changeInfo != undefined && changeInfo.url != undefined) {
|
||||
let id = getYouTubeVideoID(changeInfo.url);
|
||||
if (changeInfo.url && id) { // If URL changed and is youtube video message contentScript the video id
|
||||
videoIDChange(id);
|
||||
//when a new tab is highlighted
|
||||
chrome.tabs.onActivated.addListener(
|
||||
function(activeInfo) {
|
||||
chrome.tabs.get(activeInfo.tabId, function(tab) {
|
||||
let id = getYouTubeVideoID(tab.url);
|
||||
|
||||
chrome.tabs.sendMessage( tabId, {
|
||||
message: 'ytvideoid',
|
||||
id: id
|
||||
});
|
||||
//if this even is a YouTube tab
|
||||
if (id) {
|
||||
videoIDChange(id, activeInfo.tabId);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
//when a tab changes URLs
|
||||
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
|
||||
if (changeInfo != undefined && changeInfo.url != undefined) {
|
||||
let id = getYouTubeVideoID(changeInfo.url);
|
||||
|
||||
//if URL changed and is youtube video message contentScript the video id
|
||||
if (changeInfo.url && id) {
|
||||
videoIDChange(id, tabId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
if (request.message == "submitTimes") {
|
||||
submitTimes(request.videoID, callback);
|
||||
|
||||
//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);
|
||||
}
|
||||
} else if (request.message == "addSponsorTime") {
|
||||
addSponsorTime(request.time);
|
||||
addSponsorTime(request.time, request.videoID);
|
||||
} else if (request.message == "getSponsorTimes") {
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
@@ -63,22 +69,22 @@ function getSponsorTimes(videoID, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function addSponsorTime(time) {
|
||||
getSponsorTimes(previousVideoID, function(sponsorTimes) {
|
||||
function addSponsorTime(time, videoID) {
|
||||
getSponsorTimes(videoID, function(sponsorTimes) {
|
||||
//add to sponsorTimes
|
||||
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
//it is an end time
|
||||
sponsorTimes[sponsorTimes.length - 1][1] = parseInt(time);
|
||||
sponsorTimes[sponsorTimes.length - 1][1] = time;
|
||||
} else {
|
||||
//it is a start time
|
||||
let sponsorTimesIndex = sponsorTimes.length;
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][0] = parseInt(time);
|
||||
sponsorTimes[sponsorTimesIndex][0] = time;
|
||||
}
|
||||
|
||||
//save this info
|
||||
let sponsorTimeKey = "sponsorTimes" + previousVideoID;
|
||||
let sponsorTimeKey = "sponsorTimes" + videoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
});
|
||||
}
|
||||
@@ -147,7 +153,13 @@ function submitTimes(videoID, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function videoIDChange(currentVideoID) {
|
||||
function videoIDChange(currentVideoID, tabId) {
|
||||
//send a message to the content script
|
||||
chrome.tabs.sendMessage(tabId, {
|
||||
message: 'ytvideoid',
|
||||
id: currentVideoID
|
||||
});
|
||||
|
||||
//warn them if they had unsubmitted times
|
||||
if (previousVideoID != null) {
|
||||
//get the sponsor times from storage
|
||||
@@ -186,6 +198,12 @@ function getUserID(callback) {
|
||||
userID = userIDStorage;
|
||||
callback(userID);
|
||||
} else {
|
||||
//double check if a UUID hasn't been created since this was first called
|
||||
if (userID != null) {
|
||||
callback(userID);
|
||||
return;
|
||||
}
|
||||
|
||||
//generate a userID
|
||||
userID = generateUUID();
|
||||
|
||||
|
||||
12
content.css
12
content.css
@@ -1,3 +1,15 @@
|
||||
.popup {
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.smallLink {
|
||||
font-size: 10px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playerButtonImage {
|
||||
height: 60%;
|
||||
top: 0;
|
||||
|
||||
337
content.js
337
content.js
@@ -1,28 +1,24 @@
|
||||
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
videoIDChange(id);
|
||||
|
||||
//tell background.js about this
|
||||
chrome.runtime.sendMessage({
|
||||
message: "ytvideoid",
|
||||
videoID: id
|
||||
});
|
||||
}
|
||||
|
||||
//was sponsor data found when doing SponsorsLookup
|
||||
var sponsorDataFound = false;
|
||||
|
||||
//the actual sponsorTimes if loaded and UUIDs associated with them
|
||||
var sponsorTimes = undefined;
|
||||
var UUIDs = undefined;
|
||||
var sponsorTimes = null;
|
||||
var UUIDs = null;
|
||||
//what video id are these sponsors for
|
||||
var sponsorVideoID = null;
|
||||
|
||||
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
videoIDChange(id);
|
||||
}
|
||||
|
||||
//the video
|
||||
var v;
|
||||
|
||||
//the last time looked at (used to see if this time is in the interval)
|
||||
var lastTime;
|
||||
var lastTime = -1;
|
||||
|
||||
//the last time skipped to
|
||||
var lastTimeSkippedTo = -1;
|
||||
//the actual time (not video time) that the last skip happened
|
||||
var lastUnixTimeSkipped = -1;
|
||||
|
||||
//the last time in the video a sponsor was skipped
|
||||
//used for the go back button
|
||||
@@ -36,6 +32,21 @@ var showingStartSponsor = true;
|
||||
//should the video controls buttons be added
|
||||
var hideVideoPlayerControls = false;
|
||||
|
||||
//becomes true when isInfoFound is called
|
||||
//this is used to close the popup on YouTube when the other popup opens
|
||||
var popupInitialised = false;
|
||||
|
||||
//should view counts be tracked
|
||||
var trackViewCount = false;
|
||||
chrome.storage.sync.get(["trackViewCount"], function(result) {
|
||||
let trackViewCountStorage = result.trackViewCount;
|
||||
if (trackViewCountStorage != undefined) {
|
||||
trackViewCount = trackViewCountStorage;
|
||||
} else {
|
||||
trackViewCount = true;
|
||||
}
|
||||
});
|
||||
|
||||
//if the notice should not be shown
|
||||
//happens when the user click's the "Don't show notice again" button
|
||||
var dontShowNotice = false;
|
||||
@@ -55,7 +66,7 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
|
||||
|
||||
//messages from popup script
|
||||
if (request.message == "sponsorStart") {
|
||||
sponsorMessageStarted();
|
||||
sponsorMessageStarted(sendResponse);
|
||||
}
|
||||
|
||||
if (request.message == "isInfoFound") {
|
||||
@@ -64,7 +75,14 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
|
||||
found: sponsorDataFound,
|
||||
sponsorTimes: sponsorTimes,
|
||||
UUIDs: UUIDs
|
||||
})
|
||||
});
|
||||
|
||||
if (popupInitialised && document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||
//the popup should be closed now that another is opening
|
||||
closeInfoMenu();
|
||||
}
|
||||
|
||||
popupInitialised = true;
|
||||
}
|
||||
|
||||
if (request.message == "getVideoID") {
|
||||
@@ -86,9 +104,46 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
}
|
||||
|
||||
if (request.message == "trackViewCount") {
|
||||
trackViewCount = request.value;
|
||||
}
|
||||
});
|
||||
|
||||
//check for hotkey pressed
|
||||
document.onkeydown = function(e){
|
||||
e = e || window.event;
|
||||
var key = e.which || e.keyCode;
|
||||
|
||||
let video = document.getElementById("movie_player");
|
||||
|
||||
//is the video in focus, otherwise they could be typing a comment
|
||||
if (document.activeElement === video) {
|
||||
if(key == 186){
|
||||
//semicolon
|
||||
startSponsorClicked();
|
||||
} else if (key == 222) {
|
||||
//single quote
|
||||
submitSponsorTimes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function videoIDChange(id) {
|
||||
//not a url change
|
||||
if (sponsorVideoID == id){
|
||||
return;
|
||||
}
|
||||
|
||||
//reset last sponsor times
|
||||
lastTime = -1;
|
||||
lastUnixTimeSkipped = -1;
|
||||
|
||||
//reset sponsor times
|
||||
sponsorTimes = null;
|
||||
UUIDs = null;
|
||||
sponsorVideoID = id;
|
||||
|
||||
//reset sponsor data found check
|
||||
sponsorDataFound = false;
|
||||
sponsorsLookup(id);
|
||||
@@ -100,10 +155,13 @@ function videoIDChange(id) {
|
||||
}, function(response) {
|
||||
if (response != undefined) {
|
||||
let sponsorTimes = response.sponsorTimes;
|
||||
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();
|
||||
if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length >= 2) {
|
||||
changeStartSponsorButton(true, true);
|
||||
} else if (sponsorTimes != null && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
|
||||
changeStartSponsorButton(false, true);
|
||||
} else {
|
||||
changeStartSponsorButton(true, true);
|
||||
document.getElementById("submitButton").style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -155,16 +213,22 @@ function sponsorsLookup(id) {
|
||||
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
|
||||
//also check if the last time skipped to is not too close to now, to make sure not to get too many
|
||||
//this means part of the video was just skipped
|
||||
if (Math.abs(v.currentTime - lastTime) > 1 && lastTime != -1) {
|
||||
//make lastTime as if the video was playing normally
|
||||
lastTime = v.currentTime - 0.0001;
|
||||
}
|
||||
|
||||
let currentTime = Date.now();
|
||||
|
||||
//If the sponsor time is in between these times, skip it
|
||||
//Checks 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)) {
|
||||
//the last term makes 0 second start times possible
|
||||
if ((Math.abs(v.currentTime - sponsorTimes[i][0]) < 0.3 && sponsorTimes[i][0] >= lastTime && sponsorTimes[i][0] <= v.currentTime
|
||||
&& (lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && sponsorTimes[i][0] == 0)) {
|
||||
//skip it
|
||||
v.currentTime = sponsorTimes[i][1];
|
||||
lastTimeSkippedTo = sponsorTimes[i][1];
|
||||
|
||||
lastSponsorTimeSkipped = sponsorTimes[i][0];
|
||||
|
||||
@@ -172,19 +236,25 @@ function sponsorCheck(sponsorTimes) { // Video skipping
|
||||
lastSponsorTimeSkippedUUID = currentUUID;
|
||||
|
||||
//send out the message saying that a sponsor message was skipped
|
||||
openSkipNotice();
|
||||
openSkipNotice(currentUUID);
|
||||
|
||||
setTimeout(() => closeSkipNotice(currentUUID), 7000);
|
||||
|
||||
//send telemetry that a this sponsor was skipped happened
|
||||
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
||||
if (trackViewCount) {
|
||||
sendRequestToServer("GET", "/api/viewedVideoSponsorTime?UUID=" + currentUUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
lastTime = v.currentTime;
|
||||
|
||||
//don't keep track until they are loaded in
|
||||
if (sponsorTimes.length > 0) {
|
||||
lastTime = v.currentTime;
|
||||
}
|
||||
}
|
||||
|
||||
function goBackToPreviousTime(UUID) {
|
||||
if (sponsorTimes != undefined) {
|
||||
if (sponsorTimes != null) {
|
||||
//add a tiny bit of time to make sure it is not skipped again
|
||||
v.currentTime = sponsorTimes[UUIDs.indexOf(UUID)][0] + 0.001;
|
||||
|
||||
@@ -225,21 +295,25 @@ function removePlayerControlsButton() {
|
||||
|
||||
//adds or removes the player controls button to what it should be
|
||||
function updateVisibilityOfPlayerControlsButton() {
|
||||
addPlayerControlsButton();
|
||||
addInfoButton();
|
||||
addSubmitButton();
|
||||
if (hideVideoPlayerControls) {
|
||||
removePlayerControlsButton();
|
||||
} else {
|
||||
addPlayerControlsButton();
|
||||
addSubmitButton();
|
||||
}
|
||||
}
|
||||
|
||||
function startSponsorClicked() {
|
||||
//it can't update to this info yet
|
||||
closeInfoMenu();
|
||||
|
||||
toggleStartSponsorButton();
|
||||
|
||||
//send back current time with message
|
||||
chrome.runtime.sendMessage({
|
||||
message: "addSponsorTime",
|
||||
time: v.currentTime
|
||||
time: v.currentTime,
|
||||
videoID: getYouTubeVideoID(document.URL)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -247,6 +321,7 @@ function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
||||
if (showStartSponsor) {
|
||||
showingStartSponsor = true;
|
||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png");
|
||||
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Starts Now");
|
||||
|
||||
if (document.getElementById("startSponsorImage").style.display != "none" && uploadButtonVisible) {
|
||||
document.getElementById("submitButton").style.display = "unset";
|
||||
@@ -257,6 +332,7 @@ function changeStartSponsorButton(showStartSponsor, uploadButtonVisible) {
|
||||
} else {
|
||||
showingStartSponsor = false;
|
||||
document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png");
|
||||
document.getElementById("startSponsorButton").setAttribute("title", "Sponsor Ends Now");
|
||||
|
||||
//disable submit button
|
||||
document.getElementById("submitButton").style.display = "none";
|
||||
@@ -267,6 +343,32 @@ function toggleStartSponsorButton() {
|
||||
changeStartSponsorButton(!showingStartSponsor, true);
|
||||
}
|
||||
|
||||
//shows the info button on the video player
|
||||
function addInfoButton() {
|
||||
if (document.getElementById("infoButton") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
//make a submit button
|
||||
let infoButton = document.createElement("button");
|
||||
infoButton.id = "infoButton";
|
||||
infoButton.className = "ytp-button playerButton";
|
||||
infoButton.setAttribute("title", "Open SponsorBlock Popup");
|
||||
infoButton.addEventListener("click", openInfoMenu);
|
||||
|
||||
let infoImage = document.createElement("img");
|
||||
infoImage.id = "infoButtonImage";
|
||||
infoImage.className = "playerButtonImage";
|
||||
infoImage.src = chrome.extension.getURL("icons/PlayerInfoIconSponsorBlocker256px.png");
|
||||
|
||||
//add the image to the button
|
||||
infoButton.appendChild(infoImage);
|
||||
|
||||
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0];
|
||||
referenceNode.prepend(infoButton);
|
||||
}
|
||||
|
||||
//shows the submit button on the video player
|
||||
function addSubmitButton() {
|
||||
if (document.getElementById("submitButton") != null) {
|
||||
@@ -295,13 +397,80 @@ function addSubmitButton() {
|
||||
referenceNode.prepend(submitButton);
|
||||
}
|
||||
|
||||
function openInfoMenu() {
|
||||
if (document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||
//it's already added
|
||||
return;
|
||||
}
|
||||
|
||||
popupInitialised = false;
|
||||
|
||||
//hide info button
|
||||
document.getElementById("infoButton").style.display = "none";
|
||||
|
||||
let popup = document.createElement("div");
|
||||
popup.id = "sponsorBlockPopupContainer";
|
||||
|
||||
let popupFrame = document.createElement("iframe");
|
||||
popupFrame.id = "sponsorBlockPopupFrame"
|
||||
popupFrame.src = chrome.extension.getURL("popup.html");
|
||||
popupFrame.className = "popup";
|
||||
|
||||
//close button
|
||||
let closeButton = document.createElement("div");
|
||||
closeButton.innerText = "Close Popup";
|
||||
closeButton.classList = "smallLink";
|
||||
closeButton.setAttribute("align", "center");
|
||||
closeButton.addEventListener("click", closeInfoMenu);
|
||||
|
||||
popup.appendChild(closeButton);
|
||||
popup.appendChild(popupFrame);
|
||||
|
||||
let parentNode = document.getElementById("secondary");
|
||||
|
||||
parentNode.prepend(popup);
|
||||
}
|
||||
|
||||
function closeInfoMenu() {
|
||||
let popup = document.getElementById("sponsorBlockPopupContainer");
|
||||
if (popup != null) {
|
||||
popup.remove();
|
||||
|
||||
//show info button
|
||||
document.getElementById("infoButton").style.display = "unset";
|
||||
}
|
||||
}
|
||||
|
||||
//Opens the notice that tells the user that a sponsor was just skipped
|
||||
function openSkipNotice(){
|
||||
function openSkipNotice(UUID){
|
||||
if (dontShowNotice) {
|
||||
//don't show, return
|
||||
return;
|
||||
}
|
||||
|
||||
//check if page is loaded yet (for 0 second sponsors, the page might not be loaded yet)
|
||||
//it looks for the view count div and sees if it is full yet
|
||||
//querySelectorAll is being used like findElementById for multiple objects, because for
|
||||
//some reason YouTube has put more than one object with one ID.
|
||||
let viewCountNode = document.querySelectorAll("#count");
|
||||
//check to see if the length is over zero, otherwise it's a different YouTube theme probably
|
||||
if (viewCountNode.length > 0) {
|
||||
//check if any of these have text
|
||||
let viewCountVisible = false;
|
||||
for (let i = 0; i < viewCountNode.length; i++) {
|
||||
if (viewCountNode[i].innerText != null) {
|
||||
viewCountVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!viewCountVisible) {
|
||||
//this is the new YouTube layout and it is still loading
|
||||
//wait a bit for opening the notice
|
||||
setTimeout(() => openSkipNotice(UUID), 200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let amountOfPreviousNotices = document.getElementsByClassName("sponsorSkipNotice").length;
|
||||
|
||||
if (amountOfPreviousNotices > 0) {
|
||||
@@ -311,45 +480,43 @@ function openSkipNotice(){
|
||||
previousNotice.classList.add("secondSkipNotice")
|
||||
}
|
||||
|
||||
let UUID = lastSponsorTimeSkippedUUID;
|
||||
|
||||
let noticeElement = document.createElement("div");
|
||||
//what sponsor time this is about
|
||||
noticeElement.id = "sponsorSkipNotice" + lastSponsorTimeSkippedUUID;
|
||||
noticeElement.id = "sponsorSkipNotice" + UUID;
|
||||
noticeElement.classList.add("sponsorSkipObject");
|
||||
noticeElement.classList.add("sponsorSkipNotice");
|
||||
noticeElement.style.zIndex = 1 + amountOfPreviousNotices;
|
||||
noticeElement.style.zIndex = 5 + amountOfPreviousNotices;
|
||||
|
||||
let logoElement = document.createElement("img");
|
||||
logoElement.id = "sponsorSkipLogo" + lastSponsorTimeSkippedUUID;
|
||||
logoElement.id = "sponsorSkipLogo" + UUID;
|
||||
logoElement.className = "sponsorSkipLogo";
|
||||
logoElement.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png");
|
||||
|
||||
let noticeMessage = document.createElement("div");
|
||||
noticeMessage.id = "sponsorSkipMessage" + lastSponsorTimeSkippedUUID;
|
||||
noticeMessage.id = "sponsorSkipMessage" + UUID;
|
||||
noticeMessage.classList.add("sponsorSkipMessage");
|
||||
noticeMessage.classList.add("sponsorSkipObject");
|
||||
noticeMessage.innerText = "Hey, you just skipped a sponsor!";
|
||||
|
||||
let noticeInfo = document.createElement("p");
|
||||
noticeInfo.id = "sponsorSkipInfo" + lastSponsorTimeSkippedUUID;
|
||||
noticeInfo.id = "sponsorSkipInfo" + UUID;
|
||||
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.id = "sponsorTimesVoteButtonsContainer" + UUID;
|
||||
voteButtonsContainer.setAttribute("align", "center");
|
||||
|
||||
let upvoteButton = document.createElement("img");
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + lastSponsorTimeSkippedUUID;
|
||||
upvoteButton.id = "sponsorTimesUpvoteButtonsContainer" + UUID;
|
||||
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.id = "sponsorTimesDownvoteButtonsContainer" + UUID;
|
||||
downvoteButton.className = "sponsorSkipObject voteButton";
|
||||
downvoteButton.src = chrome.extension.getURL("icons/downvote.png");
|
||||
downvoteButton.addEventListener("click", () => vote(0, UUID));
|
||||
@@ -510,20 +677,47 @@ function dontShowNoticeAgain() {
|
||||
closeAllSkipNotices();
|
||||
}
|
||||
|
||||
function sponsorMessageStarted() {
|
||||
function sponsorMessageStarted(callback) {
|
||||
let v = document.querySelector('video');
|
||||
|
||||
//send back current time
|
||||
chrome.runtime.sendMessage({
|
||||
message: "time",
|
||||
callback({
|
||||
time: v.currentTime
|
||||
});
|
||||
})
|
||||
|
||||
//update button
|
||||
toggleStartSponsorButton();
|
||||
}
|
||||
|
||||
function submitSponsorTimes() {
|
||||
if (document.getElementById("submitButton").style.display == "none") {
|
||||
//don't submit, not ready
|
||||
return;
|
||||
}
|
||||
|
||||
//it can't update to this info yet
|
||||
closeInfoMenu();
|
||||
|
||||
let currentVideoID = getYouTubeVideoID(document.URL);
|
||||
|
||||
let sponsorTimeKey = 'sponsorTimes' + currentVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
let confirmMessage = "Are you sure you want to submit this?\n\n" + getSponsorTimesMessage(sponsorTimes);
|
||||
confirmMessage += "\n\nTo see more information, open the popup by clicking the extensions icon in the top right corner."
|
||||
if(!confirm(confirmMessage)) return;
|
||||
|
||||
sendSubmitMessage();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
//send the message to the background js
|
||||
//called after all the checks have been made that it's okay to do so
|
||||
function sendSubmitMessage(){
|
||||
//add loading animation
|
||||
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
|
||||
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
|
||||
@@ -559,6 +753,42 @@ function submitSponsorTimes() {
|
||||
});
|
||||
}
|
||||
|
||||
//get the message that visually displays the video times
|
||||
function getSponsorTimesMessage(sponsorTimes) {
|
||||
let sponsorTimesMessage = "";
|
||||
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
for (let s = 0; s < sponsorTimes[i].length; s++) {
|
||||
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
|
||||
//if this is an end time
|
||||
if (s == 1) {
|
||||
timeMessage = " to " + timeMessage;
|
||||
} else if (i > 0) {
|
||||
//add commas if necessary
|
||||
timeMessage = ", " + timeMessage;
|
||||
}
|
||||
|
||||
sponsorTimesMessage += timeMessage;
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorTimesMessage;
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes:seconds
|
||||
function getFormattedTime(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
let secondsDisplay = Math.round(seconds - minutes * 60);
|
||||
if (secondsDisplay < 10) {
|
||||
//add a zero
|
||||
secondsDisplay = "0" + secondsDisplay;
|
||||
}
|
||||
|
||||
let formatted = minutes+ ":" + secondsDisplay;
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
function sendRequestToServer(type, address, callback) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
@@ -600,5 +830,6 @@ function sendRequestToCustomServer(type, fullAddress, callback) {
|
||||
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);
|
||||
return (match && match[7].length == 11) ? match[7] : false;
|
||||
}
|
||||
var id = new URL(url).searchParams.get("v");
|
||||
return (match && match[7].length == 11) ? id : false;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "SponsorBlock - YouTube Sponsorship Blocker",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.12",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
@@ -26,7 +26,8 @@
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
"icons/downvote.png",
|
||||
"icons/PlayerInfoIconSponsorBlocker256px.png"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
|
||||
BIN
icons/PlayerInfoIconSponsorBlocker256px.png
Normal file
BIN
icons/PlayerInfoIconSponsorBlocker256px.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "SponsorBlock - YouTube Sponsorship Blocker",
|
||||
"name": "SponsorBlock for YouTube - Skip Sponsorships",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.15",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
@@ -26,7 +26,9 @@
|
||||
"icons/PlayerUploadIconSponsorBlocker256px.png",
|
||||
"icons/PlayerUploadFailedIconSponsorBlocker256px.png",
|
||||
"icons/upvote.png",
|
||||
"icons/downvote.png"
|
||||
"icons/downvote.png",
|
||||
"icons/PlayerInfoIconSponsorBlocker256px.png",
|
||||
"popup.html"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
|
||||
12
popup.css
12
popup.css
@@ -8,7 +8,7 @@ h1 {
|
||||
|
||||
body {
|
||||
font-size: 14px;
|
||||
width: 300px;
|
||||
min-width: 300px;
|
||||
background-color: #ffd9d9;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,16 @@ body {
|
||||
filter: brightness(80%);
|
||||
}
|
||||
|
||||
#discordButtonContainer {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.smallLink {
|
||||
font-size: 10px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.greenButton {
|
||||
background-color:#ec1c1c;
|
||||
-moz-border-radius:28px;
|
||||
|
||||
40
popup.html
40
popup.html
@@ -71,7 +71,9 @@
|
||||
<div>
|
||||
<button id="sponsorStart" class="greenButton">Sponsorship Starts Now</button>
|
||||
</div>
|
||||
|
||||
|
||||
<sub>Hint: Press the semicolon key while focused on a video report the start/end of a sponsor and quote to submit.</sub>
|
||||
|
||||
<div id="submissionSection" style="display: none">
|
||||
<h3>Latest Sponsor Message Times Chosen</h3>
|
||||
<b>
|
||||
@@ -98,6 +100,20 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="discordButtonContainer" style="display: none">
|
||||
<br/>
|
||||
|
||||
<a href="https://discord.gg/QnmVMpU" target="_blank"><img src="https://www.logolynx.com/images/logolynx/1b/1bcc0f0aefe71b2c8ce66ffe8645d365.png" height="32px"/></a>
|
||||
|
||||
<br/>
|
||||
|
||||
Come join the official discord server to give suggestions and feedback!
|
||||
|
||||
<br/>
|
||||
|
||||
<span id="hideDiscordButton" class="smallLink">Hide this</span>
|
||||
</div>
|
||||
|
||||
<div id="optionsButtonContainer">
|
||||
<br/>
|
||||
<br/>
|
||||
@@ -112,10 +128,30 @@
|
||||
|
||||
<button id="hideVideoPlayerControls" class="warningButton">Hide Button On YouTube Player</button>
|
||||
<button id="showVideoPlayerControls" style="display: none" class="warningButton">Show Button On YouTube Player</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This hides the button that appears on the YouTube player to submit sponsors. I can see this being annoying for some
|
||||
people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears,
|
||||
use the button that appears on the notice saying "Don't show this again". You can always enable these settings again
|
||||
later.
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="disableSponsorViewTracking" class="warningButton">Disable Sponsor View Tracking</button>
|
||||
<button id="enableSponsorViewTracking" style="display: none" class="warningButton">Enable Sponsor View Tracking</button>
|
||||
<br/>
|
||||
<sub>
|
||||
This feature tracks which sponsors you have skipped to let users know how much their submission has helped others and
|
||||
used as a metric along with upvotes to ensure that spam doesn't get into the database. The extension sends a message
|
||||
to the server each time you skip a sponsor. Hopefully most people don't change this setting so that the view numbers
|
||||
are accurate. :)
|
||||
</sub>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
<button id="showNoticeAgain" style="display: none" class="dangerButton">Show Notice Again</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
420
popup.js
420
popup.js
@@ -1,12 +1,42 @@
|
||||
|
||||
// References
|
||||
var SB = {};
|
||||
|
||||
SB.sponsorStart = document.getElementById("sponsorStart");
|
||||
SB.clearTimes = document.getElementById("clearTimes");
|
||||
SB.submitTimes = document.getElementById("submitTimes");
|
||||
SB.showNoticeAgain = document.getElementById("showNoticeAgain");
|
||||
SB.hideVideoPlayerControls = document.getElementById("hideVideoPlayerControls");
|
||||
SB.showVideoPlayerControls = document.getElementById("showVideoPlayerControls");
|
||||
SB.disableSponsorViewTracking = document.getElementById("disableSponsorViewTracking");
|
||||
SB.enableSponsorViewTracking = document.getElementById("enableSponsorViewTracking");
|
||||
SB.optionsButton = document.getElementById("optionsButton");
|
||||
SB.reportAnIssue = document.getElementById("reportAnIssue");
|
||||
// sponsorTimesContributions
|
||||
SB.sponsorTimesContributionsContainer = document.getElementById("sponsorTimesContributionsContainer");
|
||||
SB.sponsorTimesContributionsDisplay = document.getElementById("sponsorTimesContributionsDisplay");
|
||||
SB.sponsorTimesContributionsDisplayEndWord = document.getElementById("sponsorTimesContributionsDisplayEndWord");
|
||||
// sponsorTimesViewsDisplay
|
||||
SB.sponsorTimesViewsContainer = document.getElementById("sponsorTimesViewsDisplayContainer");
|
||||
SB.sponsorTimesViewsDisplay = document.getElementById("sponsorTimesViewsDisplayDisplay");
|
||||
SB.sponsorTimesViewsDisplayEndWord = document.getElementById("sponsorTimesViewsDisplayDisplayEndWord");
|
||||
// discordButtons
|
||||
SB.discordButtonContainer = document.getElementById("discordButtonContainer");
|
||||
SB.hideDiscordButton = document.getElementById("hideDiscordButton");
|
||||
|
||||
//setup click listeners
|
||||
document.getElementById("sponsorStart").addEventListener("click", sendSponsorStartMessage);
|
||||
document.getElementById("clearTimes").addEventListener("click", clearTimes);
|
||||
document.getElementById("submitTimes").addEventListener("click", submitTimes);
|
||||
document.getElementById("showNoticeAgain").addEventListener("click", showNoticeAgain);
|
||||
document.getElementById("hideVideoPlayerControls").addEventListener("click", hideVideoPlayerControls);
|
||||
document.getElementById("showVideoPlayerControls").addEventListener("click", showVideoPlayerControls);
|
||||
document.getElementById("optionsButton").addEventListener("click", openOptions);
|
||||
document.getElementById("reportAnIssue").addEventListener("click", reportAnIssue);
|
||||
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
||||
SB.clearTimes.addEventListener("click", clearTimes);
|
||||
SB.submitTimes.addEventListener("click", submitTimes);
|
||||
SB.showNoticeAgain.addEventListener("click", showNoticeAgain);
|
||||
SB.hideVideoPlayerControls.addEventListener("click", hideVideoPlayerControls);
|
||||
SB.showVideoPlayerControls.addEventListener("click", showVideoPlayerControls);
|
||||
SB.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking);
|
||||
SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking);
|
||||
SB.optionsButton.addEventListener("click", openOptions);
|
||||
SB.reportAnIssue.addEventListener("click", reportAnIssue);
|
||||
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
||||
|
||||
|
||||
//if true, the button now selects the end time
|
||||
var startTimeChosen = false;
|
||||
@@ -20,12 +50,32 @@ var currentVideoID = null;
|
||||
//is this a YouTube tab?
|
||||
var isYouTubeTab = false;
|
||||
|
||||
//see if discord link can be shown
|
||||
chrome.storage.sync.get(["hideDiscordLink"], function(result) {
|
||||
let hideDiscordLink = result.hideDiscordLink;
|
||||
if (hideDiscordLink == undefined || !hideDiscordLink) {
|
||||
chrome.storage.sync.get(["hideDiscordLaunches"], function(result) {
|
||||
let hideDiscordLaunches = result.hideDiscordLaunches;
|
||||
//only if less than 5 launches
|
||||
if (hideDiscordLaunches == undefined || hideDiscordLaunches < 10) {
|
||||
SB.discordButtonContainer.style.display = null;
|
||||
|
||||
if (hideDiscordLaunches == undefined) {
|
||||
hideDiscordButton = 1;
|
||||
}
|
||||
|
||||
chrome.storage.sync.set({"hideDiscordLaunches": hideDiscordButton + 1});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//if the don't show notice again variable is true, an option to
|
||||
// disable should be available
|
||||
chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
let dontShowNoticeAgain = result.dontShowNoticeAgain;
|
||||
if (dontShowNoticeAgain != undefined && dontShowNoticeAgain) {
|
||||
document.getElementById("showNoticeAgain").style.display = "unset";
|
||||
SB.showNoticeAgain.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,25 +83,30 @@ chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
chrome.storage.sync.get(["hideVideoPlayerControls"], function(result) {
|
||||
let hideVideoPlayerControls = result.hideVideoPlayerControls;
|
||||
if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) {
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "none";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "unset";
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//show proper tracking option
|
||||
chrome.storage.sync.get(["trackViewCount"], function(result) {
|
||||
let trackViewCount = result.trackViewCount;
|
||||
if (trackViewCount != undefined && !trackViewCount) {
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
});
|
||||
|
||||
//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."
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsors."
|
||||
} else {
|
||||
sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
|
||||
SB.sponsorTimesContributionsDisplayEndWord.innerText = "sponsor."
|
||||
}
|
||||
sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
|
||||
sponsorTimesContributionsContainer.style.display = "unset";
|
||||
SB.sponsorTimesContributionsDisplay.innerText = result.sponsorTimesContributed;
|
||||
SB.sponsorTimesContributionsContainer.style.display = "unset";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
@@ -62,19 +117,14 @@ chrome.storage.sync.get(["sponsorTimesContributed"], function(result) {
|
||||
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."
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segments."
|
||||
} else {
|
||||
sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
|
||||
SB.sponsorTimesViewsDisplayEndWord.innerText = "sponsor segment."
|
||||
}
|
||||
sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
sponsorTimesViewsContainer.style.display = "unset";
|
||||
SB.sponsorTimesViewsDisplay.innerText = viewCount;
|
||||
SB.sponsorTimesViewsContainer.style.display = "unset";
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -106,7 +156,7 @@ function loadTabData(tabs) {
|
||||
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
|
||||
if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
|
||||
startTimeChosen = true;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
|
||||
}
|
||||
|
||||
sponsorTimes = sponsorTimesStorage;
|
||||
@@ -170,40 +220,47 @@ function sendSponsorStartMessage() {
|
||||
}, tabs => {
|
||||
chrome.tabs.sendMessage(
|
||||
tabs[0].id,
|
||||
{from: 'popup', message: 'sponsorStart'}
|
||||
{from: 'popup', message: 'sponsorStart'},
|
||||
startSponsorCallback
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
if (request.message == "time") {
|
||||
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
|
||||
function startSponsorCallback(response) {
|
||||
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
|
||||
|
||||
if (sponsorTimes[sponsorTimesIndex] == undefined) {
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
}
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = request.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
//display video times on screen
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
document.getElementById("submissionSection").style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
if (sponsorTimes[sponsorTimesIndex] == undefined) {
|
||||
sponsorTimes[sponsorTimesIndex] = [];
|
||||
}
|
||||
});
|
||||
|
||||
sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time;
|
||||
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
updateStartTimeChosen();
|
||||
|
||||
//display video times on screen
|
||||
displaySponsorTimes();
|
||||
|
||||
//show submission section
|
||||
document.getElementById("submissionSection").style.display = "unset";
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
}
|
||||
|
||||
//display the video times from the array
|
||||
function displaySponsorTimes() {
|
||||
//set it to the message
|
||||
document.getElementById("sponsorMessageTimes").innerHTML = getSponsorTimesMessage(sponsorTimes);
|
||||
let sponsorMessageTimes = document.getElementById("sponsorMessageTimes");
|
||||
|
||||
//remove all children
|
||||
while (sponsorMessageTimes.firstChild) {
|
||||
sponsorMessageTimes.removeChild(sponsorMessageTimes.firstChild);
|
||||
}
|
||||
|
||||
//add sponsor times
|
||||
sponsorMessageTimes.appendChild(getSponsorTimesMessageDiv(sponsorTimes));
|
||||
}
|
||||
|
||||
//display the video times from the array at the top, in a different section
|
||||
@@ -286,6 +343,185 @@ function getSponsorTimesMessage(sponsorTimes) {
|
||||
return sponsorTimesMessage;
|
||||
}
|
||||
|
||||
//get the message that visually displays the video times
|
||||
//this version is a div that contains each with delete buttons
|
||||
function getSponsorTimesMessageDiv(sponsorTimes) {
|
||||
// let sponsorTimesMessage = "";
|
||||
let sponsorTimesContainer = document.createElement("div");
|
||||
sponsorTimesContainer.id = "sponsorTimesContainer";
|
||||
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
let currentSponsorTimeContainer = document.createElement("div");
|
||||
currentSponsorTimeContainer.id = "sponsorTimeContainer" + i;
|
||||
let currentSponsorTimeMessage = "";
|
||||
|
||||
let deleteButton = document.createElement("span");
|
||||
deleteButton.id = "sponsorTimeDeleteButton" + i;
|
||||
deleteButton.innerText = "Delete";
|
||||
deleteButton.className = "smallLink";
|
||||
let index = i;
|
||||
deleteButton.addEventListener("click", () => deleteSponsorTime(index));
|
||||
|
||||
let spacer = document.createElement("span");
|
||||
spacer.innerText = " ";
|
||||
|
||||
let editButton = document.createElement("span");
|
||||
editButton.id = "sponsorTimeEditButton" + i;
|
||||
editButton.innerText = "Edit";
|
||||
editButton.className = "smallLink";
|
||||
editButton.addEventListener("click", () => editSponsorTime(index));
|
||||
|
||||
for (let s = 0; s < sponsorTimes[i].length; s++) {
|
||||
let timeMessage = getFormattedTime(sponsorTimes[i][s]);
|
||||
//if this is an end time
|
||||
if (s == 1) {
|
||||
timeMessage = " to " + timeMessage;
|
||||
} else if (i > 0) {
|
||||
//add commas if necessary
|
||||
timeMessage = timeMessage;
|
||||
}
|
||||
|
||||
currentSponsorTimeMessage += timeMessage;
|
||||
}
|
||||
|
||||
currentSponsorTimeContainer.innerText = currentSponsorTimeMessage;
|
||||
sponsorTimesContainer.appendChild(currentSponsorTimeContainer);
|
||||
sponsorTimesContainer.appendChild(deleteButton);
|
||||
|
||||
//only if it is a complete sponsor time
|
||||
if (sponsorTimes[i].length > 1) {
|
||||
sponsorTimesContainer.appendChild(spacer);
|
||||
sponsorTimesContainer.appendChild(editButton);
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorTimesContainer;
|
||||
}
|
||||
|
||||
function editSponsorTime(index) {
|
||||
let sponsorTimeContainer = document.getElementById("sponsorTimeContainer" + index);
|
||||
|
||||
//get sponsor time minutes and seconds boxes
|
||||
let startTimeMinutes = document.createElement("input");
|
||||
startTimeMinutes.id = "startTimeMinutes" + index;
|
||||
startTimeMinutes.type = "text";
|
||||
startTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][0]);
|
||||
startTimeMinutes.style.width = "35";
|
||||
|
||||
let startTimeSeconds = document.createElement("input");
|
||||
startTimeSeconds.id = "startTimeSeconds" + index;
|
||||
startTimeSeconds.type = "text";
|
||||
startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][0]);
|
||||
startTimeSeconds.style.width = "42";
|
||||
|
||||
let endTimeMinutes = document.createElement("input");
|
||||
endTimeMinutes.id = "endTimeMinutes" + index;
|
||||
endTimeMinutes.type = "text";
|
||||
endTimeMinutes.value = getTimeInMinutes(sponsorTimes[index][1]);
|
||||
endTimeMinutes.style.width = "35";
|
||||
|
||||
let endTimeSeconds = document.createElement("input");
|
||||
endTimeSeconds.id = "endTimeSeconds" + index;
|
||||
endTimeSeconds.type = "text";
|
||||
endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]);
|
||||
endTimeSeconds.style.width = "42";
|
||||
|
||||
let colonText = document.createElement("span");
|
||||
colonText.innerText = ":";
|
||||
|
||||
let toText = document.createElement("span");
|
||||
toText.innerText = " to ";
|
||||
|
||||
//remove all children to replace
|
||||
while (sponsorTimeContainer.firstChild) {
|
||||
sponsorTimeContainer.removeChild(sponsorTimeContainer.firstChild);
|
||||
}
|
||||
|
||||
sponsorTimeContainer.appendChild(startTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(startTimeSeconds);
|
||||
sponsorTimeContainer.appendChild(toText);
|
||||
sponsorTimeContainer.appendChild(endTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(endTimeSeconds);
|
||||
|
||||
//add save button and remove edit button
|
||||
let saveButton = document.createElement("span");
|
||||
saveButton.id = "sponsorTimeSaveButton" + index;
|
||||
saveButton.innerText = "Save";
|
||||
saveButton.className = "smallLink";
|
||||
saveButton.addEventListener("click", () => saveSponsorTimeEdit(index));
|
||||
|
||||
let editButton = document.getElementById("sponsorTimeEditButton" + index);
|
||||
let sponsorTimesContainer = document.getElementById("sponsorTimesContainer");
|
||||
|
||||
sponsorTimesContainer.removeChild(editButton);
|
||||
sponsorTimesContainer.appendChild(saveButton);
|
||||
}
|
||||
|
||||
function saveSponsorTimeEdit(index) {
|
||||
let startTimeMinutes = document.getElementById("startTimeMinutes" + index);
|
||||
let startTimeSeconds = document.getElementById("startTimeSeconds" + index);
|
||||
|
||||
let endTimeMinutes = document.getElementById("endTimeMinutes" + index);
|
||||
let endTimeSeconds = document.getElementById("endTimeSeconds" + index);
|
||||
|
||||
sponsorTimes[index][0] = parseInt(startTimeMinutes.value) * 60 + parseFloat(startTimeSeconds.value);
|
||||
sponsorTimes[index][1] = parseInt(endTimeMinutes.value) * 60 + parseFloat(endTimeSeconds.value);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
displaySponsorTimes();
|
||||
}
|
||||
|
||||
//deletes the sponsor time submitted at an index
|
||||
function deleteSponsorTime(index) {
|
||||
//if it is not a complete sponsor time
|
||||
if (sponsorTimes[index].length < 2) {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
|
||||
resetStartTimeChosen();
|
||||
}
|
||||
|
||||
sponsorTimes.splice(index, 1);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes});
|
||||
|
||||
//update display
|
||||
displaySponsorTimes();
|
||||
|
||||
//if they are all removed
|
||||
if (sponsorTimes.length == 0) {
|
||||
//update chrome tab
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "changeStartSponsorButton",
|
||||
showStartSponsor: true,
|
||||
uploadButtonVisible: false
|
||||
});
|
||||
});
|
||||
|
||||
//hide submission section
|
||||
document.getElementById("submissionSection").style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function clearTimes() {
|
||||
//send new sponsor time state to tab
|
||||
if (sponsorTimes.length > 0) {
|
||||
@@ -341,7 +577,7 @@ function submitTimes() {
|
||||
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("submitTimesInfoMessage").innerText = "There was an error submitting your sponsor times, please try again later. Error code " + response.statusCode;
|
||||
document.getElementById("submitTimesInfoMessageContainer").style.display = "unset";
|
||||
}
|
||||
}
|
||||
@@ -361,7 +597,7 @@ function showNoticeAgain() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("showNoticeAgain").style.display = "none";
|
||||
SB.showNoticeAgain.style.display = "none";
|
||||
}
|
||||
|
||||
function hideVideoPlayerControls() {
|
||||
@@ -377,8 +613,8 @@ function hideVideoPlayerControls() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "none";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "unset";
|
||||
SB.hideVideoPlayerControls.style.display = "none";
|
||||
SB.showVideoPlayerControls.style.display = "unset";
|
||||
}
|
||||
|
||||
function showVideoPlayerControls() {
|
||||
@@ -394,15 +630,49 @@ function showVideoPlayerControls() {
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("hideVideoPlayerControls").style.display = "unset";
|
||||
document.getElementById("showVideoPlayerControls").style.display = "none";
|
||||
SB.hideVideoPlayerControls.style.display = "unset";
|
||||
SB.showVideoPlayerControls.style.display = "none";
|
||||
}
|
||||
|
||||
function disableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": false});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: false
|
||||
});
|
||||
});
|
||||
|
||||
SB.disableSponsorViewTracking.style.display = "none";
|
||||
SB.enableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
function enableSponsorViewTracking() {
|
||||
chrome.storage.sync.set({"trackViewCount": true});
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, function(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {
|
||||
message: "trackViewCount",
|
||||
value: true
|
||||
});
|
||||
});
|
||||
|
||||
SB.enableSponsorViewTracking.style.display = "none";
|
||||
SB.disableSponsorViewTracking.style.display = "unset";
|
||||
}
|
||||
|
||||
function updateStartTimeChosen() {
|
||||
//update startTimeChosen variable
|
||||
if (!startTimeChosen) {
|
||||
startTimeChosen = true;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Ends Now";
|
||||
} else {
|
||||
resetStartTimeChosen();
|
||||
}
|
||||
@@ -411,7 +681,7 @@ function updateStartTimeChosen() {
|
||||
//set it to false
|
||||
function resetStartTimeChosen() {
|
||||
startTimeChosen = false;
|
||||
document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now";
|
||||
SB.sponsorStart.innerHTML = "Sponsorship Starts Now";
|
||||
}
|
||||
|
||||
//hides and shows the submit times button when needed
|
||||
@@ -440,7 +710,7 @@ function displayNoVideo() {
|
||||
|
||||
function reportAnIssue() {
|
||||
document.getElementById("issueReporterContainer").style.display = "unset";
|
||||
document.getElementById("reportAnIssue").style.display = "none";
|
||||
SB.reportAnIssue.style.display = "none";
|
||||
}
|
||||
|
||||
function addVoteMessage(message, UUID) {
|
||||
@@ -484,6 +754,12 @@ function vote(type, UUID) {
|
||||
});
|
||||
}
|
||||
|
||||
function hideDiscordButton() {
|
||||
chrome.storage.sync.set({"hideDiscordLink": false});
|
||||
|
||||
SB.discordButtonContainer.style.display = "none";
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes:seconds
|
||||
function getFormattedTime(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
@@ -498,6 +774,24 @@ function getFormattedTime(seconds) {
|
||||
return formatted;
|
||||
}
|
||||
|
||||
//converts time in seconds to minutes
|
||||
function getTimeInMinutes(seconds) {
|
||||
let minutes = Math.floor(seconds / 60);
|
||||
|
||||
return minutes;
|
||||
}
|
||||
|
||||
//converts time in seconds to seconds past the last minute
|
||||
function getTimeInFormattedSeconds(seconds) {
|
||||
let secondsFormatted = (seconds % 60).toFixed(3);
|
||||
|
||||
if (secondsFormatted < 10) {
|
||||
secondsFormatted = "0" + secondsFormatted;
|
||||
}
|
||||
|
||||
return secondsFormatted;
|
||||
}
|
||||
|
||||
function sendRequestToServer(type, address, callback) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
@@ -521,4 +815,4 @@ function getYouTubeVideoID(url) { // Return video id or false
|
||||
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
|
||||
var match = url.match(regExp);
|
||||
return (match && match[7].length == 11) ? match[7] : false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user