aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2020-07-03 21:20:53 -0400
committerGitHub <[email protected]>2020-07-03 21:20:53 -0400
commitfad3284c4f52c8af4e1aa125cf680e6170bccfeb (patch)
tree1cda05f453d96631d516833ce6ae3a0ab5c30827
parentdd4c903c6a9e1496fed346258a97308a8a34c3fa (diff)
parentc69047c7f9d801f94914f2ef498fdd30b688d944 (diff)
downloadSponsorBlock-fad3284c4f52c8af4e1aa125cf680e6170bccfeb.tar.gz
SponsorBlock-fad3284c4f52c8af4e1aa125cf680e6170bccfeb.zip
Merge pull request #399 from ajayyy/react2.0.3
Save category in preview submissions and other fixes
-rw-r--r--manifest/manifest.json2
-rw-r--r--public/_locales/en/messages.json11
-rw-r--r--src/background.ts47
-rw-r--r--src/components/SkipNoticeComponent.tsx7
-rw-r--r--src/components/SponsorTimeEditComponent.tsx4
-rw-r--r--src/config.ts174
-rw-r--r--src/content.ts53
-rw-r--r--src/js-components/previewBar.ts6
-rw-r--r--src/options.ts58
-rw-r--r--src/popup.ts38
-rw-r--r--src/utils.ts4
11 files changed, 193 insertions, 211 deletions
diff --git a/manifest/manifest.json b/manifest/manifest.json
index 08e507fb..d2626d74 100644
--- a/manifest/manifest.json
+++ b/manifest/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_fullName__",
"short_name": "SponsorBlock",
- "version": "2.0.2.2",
+ "version": "2.0.3",
"default_locale": "en",
"description": "__MSG_Description__",
"content_scripts": [{
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index 44897364..862d69bc 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -218,7 +218,7 @@
"message": "Show Notice Again"
},
"longDescription": {
- "message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment.",
+ "message": "SponsorBlock is an extension that will skip over sponsored segments of YouTube videos. SponsorBlock is a crowdsourced browser extension that lets anyone submit the start and end times of sponsored segments of YouTube videos. Once one person submits this information, everyone else with this extension will skip right over the sponsored segment. \n\n You can also skip intros, outros, reminders to subscribe and other categories.",
"description": "Full description of the extension on the store pages."
},
"website": {
@@ -472,9 +472,6 @@
"theKey": {
"message": "The key"
},
- "keyAlreadyUsedByYouTube": {
- "message": "is already used by youtube. Please select another key."
- },
"keyAlreadyUsed": {
"message": "is bound to another action. Please select another key."
},
@@ -489,13 +486,13 @@
"message": "Paid promotion, paid referrals and direct advertisements. Not for self-promotion or free shoutouts to causes/creators/websites/products they like."
},
"category_intro": {
- "message": "Intro Animation"
+ "message": "Intermission/Intro Animation"
},
"category_intro_description": {
- "message": "Intro animations that are recurring in the series or provide no direct value. This should not be used on music videos."
+ "message": "An interval without actual content. Could be a pause, static frame, repeating animation. This should not be used for transitions containing information or be used on music videos."
},
"category_intro_short": {
- "message": "Intro"
+ "message": "Intermission"
},
"category_outro": {
"message": "Endcards/Credits"
diff --git a/src/background.ts b/src/background.ts
index 28a1051e..ec398d59 100644
--- a/src/background.ts
+++ b/src/background.ts
@@ -41,21 +41,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
});
return true;
- case "addSponsorTime":
- addSponsorTime(request.time, request.videoID, callback);
-
- //this allows the callback to be called later
- return true;
-
- case "getSponsorTimes":
- getSponsorTimes(request.videoID, function(sponsorTimes) {
- callback({
- sponsorTimes
- });
- });
-
- //this allows the callback to be called later
- return true;
case "submitVote":
submitVote(request.type, request.UUID, request.category).then(callback);
@@ -127,38 +112,6 @@ function unregisterFirefoxContentScript(id: string) {
delete contentScriptRegistrations[id];
}
-//gets the sponsor times from memory
-function getSponsorTimes(videoID, callback) {
- let sponsorTimes = [];
- let sponsorTimesStorage = Config.config.sponsorTimes.get(videoID);
-
- if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
- sponsorTimes = sponsorTimesStorage;
- }
-
- callback(sponsorTimes);
-}
-
-function addSponsorTime(time, videoID, callback) {
- getSponsorTimes(videoID, function(sponsorTimes) {
- //add to sponsorTimes
- if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].length < 2) {
- //it is an end time
- sponsorTimes[sponsorTimes.length - 1][1] = time;
- } else {
- //it is a start time
- let sponsorTimesIndex = sponsorTimes.length;
- sponsorTimes[sponsorTimesIndex] = [];
-
- sponsorTimes[sponsorTimesIndex][0] = time;
- }
-
- //save this info
- Config.config.sponsorTimes.set(videoID, sponsorTimes);
- callback();
- });
-}
-
async function submitVote(type: number, UUID: string, category: string) {
let userID = Config.config.userID;
diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx
index 022490d0..9dab754b 100644
--- a/src/components/SkipNoticeComponent.tsx
+++ b/src/components/SkipNoticeComponent.tsx
@@ -134,13 +134,6 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
this.audio.volume = this.contentContainer().v.volume * 0.1;
this.audio.play();
}
-
- if (Config.config.categoryUpdateShowCount < 3 && Config.config.categorySelections.length <= 1) {
- this.setNoticeInfoMessageWithOnClick(() => chrome.runtime.sendMessage({"message": "openConfig"})
- , chrome.i18n.getMessage("categoryUpdate1"), chrome.i18n.getMessage("categoryUpdate2"));
-
- Config.config.categoryUpdateShowCount = Config.config.categoryUpdateShowCount + 1
- }
}
render() {
diff --git a/src/components/SponsorTimeEditComponent.tsx b/src/components/SponsorTimeEditComponent.tsx
index 52c1da0c..efcf595a 100644
--- a/src/components/SponsorTimeEditComponent.tsx
+++ b/src/components/SponsorTimeEditComponent.tsx
@@ -322,7 +322,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value;
- Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting));
+ Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimesSubmitting);
this.props.contentContainer().updatePreviewBar();
}
@@ -354,7 +354,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
sponsorTimes.splice(index, 1);
//save this
- Config.config.sponsorTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimes);
+ Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimes);
this.props.contentContainer().updatePreviewBar();
diff --git a/src/config.ts b/src/config.ts
index 31880f48..fb771545 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,12 +1,13 @@
import * as CompileConfig from "../config.json";
-import { CategorySelection, CategorySkipOption, PreviewBarOption } from "./types";
+import { CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime } from "./types";
import Utils from "./utils";
const utils = new Utils();
interface SBConfig {
userID: string,
- sponsorTimes: SBMap<string, any>,
+ // sponsorTimes: SBMap<string, SponsorTime[]>,
+ segmentTimes: SBMap<string, SponsorTime[]>,
whitelistedChannels: string[],
forceChannelCheck: boolean,
startSponsorKeybind: string,
@@ -34,8 +35,6 @@ interface SBConfig {
checkForUnlistedVideos: boolean,
testingServer: boolean,
- categoryUpdateShowCount: number,
-
// What categories should be skipped
categorySelections: CategorySelection[],
@@ -52,7 +51,7 @@ interface SBConfig {
"selfpromo": PreviewBarOption,
"preview-selfpromo": PreviewBarOption,
"music_offtopic": PreviewBarOption,
- "preview-music_offtopic": PreviewBarOption
+ "preview-music_offtopic": PreviewBarOption,
}
}
@@ -85,35 +84,39 @@ class SBMap<T, U> extends Map {
}
}
- set(key, value) {
- const result = super.set(key, value);
+ get(key): U {
+ return super.get(key);
+ }
+
+ rawSet(key, value) {
+ return super.set(key, value);
+ }
+ update() {
// Store updated SBMap locally
chrome.storage.sync.set({
[this.id]: encodeStoredItem(this)
});
+ }
+
+ set(key: T, value: U) {
+ const result = super.set(key, value);
+ this.update();
return result;
}
delete(key) {
const result = super.delete(key);
- // Store updated SBMap locally
- chrome.storage.sync.set({
- [this.id]: encodeStoredItem(this)
- });
-
+ this.update();
return result;
}
clear() {
const result = super.clear();
- chrome.storage.sync.set({
- [this.id]: encodeStoredItem(this)
- });
-
+ this.update();
return result;
}
}
@@ -125,7 +128,7 @@ var Config: SBObject = {
configListeners: [],
defaults: {
userID: null,
- sponsorTimes: new SBMap("sponsorTimes"),
+ segmentTimes: new SBMap("segmentTimes"),
whitelistedChannels: [],
forceChannelCheck: false,
startSponsorKeybind: ";",
@@ -153,8 +156,6 @@ var Config: SBObject = {
checkForUnlistedVideos: false,
testingServer: false,
- categoryUpdateShowCount: 0,
-
categorySelections: [{
name: "sponsor",
option: CategorySkipOption.AutoSkip
@@ -240,24 +241,13 @@ function encodeStoredItem<T>(data: T): T | Array<any> {
*
* @param {*} data
*/
-function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, any> {
+function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, SponsorTime[]> {
if (!Config.defaults[id]) return data;
if (Config.defaults[id] instanceof SBMap) {
try {
- let jsonData: any = data;
-
- // Check if data is stored in the old format for SBMap (a JSON string)
- if (typeof data === "string") {
- try {
- jsonData = JSON.parse(data);
- } catch(e) {
- // Continue normally (out of this if statement)
- }
- }
-
- if (!Array.isArray(jsonData)) return data;
- return new SBMap(id, jsonData);
+ if (!Array.isArray(data)) return data;
+ return new SBMap(id, data);
} catch(e) {
console.error("Failed to parse SBMap: " + id);
}
@@ -315,9 +305,9 @@ function fetchConfig() {
});
}
-async function migrateOldFormats() {
- if (Config.config["disableAutoSkip"]) {
- for (const selection of Config.config.categorySelections) {
+function migrateOldFormats(config: SBConfig) {
+ if (config["disableAutoSkip"]) {
+ for (const selection of config.categorySelections) {
if (selection.name === "sponsor") {
selection.option = CategorySkipOption.ManualSkip;
@@ -327,62 +317,108 @@ async function migrateOldFormats() {
}
// Auto vote removal
- if (Config.config["autoUpvote"]) {
+ if (config["autoUpvote"]) {
chrome.storage.sync.remove("autoUpvote");
}
-
// mobileUpdateShowCount removal
- if (Config.config["mobileUpdateShowCount"] !== undefined) {
+ if (config["mobileUpdateShowCount"] !== undefined) {
chrome.storage.sync.remove("mobileUpdateShowCount");
}
+ // categoryUpdateShowCount removal
+ if (config["categoryUpdateShowCount"] !== undefined) {
+ chrome.storage.sync.remove("categoryUpdateShowCount");
+ }
// Channel URLS
- if (Config.config.whitelistedChannels.length > 0 &&
- (Config.config.whitelistedChannels[0] == null || Config.config.whitelistedChannels[0].includes("/"))) {
- 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((JSON.parse(response.responseText)).authorId);
- } else {
- // Add it at the beginning so it gets converted later
+ if (config.whitelistedChannels.length > 0 &&
+ (config.whitelistedChannels[0] == null || config.whitelistedChannels[0].includes("/"))) {
+ const channelURLFixer = async() => {
+ let newChannelList: string[] = [];
+ for (const item of 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((JSON.parse(response.responseText)).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);
}
- } 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.whitelistedChannels = newChannelList;
}
- Config.config.whitelistedChannels = newChannelList;
+ channelURLFixer();
}
// Check if off-topic category needs to be removed
- for (let i = 0; i < Config.config.categorySelections.length; i++) {
- if (Config.config.categorySelections[i].name === "offtopic") {
- Config.config.categorySelections.splice(i, 1);
+ for (let i = 0; i < config.categorySelections.length; i++) {
+ if (config.categorySelections[i].name === "offtopic") {
+ config.categorySelections.splice(i, 1);
// Call set listener
- Config.config.categorySelections = Config.config.categorySelections;
+ config.categorySelections = config.categorySelections;
break;
}
}
+
+ // Migrate old "sponsorTimes"
+ if (config["sponsorTimes"]) {
+ let jsonData: any = config["sponsorTimes"];
+
+ // Check if data is stored in the old format for SBMap (a JSON string)
+ if (typeof jsonData === "string") {
+ try {
+ jsonData = JSON.parse(jsonData);
+ } catch(e) {
+ // Continue normally (out of this if statement)
+ }
+ }
+
+ // Otherwise junk data
+ if (Array.isArray(jsonData)) {
+ let oldMap = new Map(jsonData);
+ oldMap.forEach((sponsorTimes: number[][], key) => {
+ let segmentTimes: SponsorTime[] = [];
+ for (const segment of sponsorTimes) {
+ segmentTimes.push({
+ segment: segment,
+ category: "sponsor",
+ UUID: null
+ });
+ }
+
+ config.segmentTimes.rawSet(key, segmentTimes);
+ });
+
+ config.segmentTimes.update();
+ }
+
+ chrome.storage.sync.remove("sponsorTimes");
+ }
}
async function setupConfig() {
await fetchConfig();
addDefaults();
convertJSON();
- Config.config = configProxy();
- migrateOldFormats();
+ const config = configProxy();
+ migrateOldFormats(config);
+
+ Config.config = config;
}
// Reset config
@@ -401,6 +437,12 @@ function addDefaults() {
for (const key in Config.defaults) {
if(!Config.localConfig.hasOwnProperty(key)) {
Config.localConfig[key] = Config.defaults[key];
+ } else if (key === "barTypes") {
+ for (const key2 in Config.defaults[key]) {
+ if(!Config.localConfig[key].hasOwnProperty(key2)) {
+ Config.localConfig[key][key2] = Config.defaults[key][key2];
+ }
+ }
}
}
};
diff --git a/src/content.ts b/src/content.ts
index 0feb3e61..d6a16c39 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -323,13 +323,13 @@ async function videoIDChange(id) {
//warn them if they had unsubmitted times
if (previousVideoID != null) {
//get the sponsor times from storage
- let sponsorTimes = Config.config.sponsorTimes.get(previousVideoID);
+ let sponsorTimes = Config.config.segmentTimes.get(previousVideoID);
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
//warn them that they have unsubmitted sponsor times
- chrome.runtime.sendMessage({
- message: "alertPrevious",
- previousVideoID: previousVideoID
- })
+ chrome.runtime.sendMessage({
+ message: "alertPrevious",
+ previousVideoID: previousVideoID
+ });
}
//set the previous video id to the currentID
@@ -347,10 +347,10 @@ async function videoIDChange(id) {
//make sure everything is properly added
updateVisibilityOfPlayerControlsButton().then(() => {
//see if the onvideo control image needs to be changed
- let segments = Config.config.sponsorTimes.get(sponsorVideoID);
- if (segments != null && segments.length > 0 && segments[segments.length - 1].length >= 2) {
+ let segments = Config.config.segmentTimes.get(sponsorVideoID);
+ if (segments != null && segments.length > 0 && segments[segments.length - 1].segment.length >= 2) {
changeStartSponsorButton(true, true);
- } else if (segments != null && segments.length > 0 && segments[segments.length - 1].length < 2) {
+ } else if (segments != null && segments.length > 0 && segments[segments.length - 1].segment.length < 2) {
changeStartSponsorButton(false, true);
} else {
changeStartSponsorButton(true, false);
@@ -1173,31 +1173,24 @@ function startSponsorClicked() {
});
}
- // Create raw segment list
- let segments: number[][] = [];
- for (const sponsorTime of sponsorTimesSubmitting) {
- segments.push(sponsorTime.segment);
- }
-
//save this info
- Config.config.sponsorTimes.set(sponsorVideoID, segments);
+ Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
updateSponsorTimesSubmitting(false)
}
function updateSponsorTimesSubmitting(getFromConfig: boolean = true) {
- let segments = Config.config.sponsorTimes.get(sponsorVideoID);
+ let segmentTimes = Config.config.segmentTimes.get(sponsorVideoID);
//see if this data should be saved in the sponsorTimesSubmitting variable
- if (getFromConfig && segments != undefined) {
+ if (getFromConfig && segmentTimes != undefined) {
sponsorTimesSubmitting = [];
- for (const segment of segments) {
+ for (const segmentTime of segmentTimes) {
sponsorTimesSubmitting.push({
- segment: segment,
+ segment: segmentTime.segment,
UUID: null,
- // Default to sponsor
- category: "sponsor"
+ category: segmentTime.category
});
}
}
@@ -1321,7 +1314,7 @@ function clearSponsorTimes() {
let currentVideoID = sponsorVideoID;
- let sponsorTimes = Config.config.sponsorTimes.get(currentVideoID);
+ let sponsorTimes = Config.config.segmentTimes.get(currentVideoID);
if (sponsorTimes != undefined && sponsorTimes.length > 0) {
let confirmMessage = chrome.i18n.getMessage("clearThis") + getSegmentsMessage(sponsorTimes)
@@ -1329,7 +1322,7 @@ function clearSponsorTimes() {
if(!confirm(confirmMessage)) return;
//clear the sponsor times
- Config.config.sponsorTimes.delete(currentVideoID);
+ Config.config.segmentTimes.delete(currentVideoID);
//clear sponsor times submitting
sponsorTimesSubmitting = [];
@@ -1451,14 +1444,14 @@ async function sendSubmitMessage(){
}
//update sponsorTimes
- Config.config.sponsorTimes.set(sponsorVideoID, utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting));
+ Config.config.segmentTimes.set(sponsorVideoID, sponsorTimesSubmitting);
// Check to see if any of the submissions are below the minimum duration set
if (Config.config.minDuration > 0) {
for (let i = 0; i < sponsorTimesSubmitting.length; i++) {
if (sponsorTimesSubmitting[i].segment[1] - sponsorTimesSubmitting[i].segment[0] < Config.config.minDuration) {
let confirmShort = chrome.i18n.getMessage("shortCheck") + "\n\n" +
- getSegmentsMessage(utils.getSegmentsFromSponsorTimes(sponsorTimesSubmitting));
+ getSegmentsMessage(sponsorTimesSubmitting);
if(!confirm(confirmShort)) return;
}
@@ -1488,7 +1481,7 @@ async function sendSubmitMessage(){
submitButton.addEventListener("animationend", animationEndListener);
//clear the sponsor times
- Config.config.sponsorTimes.delete(sponsorVideoID);
+ Config.config.segmentTimes.delete(sponsorVideoID);
//add submissions to current sponsors list
if (sponsorTimes === null) sponsorTimes = [];
@@ -1516,12 +1509,12 @@ async function sendSubmitMessage(){
}
//get the message that visually displays the video times
-function getSegmentsMessage(segments: number[][]): string {
+function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
let sponsorTimesMessage = "";
- for (let i = 0; i < segments.length; i++) {
- for (let s = 0; s < segments[i].length; s++) {
- let timeMessage = utils.getFormattedTime(segments[i][s]);
+ for (let i = 0; i < sponsorTimes.length; i++) {
+ for (let s = 0; s < sponsorTimes[i].segment.length; s++) {
+ let timeMessage = utils.getFormattedTime(sponsorTimes[i].segment[s]);
//if this is an end time
if (s == 1) {
timeMessage = " to " + timeMessage;
diff --git a/src/js-components/previewBar.ts b/src/js-components/previewBar.ts
index e0931d91..bef397c1 100644
--- a/src/js-components/previewBar.ts
+++ b/src/js-components/previewBar.ts
@@ -6,6 +6,8 @@
'use strict';
import Config from "../config";
+import Utils from "../utils";
+let utils = new Utils();
class PreviewBar {
container: HTMLUListElement;
@@ -79,8 +81,8 @@ class PreviewBar {
tooltipTextWrapper.classList.remove("sbTooltipOneTitleThumbnailOffset");
} else if (category !== null) {
categoryTooltip.classList.remove("sbHidden");
- categoryTooltip.textContent = chrome.i18n.getMessage("category_" + category)
- || (chrome.i18n.getMessage("preview") + " " + chrome.i18n.getMessage("category_" + category.split("preview-")[1]));
+ categoryTooltip.textContent = utils.shortCategoryName(category)
+ || (chrome.i18n.getMessage("preview") + " " + utils.shortCategoryName(category.split("preview-")[1]));
// There is a title now
tooltip.classList.remove("ytp-tooltip-text-no-title");
diff --git a/src/options.ts b/src/options.ts
index 0a196a9a..5e184505 100644
--- a/src/options.ts
+++ b/src/options.ts
@@ -237,7 +237,7 @@ function invidiousInstanceAddInit(element: HTMLElement, option: string) {
let setButton = element.querySelector(".text-change-set");
setButton.addEventListener("click", async function(e) {
- if (textBox.value == "" || textBox.value.includes("/") || textBox.value.includes("http") || textBox.value.includes(":")) {
+ if (textBox.value == "" || textBox.value.includes("/") || textBox.value.includes("http")) {
alert(chrome.i18n.getMessage("addInvidiousInstanceError"));
} else {
// Add this
@@ -298,19 +298,23 @@ function invidiousInit(checkbox: HTMLInputElement, option: string) {
* @param checkbox
* @param option
*/
-function invidiousOnClick(checkbox: HTMLInputElement, option: string) {
- if (checkbox.checked) {
- utils.setupExtraSitePermissions(function (granted) {
- if (!granted) {
- Config.config[option] = false;
- checkbox.checked = false;
- } else {
- checkbox.checked = true;
- }
- });
- } else {
- utils.removeExtraSiteRegistration();
- }
+async function invidiousOnClick(checkbox: HTMLInputElement, option: string) {
+ return new Promise((resolve) => {
+ if (checkbox.checked) {
+ utils.setupExtraSitePermissions(function (granted) {
+ if (!granted) {
+ Config.config[option] = false;
+ checkbox.checked = false;
+ } else {
+ checkbox.checked = true;
+ }
+
+ resolve();
+ });
+ } else {
+ utils.removeExtraSiteRegistration();
+ }
+ });
}
/**
@@ -358,15 +362,6 @@ function keybindKeyPressed(element: HTMLElement, e: KeyboardEvent) {
let button: HTMLElement = element.querySelector(".trigger-button");
let option = element.getAttribute("sync-option");
- // Don't allow keys which are already listened for by youtube
- let restrictedKeys = "1234567890,.jklftcibmJKLFTCIBMNP/<> -+";
- if (restrictedKeys.indexOf(key) !== -1 ) {
- closeKeybindOption(element, button);
-
- alert(chrome.i18n.getMessage("theKey") + " " + key + " " + chrome.i18n.getMessage("keyAlreadyUsedByYouTube"));
- return;
- }
-
// Make sure keybind isn't used by the other listener
// TODO: If other keybindings are going to be added, we need a better way to find the other keys used.
let otherKeybind = (option === "startSponsorKeybind") ? Config.config['submitKeybind'] : Config.config['startSponsorKeybind'];
@@ -435,8 +430,8 @@ function activatePrivateTextChange(element: HTMLElement) {
case "*":
let jsonData = JSON.parse(JSON.stringify(Config.localConfig));
- // Fix sponsorTimes data as it is destroyed from the JSON stringify
- jsonData.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes);
+ // Fix segmentTimes data as it is destroyed from the JSON stringify
+ jsonData.segmentTimes = Config.encodeStoredItem(Config.localConfig.segmentTimes);
result = JSON.stringify(jsonData);
break;
@@ -445,7 +440,7 @@ function activatePrivateTextChange(element: HTMLElement) {
textBox.value = result;
let setButton = element.querySelector(".text-change-set");
- setButton.addEventListener("click", () => {
+ setButton.addEventListener("click", async () => {
let confirmMessage = element.getAttribute("confirm-message");
if (confirmMessage === null || confirm(chrome.i18n.getMessage(confirmMessage))) {
@@ -460,15 +455,14 @@ function activatePrivateTextChange(element: HTMLElement) {
}
Config.convertJSON();
- // Reload options on page
- init();
-
if (newConfig.supportInvidious) {
let checkbox = <HTMLInputElement> document.querySelector("#support-invidious > label > label > input");
checkbox.checked = true;
- invidiousOnClick(checkbox, "supportInvidious");
+ await invidiousOnClick(checkbox, "supportInvidious");
}
+
+ window.location.reload();
} catch (e) {
alert(chrome.i18n.getMessage("incorrectlyFormattedOptions"));
@@ -519,8 +513,8 @@ function copyDebugOutputToClipboard() {
config: JSON.parse(JSON.stringify(Config.localConfig)) // Deep clone config object
};
- // Fix sponsorTimes data as it is destroyed from the JSON stringify
- output.config.sponsorTimes = Config.encodeStoredItem(Config.localConfig.sponsorTimes);
+ // Fix segmentTimes data as it is destroyed from the JSON stringify
+ output.config.segmentTimes = Config.encodeStoredItem(Config.localConfig.segmentTimes);
// Sanitise sensitive user config values
delete output.config.userID;
diff --git a/src/popup.ts b/src/popup.ts
index ee5c9930..239fefbd 100644
--- a/src/popup.ts
+++ b/src/popup.ts
@@ -119,7 +119,7 @@ async function runThePopup(messageListener?: MessageListener) {
let startTimeChosen = false;
//the start and end time pairs (2d)
- let sponsorTimes = [];
+ let sponsorTimes: SponsorTime[] = [];
//current video ID of this tab
let currentVideoID = null;
@@ -252,9 +252,9 @@ async function runThePopup(messageListener?: MessageListener) {
}
//load video times for this video
- let sponsorTimesStorage = Config.config.sponsorTimes.get(currentVideoID);
+ let sponsorTimesStorage = Config.config.segmentTimes.get(currentVideoID);
if (sponsorTimesStorage != undefined && sponsorTimesStorage.length > 0) {
- if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].length < 2) {
+ if (sponsorTimesStorage[sponsorTimesStorage.length - 1] != undefined && sponsorTimesStorage[sponsorTimesStorage.length - 1].segment.length < 2) {
startTimeChosen = true;
PageElements.sponsorStart.innerHTML = chrome.i18n.getMessage("sponsorEnd");
}
@@ -336,13 +336,17 @@ async function runThePopup(messageListener?: MessageListener) {
let sponsorTimesIndex = sponsorTimes.length - (startTimeChosen ? 1 : 0);
if (sponsorTimes[sponsorTimesIndex] == undefined) {
- sponsorTimes[sponsorTimesIndex] = [];
+ sponsorTimes[sponsorTimesIndex] = {
+ segment: [],
+ category: "sponsor",
+ UUID: null
+ };
}
- sponsorTimes[sponsorTimesIndex][startTimeChosen ? 1 : 0] = response.time;
+ sponsorTimes[sponsorTimesIndex].segment[startTimeChosen ? 1 : 0] = response.time;
let localStartTimeChosen = startTimeChosen;
- Config.config.sponsorTimes.set(currentVideoID, sponsorTimes);
+ Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
//send a message to the client script
if (localStartTimeChosen) {
@@ -528,7 +532,7 @@ async function runThePopup(messageListener?: MessageListener) {
}
function previewSponsorTime(index) {
- let skipTime = sponsorTimes[index][0];
+ let skipTime = sponsorTimes[index].segment[0];
if (document.getElementById("startTimeMinutes" + index) != null) {
//edit is currently open, use that time
@@ -575,28 +579,28 @@ async function runThePopup(messageListener?: MessageListener) {
startTimeMinutes.id = "startTimeMinutes" + index;
startTimeMinutes.className = "sponsorTime popupElement";
startTimeMinutes.type = "text";
- startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][0]));
+ startTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[0]));
startTimeMinutes.style.width = "45px";
let startTimeSeconds = document.createElement("input");
startTimeSeconds.id = "startTimeSeconds" + index;
startTimeSeconds.className = "sponsorTime popupElement";
startTimeSeconds.type = "text";
- startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][0]);
+ startTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[0]);
startTimeSeconds.style.width = "60px";
let endTimeMinutes = document.createElement("input");
endTimeMinutes.id = "endTimeMinutes" + index;
endTimeMinutes.className = "sponsorTime popupElement";
endTimeMinutes.type = "text";
- endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index][1]));
+ endTimeMinutes.value = String(getTimeInMinutes(sponsorTimes[index].segment[1]));
endTimeMinutes.style.width = "45px";
let endTimeSeconds = document.createElement("input");
endTimeSeconds.id = "endTimeSeconds" + index;
endTimeSeconds.className = "sponsorTime popupElement";
endTimeSeconds.type = "text";
- endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index][1]);
+ endTimeSeconds.value = getTimeInFormattedSeconds(sponsorTimes[index].segment[1]);
endTimeSeconds.style.width = "60px";
//the button to set the current time
@@ -668,11 +672,11 @@ async function runThePopup(messageListener?: MessageListener) {
}
function saveSponsorTimeEdit(index, closeEditMode = true) {
- sponsorTimes[index][0] = getSponsorTimeEditTimes("startTime", index);
- sponsorTimes[index][1] = getSponsorTimeEditTimes("endTime", index);
+ sponsorTimes[index].segment[0] = getSponsorTimeEditTimes("startTime", index);
+ sponsorTimes[index].segment[1] = getSponsorTimeEditTimes("endTime", index);
//save this
- Config.config.sponsorTimes.set(currentVideoID, sponsorTimes);
+ Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
messageHandler.query({
active: true,
@@ -692,7 +696,7 @@ async function runThePopup(messageListener?: MessageListener) {
//deletes the sponsor time submitted at an index
function deleteSponsorTime(index) {
//if it is not a complete sponsor time
- if (sponsorTimes[index].length < 2) {
+ if (sponsorTimes[index].segment.length < 2) {
messageHandler.query({
active: true,
currentWindow: true
@@ -710,7 +714,7 @@ async function runThePopup(messageListener?: MessageListener) {
sponsorTimes.splice(index, 1);
//save this
- Config.config.sponsorTimes.set(currentVideoID, sponsorTimes);
+ Config.config.segmentTimes.set(currentVideoID, sponsorTimes);
//if they are all removed
if (sponsorTimes.length == 0) {
@@ -780,7 +784,7 @@ async function runThePopup(messageListener?: MessageListener) {
//hides and shows the submit times button when needed
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) {
+ if (sponsorTimes.length > 0 && sponsorTimes[sponsorTimes.length - 1].segment.length > 1) {
//show submit times button
document.getElementById("submitTimesContainer").style.display = "unset";
} else {
diff --git a/src/utils.ts b/src/utils.ts
index db766772..ceaefeda 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -350,6 +350,10 @@ class Utils {
return formatted;
}
+ shortCategoryName(categoryName: string): string {
+ return chrome.i18n.getMessage("category_" + categoryName + "_short") || chrome.i18n.getMessage("category_" + categoryName);
+ }
+
getRawSeconds(minutes: number, seconds: number): number {
return minutes * 60 + seconds;
}