diff --git a/.gitignore b/.gitignore index 045c879c..a98ca8ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -content-config.js \ No newline at end of file +content-config.js +ignored \ No newline at end of file diff --git a/README.md b/README.md index c9cce414..1a90287f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +![Logo](icons/LogoSponsorBlocker256px.png) +
Logo by [@munadikieh](https://github.com/munadikieh) + # SponsorBlocker SponsorBlocker is an extension that will skip over sponsored segments of YouTube videos. SponsorBlocker is a crowdsourced browser extension that let's anyone submit the start and end time's of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment. diff --git a/background.js b/background.js index 1390b093..3997e50e 100644 --- a/background.js +++ b/background.js @@ -1,5 +1,8 @@ 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) { @@ -16,8 +19,6 @@ chrome.tabs.onUpdated.addListener( // On tab update } ); - - chrome.runtime.onMessage.addListener(function (request, sender, callback) { if (request.message == "submitTimes") { submitTimes(request.videoID); @@ -25,13 +26,59 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) { callback({ success: true }); - } else if(request.message == "ytvideoid") { + } else if (request.message == "ytvideoid") { if (previousVideoID != request.videoID) { videoIDChange(request.videoID); } + } else if (request.message == "addSponsorTime") { + addSponsorTime(request.time); + } else if (request.message == "getSponsorTimes") { + getSponsorTimes(request.videoID, function(sponsorTimes) { + callback({ + sponsorTimes: sponsorTimes + }) + }); + + //this allows the callback to be called later + return true; } }); + +//gets the sponsor times from memory +function getSponsorTimes(videoID, callback) { + let sponsorTimes = []; + let sponsorTimeKey = "sponsorTimes" + videoID; + chrome.storage.local.get([sponsorTimeKey], function(result) { + let sponsorTimesStorage = result[sponsorTimeKey]; + if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) { + sponsorTimes = sponsorTimesStorage; + } + + callback(sponsorTimes) + }); +} + +function addSponsorTime(time) { + getSponsorTimes(previousVideoID, 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); + } else { + //it is a start time + let sponsorTimesIndex = sponsorTimes.length; + sponsorTimes[sponsorTimesIndex] = []; + + sponsorTimes[sponsorTimesIndex][0] = parseInt(time); + } + + //save this info + let sponsorTimeKey = "sponsorTimes" + previousVideoID; + chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes}); + }); +} + function submitTimes(videoID) { //get the video times from storage let sponsorTimeKey = 'sponsorTimes' + videoID; @@ -42,9 +89,13 @@ function submitTimes(videoID) { //submit these times for (let i = 0; i < sponsorTimes.length; i++) { let xmlhttp = new XMLHttpRequest(); - //submit the sponsorTime - xmlhttp.open('GET', 'http://localhost/api/postVideoSponsorTimes?videoID=' + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1], true); - xmlhttp.send(); + + let userIDStorage = getUserID(function(userIDStorage) { + //submit the sponsorTime + xmlhttp.open('GET', 'http://localhost/api/postVideoSponsorTimes?videoID=' + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1] + + "&userID=" + userIDStorage, true); + xmlhttp.send(); + }); } } }); @@ -64,7 +115,7 @@ function videoIDChange(currentVideoID) { 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: "icon.png" + iconUrl: "./icons/LogoSponsorBlocker256px.png" }); } @@ -72,13 +123,38 @@ function videoIDChange(currentVideoID) { previousVideoID = currentVideoID; }); } else { - console.log(currentVideoID) previousVideoID = currentVideoID; } } +function getUserID(callback) { + if (userID != null) { + callback(userID); + } + + //if it is not cached yet, grab it from storage + chrome.storage.local.get(["userID"], function(result) { + let userIDStorage = result.userID; + if (userIDStorage != undefined) { + userID = userIDStorage; + callback(userID); + } else { + //generate a userID + userID = generateUUID(); + + //save this UUID + chrome.storage.local.set({"userID": userID}); + + callback(userID); + } + }); +} + 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; -} \ No newline at end of file +} + +//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)} \ No newline at end of file diff --git a/content.css b/content.css new file mode 100644 index 00000000..89cfcdea --- /dev/null +++ b/content.css @@ -0,0 +1,85 @@ +.sponsorSkipObject { + font-family: 'Source Sans Pro', sans-serif; +} + +#sponsorSkipLogo { + height: 64px; + position: absolute; + top: 0; + bottom: 0; + margin: auto; + margin-left: 10px; +} + +#sponsorSkipNotice { + min-height: 125px; + min-width: 400px; + background-color: rgba(255, 217, 217, 0.8); + position: absolute; + z-index: 1; + border: 3px solid rgba(0, 0, 0, 0.8); +} + +#sponsorSkipMessage { + font-size: 18px; + color: #000000; + text-align: center; + margin-top: 10px; + font-weight: bold; +} + +#sponsorSkipInfo { + font-size: 10px; + color: #000000; + text-align: center; +} + +.sponsorSkipButton { + background-color:#ec1c1c; + -moz-border-radius:28px; + -webkit-border-radius:28px; + border-radius:28px; + border:1px solid #d31919; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:14px; + padding:4px 15px; + text-decoration:none; + text-shadow:0px 0px 0px #662727; + + margin-top: 5px; + margin-right: 15px; +} +.sponsorSkipButton:hover { + background-color:#bf2a2a; +} +.sponsorSkipButton:active { + position:relative; + top:1px; +} + +.sponsorSkipDontShowButton { + -moz-box-shadow:inset 0px 1px 0px 0px #cf866c; + -webkit-box-shadow:inset 0px 1px 0px 0px #cf866c; + box-shadow:inset 0px 1px 0px 0px #cf866c; + background-color:#d0451b; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + border:1px solid #942911; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:13px; + padding:6px 24px; + text-decoration:none; + text-shadow:0px 1px 0px #854629; +} +.sponsorSkipDontShowButton:hover { + background-color:#bc3315; +} +.sponsorSkipDontShowButton:active { + position:relative; + top:1px; +} \ No newline at end of file diff --git a/content.js b/content.js index 0a37e502..a15885ae 100644 --- a/content.js +++ b/content.js @@ -1,7 +1,5 @@ if(id = getYouTubeVideoID(document.URL)){ // Direct Links - //reset sponsor data found check - sponsorDataFound = false; - sponsorsLookup(id); + videoIDChange(id); //tell background.js about this chrome.runtime.sendMessage({ @@ -26,6 +24,12 @@ var lastTime; //used for the go back button var lastSponsorTimeSkipped = null; +//if showing the start sponsor button or the end sponsor button on the player +var showingStartSponsor = true; + +//should the video controls buttons be added +var hideVideoPlayerControls = false; + //if the notice should not be shown //happens when the user click's the "Don't show notice again" button var dontShowNotice = false; @@ -40,9 +44,7 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes function(request, sender, sendResponse) { //message from background script if (request.message == "ytvideoid") { - //reset sponsor data found check - sponsorDataFound = false; - sponsorsLookup(request.id); + videoIDChange(request.id); } //messages from popup script @@ -67,8 +69,46 @@ chrome.runtime.onMessage.addListener( // Detect URL Changes if (request.message == "showNoticeAgain") { dontShowNotice = false; } + + if (request.message == "toggleStartSponsorButton") { + toggleStartSponsorButton(); + } + + if (request.message == "changeVideoPlayerControlsVisibility") { + hideVideoPlayerControls = request.value; + + updateVisibilityOfPlayerControlsButton(); + } }); +function videoIDChange(id) { + //reset sponsor data found check + sponsorDataFound = false; + sponsorsLookup(id); + + //see if the onvideo control image needs to be changed + chrome.runtime.sendMessage({ + message: "getSponsorTimes", + videoID: id + }, function(response) { + if (response != undefined) { + let sponsorTimes = response.sponsorTimes; + if (sponsorTimes != undefined && sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) { + toggleStartSponsorButton(); + } + } + }); + + //see if video control buttons should be added + chrome.storage.local.get(["hideVideoPlayerControls"], function(result) { + if (result.hideVideoPlayerControls != undefined) { + hideVideoPlayerControls = result.hideVideoPlayerControls; + } + + updateVisibilityOfPlayerControlsButton(); + }); +} + function sponsorsLookup(id) { v = document.querySelector('video') // Youtube video player let xmlhttp = new XMLHttpRequest(); @@ -108,7 +148,7 @@ function sponsorCheck(sponsorTimes) { // Video skipping //send out the message saying that a sponsor message was skipped openSkipNotice(); - setTimeout(closeSkipNotice, 2500); + setTimeout(closeSkipNotice, 7000); } lastTime = v.currentTime; @@ -124,6 +164,64 @@ function goBackToPreviousTime() { } } +//Adds a sponsorship starts button to the player controls +function addPlayerControlsButton() { + let startSponsorButton = document.createElement("button"); + startSponsorButton.id = "startSponsorButton"; + startSponsorButton.className = "ytp-button"; + startSponsorButton.setAttribute("title", "Sponsor Starts Now"); + startSponsorButton.addEventListener("click", startSponsorClicked); + + let startSponsorImage = document.createElement("img"); + startSponsorImage.id = "startSponsorImage"; + startSponsorImage.style.height = "60%"; + startSponsorImage.style.top = "0"; + startSponsorImage.style.bottom = "0"; + startSponsorImage.style.display = "block"; + startSponsorImage.style.margin = "auto"; + startSponsorImage.src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png"); + + //add the image to the button + startSponsorButton.appendChild(startSponsorImage); + + let referenceNode = document.getElementsByClassName("ytp-right-controls")[0]; + + referenceNode.prepend(startSponsorButton); +} + +function removePlayerControlsButton() { + document.getElementById("startSponsorButton").style.display = "none"; +} + +//adds or removes the player controls button to what it should be +function updateVisibilityOfPlayerControlsButton() { + if (hideVideoPlayerControls) { + removePlayerControlsButton(); + } else { + addPlayerControlsButton(); + } +} + +function startSponsorClicked() { + toggleStartSponsorButton(); + + //send back current time with message + chrome.runtime.sendMessage({ + message: "addSponsorTime", + time: v.currentTime + }); +} + +function toggleStartSponsorButton() { + if (showingStartSponsor) { + showingStartSponsor = false; + document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStopIconSponsorBlocker256px.png"); + } else { + showingStartSponsor = true; + document.getElementById("startSponsorImage").src = chrome.extension.getURL("icons/PlayerStartIconSponsorBlocker256px.png"); + } +} + //Opens the notice that tells the user that a sponsor was just skipped function openSkipNotice(){ if (dontShowNotice) { @@ -131,56 +229,57 @@ function openSkipNotice(){ return; } - var noticeElement = document.createElement("div"); + let noticeElement = document.createElement("div"); + noticeElement.id = "sponsorSkipNotice"; + noticeElement.className = "sponsorSkipObject"; + + let logoElement = document.createElement("img"); + logoElement.id = "sponsorSkipLogo"; + logoElement.src = chrome.extension.getURL("icons/LogoSponsorBlocker256px.png"); + + let noticeMessage = document.createElement("div"); + noticeMessage.id = "sponsorSkipMessage"; + noticeMessage.className = "sponsorSkipObject"; + noticeMessage.innerText = "Hey, you just skipped a sponsor!"; - noticeElement.id = 'sponsorSkipNotice' - noticeElement.style.minHeight = "100px"; - noticeElement.style.minWidth = "400px"; - noticeElement.style.backgroundColor = "rgba(153, 153, 153, 0.8)"; - noticeElement.style.fontSize = "24px"; - noticeElement.style.position = "absolute" - noticeElement.style.zIndex = "1"; + let noticeInfo = document.createElement("p"); + noticeInfo.id = "sponsorSkipInfo"; + noticeInfo.className = "sponsorSkipObject"; + noticeInfo.innerText = "This message will disapear in 7 seconds"; - var noticeMessage = document.createElement("p"); - noticeMessage.innerText = "Hey, you just skipped a sponsor!"; - noticeMessage.style.fontSize = "18px"; - noticeMessage.style.color = "#000000"; - noticeMessage.style.textAlign = "center"; - noticeMessage.style.marginTop = "10px"; - - var buttonContainer = document.createElement("div"); + let buttonContainer = document.createElement("div"); buttonContainer.setAttribute("align", "center"); - var goBackButton = document.createElement("button"); - goBackButton.innerText = "Go back"; - goBackButton.style.fontSize = "13px"; - goBackButton.style.color = "#000000"; - goBackButton.style.marginTop = "5px"; + let goBackButton = document.createElement("button"); + goBackButton.innerText = "Go back"; + goBackButton.className = "sponsorSkipObject"; + goBackButton.className = "sponsorSkipButton"; goBackButton.addEventListener("click", goBackToPreviousTime); - var hideButton = document.createElement("button"); - hideButton.innerText = "Hide"; - hideButton.style.fontSize = "13px"; - hideButton.style.color = "#000000"; - hideButton.style.marginTop = "5px"; + let hideButton = document.createElement("button"); + hideButton.innerText = "Dismiss"; + hideButton.className = "sponsorSkipObject"; + hideButton.className = "sponsorSkipButton"; hideButton.addEventListener("click", closeSkipNotice); - var dontShowAgainButton = document.createElement("button"); - dontShowAgainButton.innerText = "Don't Show This Again"; - dontShowAgainButton.style.fontSize = "13px"; - dontShowAgainButton.style.color = "#000000"; - dontShowAgainButton.style.marginTop = "5px"; + let dontShowAgainButton = document.createElement("button"); + dontShowAgainButton.innerText = "Don't Show This Again"; + dontShowAgainButton.className = "sponsorSkipObject"; + dontShowAgainButton.className = "sponsorSkipDontShowButton"; dontShowAgainButton.addEventListener("click", dontShowNoticeAgain); buttonContainer.appendChild(goBackButton); buttonContainer.appendChild(hideButton); buttonContainer.appendChild(document.createElement("br")); + buttonContainer.appendChild(document.createElement("br")); buttonContainer.appendChild(dontShowAgainButton); + noticeElement.appendChild(logoElement); noticeElement.appendChild(noticeMessage); + noticeElement.appendChild(noticeInfo); noticeElement.appendChild(buttonContainer); - var referenceNode = document.getElementById("info"); + let referenceNode = document.getElementById("info"); if (referenceNode == null) { //old YouTube referenceNode = document.getElementById("watch-header"); @@ -207,13 +306,14 @@ function dontShowNoticeAgain() { function sponsorMessageStarted() { let v = document.querySelector('video'); - console.log(v.currentTime) - //send back current time chrome.runtime.sendMessage({ message: "time", time: v.currentTime }); + + //update button + toggleStartSponsorButton(); } function getYouTubeVideoID(url) { // Returns with video id else returns false diff --git a/icons/IconSponsorBlocker16px.png b/icons/IconSponsorBlocker16px.png new file mode 100644 index 00000000..5217e70b Binary files /dev/null and b/icons/IconSponsorBlocker16px.png differ diff --git a/icons/IconSponsorBlocker256px.png b/icons/IconSponsorBlocker256px.png new file mode 100644 index 00000000..9870f586 Binary files /dev/null and b/icons/IconSponsorBlocker256px.png differ diff --git a/icons/IconSponsorBlocker32px.png b/icons/IconSponsorBlocker32px.png new file mode 100644 index 00000000..c796bb07 Binary files /dev/null and b/icons/IconSponsorBlocker32px.png differ diff --git a/icons/LogoSponsorBlocker128px.png b/icons/LogoSponsorBlocker128px.png new file mode 100644 index 00000000..dbf305de Binary files /dev/null and b/icons/LogoSponsorBlocker128px.png differ diff --git a/icons/LogoSponsorBlocker256px.png b/icons/LogoSponsorBlocker256px.png new file mode 100644 index 00000000..db351b15 Binary files /dev/null and b/icons/LogoSponsorBlocker256px.png differ diff --git a/icons/LogoSponsorBlocker64px.png b/icons/LogoSponsorBlocker64px.png new file mode 100644 index 00000000..933f635c Binary files /dev/null and b/icons/LogoSponsorBlocker64px.png differ diff --git a/icons/PlayerStartIconSponsorBlocker256px.png b/icons/PlayerStartIconSponsorBlocker256px.png new file mode 100644 index 00000000..3adff0a4 Binary files /dev/null and b/icons/PlayerStartIconSponsorBlocker256px.png differ diff --git a/icons/PlayerStopIconSponsorBlocker256px.png b/icons/PlayerStopIconSponsorBlocker256px.png new file mode 100644 index 00000000..80ef4a6e Binary files /dev/null and b/icons/PlayerStopIconSponsorBlocker256px.png differ diff --git a/libs/Source+Sans+Pro.css b/libs/Source+Sans+Pro.css new file mode 100644 index 00000000..3a00466c --- /dev/null +++ b/libs/Source+Sans+Pro.css @@ -0,0 +1,56 @@ +/* cyrillic-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNa7lqDY.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qPK7lqDY.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNK7lqDY.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qO67lqDY.woff2) format('woff2'); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qN67lqDY.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qNq7lqDY.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro Regular'), local('SourceSansPro-Regular'), url(https://fonts.gstatic.com/s/sourcesanspro/v12/6xK3dSBYKcSV-LCoeQqfX1RYOo3qOK7l.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/manifest.json b/manifest.json index 73259e2f..9c7a7dd6 100644 --- a/manifest.json +++ b/manifest.json @@ -10,9 +10,19 @@ "js": [ "content-config.js", "content.js" + ], + "css": [ + "content.css", + "./libs/Source+Sans+Pro.css" ] } ], + "web_accessible_resources": [ + "icons/LogoSponsorBlocker256px.png", + "icons/IconSponsorBlocker256px.png", + "icons/PlayerStartIconSponsorBlocker256px.png", + "icons/PlayerStopIconSponsorBlocker256px.png" + ], "permissions": [ "tabs", "storage", @@ -25,5 +35,12 @@ "background": { "scripts":["background.js"] }, + "icons": { + "16": "icons/IconSponsorBlocker16px.png", + "32": "icons/IconSponsorBlocker32px.png", + "64": "icons/LogoSponsorBlocker64px.png", + "128": "icons/LogoSponsorBlocker128px.png", + "256": "icons/LogoSponsorBlocker256px.png" + }, "manifest_version": 2 } diff --git a/popup.css b/popup.css index 2c0193cd..9c59f74f 100644 --- a/popup.css +++ b/popup.css @@ -1,7 +1,106 @@ * { - font-family: 'Arial'; + font-family: 'Source Sans Pro', sans-serif; +} + +h1 { + margin-top: 0px; } body { + font-size: 14px; width: 300px; -} \ No newline at end of file + background-color: #ffd9d9; +} + +.greenButton { + background-color:#ec1c1c; + -moz-border-radius:28px; + -webkit-border-radius:28px; + border-radius:28px; + border:1px solid #d31919; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:16px; + padding:8px 37px; + text-decoration:none; + text-shadow:0px 0px 0px #662727; +} +.greenButton:hover { + background-color:#bf2a2a; +} +.greenButton:active { + position:relative; + top:1px; +} + +.dangerButton { + -moz-box-shadow:inset 0px 1px 0px 0px #cf866c; + -webkit-box-shadow:inset 0px 1px 0px 0px #cf866c; + box-shadow:inset 0px 1px 0px 0px #cf866c; + background-color:#d0451b; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + border:1px solid #942911; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:13px; + padding:6px 24px; + text-decoration:none; + text-shadow:0px 1px 0px #854629; +} +.dangerButton:hover { + background-color:#bc3315; +} +.dangerButton:active { + position:relative; + top:1px; +} + +.warningButton { + -moz-box-shadow:inset 0px 1px 0px 0px #cfbd6c; + -webkit-box-shadow:inset 0px 1px 0px 0px #cfbd6c; + box-shadow:inset 0px 1px 0px 0px #cfbd6c; + background-color:#d0821b; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + border:1px solid #948b11; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:13px; + padding:6px 24px; + text-decoration:none; + text-shadow:0px 1px 0px #856829; +} +.warningButton:hover { + background-color:#bc8215; +} +.warningButton:active { + position:relative; + top:1px; +} + +.smallButton { + background-color:#f9902d; + -moz-border-radius:3px; + -webkit-border-radius:3px; + border-radius:3px; + border:1px solid #f9a72d; + display:inline-block; + cursor:pointer; + color:#ffffff; + font-size:14px; + padding:6px 10px; + text-decoration:none; +} +.smallButton:hover { + background-color:#fa9806; +} +.smallButton:active { + position:relative; + top:1px; +} diff --git a/popup.html b/popup.html index bcbc111a..79b7adde 100644 --- a/popup.html +++ b/popup.html @@ -1,11 +1,14 @@ Set Page Color Popup +
+ +

SponsorBlock

@@ -13,46 +16,62 @@
diff --git a/popup.js b/popup.js index 3b6d337c..d5b984f0 100644 --- a/popup.js +++ b/popup.js @@ -3,6 +3,9 @@ document.getElementById("sponsorStart").addEventListener("click", sendSponsorSta 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); //if true, the button now selects the end time var startTimeChosen = false; @@ -25,13 +28,14 @@ chrome.storage.local.get(["dontShowNoticeAgain"], function(result) { } }); -//if no response comes by this point, give up -setTimeout(function() { - if (!isYouTubeTab) { - document.getElementById("loadingIndicator").innerHTML = "This probably isn't a YouTube tab, or you clicked too early. " + - "If you know this is a YouTube tab, close this popup and open it again."; +//show proper video player controls option +chrome.storage.local.get(["hideVideoPlayerControls"], function(result) { + let hideVideoPlayerControls = result.hideVideoPlayerControls; + if (hideVideoPlayerControls != undefined && hideVideoPlayerControls) { + document.getElementById("hideVideoPlayerControls").style.display = "none"; + document.getElementById("showVideoPlayerControls").style.display = "unset"; } -}, 100); +}); chrome.tabs.query({ active: true, @@ -42,6 +46,12 @@ function loadTabData(tabs) { //set current videoID currentVideoID = getYouTubeVideoID(tabs[0].url); + if (!currentVideoID) { + //this isn't a YouTube video then + displayNoVideo(); + return; + } + //load video times for this video let sponsorTimeKey = "sponsorTimes" + currentVideoID; chrome.storage.local.get([sponsorTimeKey], function(result) { @@ -58,11 +68,11 @@ function loadTabData(tabs) { //show submission section document.getElementById("submissionSection").style.display = "unset"; + + showSubmitTimesIfNecessary(); } }); - - //check if this video's sponsors are known chrome.tabs.sendMessage( tabs[0].id, @@ -72,6 +82,12 @@ function loadTabData(tabs) { } function infoFound(request) { + if(chrome.runtime.lastError) { + //This page doesn't have the injected content script, or at least not yet + displayNoVideo(); + return; + } + //if request is undefined, then the page currently being browsed is not YouTube if (request != undefined) { //this must be a YouTube video @@ -125,20 +141,15 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) { let sponsorTimeKey = "sponsorTimes" + currentVideoID; chrome.storage.local.set({[sponsorTimeKey]: sponsorTimes}); - //update startTimeChosen variable - if (!startTimeChosen) { - startTimeChosen = true; - document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now"; - } else { - startTimeChosen = false; - document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now"; - } + updateStartTimeChosen(); //display video times on screen displaySponsorTimes(); //show submission section document.getElementById("submissionSection").style.display = "unset"; + + showSubmitTimesIfNecessary(); } }); @@ -179,6 +190,19 @@ function getSponsorTimesMessage(sponsorTimes) { } function clearTimes() { + //check if the player controls should be toggled + if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) { + chrome.tabs.query({ + active: true, + currentWindow: true + }, function(tabs) { + chrome.tabs.sendMessage(tabs[0].id, { + message: "toggleStartSponsorButton" + }); + }); + } + + //reset sponsorTimes sponsorTimes = []; let sponsorTimeKey = "sponsorTimes" + currentVideoID; @@ -188,6 +212,8 @@ function clearTimes() { //hide submission section document.getElementById("submissionSection").style.display = "none"; + + resetStartTimeChosen(); } function submitTimes() { @@ -216,10 +242,87 @@ function showNoticeAgain() { document.getElementById("showNoticeAgain").style.display = "none"; } +function hideVideoPlayerControls() { + chrome.storage.local.set({"hideVideoPlayerControls": true}); + + chrome.tabs.query({ + active: true, + currentWindow: true + }, function(tabs) { + chrome.tabs.sendMessage(tabs[0].id, { + message: "changeVideoPlayerControlsVisibility", + value: true + }); + }); + + document.getElementById("hideVideoPlayerControls").style.display = "none"; + document.getElementById("showVideoPlayerControls").style.display = "unset"; +} + +function showVideoPlayerControls() { + chrome.storage.local.set({"hideVideoPlayerControls": false}); + + chrome.tabs.query({ + active: true, + currentWindow: true + }, function(tabs) { + chrome.tabs.sendMessage(tabs[0].id, { + message: "changeVideoPlayerControlsVisibility", + value: false + }); + }); + + document.getElementById("hideVideoPlayerControls").style.display = "unset"; + document.getElementById("showVideoPlayerControls").style.display = "none"; +} + +function updateStartTimeChosen() { + //update startTimeChosen variable + if (!startTimeChosen) { + startTimeChosen = true; + document.getElementById("sponsorStart").innerHTML = "Sponsorship Ends Now"; + } else { + resetStartTimeChosen(); + } +} + +//set it to false +function resetStartTimeChosen() { + startTimeChosen = false; + document.getElementById("sponsorStart").innerHTML = "Sponsorship Starts Now"; +} + +function showSubmitTimesIfNecessary() { + //check if an end time has been specified for the latest sponsor time + if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length > 1) { + //show submit times button + document.getElementById("submitTimes").style.display = "unset"; + } else { + document.getElementById("submitTimes").style.display = "none"; + } +} + +//make the options div visisble +function openOptions() { + document.getElementById("optionsButtonContainer").style.display = "none"; + document.getElementById("options").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. " + + "If you know this is a YouTube tab, close this popup and open it again."; +} + //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;