Compare commits

...

43 Commits

Author SHA1 Message Date
Ajay Ramachandran
6358ba2e11 Merge pull request #44 from ajayyy/experimental
Added discord link to popup
2019-07-28 23:53:39 -04:00
Ajay Ramachandran
2415784eee Added discord link to popup. 2019-07-28 23:52:32 -04:00
Ajay Ramachandran
acb3c67629 Merge pull request #43 from ajayyy/experimental
Updates to the video player controls
2019-07-28 20:53:38 -04:00
Ajay Ramachandran
622b2ea158 Updated version number. 2019-07-28 20:51:09 -04:00
Ajay Ramachandran
7a9af6cbcf Alt-text now updates with state on player button 2019-07-28 18:51:46 -04:00
Ajay Ramachandran
51a389284d Made video player controls state properly update when the video changes. 2019-07-28 18:48:28 -04:00
Ajay Ramachandran
2ff70f1511 Added missing references. 2019-07-28 18:32:53 -04:00
Ajay Ramachandran
ff9badf2e9 Merge pull request #39 from ajayyy/experimental
Fixed an issue on Firefox where the old video's sponsors would sometimes play on the next video
2019-07-28 17:56:50 -04:00
Ajay Ramachandran
aefc880486 Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into experimental
# Conflicts:
#	content.js
#	firefox_manifest.json
#	manifest.json
2019-07-28 17:24:25 -04:00
Ajay Ramachandran
e749456719 Updated version number. 2019-07-28 17:23:01 -04:00
Ajay Ramachandran
a2312a10be Fixed an issue on Firefox where the old video's sponsors would sometimes play on the next video. 2019-07-28 17:22:05 -04:00
Ajay Ramachandran
b0090a3334 Merge pull request #37 from OfficialNoob/patch-5
getYouTubeVideoID Better ID Parser
2019-07-27 17:30:01 -04:00
Official Noob
7100831956 getYouTubeVideoID Video ID Parser 2019-07-27 22:18:43 +01:00
Ajay Ramachandran
30c1b2d919 Added reference and updated version number. 2019-07-27 11:18:50 -04:00
Ajay Ramachandran
3ec6caee9d Merge pull request #32 from OfficialNoob/patch-3
Added references
2019-07-27 11:13:21 -04:00
Ajay Ramachandran
7f505a52ca Merge pull request #30 from OfficialNoob/patch-1
Added confirm for submitSponsorTimes
2019-07-27 11:12:36 -04:00
Ajay Ramachandran
84b8e59b39 Merge branch 'master' into patch-1 2019-07-27 11:12:27 -04:00
Ajay Ramachandran
808dfe42ce Merge pull request #35 from ajayyy/experimental
Made it not possible to submit from the hotkey when not ready
2019-07-27 11:10:23 -04:00
Ajay Ramachandran
600365d998 Made it not possible to submit from the hotkey when not ready. 2019-07-27 11:08:29 -04:00
Official Noob
569699cbc1 Added references 2019-07-27 13:57:04 +01:00
Official Noob
08cb324125 Added confirm for submitSponsorTimes 2019-07-27 12:57:44 +01:00
Ajay Ramachandran
504f0b0ede Merge pull request #29 from ajayyy/experimental
Removed logging
2019-07-26 22:43:25 -04:00
Ajay Ramachandran
00877fb087 Removed logging. 2019-07-26 22:43:09 -04:00
Ajay Ramachandran
d654d8934b Merge pull request #26 from ajayyy/experimental
Fixed bug making player controls only submit integers
2019-07-26 21:47:56 -04:00
Ajay Ramachandran
97e202dbd0 Fixed bug making player controls only submit integers. 2019-07-26 21:44:39 -04:00
Ajay Ramachandran
64be41b008 Merge pull request #25 from ajayyy/experimental
Fixed old unsponsored times sometimes being used
2019-07-26 20:26:29 -04:00
Ajay Ramachandran
b3684a8730 Added hint about the hotkey. 2019-07-26 20:23:13 -04:00
Ajay Ramachandran
45f0d65f69 Fixed old unsponsored times sometimes being used. 2019-07-26 20:19:51 -04:00
Ajay Ramachandran
5436a1651e Merge pull request #9 from ajayyy/experimental
Added support for hotkeys to submit data
2019-07-26 16:24:11 -04:00
Ajay Ramachandran
33fe63084b Added support for hotkeys to submit data. 2019-07-26 16:20:07 -04:00
Ajay Ramachandran
8f47513c98 Merge pull request #8 from ajayyy/experimental
Added quick fix for changing UUID when submitting two times
2019-07-26 14:21:50 -04:00
Ajay Ramachandran
7a17cc2b0a Updated version number. 2019-07-26 14:19:21 -04:00
Ajay Ramachandran
c7cb845d8a Added quick fix for changing UUID when submitting two times. 2019-07-26 14:19:01 -04:00
Ajay Ramachandran
250c75a78f Merge pull request #7 from ajayyy/experimental
Zero second sponsors and support for switching tabs
2019-07-25 20:07:52 -04:00
Ajay Ramachandran
a86e55ac67 Update version number. 2019-07-25 20:07:08 -04:00
Ajay Ramachandran
30f2f638fe Added support for sponsors at the zero second mark.
Also fixed some issues on the old YouTube theme.
2019-07-25 20:00:07 -04:00
Ajay Ramachandran
725ab783e3 Made it work when multiple tabs are opened in the background.
Now uses the focused tab instead of last tab updated.
2019-07-25 18:25:50 -04:00
Ajay Ramachandran
30e3222177 Updated version number 2019-07-25 17:00:02 -04:00
Ajay Ramachandran
d9789c20d6 Merge pull request #6 from ajayyy/experimental
Added better error display
2019-07-25 16:59:05 -04:00
Ajay Ramachandran
c8114e2d7e Added better error display. 2019-07-25 16:55:07 -04:00
Ajay Ramachandran
c7da0f0c65 Merge pull request #5 from ajayyy/experimental
Added option to disable view count tracking
2019-07-23 21:09:36 -04:00
Ajay Ramachandran
0f561d4a5a Added option to disable the view count tracking. 2019-07-23 21:06:36 -04:00
Ajay Ramachandran
55c7529731 Update README.md 2019-07-23 20:06:08 -04:00
8 changed files with 365 additions and 118 deletions

View File

@@ -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/mnjggcdmjocbbbhaepdhchncahnbgone/
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

View File

@@ -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();

View File

@@ -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,17 @@ var showingStartSponsor = true;
//should the video controls buttons be added
var hideVideoPlayerControls = 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;
@@ -48,6 +55,7 @@ chrome.storage.sync.get(["dontShowNoticeAgain"], function(result) {
chrome.runtime.onMessage.addListener( // Detect URL Changes
function(request, sender, sendResponse) {
console.log(request.message)
//message from background script
if (request.message == "ytvideoid") {
videoIDChange(request.id);
@@ -86,9 +94,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 +145,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 +203,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 +226,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,11 +285,10 @@ function removePlayerControlsButton() {
//adds or removes the player controls button to what it should be
function updateVisibilityOfPlayerControlsButton() {
addPlayerControlsButton();
addSubmitButton();
if (hideVideoPlayerControls) {
removePlayerControlsButton();
} else {
addPlayerControlsButton();
addSubmitButton();
}
}
@@ -239,7 +298,8 @@ function startSponsorClicked() {
//send back current time with message
chrome.runtime.sendMessage({
message: "addSponsorTime",
time: v.currentTime
time: v.currentTime,
videoID: getYouTubeVideoID(document.URL)
});
}
@@ -247,6 +307,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 +318,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";
@@ -296,12 +358,35 @@ function addSubmitButton() {
}
//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 +396,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));
@@ -524,6 +607,13 @@ function sponsorMessageStarted() {
}
function submitSponsorTimes() {
if(!confirm("Are you sure you want to submit this?")) return;
if (document.getElementById("submitButton").style.display == "none") {
//don't submit, not ready
return;
}
//add loading animation
document.getElementById("submitButtonImage").src = chrome.extension.getURL("icons/PlayerUploadIconSponsorBlocker256px.png");
document.getElementById("submitButton").style.animation = "rotate 1s 0s infinite";
@@ -600,5 +690,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;
}

View File

@@ -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": [
{

View File

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

View File

@@ -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;

View File

@@ -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>

168
popup.js
View File

@@ -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;
@@ -341,7 +391,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 +411,7 @@ function showNoticeAgain() {
});
});
document.getElementById("showNoticeAgain").style.display = "none";
SB.showNoticeAgain.style.display = "none";
}
function hideVideoPlayerControls() {
@@ -377,8 +427,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 +444,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 +495,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 +524,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 +568,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);
@@ -521,4 +611,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;
}
}