Merge pull request #68 from ajayyy/experimental

Channel whitelisting, more support and bug fixes
This commit is contained in:
Ajay Ramachandran
2019-08-03 22:17:29 -04:00
committed by GitHub
6 changed files with 312 additions and 16 deletions

View File

@@ -39,7 +39,10 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//this allows the callback to be called later by the submitTimes function //this allows the callback to be called later by the submitTimes function
return true; return true;
} else if (request.message == "addSponsorTime") { } else if (request.message == "addSponsorTime") {
addSponsorTime(request.time, request.videoID); addSponsorTime(request.time, request.videoID, callback);
//this allows the callback to be called later
return true;
} else if (request.message == "getSponsorTimes") { } else if (request.message == "getSponsorTimes") {
getSponsorTimes(request.videoID, function(sponsorTimes) { getSponsorTimes(request.videoID, function(sponsorTimes) {
callback({ callback({
@@ -85,7 +88,7 @@ function getSponsorTimes(videoID, callback) {
}); });
} }
function addSponsorTime(time, videoID) { function addSponsorTime(time, videoID, callback) {
getSponsorTimes(videoID, function(sponsorTimes) { getSponsorTimes(videoID, function(sponsorTimes) {
//add to sponsorTimes //add to sponsorTimes
if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) { if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
@@ -101,7 +104,7 @@ function addSponsorTime(time, videoID) {
//save this info //save this info
let sponsorTimeKey = "sponsorTimes" + videoID; let sponsorTimeKey = "sponsorTimes" + videoID;
chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}); chrome.storage.sync.set({[sponsorTimeKey]: sponsorTimes}, callback);
}); });
} }

View File

@@ -7,6 +7,9 @@ var UUIDs = null;
//what video id are these sponsors for //what video id are these sponsors for
var sponsorVideoID = null; var sponsorVideoID = null;
//the time this video is starting at when first played, if not zero
var youtubeVideoStartTime = null;
if(id = getYouTubeVideoID(document.URL)){ // Direct Links if(id = getYouTubeVideoID(document.URL)){ // Direct Links
videoIDChange(id); videoIDChange(id);
} }
@@ -14,6 +17,12 @@ if(id = getYouTubeVideoID(document.URL)){ // Direct Links
//the video //the video
var v; var v;
//the channel this video is about
var channelURL;
//is this channel whitelised from getting sponsors skipped
var channelWhitelisted = false;
//the last time looked at (used to see if this time is in the interval) //the last time looked at (used to see if this time is in the interval)
var lastTime = -1; var lastTime = -1;
@@ -106,6 +115,23 @@ function messageListener(request, sender, sendResponse) {
}) })
} }
if (request.message == "getChannelURL") {
sendResponse({
channelURL: channelURL
})
}
if (request.message == "isChannelWhitelisted") {
sendResponse({
value: channelWhitelisted
})
}
if (request.message == "whitelistChange") {
channelWhitelisted = request.value;
sponsorsLookup(getYouTubeVideoID(document.URL));
}
if (request.message == "showNoticeAgain") { if (request.message == "showNoticeAgain") {
dontShowNotice = false; dontShowNotice = false;
} }
@@ -167,10 +193,16 @@ function videoIDChange(id) {
UUIDs = null; UUIDs = null;
sponsorVideoID = id; sponsorVideoID = id;
//see if there is a video start time
youtubeVideoStartTime = getYouTubeVideoStartTime(document.URL);
//reset sponsor data found check //reset sponsor data found check
sponsorDataFound = false; sponsorDataFound = false;
sponsorsLookup(id); sponsorsLookup(id);
//make sure everything is properly added
updateVisibilityOfPlayerControlsButton(true);
//reset sponsor times submitting //reset sponsor times submitting
sponsorTimesSubmitting = []; sponsorTimesSubmitting = [];
@@ -216,13 +248,19 @@ function videoIDChange(id) {
hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls; hideDeleteButtonPlayerControls = result.hideDeleteButtonPlayerControls;
} }
updateVisibilityOfPlayerControlsButton(); updateVisibilityOfPlayerControlsButton(false);
}); });
} }
function sponsorsLookup(id) { function sponsorsLookup(id) {
v = document.querySelector('video') // Youtube video player v = document.querySelector('video') // Youtube video player
//there is no video here
if (v == null) {
setTimeout(() => sponsorsLookup(id), 100);
return;
}
//check database for sponsor times //check database for sponsor times
sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) { sendRequestToServer('GET', "/api/getVideoSponsorTimes?videoID=" + id, function(xmlhttp) {
@@ -231,6 +269,9 @@ function sponsorsLookup(id) {
sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes; sponsorTimes = JSON.parse(xmlhttp.responseText).sponsorTimes;
UUIDs = JSON.parse(xmlhttp.responseText).UUIDs; UUIDs = JSON.parse(xmlhttp.responseText).UUIDs;
getChannelID();
} else if (xmlhttp.readyState == 4) { } else if (xmlhttp.readyState == 4) {
sponsorDataFound = false; sponsorDataFound = false;
@@ -255,6 +296,47 @@ function sponsorsLookup(id) {
}; };
} }
function getChannelID() {
//get channel id
let channelContainers = document.querySelectorAll("#owner-name");
let channelURLContainer = null;
for (let i = 0; i < channelContainers.length; i++) {
if (channelContainers[i].firstElementChild != null) {
channelURLContainer = channelContainers[i].firstElementChild;
}
}
if (channelContainers.length == 0) {
//old YouTube theme
channelContainers = document.getElementsByClassName("yt-user-info");
if (channelContainers.length != 0) {
channelURLContainer = channelContainers[0].firstElementChild;
}
}
if (channelURLContainer == null) {
//try later
setTimeout(getChannelID, 100);
return;
}
channelURL = channelURLContainer.getAttribute("href");
//see if this is a whitelisted channel
chrome.storage.sync.get(["whitelistedChannels"], function(result) {
let whitelistedChannels = result.whitelistedChannels;
if (whitelistedChannels != undefined && whitelistedChannels.includes(channelURL)) {
//reset sponsor times to nothing
sponsorTimes = [];
UUIDs = [];
channelWhitelisted = true;
}
});
}
//video skipping //video skipping
function sponsorCheck() { function sponsorCheck() {
let skipHappened = false; let skipHappened = false;
@@ -310,9 +392,9 @@ function checkIfTimeToSkip(currentVideoTime, startTime) {
//If the sponsor time is in between these times, skip it //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 //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) // sponsor times in a row (from one troll)
//the last term makes 0 second start times possible //the last term makes 0 second start times possible only if the video is not setup to start at a different time from zero
return (Math.abs(currentVideoTime - startTime) < 0.3 && startTime >= lastTime && startTime <= currentVideoTime && return (Math.abs(currentVideoTime - startTime) < 0.3 && startTime >= lastTime && startTime <= currentVideoTime &&
(lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && startTime == 0); (lastUnixTimeSkipped == -1 || currentTime - lastUnixTimeSkipped > 500)) || (lastTime == -1 && startTime == 0 && youtubeVideoStartTime == null)
} }
//skip fromt he start time to the end time for a certain index sponsor time //skip fromt he start time to the end time for a certain index sponsor time
@@ -367,8 +449,15 @@ function addPlayerControlsButton() {
//add the image to the button //add the image to the button
startSponsorButton.appendChild(startSponsorImage); startSponsorButton.appendChild(startSponsorImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0]; let controls = document.getElementsByClassName("ytp-right-controls");
let referenceNode = controls[controls.length - 1];
if (referenceNode == undefined) {
//page not loaded yet
setTimeout(addPlayerControlsButton, 100);
return;
}
referenceNode.prepend(startSponsorButton); referenceNode.prepend(startSponsorButton);
} }
@@ -379,6 +468,9 @@ function removePlayerControlsButton() {
//adds or removes the player controls button to what it should be //adds or removes the player controls button to what it should be
function updateVisibilityOfPlayerControlsButton() { function updateVisibilityOfPlayerControlsButton() {
//not on a proper video yet
if (!getYouTubeVideoID(document.URL)) return;
addPlayerControlsButton(); addPlayerControlsButton();
addInfoButton(); addInfoButton();
addDeleteButton(); addDeleteButton();
@@ -482,7 +574,15 @@ function addInfoButton() {
//add the image to the button //add the image to the button
infoButton.appendChild(infoImage); infoButton.appendChild(infoImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0]; let controls = document.getElementsByClassName("ytp-right-controls");
let referenceNode = controls[controls.length - 1];
if (referenceNode == undefined) {
//page not loaded yet
setTimeout(addInfoButton, 100);
return;
}
referenceNode.prepend(infoButton); referenceNode.prepend(infoButton);
} }
@@ -510,7 +610,15 @@ function addDeleteButton() {
//add the image to the button //add the image to the button
deleteButton.appendChild(deleteImage); deleteButton.appendChild(deleteImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0]; let controls = document.getElementsByClassName("ytp-right-controls");
let referenceNode = controls[controls.length - 1];
if (referenceNode == undefined) {
//page not loaded yet
setTimeout(addDeleteButton, 100);
return;
}
referenceNode.prepend(deleteButton); referenceNode.prepend(deleteButton);
} }
@@ -538,7 +646,15 @@ function addSubmitButton() {
//add the image to the button //add the image to the button
submitButton.appendChild(submitImage); submitButton.appendChild(submitImage);
let referenceNode = document.getElementsByClassName("ytp-right-controls")[0]; let controls = document.getElementsByClassName("ytp-right-controls");
let referenceNode = controls[controls.length - 1];
if (referenceNode == undefined) {
//page not loaded yet
setTimeout(addSubmitButton, 100);
return;
}
referenceNode.prepend(submitButton); referenceNode.prepend(submitButton);
} }
@@ -859,7 +975,7 @@ function dontShowNoticeAgain() {
} }
function sponsorMessageStarted(callback) { function sponsorMessageStarted(callback) {
let v = document.querySelector('video'); v = document.querySelector('video');
//send back current time //send back current time
callback({ callback({
@@ -916,9 +1032,15 @@ function sendSubmitMessage(){
//finish this animation //finish this animation
submitButton.style.animation = "rotate 1s"; submitButton.style.animation = "rotate 1s";
//when the animation is over, hide the button //when the animation is over, hide the button
submitButton.addEventListener("animationend", function() { let animationEndListener = function() {
changeStartSponsorButton(true, false); changeStartSponsorButton(true, false);
});
submitButton.style.animation = "none";
submitButton.removeEventListener("animationend", animationEndListener);
};
submitButton.addEventListener("animationend", animationEndListener);
//clear the sponsor times //clear the sponsor times
let sponsorTimeKey = "sponsorTimes" + currentVideoID; let sponsorTimeKey = "sponsorTimes" + currentVideoID;
@@ -1030,3 +1152,14 @@ function getYouTubeVideoID(url) { // Returns with video id else returns false
return (match && match[7].length == 11) ? id : false; return (match && match[7].length == 11) ? id : false;
} }
//returns the start time of the video if there was one specified (ex. ?t=5s)
function getYouTubeVideoStartTime(url) {
let searchParams = new URL(url).searchParams;
var startTime = searchParams.get("t");
if (startTime == null) {
startTime = searchParams.get("time_continue");
}
return startTime;
}

View File

@@ -1,7 +1,7 @@
{ {
"name": "SponsorBlock for YouTube - Skip Sponsorships", "name": "SponsorBlock for YouTube - Skip Sponsorships",
"short_name": "SponsorBlock", "short_name": "SponsorBlock",
"version": "1.0.26", "version": "1.0.28",
"description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.", "description": "Skip over sponsorship on YouTube videos. Report sponsors on videos you watch to save the time of others.",
"content_scripts": [ "content_scripts": [
{ {

View File

@@ -86,6 +86,32 @@ h1.popupElement {
cursor: pointer; cursor: pointer;
} }
.whitelistButton.popupElement {
background-color:#3acc3a;
-moz-border-radius:28px;
-webkit-border-radius:28px;
border-radius:28px;
border: none;
display:inline-block;
cursor:pointer;
color:#ffffff;
font-size:16px;
padding:8px 37px;
text-decoration:none;
text-shadow:0px 0px 0px #27663c;
}
.whitelistButton:hover.popupElement {
background-color:#218b26;
}
.whitelistButton:focus.popupElement {
outline: none;
background-color:#218b26;
}
.whitelistButton:active.popupElement {
position:relative;
top:1px;
}
.greenButton.popupElement { .greenButton.popupElement {
background-color:#ec1c1c; background-color:#ec1c1c;
-moz-border-radius:28px; -moz-border-radius:28px;

View File

@@ -25,7 +25,18 @@
<div id="downloadedSponsorMessageTimes" class="popupElement"> <div id="downloadedSponsorMessageTimes" class="popupElement">
</div> </div>
<br/>
<div>
<button id="whitelistChannel" class="whitelistButton popupElement">Whitelist Channel</button>
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">Remove Channel From Whitelist</button>
</div>
<sub class="popupElement">
Whitelist the channels who do sponsorships ethically to encourage good behavior, or maybe if they are just entertaining and funny. Or don't, that's your call.
</sub>
<br/>
<br/> <br/>
<button id="reportAnIssue" class="dangerButton popupElement">Vote On A Sponsor Time</button> <button id="reportAnIssue" class="dangerButton popupElement">Vote On A Sponsor Time</button>

125
popup.js
View File

@@ -25,6 +25,8 @@ function runThePopup() {
var SB = {}; var SB = {};
["sponsorStart", ["sponsorStart",
"whitelistChannel",
"unwhitelistChannel",
"clearTimes", "clearTimes",
"submitTimes", "submitTimes",
"showNoticeAgain", "showNoticeAgain",
@@ -63,6 +65,8 @@ function runThePopup() {
//setup click listeners //setup click listeners
SB.sponsorStart.addEventListener("click", sendSponsorStartMessage); SB.sponsorStart.addEventListener("click", sendSponsorStartMessage);
SB.whitelistChannel.addEventListener("click", whitelistChannel);
SB.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
SB.clearTimes.addEventListener("click", clearTimes); SB.clearTimes.addEventListener("click", clearTimes);
SB.submitTimes.addEventListener("click", submitTimes); SB.submitTimes.addEventListener("click", submitTimes);
SB.showNoticeAgain.addEventListener("click", showNoticeAgain); SB.showNoticeAgain.addEventListener("click", showNoticeAgain);
@@ -118,6 +122,26 @@ function runThePopup() {
}); });
} }
}); });
//see if whitelist button should be swapped
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{message: 'isChannelWhitelisted'},
function(response) {
if (response.value) {
SB.whitelistChannel.style.display = "none";
SB.unwhitelistChannel.style.display = "unset";
SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
}
});
}
);
//if the don't show notice again letiable is true, an option to //if the don't show notice again letiable is true, an option to
// disable should be available // disable should be available
@@ -343,7 +367,9 @@ function runThePopup() {
function displayDownloadedSponsorTimes(request) { function displayDownloadedSponsorTimes(request) {
if (request.sponsorTimes != undefined) { if (request.sponsorTimes != undefined) {
//set it to the message //set it to the message
SB.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes); if (SB.downloadedSponsorMessageTimes.innerText != "Channel Whitelisted!") {
SB.downloadedSponsorMessageTimes.innerText = getSponsorTimesMessage(request.sponsorTimes);
}
//add them as buttons to the issue reporting container //add them as buttons to the issue reporting container
let container = document.getElementById("issueReporterTimeButtons"); let container = document.getElementById("issueReporterTimeButtons");
@@ -966,6 +992,103 @@ function runThePopup() {
return formatted; return formatted;
} }
function whitelistChannel() {
//get the channel url
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{message: 'getChannelURL'},
function(response) {
//get whitelisted channels
chrome.storage.sync.get(["whitelistedChannels"], function(result) {
let whitelistedChannels = result.whitelistedChannels;
if (whitelistedChannels == undefined) {
whitelistedChannels = [];
}
//add on this channel
whitelistedChannels.push(response.channelURL);
//change button
SB.whitelistChannel.style.display = "none";
SB.unwhitelistChannel.style.display = "unset";
SB.downloadedSponsorMessageTimes.innerText = "Channel Whitelisted!";
SB.downloadedSponsorMessageTimes.style.fontWeight = "bold";
//save this
chrome.storage.sync.set({whitelistedChannels: whitelistedChannels});
//send a message to the client
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id, {
message: 'whitelistChange',
value: true
});
}
);
});
}
);
});
}
function unwhitelistChannel() {
//get the channel url
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id,
{message: 'getChannelURL'},
function(response) {
//get whitelisted channels
chrome.storage.sync.get(["whitelistedChannels"], function(result) {
let whitelistedChannels = result.whitelistedChannels;
if (whitelistedChannels == undefined) {
whitelistedChannels = [];
}
//remove this channel
let index = whitelistedChannels.indexOf(response.channelURL);
whitelistedChannels.splice(index, 1);
//change button
SB.whitelistChannel.style.display = "unset";
SB.unwhitelistChannel.style.display = "none";
SB.downloadedSponsorMessageTimes.innerText = "";
SB.downloadedSponsorMessageTimes.style.fontWeight = "unset";
//save this
chrome.storage.sync.set({whitelistedChannels: whitelistedChannels});
//send a message to the client
chrome.tabs.query({
active: true,
currentWindow: true
}, tabs => {
chrome.tabs.sendMessage(
tabs[0].id, {
message: 'whitelistChange',
value: false
});
}
);
});
}
);
});
}
//converts time in seconds to minutes //converts time in seconds to minutes
function getTimeInMinutes(seconds) { function getTimeInMinutes(seconds) {