mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-09 04:57:09 +03:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
137ba895bb | ||
|
|
ecc48de396 | ||
|
|
aa95687b56 | ||
|
|
a8147738ef | ||
|
|
4a3d36b952 | ||
|
|
f9bd82db35 | ||
|
|
c8438b9d59 | ||
|
|
5347340c1c | ||
|
|
524e443f4d | ||
|
|
b9091c3a97 | ||
|
|
5445146b56 | ||
|
|
13d0e4a33a | ||
|
|
8f0a9d97f6 | ||
|
|
5feed6bfcc | ||
|
|
5916baf5ea | ||
|
|
1c3a857fcf | ||
|
|
640ad58c65 | ||
|
|
41aa58e004 | ||
|
|
6b3eb09198 | ||
|
|
44c4671977 | ||
|
|
ac118173a5 | ||
|
|
3f815a18c4 | ||
|
|
e281b90699 | ||
|
|
012a36b931 | ||
|
|
43e3d03e9a | ||
|
|
5adeeed634 | ||
|
|
29a8608f9d | ||
|
|
67c4acbc5e | ||
|
|
a5d605f539 | ||
|
|
66b6985c5e | ||
|
|
0025785a78 | ||
|
|
ba284aec2f | ||
|
|
5ffe207a86 | ||
|
|
3a4d867ae3 | ||
|
|
7a2c57aae9 | ||
|
|
05faa7e138 | ||
|
|
f254a99d6f | ||
|
|
19a1a5efda | ||
|
|
28322f19b5 | ||
|
|
c7d03aa423 | ||
|
|
60242df3c9 | ||
|
|
1aab52edbe | ||
|
|
2580577ce0 | ||
|
|
1ab33375ec | ||
|
|
e1f5046ace | ||
|
|
b28087f723 | ||
|
|
866cc33f0e | ||
|
|
02448307ab | ||
|
|
1b5d5f8a3a | ||
|
|
6707d6df8d | ||
|
|
883871123a | ||
|
|
301e16b8f1 | ||
|
|
e1f1814748 | ||
|
|
074f7c5456 | ||
|
|
2a64afe9dc | ||
|
|
4c12bb9c2f | ||
|
|
22e7c6a40d | ||
|
|
a9ea22f505 | ||
|
|
2067b1c787 | ||
|
|
410f5fc138 | ||
|
|
077efd2de3 | ||
|
|
62632792cc | ||
|
|
bbbb4f4877 |
148
background.js
148
background.js
@@ -1,55 +1,43 @@
|
||||
//when a new tab is highlighted
|
||||
chrome.tabs.onActivated.addListener(
|
||||
function(activeInfo) {
|
||||
chrome.tabs.get(activeInfo.tabId, function(tab) {
|
||||
let id = getYouTubeVideoID(tab.url);
|
||||
|
||||
//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.tabs.sendMessage(tabId, {
|
||||
message: 'update',
|
||||
});
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
||||
if (request.message == "submitTimes") {
|
||||
submitTimes(request.videoID, callback);
|
||||
switch(request.message) {
|
||||
case "submitTimes":
|
||||
submitTimes(request.videoID, callback);
|
||||
|
||||
//this allows the callback to be called later by the submitTimes function
|
||||
return true;
|
||||
} else if (request.message == "addSponsorTime") {
|
||||
addSponsorTime(request.time, request.videoID, callback);
|
||||
//this allows the callback to be called later by the submitTimes function
|
||||
return true;
|
||||
case "addSponsorTime":
|
||||
addSponsorTime(request.time, request.videoID, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
} else if (request.message == "getSponsorTimes") {
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
sponsorTimes: sponsorTimes
|
||||
})
|
||||
});
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "getSponsorTimes":
|
||||
getSponsorTimes(request.videoID, function(sponsorTimes) {
|
||||
callback({
|
||||
sponsorTimes: sponsorTimes
|
||||
})
|
||||
});
|
||||
|
||||
//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;
|
||||
case "submitVote":
|
||||
submitVote(request.type, request.UUID, callback);
|
||||
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
}
|
||||
//this allows the callback to be called later
|
||||
return true;
|
||||
case "alertPrevious":
|
||||
chrome.notifications.create("stillThere" + Math.random(), {
|
||||
type: "basic",
|
||||
title: "Do you want to submit the sponsor times for video id " + request.previousVideoID + "?",
|
||||
message: "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted).",
|
||||
iconUrl: "./icons/LogoSponsorBlocker256px.png"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//add help page on install
|
||||
@@ -154,7 +142,7 @@ function submitVote(type, UUID, callback) {
|
||||
function submitTimes(videoID, callback) {
|
||||
//get the video times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + videoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
chrome.storage.sync.get([sponsorTimeKey, "userID"], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
let userID = result.userID;
|
||||
|
||||
@@ -193,56 +181,6 @@ function submitTimes(videoID, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
function videoIDChange(currentVideoID, tabId) {
|
||||
//send a message to the content script
|
||||
chrome.tabs.sendMessage(tabId, {
|
||||
message: 'ytvideoid',
|
||||
id: currentVideoID
|
||||
});
|
||||
|
||||
chrome.storage.sync.get(["sponsorVideoID", "previousVideoID"], function(result) {
|
||||
const sponsorVideoID = result.sponsorVideoID;
|
||||
const previousVideoID = result.previousVideoID;
|
||||
|
||||
//not a url change
|
||||
if (sponsorVideoID == currentVideoID){
|
||||
return;
|
||||
}
|
||||
|
||||
chrome.storage.sync.set({
|
||||
"sponsorVideoID": currentVideoID
|
||||
});
|
||||
|
||||
//warn them if they had unsubmitted times
|
||||
if (previousVideoID != null) {
|
||||
//get the sponsor times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + previousVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
//warn them that they have unsubmitted sponsor times
|
||||
chrome.notifications.create("stillThere" + Math.random(), {
|
||||
type: "basic",
|
||||
title: "Do you want to submit the sponsor times for watch?v=" + previousVideoID + "?",
|
||||
message: "You seem to have left some sponsor times unsubmitted. Go back to that page to submit them (they are not deleted).",
|
||||
iconUrl: "./icons/LogoSponsorBlocker256px.png"
|
||||
});
|
||||
}
|
||||
|
||||
//set the previous video id to the currentID
|
||||
chrome.storage.sync.set({
|
||||
"previousVideoID": currentVideoID
|
||||
});
|
||||
});
|
||||
} else {
|
||||
chrome.storage.sync.set({
|
||||
"previousVideoID": currentVideoID
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendRequestToServer(type, address, callback) {
|
||||
let xmlhttp = new XMLHttpRequest();
|
||||
|
||||
@@ -262,5 +200,21 @@ function sendRequestToServer(type, address, callback) {
|
||||
xmlhttp.send();
|
||||
}
|
||||
|
||||
//uuid generator function from https://gist.github.com/jed/982883
|
||||
function generateUUID(a){return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,generateUUID)}
|
||||
function generateUUID(length = 36) {
|
||||
let charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
let result = "";
|
||||
let isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
||||
if (window.crypto && window.crypto.getRandomValues) {
|
||||
values = new Uint32Array(length);
|
||||
window.crypto.getRandomValues(values);
|
||||
for (i = 0; i < length; i++) {
|
||||
result += charset[values[i] % charset.length];
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += charset[Math.floor(Math.random() * charset.length)];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
18
content.css
18
content.css
@@ -1,3 +1,21 @@
|
||||
#previewbar {
|
||||
overflow: visible;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
pointer-events: none;
|
||||
|
||||
height: 100%;
|
||||
transform: scaleY(0.6) translateY(-30%) translateY(1.5px);
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
.previewbar {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.popup {
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
|
||||
117
content.js
117
content.js
@@ -1,24 +1,33 @@
|
||||
//was sponsor data found when doing SponsorsLookup
|
||||
var sponsorDataFound = false;
|
||||
|
||||
var previousVideoID = null;
|
||||
//the actual sponsorTimes if loaded and UUIDs associated with them
|
||||
var sponsorTimes = null;
|
||||
var UUIDs = null;
|
||||
//what video id are these sponsors for
|
||||
var sponsorVideoID = null;
|
||||
|
||||
//these are sponsors that have been downvoted
|
||||
var hiddenSponsorTimes = [];
|
||||
|
||||
//the time this video is starting at when first played, if not zero
|
||||
var youtubeVideoStartTime = null;
|
||||
|
||||
//the video
|
||||
var v;
|
||||
|
||||
var listenerAdded;
|
||||
|
||||
//the channel this video is about
|
||||
var channelURL;
|
||||
|
||||
//is this channel whitelised from getting sponsors skipped
|
||||
var channelWhitelisted = false;
|
||||
|
||||
// create preview bar
|
||||
let progressBar = document.getElementsByClassName("ytp-progress-bar-container")[0] || document.getElementsByClassName("no-model cue-range-markers")[0];
|
||||
var previewBar = new PreviewBar(progressBar);
|
||||
|
||||
if(id = getYouTubeVideoID(document.URL)){ // Direct Links
|
||||
videoIDChange(id);
|
||||
}
|
||||
@@ -29,6 +38,10 @@ var lastTime = -1;
|
||||
//the actual time (not video time) that the last skip happened
|
||||
var lastUnixTimeSkipped = -1;
|
||||
|
||||
//the amount of times the sponsor lookup has retried
|
||||
//this only happens if there is an error
|
||||
var sponsorLookupRetries = 0;
|
||||
|
||||
//the last time in the video a sponsor was skipped
|
||||
//used for the go back button
|
||||
var lastSponsorTimeSkipped = null;
|
||||
@@ -79,12 +92,12 @@ chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
|
||||
chrome.runtime.onMessage.addListener(messageListener);
|
||||
|
||||
function messageListener(request, sender, sendResponse) {
|
||||
//message from background script
|
||||
if (request.message == "ytvideoid") {
|
||||
videoIDChange(request.id);
|
||||
//messages from popup script
|
||||
|
||||
if (request.message == "update") {
|
||||
if(id = getYouTubeVideoID(document.URL)) videoIDChange(id);
|
||||
}
|
||||
|
||||
//messages from popup script
|
||||
if (request.message == "sponsorStart") {
|
||||
sponsorMessageStarted(sendResponse);
|
||||
}
|
||||
@@ -98,6 +111,7 @@ function messageListener(request, sender, sendResponse) {
|
||||
sendResponse({
|
||||
found: sponsorDataFound,
|
||||
sponsorTimes: sponsorTimes,
|
||||
hiddenSponsorTimes: hiddenSponsorTimes,
|
||||
UUIDs: UUIDs
|
||||
});
|
||||
|
||||
@@ -115,6 +129,16 @@ function messageListener(request, sender, sendResponse) {
|
||||
})
|
||||
}
|
||||
|
||||
if (request.message == "skipToTime") {
|
||||
v.currentTime = request.time;
|
||||
}
|
||||
|
||||
if (request.message == "getCurrentTime") {
|
||||
sendResponse({
|
||||
currentTime: v.currentTime
|
||||
});
|
||||
}
|
||||
|
||||
if (request.message == "getChannelURL") {
|
||||
sendResponse({
|
||||
channelURL: channelURL
|
||||
@@ -179,9 +203,31 @@ document.onkeydown = function(e){
|
||||
}
|
||||
|
||||
function videoIDChange(id) {
|
||||
|
||||
//not a url change
|
||||
if (sponsorVideoID == id){
|
||||
return;
|
||||
if (sponsorVideoID == id) return;
|
||||
|
||||
//warn them if they had unsubmitted times
|
||||
if (previousVideoID != null) {
|
||||
//get the sponsor times from storage
|
||||
let sponsorTimeKey = 'sponsorTimes' + previousVideoID;
|
||||
chrome.storage.sync.get([sponsorTimeKey], function(result) {
|
||||
let sponsorTimes = result[sponsorTimeKey];
|
||||
|
||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
||||
//warn them that they have unsubmitted sponsor times
|
||||
chrome.runtime.sendMessage({
|
||||
message: "alertPrevious",
|
||||
previousVideoID: previousVideoID
|
||||
})
|
||||
}
|
||||
|
||||
//set the previous video id to the currentID
|
||||
previousVideoID = id;
|
||||
});
|
||||
} else {
|
||||
//set the previous id now, don't wait for chrome.storage.get
|
||||
previousVideoID = id;
|
||||
}
|
||||
|
||||
//close popup
|
||||
@@ -195,6 +241,10 @@ function videoIDChange(id) {
|
||||
sponsorTimes = null;
|
||||
UUIDs = null;
|
||||
sponsorVideoID = id;
|
||||
sponsorLookupRetries = 0;
|
||||
|
||||
//empty the preview bar
|
||||
previewBar.set([], [], 0);
|
||||
|
||||
//see if there is a video start time
|
||||
youtubeVideoStartTime = getYouTubeVideoStartTime(document.URL);
|
||||
@@ -273,9 +323,21 @@ function sponsorsLookup(id) {
|
||||
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
|
||||
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
|
||||
|
||||
//update the preview bar
|
||||
//leave the type blank for now until categories are added
|
||||
console.log(v.duration)
|
||||
if (isNaN(v.duration)) {
|
||||
//wait until it is loaded
|
||||
v.addEventListener('durationchange', updatePreviewBar);
|
||||
} else {
|
||||
//set it now
|
||||
updatePreviewBar();
|
||||
}
|
||||
|
||||
getChannelID();
|
||||
|
||||
} else if (xmlhttp.readyState == 4) {
|
||||
sponsorLookupRetries = 0;
|
||||
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 404) {
|
||||
sponsorDataFound = false;
|
||||
|
||||
//check if this video was uploaded recently
|
||||
@@ -290,6 +352,13 @@ function sponsorsLookup(id) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
sponsorLookupRetries = 0;
|
||||
} else if (xmlhttp.readyState == 4 && sponsorLookupRetries < 90) {
|
||||
//some error occurred, try again in a second
|
||||
setTimeout(() => sponsorsLookup(id), 1000);
|
||||
|
||||
sponsorLookupRetries++;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -299,6 +368,13 @@ function sponsorsLookup(id) {
|
||||
};
|
||||
}
|
||||
|
||||
function updatePreviewBar() {
|
||||
previewBar.set(sponsorTimes, [], v.duration);
|
||||
|
||||
//the listener is only needed once
|
||||
v.removeEventListener('durationchange', updatePreviewBar);
|
||||
}
|
||||
|
||||
function getChannelID() {
|
||||
//get channel id
|
||||
let channelContainers = document.querySelectorAll("#owner-name");
|
||||
@@ -378,7 +454,7 @@ function checkSponsorTime(sponsorTimes, index, openNotice) {
|
||||
lastTime = v.currentTime - 0.0001;
|
||||
}
|
||||
|
||||
if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0])) {
|
||||
if (checkIfTimeToSkip(v.currentTime, sponsorTimes[index][0]) && !hiddenSponsorTimes.includes(index)) {
|
||||
//skip it
|
||||
skipToTime(v, index, sponsorTimes, openNotice);
|
||||
|
||||
@@ -889,6 +965,26 @@ function afterDownvote(UUID) {
|
||||
//add element to div
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingText);
|
||||
document.getElementById("sponsorTimesVoteButtonsContainer" + UUID).appendChild(thanksForVotingInfoText);
|
||||
|
||||
//remove this sponsor from the sponsors looked up
|
||||
//find which one it is
|
||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||
if (UUIDs[i] == UUID) {
|
||||
//this one is the one to hide
|
||||
|
||||
//add this as a hidden sponsorTime
|
||||
hiddenSponsorTimes.push(i);
|
||||
|
||||
let sponsorTimesLeft = sponsorTimes.slice();
|
||||
for (let j = 0; j < hiddenSponsorTimes.length; j++) {
|
||||
//remove this sponsor time
|
||||
sponsorTimesLeft.splice(hiddenSponsorTimes[j], 1);
|
||||
}
|
||||
|
||||
//update the preview
|
||||
previewBar.set(sponsorTimesLeft, [], v.duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addLoadingInfo(message, UUID) {
|
||||
@@ -1048,6 +1144,9 @@ function sendSubmitMessage(){
|
||||
//clear the sponsor times
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
chrome.storage.sync.set({[sponsorTimeKey]: []});
|
||||
|
||||
//request the sponsors from the server again
|
||||
sponsorsLookup(currentVideoID);
|
||||
} else {
|
||||
//for a more detailed error message, they should check the popup
|
||||
//show that the upload failed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "SponsorBlock for YouTube - Skip Sponsorships",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "1.0.30",
|
||||
"version": "1.0.35",
|
||||
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
|
||||
"content_scripts": [
|
||||
{
|
||||
@@ -11,6 +11,7 @@
|
||||
"all_frames": true,
|
||||
"js": [
|
||||
"config.js",
|
||||
"utils/previewBar.js",
|
||||
"utils.js",
|
||||
"content.js",
|
||||
"popup.js"
|
||||
@@ -36,7 +37,6 @@
|
||||
"popup.html"
|
||||
],
|
||||
"permissions": [
|
||||
"tabs",
|
||||
"storage",
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
|
||||
10
popup.css
10
popup.css
@@ -80,8 +80,14 @@ h1.popupElement {
|
||||
|
||||
.mediumLink.popupElement {
|
||||
font-size: 15px;
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
margin-left: 25px;
|
||||
margin-right: 25px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tinyLink.popupElement {
|
||||
font-size: 10px;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
29
popup.html
29
popup.html
@@ -94,6 +94,8 @@
|
||||
</div>
|
||||
</b>
|
||||
|
||||
<br/>
|
||||
|
||||
<button id="clearTimes" class="smallButton popupElement">Clear Times</button>
|
||||
|
||||
<br/>
|
||||
@@ -112,6 +114,31 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div id="setUsernameContainer" class="popupElement">
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="setUsernameButton" class="warningButton popupElement">Set Username</button>
|
||||
</div>
|
||||
|
||||
<div id="setUsername" class="popupElement" style="display: none">
|
||||
<br/>
|
||||
|
||||
<h3>Set Username</h3>
|
||||
|
||||
<div id="setUsernameStatusContainer" style="display: none">
|
||||
<h2 id="setUsernameStatus"></h2>
|
||||
</div>
|
||||
|
||||
|
||||
<input id="usernameInput" hint="Username"></input>
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<button id="submitUsername" class="warningButton popupElement">Submit Username</button>
|
||||
</div>
|
||||
|
||||
<div id="discordButtonContainer" class="popupElement" style="display: none">
|
||||
<br/>
|
||||
|
||||
@@ -119,7 +146,7 @@
|
||||
|
||||
<br/>
|
||||
|
||||
Come join the official discord server to give suggestions and feedback!
|
||||
Come join the official discord server to give suggestions and feedback!
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
185
popup.js
185
popup.js
@@ -54,6 +54,14 @@ function runThePopup() {
|
||||
// submitTimesInfoMessage
|
||||
"submitTimesInfoMessageContainer",
|
||||
"submitTimesInfoMessage",
|
||||
// Username
|
||||
"setUsernameContainer",
|
||||
"setUsernameButton",
|
||||
"setUsernameStatusContainer",
|
||||
"setUsernameStatus",
|
||||
"setUsername",
|
||||
"usernameInput",
|
||||
"submitUsername",
|
||||
// More
|
||||
"submissionSection",
|
||||
"mainControls",
|
||||
@@ -78,6 +86,8 @@ function runThePopup() {
|
||||
SB.showDeleteButtonPlayerControls.addEventListener("click", showDeleteButtonPlayerControls);
|
||||
SB.disableSponsorViewTracking.addEventListener("click", disableSponsorViewTracking);
|
||||
SB.enableSponsorViewTracking.addEventListener("click", enableSponsorViewTracking);
|
||||
SB.setUsernameButton.addEventListener("click", setUsernameButton);
|
||||
SB.submitUsername.addEventListener("click", submitUsername);
|
||||
SB.optionsButton.addEventListener("click", openOptions);
|
||||
SB.reportAnIssue.addEventListener("click", reportAnIssue);
|
||||
SB.hideDiscordButton.addEventListener("click", hideDiscordButton);
|
||||
@@ -201,17 +211,25 @@ function runThePopup() {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, loadTabData);
|
||||
}, onTabs);
|
||||
|
||||
function onTabs(tabs) {
|
||||
chrome.tabs.sendMessage(tabs[0].id, {message: 'getVideoID'}, function(result) {
|
||||
if (result != undefined && result.videoID) {
|
||||
currentVideoID = result.videoID;
|
||||
|
||||
loadTabData(tabs);
|
||||
} else if (result == undefined && chrome.runtime.lastError) {
|
||||
//this isn't a YouTube video then, or at least the content script is not loaded
|
||||
displayNoVideo();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadTabData(tabs) {
|
||||
//set current videoID
|
||||
currentVideoID = getYouTubeVideoID(tabs[0].url);
|
||||
|
||||
if (!currentVideoID) {
|
||||
//this isn't a YouTube video then
|
||||
displayNoVideo();
|
||||
@@ -376,7 +394,14 @@ function runThePopup() {
|
||||
for (let i = 0; i < request.sponsorTimes.length; i++) {
|
||||
let sponsorTimeButton = document.createElement("button");
|
||||
sponsorTimeButton.className = "warningButton popupElement";
|
||||
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]);
|
||||
|
||||
let extraInfo = "";
|
||||
if (request.hiddenSponsorTimes.includes(i)) {
|
||||
//this one is hidden
|
||||
extraInfo = " (hidden)";
|
||||
}
|
||||
|
||||
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i][0]) + " to " + getFormattedTime(request.sponsorTimes[i][1]) + extraInfo;
|
||||
|
||||
let votingButtons = document.createElement("div");
|
||||
|
||||
@@ -465,8 +490,11 @@ function runThePopup() {
|
||||
let index = i;
|
||||
deleteButton.addEventListener("click", () => deleteSponsorTime(index));
|
||||
|
||||
let spacer = document.createElement("span");
|
||||
spacer.innerText = " ";
|
||||
let previewButton = document.createElement("span");
|
||||
previewButton.id = "sponsorTimePreviewButton" + i;
|
||||
previewButton.innerText = "Preview";
|
||||
previewButton.className = "mediumLink popupElement";
|
||||
previewButton.addEventListener("click", () => previewSponsorTime(index));
|
||||
|
||||
let editButton = document.createElement("span");
|
||||
editButton.id = "sponsorTimeEditButton" + i;
|
||||
@@ -488,20 +516,47 @@ function runThePopup() {
|
||||
}
|
||||
|
||||
currentSponsorTimeContainer.innerText = currentSponsorTimeMessage;
|
||||
currentSponsorTimeContainer.addEventListener("click", () => editSponsorTime(index));
|
||||
|
||||
sponsorTimesContainer.appendChild(currentSponsorTimeContainer);
|
||||
sponsorTimesContainer.appendChild(deleteButton);
|
||||
|
||||
//only if it is a complete sponsor time
|
||||
if (sponsorTimes[i].length > 1) {
|
||||
sponsorTimesContainer.appendChild(previewButton);
|
||||
sponsorTimesContainer.appendChild(editButton);
|
||||
|
||||
currentSponsorTimeContainer.addEventListener("click", () => editSponsorTime(index));
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorTimesContainer;
|
||||
}
|
||||
|
||||
function previewSponsorTime(index) {
|
||||
let skipTime = sponsorTimes[index][0];
|
||||
|
||||
if (document.getElementById("startTimeMinutes" + index) != null) {
|
||||
//edit is currently open, use that time
|
||||
|
||||
skipTime = getSponsorTimeEditTimes("startTime", index);
|
||||
|
||||
//save the edit
|
||||
saveSponsorTimeEdit(index, false);
|
||||
}
|
||||
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, tabs => {
|
||||
chrome.tabs.sendMessage(
|
||||
tabs[0].id, {
|
||||
message: "skipToTime",
|
||||
time: skipTime - 2
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function editSponsorTime(index) {
|
||||
if (document.getElementById("startTimeMinutes" + index) != null) {
|
||||
//already open
|
||||
@@ -513,6 +568,13 @@ function runThePopup() {
|
||||
|
||||
let sponsorTimeContainer = document.getElementById("sponsorTimeContainer" + index);
|
||||
|
||||
//the button to set the current time
|
||||
let startTimeNowButton = document.createElement("span");
|
||||
startTimeNowButton.id = "startTimeNowButton" + index;
|
||||
startTimeNowButton.innerText = "(Now)";
|
||||
startTimeNowButton.className = "tinyLink popupElement";
|
||||
startTimeNowButton.addEventListener("click", () => setEditTimeToCurrentTime("startTime", index));
|
||||
|
||||
//get sponsor time minutes and seconds boxes
|
||||
let startTimeMinutes = document.createElement("input");
|
||||
startTimeMinutes.id = "startTimeMinutes" + index;
|
||||
@@ -542,6 +604,13 @@ function runThePopup() {
|
||||
endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]);
|
||||
endTimeSeconds.style.width = "60px";
|
||||
|
||||
//the button to set the current time
|
||||
let endTimeNowButton = document.createElement("span");
|
||||
endTimeNowButton.id = "endTimeNowButton" + index;
|
||||
endTimeNowButton.innerText = "(Now)";
|
||||
endTimeNowButton.className = "tinyLink popupElement";
|
||||
endTimeNowButton.addEventListener("click", () => setEditTimeToCurrentTime("endTime", index));
|
||||
|
||||
let colonText = document.createElement("span");
|
||||
colonText.innerText = ":";
|
||||
|
||||
@@ -553,6 +622,7 @@ function runThePopup() {
|
||||
sponsorTimeContainer.removeChild(sponsorTimeContainer.firstChild);
|
||||
}
|
||||
|
||||
sponsorTimeContainer.appendChild(startTimeNowButton);
|
||||
sponsorTimeContainer.appendChild(startTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(startTimeSeconds);
|
||||
@@ -560,6 +630,7 @@ function runThePopup() {
|
||||
sponsorTimeContainer.appendChild(endTimeMinutes);
|
||||
sponsorTimeContainer.appendChild(colonText);
|
||||
sponsorTimeContainer.appendChild(endTimeSeconds);
|
||||
sponsorTimeContainer.appendChild(endTimeNowButton);
|
||||
|
||||
//add save button and remove edit button
|
||||
let saveButton = document.createElement("span");
|
||||
@@ -574,15 +645,36 @@ function runThePopup() {
|
||||
sponsorTimesContainer.replaceChild(saveButton, editButton);
|
||||
}
|
||||
|
||||
function saveSponsorTimeEdit(index) {
|
||||
let startTimeMinutes = document.getElementById("startTimeMinutes" + index);
|
||||
let startTimeSeconds = document.getElementById("startTimeSeconds" + index);
|
||||
function setEditTimeToCurrentTime(idStartName, index) {
|
||||
chrome.tabs.query({
|
||||
active: true,
|
||||
currentWindow: true
|
||||
}, tabs => {
|
||||
chrome.tabs.sendMessage(
|
||||
tabs[0].id,
|
||||
{message: "getCurrentTime"},
|
||||
function (response) {
|
||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
||||
|
||||
let endTimeMinutes = document.getElementById("endTimeMinutes" + index);
|
||||
let endTimeSeconds = document.getElementById("endTimeSeconds" + index);
|
||||
minutes.value = getTimeInMinutes(response.currentTime);
|
||||
seconds.value = getTimeInFormattedSeconds(response.currentTime);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
sponsorTimes[index][0] = parseInt(startTimeMinutes.value) * 60 + parseFloat(startTimeSeconds.value);
|
||||
sponsorTimes[index][1] = parseInt(endTimeMinutes.value) * 60 + parseFloat(endTimeSeconds.value);
|
||||
//id start name is whether it is the startTime or endTime
|
||||
//gives back the time in seconds
|
||||
function getSponsorTimeEditTimes(idStartName, index) {
|
||||
let minutes = document.getElementById(idStartName + "Minutes" + index);
|
||||
let seconds = document.getElementById(idStartName + "Seconds" + index);
|
||||
|
||||
return parseInt(minutes.value) * 60 + parseFloat(seconds.value);
|
||||
}
|
||||
|
||||
function saveSponsorTimeEdit(index, closeEditMode = true) {
|
||||
sponsorTimes[index][0] = getSponsorTimeEditTimes("startTime", index);
|
||||
sponsorTimes[index][1] = getSponsorTimeEditTimes("endTime", index);
|
||||
|
||||
//save this
|
||||
let sponsorTimeKey = "sponsorTimes" + currentVideoID;
|
||||
@@ -598,9 +690,11 @@ function runThePopup() {
|
||||
});
|
||||
});
|
||||
|
||||
displaySponsorTimes();
|
||||
if (closeEditMode) {
|
||||
displaySponsorTimes();
|
||||
|
||||
showSubmitTimesIfNecessary();
|
||||
showSubmitTimesIfNecessary();
|
||||
}
|
||||
}
|
||||
|
||||
//deletes the sponsor time submitted at an index
|
||||
@@ -911,12 +1005,65 @@ function runThePopup() {
|
||||
}
|
||||
}
|
||||
|
||||
//make the options div visisble
|
||||
//make the options div visible
|
||||
function openOptions() {
|
||||
document.getElementById("optionsButtonContainer").style.display = "none";
|
||||
document.getElementById("options").style.display = "unset";
|
||||
}
|
||||
|
||||
//make the options username setting option visible
|
||||
function setUsernameButton() {
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
//get username from the server
|
||||
sendRequestToServer("GET", "/api/getUsername?userID=" + result.userID, function (xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
SB.usernameInput.value = JSON.parse(xmlhttp.responseText).userName;
|
||||
|
||||
SB.submitUsername.style.display = "unset";
|
||||
SB.usernameInput.style.display = "unset";
|
||||
|
||||
SB.setUsernameContainer.style.display = "none";
|
||||
SB.setUsername.style.display = "unset";
|
||||
} else {
|
||||
SB.setUsername.style.display = "unset";
|
||||
SB.submitUsername.style.display = "none";
|
||||
SB.usernameInput.style.display = "none";
|
||||
|
||||
SB.setUsernameStatus.innerText = "Couldn't connect to server. Error code: " + xmlhttp.status;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//submit the new username
|
||||
function submitUsername() {
|
||||
//add loading indicator
|
||||
SB.setUsernameStatusContainer.style.display = "unset";
|
||||
SB.setUsernameStatus.innerText = "Loading...";
|
||||
|
||||
//get the userID
|
||||
chrome.storage.sync.get(["userID"], function(result) {
|
||||
sendRequestToServer("POST", "/api/setUsername?userID=" + result.userID + "&username=" + SB.usernameInput.value, function (xmlhttp, error) {
|
||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||
//submitted
|
||||
SB.submitUsername.style.display = "none";
|
||||
SB.usernameInput.style.display = "none";
|
||||
|
||||
SB.setUsernameStatus.innerText = "Success!";
|
||||
} else if (xmlhttp.readyState == 4 && xmlhttp.status == 400) {
|
||||
SB.setUsernameStatus.innerText = "Bad Request";
|
||||
} else {
|
||||
SB.setUsernameStatus.innerText = getErrorMessage(EN_US, xmlhttp.status);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
SB.setUsernameContainer.style.display = "none";
|
||||
SB.setUsername.style.display = "unset";
|
||||
}
|
||||
|
||||
//this is not a YouTube video page
|
||||
function displayNoVideo() {
|
||||
document.getElementById("loadingIndicator").innerHTML = "This probably isn't a YouTube tab, or you clicked too early. " +
|
||||
|
||||
86
utils/previewBar.js
Normal file
86
utils/previewBar.js
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
This is based on code from VideoSegments.
|
||||
https://github.com/videosegments/videosegments/commits/f1e111bdfe231947800c6efdd51f62a4e7fef4d4/segmentsbar/segmentsbar.js
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let barTypes = {
|
||||
"undefined": {
|
||||
color: "#00d400",
|
||||
opacity: "0.5"
|
||||
},
|
||||
"sponsor": {
|
||||
color: "#00d400",
|
||||
opacity: "0.5"
|
||||
}
|
||||
};
|
||||
|
||||
class PreviewBar {
|
||||
constructor(parent) {
|
||||
this.container = document.createElement('ul');
|
||||
this.container.id = 'previewbar';
|
||||
this.parent = parent;
|
||||
this.bars = []
|
||||
|
||||
this.updatePosition();
|
||||
}
|
||||
|
||||
updatePosition() {
|
||||
//below the seek bar
|
||||
// this.parent.insertAdjacentElement("afterEnd", this.container);
|
||||
|
||||
//on the seek bar
|
||||
this.parent.insertAdjacentElement("afterBegin", this.container);
|
||||
}
|
||||
|
||||
updateColor(segment, color, opacity) {
|
||||
let bars = document.querySelectorAll('[data-vs-segment-type=' + segment + ']');
|
||||
for (let bar of bars) {
|
||||
bar.style.backgroundColor = color;
|
||||
bar.style.opacity = opacity;
|
||||
}
|
||||
}
|
||||
|
||||
set(timestamps, types, duration) {
|
||||
while (this.container.firstChild) {
|
||||
this.container.removeChild(this.container.firstChild);
|
||||
}
|
||||
|
||||
if (!timestamps || !types) {
|
||||
return;
|
||||
}
|
||||
|
||||
// to avoid rounding error resulting in width more than 100%
|
||||
duration = Math.floor(duration * 100) / 100;
|
||||
let width;
|
||||
for (let i = 0; i < timestamps.length; i++) {
|
||||
width = (timestamps[i][1] - timestamps[i][0]) / duration * 100;
|
||||
width = Math.floor(width * 100) / 100;
|
||||
|
||||
let bar = this.createBar();
|
||||
bar.setAttribute('data-vs-segment-type', types[i]);
|
||||
|
||||
bar.style.backgroundColor = barTypes[types[i]].color;
|
||||
bar.style.opacity = barTypes[types[i]].opacity;
|
||||
bar.style.width = width + '%';
|
||||
bar.style.left = (timestamps[i][0] / duration * 100) + "%";
|
||||
bar.style.position = "absolute"
|
||||
|
||||
this.container.insertAdjacentElement('beforeEnd', bar);
|
||||
this.bars[i] = bar;
|
||||
}
|
||||
}
|
||||
|
||||
createBar() {
|
||||
let bar = document.createElement('li');
|
||||
bar.classList.add('previewbar');
|
||||
bar.innerHTML = ' ';
|
||||
return bar;
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.container.remove();
|
||||
this.container = undefined;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user