mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2026-01-02 06:39:20 +03:00
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -68,11 +68,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
args: builds/ChromeExtension.zip
|
args: builds/ChromeExtension.zip
|
||||||
name: ChromeExtension.zip
|
name: ChromeExtension.zip
|
||||||
|
path: ./builds/ChromeExtension.zip
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Upload to release
|
- name: Upload to release
|
||||||
uses: Shopify/upload-to-release@master
|
uses: Shopify/upload-to-release@master
|
||||||
with:
|
with:
|
||||||
args: builds/FirefoxExtension.zip
|
args: builds/FirefoxExtension.zip
|
||||||
name: FirefoxExtension.zip
|
name: FirefoxExtension.zip
|
||||||
|
path: ./builds/FirefoxExtension.zip
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "__MSG_fullName__",
|
"name": "__MSG_fullName__",
|
||||||
"short_name": "__MSG_Name__",
|
"short_name": "__MSG_Name__",
|
||||||
"version": "1.2.26",
|
"version": "1.2.27",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"description": "__MSG_Description__",
|
"description": "__MSG_Description__",
|
||||||
"content_scripts": [{
|
"content_scripts": [{
|
||||||
|
|||||||
@@ -189,7 +189,7 @@
|
|||||||
"message": "Hide Buttons On YouTube Player"
|
"message": "Hide Buttons On YouTube Player"
|
||||||
},
|
},
|
||||||
"hideButtonsDescription": {
|
"hideButtonsDescription": {
|
||||||
"message": "This hides the buttons that appear on the YouTube player to submit sponsors. I can see this being annoying for some\n people. Instead of using the button there, this popup can be used to submit sponsors. To hide the notice that appears, \n use the button that appears on the notice saying \"Don't show this again\". You can always enable these settings again later."
|
"message": "This hides the buttons that appear on the YouTube player to submit skip segments."
|
||||||
},
|
},
|
||||||
"showInfoButton": {
|
"showInfoButton": {
|
||||||
"message": "Show Info Button On YouTube Player"
|
"message": "Show Info Button On YouTube Player"
|
||||||
@@ -207,7 +207,7 @@
|
|||||||
"message": "Show Delete Button On YouTube Player"
|
"message": "Show Delete Button On YouTube Player"
|
||||||
},
|
},
|
||||||
"whatDeleteButton": {
|
"whatDeleteButton": {
|
||||||
"message": "This is the button that allows you to clear all sponsors on the YouTube player."
|
"message": "This is the button on the YouTube player that will clear all your un-submitted segments for the current video."
|
||||||
},
|
},
|
||||||
"disableViewTracking": {
|
"disableViewTracking": {
|
||||||
"message": "Disable Sponsor Skip Count Tracking"
|
"message": "Disable Sponsor Skip Count Tracking"
|
||||||
@@ -420,10 +420,10 @@
|
|||||||
"message": "The video has been detected as unlisted. Click cancel if you do not want to check for sponsors."
|
"message": "The video has been detected as unlisted. Click cancel if you do not want to check for sponsors."
|
||||||
},
|
},
|
||||||
"unlistedCheck": {
|
"unlistedCheck": {
|
||||||
"message": "Ignore Unlisted Videos"
|
"message": "Ignore Unlisted/Private Videos"
|
||||||
},
|
},
|
||||||
"whatUnlistedCheck": {
|
"whatUnlistedCheck": {
|
||||||
"message": "This setting will significantly slow down SponsorBlock. Sponsor lookups require sending the video ID to the server. If you are concerned about unlisted video IDs being sent over the internet, enable this option."
|
"message": "This setting will slightly slow down SponsorBlock. Sponsor lookups require sending the video ID to the server. If you are concerned about unlisted video IDs being sent over the internet, enable this option."
|
||||||
},
|
},
|
||||||
"mobileUpdateInfo": {
|
"mobileUpdateInfo": {
|
||||||
"message": "m.youtube.com is now supported"
|
"message": "m.youtube.com is now supported"
|
||||||
@@ -527,5 +527,32 @@
|
|||||||
},
|
},
|
||||||
"moreCategories": {
|
"moreCategories": {
|
||||||
"message": "More Categories"
|
"message": "More Categories"
|
||||||
|
},
|
||||||
|
"bracketEnd": {
|
||||||
|
"message": "(End)"
|
||||||
|
},
|
||||||
|
"hiddenDueToDownvote": {
|
||||||
|
"message": "hidden: downvote"
|
||||||
|
},
|
||||||
|
"hiddenDueToDuration": {
|
||||||
|
"message": "hidden: too short"
|
||||||
|
},
|
||||||
|
"channelDataNotFound": {
|
||||||
|
"message": "Channel ID not loaded yet."
|
||||||
|
},
|
||||||
|
"adblockerIssue": {
|
||||||
|
"message": "It seems that something is blocking SponsorBlock's ability to get video data. This is probably your ad blocker. Please check https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests"
|
||||||
|
},
|
||||||
|
"itCouldBeAdblockerIssue": {
|
||||||
|
"message": "If this keeps occuring, it could be caused by your ad blocker. Please check https://github.com/ajayyy/SponsorBlock/wiki/Fix-Ad-Blocker-Blocking-SponsorBlock's-Requests"
|
||||||
|
},
|
||||||
|
"forceChannelCheck": {
|
||||||
|
"message": "Force Channel Check Before Skipping Sponsors"
|
||||||
|
},
|
||||||
|
"whatForceChannelCheck": {
|
||||||
|
"message": "By default, it will skip sponsors right away before it even knows what the channel is. By default, some zero second sponsors might be skipped on whitelisted channels. Enabling this option will prevent this but making all skipping have a slight delay as getting the channelID can take some time. This delay might be unnoticeable if you have fast internet."
|
||||||
|
},
|
||||||
|
"forceChannelCheckPopup": {
|
||||||
|
"message": "Consider Enabling Force Channel Check Before Skipping Sponsors"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,6 +83,8 @@
|
|||||||
border-spacing: 5px 10px;
|
border-spacing: 5px 10px;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
|
|
||||||
|
border-collapse: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sponsorSkipNoticeFadeIn {
|
.sponsorSkipNoticeFadeIn {
|
||||||
|
|||||||
@@ -39,10 +39,8 @@ sub.popupElement {
|
|||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
.popupElement {
|
.logoText {
|
||||||
font-family: 'Source Sans Pro', sans-serif;
|
color: white;
|
||||||
|
|
||||||
color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1.popupElement {
|
h1.popupElement {
|
||||||
@@ -52,12 +50,21 @@ h1.popupElement {
|
|||||||
|
|
||||||
.popupBody {
|
.popupBody {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background-color: #ffd9d9;
|
background-color: #333;
|
||||||
padding: 0px 5px;
|
padding: 0px 5px;
|
||||||
|
|
||||||
|
font-family: 'Source Sans Pro', sans-serif;
|
||||||
|
|
||||||
|
color: #dddddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.outerPopupBody {
|
||||||
|
background-color: #222626;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discreteLink.popupElement {
|
.discreteLink.popupElement {
|
||||||
color: black;
|
color: #dddddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recordingSubtitle.popupElement {
|
.recordingSubtitle.popupElement {
|
||||||
@@ -102,7 +109,7 @@ h1.popupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.whitelistButton.popupElement {
|
.whitelistButton.popupElement {
|
||||||
background-color:#3acc3a;
|
background-color:#27a52d;
|
||||||
-moz-border-radius:28px;
|
-moz-border-radius:28px;
|
||||||
-webkit-border-radius:28px;
|
-webkit-border-radius:28px;
|
||||||
border-radius:28px;
|
border-radius:28px;
|
||||||
@@ -114,13 +121,15 @@ h1.popupElement {
|
|||||||
padding:8px 37px;
|
padding:8px 37px;
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
text-shadow:0px 0px 0px #27663c;
|
text-shadow:0px 0px 0px #27663c;
|
||||||
}
|
|
||||||
|
transition: 0.01s background-color;
|
||||||
|
}
|
||||||
.whitelistButton:hover.popupElement {
|
.whitelistButton:hover.popupElement {
|
||||||
background-color:#218b26;
|
background-color:#3acc3a;
|
||||||
}
|
}
|
||||||
.whitelistButton:focus.popupElement {
|
.whitelistButton:focus.popupElement {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color:#218b26;
|
background-color:#3acc3a;
|
||||||
}
|
}
|
||||||
.whitelistButton:active.popupElement {
|
.whitelistButton:active.popupElement {
|
||||||
position:relative;
|
position:relative;
|
||||||
@@ -128,25 +137,27 @@ h1.popupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.greenButton.popupElement {
|
.greenButton.popupElement {
|
||||||
background-color:#ec1c1c;
|
background-color:#cc1717;
|
||||||
-moz-border-radius:28px;
|
-moz-border-radius:28px;
|
||||||
-webkit-border-radius:28px;
|
-webkit-border-radius:28px;
|
||||||
border-radius:28px;
|
border-radius:28px;
|
||||||
border:1px solid #d31919;
|
border: none;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
color:#ffffff;
|
color:#ffffff;
|
||||||
font-size:16px;
|
font-size:16px;
|
||||||
padding:8px 37px;
|
padding:8px 37px;
|
||||||
text-decoration:none;
|
text-decoration:none;
|
||||||
text-shadow:0px 0px 0px #662727;
|
text-shadow:0px 0px 0px #662727;
|
||||||
|
|
||||||
|
transition: 0.01s background-color;
|
||||||
}
|
}
|
||||||
.greenButton:hover.popupElement {
|
.greenButton:hover.popupElement {
|
||||||
background-color:#bf2a2a;
|
background-color:#ec1c1c;
|
||||||
}
|
}
|
||||||
.greenButton:focus.popupElement {
|
.greenButton:focus.popupElement {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color:#bf2a2a;
|
background-color:#ec1c1c;
|
||||||
}
|
}
|
||||||
.greenButton:active.popupElement {
|
.greenButton:active.popupElement {
|
||||||
position:relative;
|
position:relative;
|
||||||
@@ -154,14 +165,11 @@ h1.popupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dangerButton.popupElement {
|
.dangerButton.popupElement {
|
||||||
-moz-box-shadow:inset 0px 1px 0px 0px #cf866c;
|
background-color:#bc3315;
|
||||||
-webkit-box-shadow:inset 0px 1px 0px 0px #cf866c;
|
|
||||||
box-shadow:inset 0px 1px 0px 0px #cf866c;
|
|
||||||
background-color:#d0451b;
|
|
||||||
-moz-border-radius:3px;
|
-moz-border-radius:3px;
|
||||||
-webkit-border-radius:3px;
|
-webkit-border-radius:3px;
|
||||||
border-radius:3px;
|
border-radius:3px;
|
||||||
border:1px solid #942911;
|
border: none;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
color:#ffffff;
|
color:#ffffff;
|
||||||
@@ -171,11 +179,11 @@ h1.popupElement {
|
|||||||
text-shadow:0px 1px 0px #854629;
|
text-shadow:0px 1px 0px #854629;
|
||||||
}
|
}
|
||||||
.dangerButton:hover.popupElement {
|
.dangerButton:hover.popupElement {
|
||||||
background-color:#bc3315;
|
background-color:#d0451b;
|
||||||
}
|
}
|
||||||
.dangerButton:focus.popupElement {
|
.dangerButton:focus.popupElement {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color:#bc3315;
|
background-color:#d0451b;
|
||||||
}
|
}
|
||||||
.dangerButton:active.popupElement {
|
.dangerButton:active.popupElement {
|
||||||
position:relative;
|
position:relative;
|
||||||
@@ -183,14 +191,11 @@ h1.popupElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.warningButton.popupElement {
|
.warningButton.popupElement {
|
||||||
-moz-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
|
background-color:#bc8215;
|
||||||
-webkit-box-shadow:inset 0px 1px 0px 0px #cfbd6c;
|
|
||||||
box-shadow:inset 0px 1px 0px 0px #cfbd6c;
|
|
||||||
background-color:#d0821b;
|
|
||||||
-moz-border-radius:3px;
|
-moz-border-radius:3px;
|
||||||
-webkit-border-radius:3px;
|
-webkit-border-radius:3px;
|
||||||
border-radius:3px;
|
border-radius:3px;
|
||||||
border:1px solid #948b11;
|
border: none;
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
color:#ffffff;
|
color:#ffffff;
|
||||||
@@ -200,11 +205,11 @@ h1.popupElement {
|
|||||||
text-shadow:0px 1px 0px #856829;
|
text-shadow:0px 1px 0px #856829;
|
||||||
}
|
}
|
||||||
.warningButton:hover.popupElement {
|
.warningButton:hover.popupElement {
|
||||||
background-color:#bc8215;
|
background-color:#d0821b;
|
||||||
}
|
}
|
||||||
.warningButton:focus.popupElement {
|
.warningButton:focus.popupElement {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color:#bc8215;
|
background-color:#d0821b;
|
||||||
}
|
}
|
||||||
.warningButton:active.popupElement {
|
.warningButton:active.popupElement {
|
||||||
position:relative;
|
position:relative;
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
<link id="sponsorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
|
<link id="sponsorBlockStyleSheet" rel="stylesheet" type="text/css" href="popup.css"/>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="popupBody">
|
<body class="outerPopupBody">
|
||||||
<center>
|
<center>
|
||||||
<div id="app" class="popupBody sponsorBlockPageBody">
|
<div id="app" class="popupBody sponsorBlockPageBody">
|
||||||
<h1 class="popupElement">
|
<h1 class="popupElement logoText">
|
||||||
<img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/>
|
<img src="icons/IconSponsorBlocker256px.png" height="32px" id="sponsorBlockPopupLogo"/>
|
||||||
__MSG_Name__
|
__MSG_Name__
|
||||||
</h1>
|
</h1>
|
||||||
@@ -71,6 +71,10 @@
|
|||||||
|
|
||||||
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
|
<button id="whitelistChannel" class="whitelistButton popupElement">__MSG_whitelistChannel__</button>
|
||||||
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
|
<button id="unwhitelistChannel" class="whitelistButton popupElement" style="display: none">__MSG_removeFromWhitelist__</button>
|
||||||
|
|
||||||
|
<div id="whitelistForceCheck" style="text-decoration: underline; cursor: pointer;display: none">
|
||||||
|
__MSG_forceChannelCheckPopup__
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|||||||
@@ -31,11 +31,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
|
|||||||
case "openConfig":
|
case "openConfig":
|
||||||
chrome.runtime.openOptionsPage();
|
chrome.runtime.openOptionsPage();
|
||||||
return
|
return
|
||||||
case "submitTimes":
|
|
||||||
submitTimes(request.videoID, callback);
|
|
||||||
|
|
||||||
//this allows the callback to be called later by the submitTimes function
|
|
||||||
return true;
|
|
||||||
case "addSponsorTime":
|
case "addSponsorTime":
|
||||||
addSponsorTime(request.time, request.videoID, callback);
|
addSponsorTime(request.time, request.videoID, callback);
|
||||||
|
|
||||||
@@ -182,61 +177,4 @@ function submitVote(type, UUID, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
async function submitTimes(videoID: string, callback) {
|
|
||||||
//get the video times from storage
|
|
||||||
let sponsorTimes = Config.config.sponsorTimes.get(videoID);
|
|
||||||
let userID = Config.config.userID;
|
|
||||||
|
|
||||||
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
|
|
||||||
let durationResult = <Types.VideoDurationResponse> await new Promise((resolve, reject) => {
|
|
||||||
chrome.tabs.query({
|
|
||||||
active: true,
|
|
||||||
currentWindow: true
|
|
||||||
}, function(tabs) {
|
|
||||||
chrome.tabs.sendMessage(tabs[0].id, {
|
|
||||||
message: "getVideoDuration"
|
|
||||||
}, (response) => resolve(response));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
//check if a sponsor exceeds the duration of the video
|
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
|
||||||
if (sponsorTimes[i][1] > durationResult.duration) {
|
|
||||||
sponsorTimes[i][1] = durationResult.duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//submit these times
|
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
|
||||||
//to prevent it from happeneing twice
|
|
||||||
let increasedContributionAmount = false;
|
|
||||||
|
|
||||||
//submit the sponsorTime
|
|
||||||
utils.sendRequestToServer("GET", "/api/postVideoSponsorTimes?videoID=" + videoID + "&startTime=" + sponsorTimes[i][0] + "&endTime=" + sponsorTimes[i][1]
|
|
||||||
+ "&userID=" + userID, function(xmlhttp, error) {
|
|
||||||
if (xmlhttp.readyState == 4 && !error) {
|
|
||||||
callback({
|
|
||||||
statusCode: xmlhttp.status,
|
|
||||||
responseText: xmlhttp.responseText
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (xmlhttp.status == 200) {
|
|
||||||
//save the amount contributed
|
|
||||||
if (!increasedContributionAmount) {
|
|
||||||
increasedContributionAmount = true;
|
|
||||||
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimes.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (error) {
|
|
||||||
callback({
|
|
||||||
statusCode: -1
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import Config from "../config"
|
import Config from "../config"
|
||||||
import { ContentContainer } from "../types";
|
import { ContentContainer, SponsorHideType } from "../types";
|
||||||
|
|
||||||
import Utils from "../utils";
|
import Utils from "../utils";
|
||||||
var utils = new Utils();
|
var utils = new Utils();
|
||||||
@@ -269,7 +269,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
|||||||
//this one is the one to hide
|
//this one is the one to hide
|
||||||
|
|
||||||
//add this as a hidden sponsorTime
|
//add this as a hidden sponsorTime
|
||||||
this.contentContainer().hiddenSponsorTimes.push(i);
|
this.contentContainer().sponsorTimes[i].hidden = SponsorHideType.Downvoted;
|
||||||
|
|
||||||
this.contentContainer().updatePreviewBar();
|
this.contentContainer().updatePreviewBar();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('keydown', function (event) {
|
document.getElementById("sponsorTimesContainer" + this.idSuffix).addEventListener('keydown', function (event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add as a config listener
|
||||||
|
Config.configListeners.push(this.configUpdate.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -130,6 +133,12 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
onClick={() => this.setTimeToNow(1)}>
|
onClick={() => this.setTimeToNow(1)}>
|
||||||
{chrome.i18n.getMessage("bracketNow")}
|
{chrome.i18n.getMessage("bracketNow")}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span id={"endButton" + this.idSuffix}
|
||||||
|
className="sponsorNowButton"
|
||||||
|
onClick={() => this.setTimeToEnd()}>
|
||||||
|
{chrome.i18n.getMessage("bracketEnd")}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -227,10 +236,18 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTimeToNow(index: number) {
|
setTimeToNow(index: number) {
|
||||||
|
this.setTimeTo(index, this.props.contentContainer().v.currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeToEnd() {
|
||||||
|
this.setTimeTo(1, this.props.contentContainer().v.duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeTo(index: number, time: number) {
|
||||||
let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
|
let sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
|
||||||
|
|
||||||
sponsorTime.segment[index] =
|
sponsorTime.segment[index] =
|
||||||
this.props.contentContainer().v.currentTime;
|
time;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
|
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
|
||||||
@@ -319,6 +336,10 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
|||||||
this.props.submissionNotice.forceUpdate();
|
this.props.submissionNotice.forceUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configUpdate() {
|
||||||
|
this.forceUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SponsorTimeEditComponent;
|
export default SponsorTimeEditComponent;
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
import * as CompileConfig from "../config.json";
|
import * as CompileConfig from "../config.json";
|
||||||
import { CategorySelection, CategorySkipOption } from "./types";
|
import { CategorySelection, CategorySkipOption } from "./types";
|
||||||
|
|
||||||
|
import Utils from "./utils";
|
||||||
|
const utils = new Utils();
|
||||||
|
|
||||||
interface SBConfig {
|
interface SBConfig {
|
||||||
userID: string,
|
userID: string,
|
||||||
sponsorTimes: SBMap<string, any>,
|
sponsorTimes: SBMap<string, any>,
|
||||||
whitelistedChannels: Array<any>,
|
whitelistedChannels: string[],
|
||||||
|
forceChannelCheck: boolean,
|
||||||
startSponsorKeybind: string,
|
startSponsorKeybind: string,
|
||||||
submitKeybind: string,
|
submitKeybind: string,
|
||||||
minutesSaved: number,
|
minutesSaved: number,
|
||||||
@@ -104,6 +108,7 @@ var Config: SBObject = {
|
|||||||
userID: null,
|
userID: null,
|
||||||
sponsorTimes: new SBMap("sponsorTimes"),
|
sponsorTimes: new SBMap("sponsorTimes"),
|
||||||
whitelistedChannels: [],
|
whitelistedChannels: [],
|
||||||
|
forceChannelCheck: false,
|
||||||
startSponsorKeybind: ";",
|
startSponsorKeybind: ";",
|
||||||
submitKeybind: "'",
|
submitKeybind: "'",
|
||||||
minutesSaved: 0,
|
minutesSaved: 0,
|
||||||
@@ -236,7 +241,7 @@ function fetchConfig() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function migrateOldFormats() {
|
async function migrateOldFormats() {
|
||||||
if (Config.config["disableAutoSkip"]) {
|
if (Config.config["disableAutoSkip"]) {
|
||||||
for (const selection of Config.config.categorySelections) {
|
for (const selection of Config.config.categorySelections) {
|
||||||
if (selection.name === "sponsor") {
|
if (selection.name === "sponsor") {
|
||||||
@@ -246,6 +251,36 @@ function migrateOldFormats() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Channel URLS
|
||||||
|
if (Config.config.whitelistedChannels.length > 0 &&
|
||||||
|
(Config.config.whitelistedChannels[0].includes("/") || Config.config.whitelistedChannels[0] == null)) {
|
||||||
|
let newChannelList: string[] = [];
|
||||||
|
for (const item of Config.config.whitelistedChannels) {
|
||||||
|
if (item != null) {
|
||||||
|
if (item.includes("/channel/")) {
|
||||||
|
newChannelList.push(item.split("/")[2]);
|
||||||
|
} else if (item.includes("/user/") && utils.isContentScript()) {
|
||||||
|
// Replace channel URL with channelID
|
||||||
|
let response = await utils.asyncRequestToCustomServer("GET", "https://sponsor.ajay.app/invidious/api/v1/channels/" + item.split("/")[2] + "?fields=authorId");
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
newChannelList.push((await response.json()).authorId);
|
||||||
|
} else {
|
||||||
|
// Add it at the beginning so it gets converted later
|
||||||
|
newChannelList.unshift(item);
|
||||||
|
}
|
||||||
|
} else if (item.includes("/user/")) {
|
||||||
|
// Add it at the beginning so it gets converted later (The API can only be called in the content script due to CORS issues)
|
||||||
|
newChannelList.unshift(item);
|
||||||
|
} else {
|
||||||
|
newChannelList.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Config.config.whitelistedChannels = newChannelList;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setupConfig() {
|
async function setupConfig() {
|
||||||
|
|||||||
313
src/content.ts
313
src/content.ts
@@ -1,6 +1,6 @@
|
|||||||
import Config from "./config";
|
import Config from "./config";
|
||||||
|
|
||||||
import { SponsorTime, CategorySkipOption, CategorySelection, VideoID } from "./types";
|
import { SponsorTime, CategorySkipOption, CategorySelection, VideoID, SponsorHideType } from "./types";
|
||||||
|
|
||||||
import { ContentContainer } from "./types";
|
import { ContentContainer } from "./types";
|
||||||
import Utils from "./utils";
|
import Utils from "./utils";
|
||||||
@@ -24,15 +24,17 @@ var sponsorTimes: SponsorTime[] = null;
|
|||||||
//what video id are these sponsors for
|
//what video id are these sponsors for
|
||||||
var sponsorVideoID: VideoID = null;
|
var sponsorVideoID: VideoID = null;
|
||||||
|
|
||||||
|
// JSON video info
|
||||||
|
var videoInfo: any = null;
|
||||||
|
//the channel this video is about
|
||||||
|
var channelID;
|
||||||
|
|
||||||
// Skips are scheduled to ensure precision.
|
// Skips are scheduled to ensure precision.
|
||||||
// Skips are rescheduled every seeking event.
|
// Skips are rescheduled every seeking event.
|
||||||
// Skips are canceled every seeking event
|
// Skips are canceled every seeking event
|
||||||
var currentSkipSchedule: NodeJS.Timeout = null;
|
var currentSkipSchedule: NodeJS.Timeout = null;
|
||||||
var seekListenerSetUp = false
|
var seekListenerSetUp = false
|
||||||
|
|
||||||
//these are sponsors that have been downvoted
|
|
||||||
var hiddenSponsorTimes: number[] = [];
|
|
||||||
|
|
||||||
/** @type {Array[boolean]} Has the sponsor been skipped */
|
/** @type {Array[boolean]} Has the sponsor been skipped */
|
||||||
var sponsorSkipped: boolean[] = [];
|
var sponsorSkipped: boolean[] = [];
|
||||||
|
|
||||||
@@ -59,12 +61,6 @@ var switchingVideos = null;
|
|||||||
var lastCheckTime = 0;
|
var lastCheckTime = 0;
|
||||||
var lastCheckVideoTime = -1;
|
var lastCheckVideoTime = -1;
|
||||||
|
|
||||||
//the channel this video is about
|
|
||||||
var channelURL;
|
|
||||||
|
|
||||||
//the title of the last video loaded. Used to make sure the channel URL has been updated yet.
|
|
||||||
var title;
|
|
||||||
|
|
||||||
//is this channel whitelised from getting sponsors skipped
|
//is this channel whitelised from getting sponsors skipped
|
||||||
var channelWhitelisted = false;
|
var channelWhitelisted = false;
|
||||||
|
|
||||||
@@ -110,7 +106,6 @@ var skipNoticeContentContainer: ContentContainer = () => ({
|
|||||||
unskipSponsorTime,
|
unskipSponsorTime,
|
||||||
sponsorTimes,
|
sponsorTimes,
|
||||||
sponsorTimesSubmitting,
|
sponsorTimesSubmitting,
|
||||||
hiddenSponsorTimes,
|
|
||||||
v: video,
|
v: video,
|
||||||
sponsorVideoID,
|
sponsorVideoID,
|
||||||
reskipSponsorTime,
|
reskipSponsorTime,
|
||||||
@@ -143,8 +138,7 @@ function messageListener(request: any, sender: any, sendResponse: (response: any
|
|||||||
//send the sponsor times along with if it's found
|
//send the sponsor times along with if it's found
|
||||||
sendResponse({
|
sendResponse({
|
||||||
found: sponsorDataFound,
|
found: sponsorDataFound,
|
||||||
sponsorTimes: sponsorTimes,
|
sponsorTimes: sponsorTimes
|
||||||
hiddenSponsorTimes: hiddenSponsorTimes
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (popupInitialised && document.getElementById("sponsorBlockPopupContainer") != null) {
|
if (popupInitialised && document.getElementById("sponsorBlockPopupContainer") != null) {
|
||||||
@@ -188,9 +182,9 @@ function messageListener(request: any, sender: any, sendResponse: (response: any
|
|||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "getChannelURL":
|
case "getChannelID":
|
||||||
sendResponse({
|
sendResponse({
|
||||||
channelURL: channelURL
|
channelID: channelID
|
||||||
});
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -267,6 +261,10 @@ function resetValues() {
|
|||||||
sponsorTimes = null;
|
sponsorTimes = null;
|
||||||
sponsorLookupRetries = 0;
|
sponsorLookupRetries = 0;
|
||||||
|
|
||||||
|
videoInfo = null;
|
||||||
|
channelWhitelisted = false;
|
||||||
|
channelID = null;
|
||||||
|
|
||||||
//empty the preview bar
|
//empty the preview bar
|
||||||
if (previewBar !== null) {
|
if (previewBar !== null) {
|
||||||
previewBar.set([], [], 0);
|
previewBar.set([], [], 0);
|
||||||
@@ -298,9 +296,16 @@ async function videoIDChange(id) {
|
|||||||
// Wait for options to be ready
|
// Wait for options to be ready
|
||||||
await utils.wait(() => Config.config !== null, 5000, 1);
|
await utils.wait(() => Config.config !== null, 5000, 1);
|
||||||
|
|
||||||
|
// Get new video info
|
||||||
|
getVideoInfo();
|
||||||
|
|
||||||
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
|
// If enabled, it will check if this video is private or unlisted and double check with the user if the sponsors should be looked up
|
||||||
if (Config.config.checkForUnlistedVideos) {
|
if (Config.config.checkForUnlistedVideos) {
|
||||||
await utils.wait(isPrivacyInfoAvailable);
|
try {
|
||||||
|
await utils.wait(() => !!videoInfo, 5000, 1);
|
||||||
|
} catch (err) {
|
||||||
|
alert(chrome.i18n.getMessage("adblockerIssue"));
|
||||||
|
}
|
||||||
|
|
||||||
if (isUnlisted()) {
|
if (isUnlisted()) {
|
||||||
let shouldContinue = confirm(chrome.i18n.getMessage("confirmPrivacy"));
|
let shouldContinue = confirm(chrome.i18n.getMessage("confirmPrivacy"));
|
||||||
@@ -308,10 +313,8 @@ async function videoIDChange(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a better method here than using type any
|
// Update whitelist data when the video data is loaded
|
||||||
// This is done to be able to do channelIDPromise.isFulfilled and channelIDPromise.isRejected
|
utils.wait(() => !!videoInfo, 5000, 10).then(whitelistCheck);
|
||||||
let channelIDPromise: any = utils.wait(getChannelID);
|
|
||||||
channelIDPromise.then(() => channelIDPromise.isFulfilled = true).catch(() => channelIDPromise.isRejected = true);
|
|
||||||
|
|
||||||
//setup the preview bar
|
//setup the preview bar
|
||||||
if (previewBar === null) {
|
if (previewBar === null) {
|
||||||
@@ -351,7 +354,7 @@ async function videoIDChange(id) {
|
|||||||
//close popup
|
//close popup
|
||||||
closeInfoMenu();
|
closeInfoMenu();
|
||||||
|
|
||||||
sponsorsLookup(id, channelIDPromise);
|
sponsorsLookup(id);
|
||||||
|
|
||||||
//make sure everything is properly added
|
//make sure everything is properly added
|
||||||
updateVisibilityOfPlayerControlsButton().then(() => {
|
updateVisibilityOfPlayerControlsButton().then(() => {
|
||||||
@@ -460,10 +463,12 @@ function startSponsorSchedule(includeIntersectingSegments: boolean = false, curr
|
|||||||
cancelSponsorSchedule();
|
cancelSponsorSchedule();
|
||||||
if (video.paused) return;
|
if (video.paused) return;
|
||||||
|
|
||||||
if (Config.config.disableSkipping || channelWhitelisted){
|
if (Config.config.disableSkipping || channelWhitelisted || (channelID === null && Config.config.forceChannelCheck)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (incorrectVideoIDCheck()) return;
|
||||||
|
|
||||||
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime;
|
if (currentTime === undefined || currentTime === null) currentTime = video.currentTime;
|
||||||
|
|
||||||
let skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments);
|
let skipInfo = getNextSkipIndex(currentTime, includeIntersectingSegments);
|
||||||
@@ -481,27 +486,17 @@ function startSponsorSchedule(includeIntersectingSegments: boolean = false, curr
|
|||||||
let forcedSkipTime: number = null;
|
let forcedSkipTime: number = null;
|
||||||
let forcedIncludeIntersectingSegments = false;
|
let forcedIncludeIntersectingSegments = false;
|
||||||
|
|
||||||
|
if (incorrectVideoIDCheck()) return;
|
||||||
|
|
||||||
if (video.currentTime >= skipTime[0] && video.currentTime < skipTime[1]) {
|
if (video.currentTime >= skipTime[0] && video.currentTime < skipTime[1]) {
|
||||||
// Double check that the videoID is correct
|
skipToTime(video, skipInfo.endIndex, skipInfo.array, skipInfo.openNotice);
|
||||||
// TODO: Remove this bug catching if statement when the bug is found
|
|
||||||
let currentVideoID = getYouTubeVideoID(document.URL);
|
|
||||||
if (currentVideoID == sponsorVideoID) {
|
|
||||||
skipToTime(video, skipInfo.endIndex, skipInfo.array, skipInfo.openNotice);
|
|
||||||
|
|
||||||
// TODO: Know the autoSkip settings for ALL items being skipped
|
// TODO: Know the autoSkip settings for ALL items being skipped
|
||||||
if (utils.getCategorySelection(currentSkip.category).option === CategorySkipOption.ManualSkip) {
|
if (utils.getCategorySelection(currentSkip.category).option === CategorySkipOption.ManualSkip) {
|
||||||
forcedSkipTime = skipTime[0] + 0.001;
|
forcedSkipTime = skipTime[0] + 0.001;
|
||||||
} else {
|
|
||||||
forcedSkipTime = skipTime[1];
|
|
||||||
forcedIncludeIntersectingSegments = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Something has really gone wrong
|
forcedSkipTime = skipTime[1];
|
||||||
console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be.");
|
forcedIncludeIntersectingSegments = true;
|
||||||
console.error("[SponsorBlock] VideoID recorded: " + sponsorVideoID + ". Actual VideoID: " + currentVideoID);
|
|
||||||
|
|
||||||
// Video ID change occured
|
|
||||||
videoIDChange(currentVideoID);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,11 +510,32 @@ function startSponsorSchedule(includeIntersectingSegments: boolean = false, curr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function sponsorsLookup(id: string, channelIDPromise?) {
|
/**
|
||||||
|
* This makes sure the videoID is still correct
|
||||||
|
*
|
||||||
|
* TODO: Remove this bug catching if statement when the bug is found
|
||||||
|
*/
|
||||||
|
function incorrectVideoIDCheck(): boolean {
|
||||||
|
let currentVideoID = getYouTubeVideoID(document.URL);
|
||||||
|
if (currentVideoID !== sponsorVideoID) {
|
||||||
|
// Something has really gone wrong
|
||||||
|
console.error("[SponsorBlock] The videoID recorded when trying to skip is different than what it should be.");
|
||||||
|
console.error("[SponsorBlock] VideoID recorded: " + sponsorVideoID + ". Actual VideoID: " + currentVideoID);
|
||||||
|
|
||||||
|
// Video ID change occured
|
||||||
|
videoIDChange(currentVideoID);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sponsorsLookup(id: string) {
|
||||||
video = document.querySelector('video') // Youtube video player
|
video = document.querySelector('video') // Youtube video player
|
||||||
//there is no video here
|
//there is no video here
|
||||||
if (video == null) {
|
if (video == null) {
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 100);
|
setTimeout(() => sponsorsLookup(id), 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -578,18 +594,6 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
startSponsorSchedule();
|
startSponsorSchedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelIDPromise !== undefined) {
|
|
||||||
if (channelIDPromise.isFulfilled) {
|
|
||||||
whitelistCheck();
|
|
||||||
} else if (channelIDPromise.isRejected) {
|
|
||||||
//try again
|
|
||||||
utils.wait(getChannelID).then(whitelistCheck).catch();
|
|
||||||
} else {
|
|
||||||
//add it as a then statement
|
|
||||||
channelIDPromise.then(whitelistCheck);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//check database for sponsor times
|
//check database for sponsor times
|
||||||
//made true once a setTimeout has been created to try again after a server error
|
//made true once a setTimeout has been created to try again after a server error
|
||||||
let recheckStarted = false;
|
let recheckStarted = false;
|
||||||
@@ -624,43 +628,16 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
|
|
||||||
sponsorTimes = recievedSegments;
|
sponsorTimes = recievedSegments;
|
||||||
|
|
||||||
// Remove all submissions smaller than the minimum duration
|
// Hide all submissions smaller than the minimum duration
|
||||||
if (Config.config.minDuration !== 0) {
|
if (Config.config.minDuration !== 0) {
|
||||||
let smallSegments: SponsorTime[] = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||||
if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] >= Config.config.minDuration) {
|
if (sponsorTimes[i].segment[1] - sponsorTimes[i].segment[0] < Config.config.minDuration) {
|
||||||
smallSegments.push(sponsorTimes[i]);
|
sponsorTimes[i].hidden = SponsorHideType.MinimumDuration;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sponsorTimes = smallSegments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!switchingVideos) {
|
startSkipScheduleCheckingForStartSponsors();
|
||||||
// See if there are any starting sponsors
|
|
||||||
let startingSponsor: number = -1;
|
|
||||||
for (const time of sponsorTimes) {
|
|
||||||
if (time[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) {
|
|
||||||
startingSponsor = time.segment[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!startingSponsor) {
|
|
||||||
for (const time of sponsorTimesSubmitting) {
|
|
||||||
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) {
|
|
||||||
startingSponsor = time.segment[0];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (startingSponsor !== -1) {
|
|
||||||
startSponsorSchedule(false, startingSponsor);
|
|
||||||
} else {
|
|
||||||
startSponsorSchedule();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset skip save
|
// Reset skip save
|
||||||
sponsorSkipped = [];
|
sponsorSkipped = [];
|
||||||
@@ -678,23 +655,13 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
sponsorDataFound = false;
|
sponsorDataFound = false;
|
||||||
|
|
||||||
//check if this video was uploaded recently
|
//check if this video was uploaded recently
|
||||||
//use the invidious api to get the time published
|
utils.wait(() => !!videoInfo).then(() => {
|
||||||
sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + id, function(xmlhttp, error) {
|
let dateUploaded = videoInfo.microformat.playerMicroformatRenderer.uploadDate;
|
||||||
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
|
||||||
let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1];
|
|
||||||
|
|
||||||
if (decodedData === undefined) {
|
//if less than 3 days old
|
||||||
console.error("[SB] Failed at getting video upload date info from YouTube.");
|
if (Date.now() - new Date(dateUploaded).getTime() < 259200000) {
|
||||||
return;
|
//TODO lower when server becomes better
|
||||||
}
|
setTimeout(() => sponsorsLookup(id), 180000);
|
||||||
|
|
||||||
let dateUploaded = JSON.parse(decodedData).microformat.playerMicroformatRenderer.uploadDate;
|
|
||||||
|
|
||||||
//if less than 3 days old
|
|
||||||
if (Date.now() - new Date(dateUploaded).getTime() < 259200000) {
|
|
||||||
//TODO lower when server becomes better
|
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 180000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -704,13 +671,62 @@ function sponsorsLookup(id: string, channelIDPromise?) {
|
|||||||
|
|
||||||
//TODO lower when server becomes better (back to 1 second)
|
//TODO lower when server becomes better (back to 1 second)
|
||||||
//some error occurred, try again in a second
|
//some error occurred, try again in a second
|
||||||
setTimeout(() => sponsorsLookup(id, channelIDPromise), 10000);
|
setTimeout(() => sponsorsLookup(id), 10000);
|
||||||
|
|
||||||
sponsorLookupRetries++;
|
sponsorLookupRetries++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only should be used when it is okay to skip a sponsor when in the middle of it
|
||||||
|
*
|
||||||
|
* Ex. When segments are first loaded
|
||||||
|
*/
|
||||||
|
function startSkipScheduleCheckingForStartSponsors() {
|
||||||
|
if (!switchingVideos) {
|
||||||
|
// See if there are any starting sponsors
|
||||||
|
let startingSponsor: number = -1;
|
||||||
|
for (const time of sponsorTimes) {
|
||||||
|
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) {
|
||||||
|
startingSponsor = time.segment[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (startingSponsor === -1) {
|
||||||
|
for (const time of sponsorTimesSubmitting) {
|
||||||
|
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) {
|
||||||
|
startingSponsor = time.segment[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingSponsor !== -1) {
|
||||||
|
startSponsorSchedule(false, startingSponsor);
|
||||||
|
} else {
|
||||||
|
startSponsorSchedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the video info for the current tab from YouTube
|
||||||
|
*/
|
||||||
|
function getVideoInfo() {
|
||||||
|
sendRequestToCustomServer('GET', "https://www.youtube.com/get_video_info?video_id=" + sponsorVideoID, function(xmlhttp, error) {
|
||||||
|
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
|
||||||
|
let decodedData = decodeURIComponent(xmlhttp.responseText).match(/player_response=([^&]*)/)[1];
|
||||||
|
if (!decodedData) {
|
||||||
|
console.error("[SB] Failed at getting video info from YouTube.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoInfo = JSON.parse(decodedData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getYouTubeVideoID(url: string) {
|
function getYouTubeVideoID(url: string) {
|
||||||
// For YouTube TV support
|
// For YouTube TV support
|
||||||
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
if(url.startsWith("https://www.youtube.com/tv#/")) url = url.replace("#", "");
|
||||||
@@ -753,55 +769,6 @@ function getYouTubeVideoID(url: string) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannelID() {
|
|
||||||
//get channel id
|
|
||||||
let channelURLContainer = null;
|
|
||||||
|
|
||||||
channelURLContainer = document.querySelector("#channel-name > #container > #text-container > #text");
|
|
||||||
if (channelURLContainer !== null) {
|
|
||||||
channelURLContainer = channelURLContainer.firstElementChild;
|
|
||||||
} else if (onInvidious) {
|
|
||||||
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
|
||||||
channelURLContainer = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a");
|
|
||||||
} else {
|
|
||||||
//old YouTube theme
|
|
||||||
let channelContainers = document.getElementsByClassName("yt-user-info");
|
|
||||||
if (channelContainers.length != 0) {
|
|
||||||
channelURLContainer = channelContainers[0].firstElementChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channelURLContainer === null) {
|
|
||||||
//try later
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//first get the title to make sure a title change has occurred (otherwise the next video might still be loading)
|
|
||||||
let titleInfoContainer = document.getElementById("info-contents");
|
|
||||||
let currentTitle = "";
|
|
||||||
if (titleInfoContainer != null) {
|
|
||||||
currentTitle = (<HTMLElement> titleInfoContainer.firstElementChild.firstElementChild.querySelector(".title").firstElementChild).innerText;
|
|
||||||
} else if (onInvidious) {
|
|
||||||
// Unfortunately, the Invidious HTML doesn't have much in the way of element identifiers...
|
|
||||||
currentTitle = document.querySelector("body > div > div.pure-u-1.pure-u-md-20-24 div.pure-u-1.pure-u-lg-3-5 > div > a > div > span").textContent;
|
|
||||||
} else {
|
|
||||||
//old YouTube theme
|
|
||||||
currentTitle = document.getElementById("eow-title").innerText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (title == currentTitle) {
|
|
||||||
//video hasn't changed yet, wait
|
|
||||||
//try later
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
title = currentTitle;
|
|
||||||
|
|
||||||
channelURL = channelURLContainer.getAttribute("href");
|
|
||||||
|
|
||||||
//reset variables
|
|
||||||
channelWhitelisted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears
|
* This function is required on mobile YouTube and will keep getting called whenever the preview bar disapears
|
||||||
*/
|
*/
|
||||||
@@ -822,7 +789,7 @@ function updatePreviewBar() {
|
|||||||
//create an array of the sponsor types
|
//create an array of the sponsor types
|
||||||
let types = [];
|
let types = [];
|
||||||
for (let i = 0; i < localSponsorTimes.length; i++) {
|
for (let i = 0; i < localSponsorTimes.length; i++) {
|
||||||
if (!hiddenSponsorTimes.includes(i)) {
|
if (localSponsorTimes[i].hidden === SponsorHideType.Visible) {
|
||||||
types.push(localSponsorTimes[i].category);
|
types.push(localSponsorTimes[i].category);
|
||||||
} else {
|
} else {
|
||||||
// Don't show this sponsor
|
// Don't show this sponsor
|
||||||
@@ -841,12 +808,17 @@ function updatePreviewBar() {
|
|||||||
|
|
||||||
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
//checks if this channel is whitelisted, should be done only after the channelID has been loaded
|
||||||
function whitelistCheck() {
|
function whitelistCheck() {
|
||||||
|
channelID = videoInfo.videoDetails.channelId;
|
||||||
|
|
||||||
//see if this is a whitelisted channel
|
//see if this is a whitelisted channel
|
||||||
let whitelistedChannels = Config.config.whitelistedChannels;
|
let whitelistedChannels = Config.config.whitelistedChannels;
|
||||||
|
|
||||||
if (whitelistedChannels != undefined && whitelistedChannels.includes(channelURL)) {
|
if (whitelistedChannels != undefined && whitelistedChannels.includes(channelID)) {
|
||||||
channelWhitelisted = true;
|
channelWhitelisted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the start of segments were missed
|
||||||
|
if (sponsorTimes && sponsorTimes.length > 0) startSkipScheduleCheckingForStartSponsors();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -856,13 +828,13 @@ function getNextSkipIndex(currentTime: number, includeIntersectingSegments: bool
|
|||||||
{array: SponsorTime[], index: number, endIndex: number, openNotice: boolean} {
|
{array: SponsorTime[], index: number, endIndex: number, openNotice: boolean} {
|
||||||
|
|
||||||
let sponsorStartTimes = getStartTimes(sponsorTimes, includeIntersectingSegments);
|
let sponsorStartTimes = getStartTimes(sponsorTimes, includeIntersectingSegments);
|
||||||
let sponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimes, includeIntersectingSegments, currentTime, true);
|
let sponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimes, includeIntersectingSegments, currentTime, true, true);
|
||||||
|
|
||||||
let minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
|
let minSponsorTimeIndex = sponsorStartTimes.indexOf(Math.min(...sponsorStartTimesAfterCurrentTime));
|
||||||
let endTimeIndex = getLatestEndTimeIndex(sponsorTimes, minSponsorTimeIndex);
|
let endTimeIndex = getLatestEndTimeIndex(sponsorTimes, minSponsorTimeIndex);
|
||||||
|
|
||||||
let previewSponsorStartTimes = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments);
|
let previewSponsorStartTimes = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments);
|
||||||
let previewSponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, currentTime, false);
|
let previewSponsorStartTimesAfterCurrentTime = getStartTimes(sponsorTimesSubmitting, includeIntersectingSegments, currentTime, true, false);
|
||||||
|
|
||||||
let minPreviewSponsorTimeIndex = previewSponsorStartTimes.indexOf(Math.min(...previewSponsorStartTimesAfterCurrentTime));
|
let minPreviewSponsorTimeIndex = previewSponsorStartTimes.indexOf(Math.min(...previewSponsorStartTimesAfterCurrentTime));
|
||||||
let previewEndTimeIndex = getLatestEndTimeIndex(sponsorTimesSubmitting, minPreviewSponsorTimeIndex);
|
let previewEndTimeIndex = getLatestEndTimeIndex(sponsorTimesSubmitting, minPreviewSponsorTimeIndex);
|
||||||
@@ -911,7 +883,7 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
|
|||||||
let latestEndTime = sponsorTimes[latestEndTimeIndex].segment[1];
|
let latestEndTime = sponsorTimes[latestEndTimeIndex].segment[1];
|
||||||
|
|
||||||
if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime
|
if (currentSegment[0] <= latestEndTime && currentSegment[1] > latestEndTime
|
||||||
&& (!hideHiddenSponsors || !hiddenSponsorTimes.includes(i))
|
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
|
||||||
&& utils.getCategorySelection(sponsorTimes[i].category).option === CategorySkipOption.AutoSkip) {
|
&& utils.getCategorySelection(sponsorTimes[i].category).option === CategorySkipOption.AutoSkip) {
|
||||||
// Overlapping segment
|
// Overlapping segment
|
||||||
latestEndTimeIndex = i;
|
latestEndTimeIndex = i;
|
||||||
@@ -937,14 +909,16 @@ function getLatestEndTimeIndex(sponsorTimes: SponsorTime[], index: number, hideH
|
|||||||
* the current time, but end after
|
* the current time, but end after
|
||||||
*/
|
*/
|
||||||
function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, minimum?: number,
|
function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments: boolean, minimum?: number,
|
||||||
hideHiddenSponsors: boolean = false): number[] {
|
onlySkippableSponsors: boolean = false, hideHiddenSponsors: boolean = false): number[] {
|
||||||
if (sponsorTimes === null) return [];
|
if (sponsorTimes === null) return [];
|
||||||
|
|
||||||
let startTimes: number[] = [];
|
let startTimes: number[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < sponsorTimes.length; i++) {
|
for (let i = 0; i < sponsorTimes.length; i++) {
|
||||||
if ((minimum === undefined || (sponsorTimes[i].segment[0] >= minimum || (includeIntersectingSegments && sponsorTimes[i].segment[1] > minimum)))
|
if ((minimum === undefined || (sponsorTimes[i].segment[0] >= minimum || (includeIntersectingSegments && sponsorTimes[i].segment[1] > minimum)))
|
||||||
&& (!hideHiddenSponsors || !hiddenSponsorTimes.includes(i))) {
|
&& (!onlySkippableSponsors || utils.getCategorySelection(sponsorTimes[i].category).option !== CategorySkipOption.ShowOverlay)
|
||||||
|
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)) {
|
||||||
|
|
||||||
startTimes.push(sponsorTimes[i].segment[0]);
|
startTimes.push(sponsorTimes[i].segment[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1490,6 +1464,9 @@ async function sendSubmitMessage(){
|
|||||||
|
|
||||||
sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting);
|
sponsorTimes = sponsorTimes.concat(sponsorTimesSubmitting);
|
||||||
|
|
||||||
|
// Increase contribution count
|
||||||
|
Config.config.sponsorTimesContributed = Config.config.sponsorTimesContributed + sponsorTimesSubmitting.length;
|
||||||
|
|
||||||
// Empty the submitting times
|
// Empty the submitting times
|
||||||
sponsorTimesSubmitting = [];
|
sponsorTimesSubmitting = [];
|
||||||
|
|
||||||
@@ -1525,30 +1502,12 @@ function getSegmentsMessage(segments: number[][]): string {
|
|||||||
return sponsorTimesMessage;
|
return sponsorTimesMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Privacy utils
|
|
||||||
function isPrivacyInfoAvailable(): boolean {
|
|
||||||
if(document.location.pathname.startsWith("/embed/")) return true;
|
|
||||||
return document.getElementsByClassName("style-scope ytd-badge-supported-renderer").length >= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* What privacy level is this YouTube video?
|
|
||||||
*/
|
|
||||||
function getPrivacy(): string {
|
|
||||||
if(document.location.pathname.startsWith("/embed/")) return "Public";
|
|
||||||
|
|
||||||
let privacyElement = <HTMLElement> document.getElementsByClassName("style-scope ytd-badge-supported-renderer")[2];
|
|
||||||
return privacyElement.innerText;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this an unlisted YouTube video.
|
* Is this an unlisted YouTube video.
|
||||||
* Assumes that the the privacy info is available.
|
* Assumes that the the privacy info is available.
|
||||||
*/
|
*/
|
||||||
function isUnlisted(): boolean {
|
function isUnlisted(): boolean {
|
||||||
let privacyElement = <HTMLElement> document.getElementsByClassName("style-scope ytd-badge-supported-renderer")[2];
|
return videoInfo.microformat.playerMicroformatRenderer.isUnlisted || videoInfo.videoDetails.isPrivate;
|
||||||
|
|
||||||
return privacyElement.innerText.toLocaleLowerCase() === "unlisted";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
96
src/popup.ts
96
src/popup.ts
@@ -1,7 +1,7 @@
|
|||||||
import Config from "./config";
|
import Config from "./config";
|
||||||
|
|
||||||
import Utils from "./utils";
|
import Utils from "./utils";
|
||||||
import { SponsorTime } from "./types";
|
import { SponsorTime, SponsorHideType } from "./types";
|
||||||
var utils = new Utils();
|
var utils = new Utils();
|
||||||
|
|
||||||
interface MessageListener {
|
interface MessageListener {
|
||||||
@@ -51,6 +51,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
// Top toggles
|
// Top toggles
|
||||||
"whitelistChannel",
|
"whitelistChannel",
|
||||||
"unwhitelistChannel",
|
"unwhitelistChannel",
|
||||||
|
"whitelistForceCheck",
|
||||||
"disableSkipping",
|
"disableSkipping",
|
||||||
"enableSkipping",
|
"enableSkipping",
|
||||||
// Options
|
// Options
|
||||||
@@ -102,6 +103,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
//setup click listeners
|
//setup click listeners
|
||||||
PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
PageElements.sponsorStart.addEventListener("click", sendSponsorStartMessage);
|
||||||
PageElements.whitelistChannel.addEventListener("click", whitelistChannel);
|
PageElements.whitelistChannel.addEventListener("click", whitelistChannel);
|
||||||
|
PageElements.whitelistForceCheck.addEventListener("click", openOptions);
|
||||||
PageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
|
PageElements.unwhitelistChannel.addEventListener("click", unwhitelistChannel);
|
||||||
PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true));
|
PageElements.disableSkipping.addEventListener("click", () => toggleSkipping(true));
|
||||||
PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false));
|
PageElements.enableSkipping.addEventListener("click", () => toggleSkipping(false));
|
||||||
@@ -273,7 +275,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function infoFound(request: {found: boolean, sponsorTimes: SponsorTime[], hiddenSponsorTimes: number[]}) {
|
function infoFound(request: {found: boolean, sponsorTimes: SponsorTime[]}) {
|
||||||
if(chrome.runtime.lastError) {
|
if(chrome.runtime.lastError) {
|
||||||
//This page doesn't have the injected content script, or at least not yet
|
//This page doesn't have the injected content script, or at least not yet
|
||||||
displayNoVideo();
|
displayNoVideo();
|
||||||
@@ -364,7 +366,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//display the video times from the array at the top, in a different section
|
//display the video times from the array at the top, in a different section
|
||||||
function displayDownloadedSponsorTimes(request: {found: boolean, sponsorTimes: SponsorTime[], hiddenSponsorTimes: number[]}) {
|
function displayDownloadedSponsorTimes(request: {found: boolean, sponsorTimes: SponsorTime[]}) {
|
||||||
if (request.sponsorTimes != undefined) {
|
if (request.sponsorTimes != undefined) {
|
||||||
//set it to the message
|
//set it to the message
|
||||||
if (PageElements.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) {
|
if (PageElements.downloadedSponsorMessageTimes.innerText != chrome.i18n.getMessage("channelWhitelisted")) {
|
||||||
@@ -378,9 +380,12 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
sponsorTimeButton.className = "warningButton popupElement";
|
sponsorTimeButton.className = "warningButton popupElement";
|
||||||
|
|
||||||
let extraInfo = "";
|
let extraInfo = "";
|
||||||
if (request.hiddenSponsorTimes.includes(i)) {
|
if (request.sponsorTimes[i].hidden === SponsorHideType.Downvoted) {
|
||||||
//this one is hidden
|
//this one is downvoted
|
||||||
extraInfo = " (hidden)";
|
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")";
|
||||||
|
} else if (request.sponsorTimes[i].hidden === SponsorHideType.MinimumDuration) {
|
||||||
|
//this one is too short
|
||||||
|
extraInfo = " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i].segment[0]) + " to " + getFormattedTime(request.sponsorTimes[i].segment[1]) + extraInfo;
|
sponsorTimeButton.innerText = getFormattedTime(request.sponsorTimes[i].segment[0]) + " to " + getFormattedTime(request.sponsorTimes[i].segment[1]) + extraInfo;
|
||||||
@@ -444,6 +449,14 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
//add commas if necessary
|
//add commas if necessary
|
||||||
timeMessage = ", " + timeMessage;
|
timeMessage = ", " + timeMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sponsorTimes[i].hidden === SponsorHideType.Downvoted) {
|
||||||
|
//this one is downvoted
|
||||||
|
timeMessage += " (" + chrome.i18n.getMessage("hiddenDueToDownvote") + ")";
|
||||||
|
} else if (sponsorTimes[i].hidden === SponsorHideType.MinimumDuration) {
|
||||||
|
//this one is too short
|
||||||
|
timeMessage += " (" + chrome.i18n.getMessage("hiddenDueToDuration") + ")";
|
||||||
|
}
|
||||||
|
|
||||||
sponsorTimesMessage += timeMessage;
|
sponsorTimesMessage += timeMessage;
|
||||||
}
|
}
|
||||||
@@ -908,39 +921,46 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
}, tabs => {
|
}, tabs => {
|
||||||
messageHandler.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'getChannelURL'},
|
{message: 'getChannelID'},
|
||||||
function(response) {
|
function(response) {
|
||||||
|
if (!response.channelID) {
|
||||||
|
alert(chrome.i18n.getMessage("channelDataNotFound") + "\n\n" +
|
||||||
|
chrome.i18n.getMessage("itCouldBeAdblockerIssue"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//get whitelisted channels
|
//get whitelisted channels
|
||||||
let whitelistedChannels = Config.config.whitelistedChannels;
|
let whitelistedChannels = Config.config.whitelistedChannels;
|
||||||
if (whitelistedChannels == undefined) {
|
if (whitelistedChannels == undefined) {
|
||||||
whitelistedChannels = [];
|
whitelistedChannels = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
//add on this channel
|
||||||
|
whitelistedChannels.push(response.channelID);
|
||||||
|
|
||||||
|
//change button
|
||||||
|
PageElements.whitelistChannel.style.display = "none";
|
||||||
|
PageElements.unwhitelistChannel.style.display = "unset";
|
||||||
|
if (!Config.config.forceChannelCheck) PageElements.whitelistForceCheck.style.display = "unset";
|
||||||
|
|
||||||
|
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
||||||
|
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
||||||
|
|
||||||
|
//save this
|
||||||
|
Config.config.whitelistedChannels = whitelistedChannels;
|
||||||
|
|
||||||
|
//send a message to the client
|
||||||
|
messageHandler.query({
|
||||||
|
active: true,
|
||||||
|
currentWindow: true
|
||||||
|
}, tabs => {
|
||||||
|
messageHandler.sendMessage(
|
||||||
|
tabs[0].id, {
|
||||||
|
message: 'whitelistChange',
|
||||||
|
value: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
);
|
||||||
//add on this channel
|
|
||||||
whitelistedChannels.push(response.channelURL);
|
|
||||||
|
|
||||||
//change button
|
|
||||||
PageElements.whitelistChannel.style.display = "none";
|
|
||||||
PageElements.unwhitelistChannel.style.display = "unset";
|
|
||||||
|
|
||||||
PageElements.downloadedSponsorMessageTimes.innerText = chrome.i18n.getMessage("channelWhitelisted");
|
|
||||||
PageElements.downloadedSponsorMessageTimes.style.fontWeight = "bold";
|
|
||||||
|
|
||||||
//save this
|
|
||||||
Config.config.whitelistedChannels = whitelistedChannels;
|
|
||||||
|
|
||||||
//send a message to the client
|
|
||||||
messageHandler.query({
|
|
||||||
active: true,
|
|
||||||
currentWindow: true
|
|
||||||
}, tabs => {
|
|
||||||
messageHandler.sendMessage(
|
|
||||||
tabs[0].id, {
|
|
||||||
message: 'whitelistChange',
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -954,7 +974,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
}, tabs => {
|
}, tabs => {
|
||||||
messageHandler.sendMessage(
|
messageHandler.sendMessage(
|
||||||
tabs[0].id,
|
tabs[0].id,
|
||||||
{message: 'getChannelURL'},
|
{message: 'getChannelID'},
|
||||||
function(response) {
|
function(response) {
|
||||||
//get whitelisted channels
|
//get whitelisted channels
|
||||||
let whitelistedChannels = Config.config.whitelistedChannels;
|
let whitelistedChannels = Config.config.whitelistedChannels;
|
||||||
@@ -963,7 +983,7 @@ async function runThePopup(messageListener?: MessageListener) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//remove this channel
|
//remove this channel
|
||||||
let index = whitelistedChannels.indexOf(response.channelURL);
|
let index = whitelistedChannels.indexOf(response.channelID);
|
||||||
whitelistedChannels.splice(index, 1);
|
whitelistedChannels.splice(index, 1);
|
||||||
|
|
||||||
//change button
|
//change button
|
||||||
|
|||||||
12
src/types.ts
12
src/types.ts
@@ -8,7 +8,6 @@ interface ContentContainer {
|
|||||||
unskipSponsorTime: (UUID: any) => void,
|
unskipSponsorTime: (UUID: any) => void,
|
||||||
sponsorTimes: SponsorTime[],
|
sponsorTimes: SponsorTime[],
|
||||||
sponsorTimesSubmitting: SponsorTime[],
|
sponsorTimesSubmitting: SponsorTime[],
|
||||||
hiddenSponsorTimes: number[],
|
|
||||||
v: HTMLVideoElement,
|
v: HTMLVideoElement,
|
||||||
sponsorVideoID,
|
sponsorVideoID,
|
||||||
reskipSponsorTime: (UUID: any) => void,
|
reskipSponsorTime: (UUID: any) => void,
|
||||||
@@ -36,11 +35,19 @@ interface CategorySelection {
|
|||||||
option: CategorySkipOption
|
option: CategorySkipOption
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum SponsorHideType {
|
||||||
|
Visible = undefined,
|
||||||
|
Downvoted = 1,
|
||||||
|
MinimumDuration
|
||||||
|
}
|
||||||
|
|
||||||
interface SponsorTime {
|
interface SponsorTime {
|
||||||
segment: number[];
|
segment: number[];
|
||||||
UUID: string;
|
UUID: string;
|
||||||
|
|
||||||
category: string;
|
category: string;
|
||||||
|
|
||||||
|
hidden?: SponsorHideType;
|
||||||
}
|
}
|
||||||
|
|
||||||
type VideoID = string;
|
type VideoID = string;
|
||||||
@@ -51,5 +58,6 @@ export {
|
|||||||
CategorySelection,
|
CategorySelection,
|
||||||
CategorySkipOption,
|
CategorySkipOption,
|
||||||
SponsorTime,
|
SponsorTime,
|
||||||
VideoID
|
VideoID,
|
||||||
|
SponsorHideType
|
||||||
};
|
};
|
||||||
30
src/utils.ts
30
src/utils.ts
@@ -270,27 +270,26 @@ class Utils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a request to the SponsorBlock server with address added as a query
|
* Sends a request to a custom server
|
||||||
*
|
*
|
||||||
* @param type The request type. "GET", "POST", etc.
|
* @param type The request type. "GET", "POST", etc.
|
||||||
* @param address The address to add to the SponsorBlock server address
|
* @param address The address to add to the SponsorBlock server address
|
||||||
* @param callback
|
* @param callback
|
||||||
*/
|
*/
|
||||||
async asyncRequestToServer(type: string, address: string, data = {}) {
|
async asyncRequestToCustomServer(type: string, url: string, data = {}) {
|
||||||
let serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
|
|
||||||
|
|
||||||
// If GET, convert JSON to parameters
|
// If GET, convert JSON to parameters
|
||||||
if (type.toLowerCase() === "get") {
|
if (type.toLowerCase() === "get") {
|
||||||
for (const key in data) {
|
for (const key in data) {
|
||||||
let seperator = address.includes("?") ? "&" : "?";
|
let seperator = url.includes("?") ? "&" : "?";
|
||||||
let value = (typeof(data[key]) === "string") ? data[key]: JSON.stringify(data[key]);
|
let value = (typeof(data[key]) === "string") ? data[key]: JSON.stringify(data[key]);
|
||||||
address += seperator + key + "=" + value;
|
url += seperator + key + "=" + value;
|
||||||
}
|
}
|
||||||
|
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(serverAddress + address, {
|
const response = await fetch(url, {
|
||||||
method: type,
|
method: type,
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@@ -302,6 +301,19 @@ class Utils {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a request to the SponsorBlock server with address added as a query
|
||||||
|
*
|
||||||
|
* @param type The request type. "GET", "POST", etc.
|
||||||
|
* @param address The address to add to the SponsorBlock server address
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
async asyncRequestToServer(type: string, address: string, data = {}) {
|
||||||
|
let serverAddress = Config.config.testingServer ? CompileConfig.testingServerAddress : Config.config.serverAddress;
|
||||||
|
|
||||||
|
return await (this.asyncRequestToCustomServer(type, serverAddress + address, data));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a request to the SponsorBlock server with address added as a query
|
* Sends a request to the SponsorBlock server with address added as a query
|
||||||
*
|
*
|
||||||
@@ -361,10 +373,14 @@ class Utils {
|
|||||||
return minutes * 60 + seconds;
|
return minutes * 60 + seconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isContentScript(): boolean {
|
||||||
|
return window.location.protocol === "http:" || window.location.protocol === "https:";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this Firefox (web-extensions)
|
* Is this Firefox (web-extensions)
|
||||||
*/
|
*/
|
||||||
isFirefox() {
|
isFirefox(): boolean {
|
||||||
return typeof(browser) !== "undefined";
|
return typeof(browser) !== "undefined";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user