aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2021-01-17 14:46:27 -0500
committerGitHub <[email protected]>2021-01-17 14:46:27 -0500
commitd2f377c8d745c5c8f4e2ede2ea7b930cb4d1c670 (patch)
tree4bfe3793a7d0fd2ac53859a53e2b8c4d1b14ea7f
parente32a251ef374c1dbffb9f36b0fa0349898089bec (diff)
parent551355d21a0e45552be7e9c2bfab2b918a298943 (diff)
downloadSponsorBlock-d2f377c8d745c5c8f4e2ede2ea7b930cb4d1c670.tar.gz
SponsorBlock-d2f377c8d745c5c8f4e2ede2ea7b930cb4d1c670.zip
Merge pull request #622 from ajayyy/fix-unsubmitted-list
Improvements
-rw-r--r--manifest/manifest.json1
-rw-r--r--public/_locales/en/messages.json12
-rw-r--r--public/options/options.html38
-rw-r--r--src/background.ts10
-rw-r--r--src/components/NoticeComponent.tsx45
-rw-r--r--src/components/SkipNoticeComponent.tsx52
-rw-r--r--src/config.ts16
-rw-r--r--src/content.ts88
-rw-r--r--src/render/SkipNotice.tsx11
-rw-r--r--src/types.ts48
10 files changed, 164 insertions, 157 deletions
diff --git a/manifest/manifest.json b/manifest/manifest.json
index 7f60599f..c25f2275 100644
--- a/manifest/manifest.json
+++ b/manifest/manifest.json
@@ -46,7 +46,6 @@
],
"permissions": [
"storage",
- "notifications",
"https://sponsor.ajay.app/*"
],
"optional_permissions": [
diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json
index 5f92d260..d631d2cc 100644
--- a/public/_locales/en/messages.json
+++ b/public/_locales/en/messages.json
@@ -97,9 +97,6 @@
"wantToSubmit": {
"message": "Do you want to submit for video id"
},
- "leftTimes": {
- "message": "You seem to have left some segments unsubmitted. Go back to that page to submit them (they are not deleted)."
- },
"clearTimes": {
"message": "Clear Segments"
},
@@ -235,6 +232,9 @@
"message": "If you still don't like it, hit the never show button.",
"description": "The second line of the message displayed after the notice was upgraded."
},
+ "setSkipShortcut": {
+ "message": "Set key for skipping a segment"
+ },
"setStartSponsorShortcut": {
"message": "Set key for start segment keybind"
},
@@ -631,12 +631,6 @@
"categoryUpdate2": {
"message": "Open the options to skip intros, outros, merch, etc."
},
- "unsubmittedWarning": {
- "message": "Unsubmitted Segments Notification"
- },
- "unsubmittedWarningDescription": {
- "message": "Send a notification when you leave a video with segments that are not uploaded"
- },
"help": {
"message": "Help"
}
diff --git a/public/options/options.html b/public/options/options.html
index 04620a9e..5907c07b 100644
--- a/public/options/options.html
+++ b/public/options/options.html
@@ -83,6 +83,27 @@
<br/>
<br/>
+
+ <div option-type="keybind-change" sync-option="skipKeybind">
+ <div class="option-button trigger-button">
+ __MSG_setSkipShortcut__
+ </div>
+
+ <div class="option-hidden-section hidden">
+ <br/>
+
+ <div class="medium-description keybind-status">
+ __MSG_keybindDescription__
+ </div>
+
+ <span class="medium-description bold keybind-status-key">
+
+ </span>
+ </div>
+ </div>
+
+ <br/>
+ <br/>
<div option-type="keybind-change" sync-option="startSponsorKeybind">
<div class="option-button trigger-button">
@@ -152,23 +173,6 @@
<br/>
<br/>
- <div option-type="toggle" sync-option="unsubmittedWarning">
- <label class="switch-container" label-name="__MSG_unsubmittedWarning__">
- <label class="switch">
- <input type="checkbox" checked>
- <span class="slider round"></span>
- </label>
- </label>
-
- <br/>
- <br/>
-
- <div class="small-description">__MSG_unsubmittedWarningDescription__</div>
- </div>
-
- <br/>
- <br/>
-
<div option-type="toggle" sync-option="forceChannelCheck">
<label class="switch-container" label-name="__MSG_forceChannelCheck__">
<label class="switch">
diff --git a/src/background.ts b/src/background.ts
index e9643667..ea011576 100644
--- a/src/background.ts
+++ b/src/background.ts
@@ -52,16 +52,6 @@ chrome.runtime.onMessage.addListener(function (request, sender, callback) {
//this allows the callback to be called later
return true;
- case "alertPrevious":
- if (Config.config.unsubmittedWarning) {
- chrome.notifications.create("stillThere" + Math.random(), {
- type: "basic",
- title: chrome.i18n.getMessage("wantToSubmit") + " " + request.previousVideoID + "?",
- message: chrome.i18n.getMessage("leftTimes"),
- iconUrl: "./icons/LogoSponsorBlocker256px.png"
- });
- }
- break;
case "registerContentScript":
registerFirefoxContentScript(request);
return false;
diff --git a/src/components/NoticeComponent.tsx b/src/components/NoticeComponent.tsx
index 9fff3be4..3867fa0a 100644
--- a/src/components/NoticeComponent.tsx
+++ b/src/components/NoticeComponent.tsx
@@ -8,6 +8,8 @@ export interface NoticeProps {
timed?: boolean,
idSuffix?: string,
+ videoSpeed?: () => number,
+
fadeIn?: boolean,
// Callback for when this is closed
@@ -19,7 +21,7 @@ export interface NoticeProps {
export interface NoticeState {
noticeTitle: string,
- maxCountdownTime?: () => number,
+ maxCountdownTime: () => number,
countdownTime: number,
countdownText: string,
@@ -28,6 +30,8 @@ export interface NoticeState {
class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownInterval: NodeJS.Timeout;
+ intervalVideoSpeed: number;
+
idSuffix: string;
amountOfPreviousNotices: number;
@@ -71,7 +75,9 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
return (
<table id={"sponsorSkipNotice" + this.idSuffix}
- className={"sponsorSkipObject sponsorSkipNotice" + (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")}
+ className={"sponsorSkipObject sponsorSkipNotice"
+ + (this.props.fadeIn ? " sponsorSkipNoticeFadeIn" : "")
+ + (this.amountOfPreviousNotices > 0 ? " secondSkipNotice" : "")}
style={noticeStyle}
onMouseEnter={() => this.timerMouseEnter()}
onMouseLeave={() => this.timerMouseLeave()}>
@@ -152,7 +158,11 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdown(): void {
if (!this.props.timed) return;
- const countdownTime = this.state.countdownTime - 1;
+ const countdownTime = Math.min(this.state.countdownTime - 1, this.state.maxCountdownTime());
+
+ if (this.props.videoSpeed && this.intervalVideoSpeed != this.props.videoSpeed()) {
+ this.setupInterval();
+ }
if (countdownTime <= 0) {
//remove this from setInterval
@@ -175,12 +185,19 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownTime
})
}
+
+ removeFadeAnimation(): void {
+ //remove the fade out class if it exists
+ const notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
+ notice.classList.remove("sponsorSkipNoticeFadeOut");
+ notice.style.animation = "none";
+ }
pauseCountdown(): void {
if (!this.props.timed) return;
//remove setInterval
- clearInterval(this.countdownInterval);
+ if (this.countdownInterval) clearInterval(this.countdownInterval);
this.countdownInterval = null;
//reset countdown and inform the user
@@ -189,10 +206,7 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownText: this.state.countdownManuallyPaused ? chrome.i18n.getMessage("manualPaused") : chrome.i18n.getMessage("paused")
});
- //remove the fade out class if it exists
- const notice = document.getElementById("sponsorSkipNotice" + this.idSuffix);
- notice.classList.remove("sponsorSkipNoticeFadeOut");
- notice.style.animation = "none";
+ this.removeFadeAnimation();
}
startCountdown(): void {
@@ -206,16 +220,29 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
countdownText: null
});
- this.countdownInterval = setInterval(this.countdown.bind(this), 1000);
+ this.setupInterval();
+ }
+
+ setupInterval(): void {
+ if (this.countdownInterval) clearInterval(this.countdownInterval);
+
+ const intervalDuration = this.props.videoSpeed ? 1000 / this.props.videoSpeed() : 1000;
+ this.countdownInterval = setInterval(this.countdown.bind(this), intervalDuration);
+
+ if (this.props.videoSpeed) this.intervalVideoSpeed = this.props.videoSpeed();
}
resetCountdown(): void {
if (!this.props.timed) return;
+ this.setupInterval();
+
this.setState({
countdownTime: this.state.maxCountdownTime(),
countdownText: null
});
+
+ this.removeFadeAnimation();
}
/**
diff --git a/src/components/SkipNoticeComponent.tsx b/src/components/SkipNoticeComponent.tsx
index aa75a587..b4f31932 100644
--- a/src/components/SkipNoticeComponent.tsx
+++ b/src/components/SkipNoticeComponent.tsx
@@ -5,7 +5,7 @@ import { ContentContainer, SponsorHideType, SponsorTime } from "../types";
import NoticeComponent from "./NoticeComponent";
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
-enum SkipNoticeAction {
+export enum SkipNoticeAction {
None,
Upvote,
Downvote,
@@ -24,23 +24,23 @@ export interface SkipNoticeProps {
}
export interface SkipNoticeState {
- noticeTitle: string;
+ noticeTitle?: string;
- messages: string[];
- messageOnClick: (event: React.MouseEvent) => unknown;
+ messages?: string[];
+ messageOnClick?: (event: React.MouseEvent) => unknown;
- countdownTime: number;
- maxCountdownTime: () => number;
- countdownText: string;
+ countdownTime?: number;
+ maxCountdownTime?: () => number;
+ countdownText?: string;
- unskipText: string;
- unskipCallback: (index: number) => void;
+ unskipText?: string;
+ unskipCallback?: (index: number) => void;
- downvoting: boolean;
- choosingCategory: boolean;
- thanksForVotingText: string; //null until the voting buttons should be hidden
+ downvoting?: boolean;
+ choosingCategory?: boolean;
+ thanksForVotingText?: string; //null until the voting buttons should be hidden
- actionState: SkipNoticeAction;
+ actionState?: SkipNoticeAction;
}
class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeState> {
@@ -91,13 +91,6 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
}
this.idSuffix += this.amountOfPreviousNotices;
- if (this.amountOfPreviousNotices > 0) {
- //another notice exists
-
- const previousNotice = document.getElementsByClassName("sponsorSkipNotice")[0];
- previousNotice.classList.add("secondSkipNotice")
- }
-
// Setup state
this.state = {
noticeTitle,
@@ -148,6 +141,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
fadeIn={true}
timed={true}
maxCountdownTime={this.state.maxCountdownTime}
+ videoSpeed={() => this.contentContainer().v?.playbackRate}
ref={this.noticeRef}
closeListener={() => this.closeListener()}>
@@ -203,7 +197,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
style={{marginLeft: "4px"}}
onClick={() => this.prepAction(SkipNoticeAction.Unskip)}>
- {this.state.unskipText}
+ {this.state.unskipText + " (" + Config.config.skipKeybind + ")"}
</button>
</td>
@@ -463,21 +457,23 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
reskip(index: number): void {
this.contentContainer().reskipSponsorTime(this.segments[index]);
- //reset countdown
- this.setState({
+ const newState: SkipNoticeState = {
unskipText: chrome.i18n.getMessage("unskip"),
unskipCallback: this.unskip.bind(this),
maxCountdownTime: () => 4,
countdownTime: 4
- });
+ };
// See if the title should be changed
if (!this.autoSkip) {
- this.setState({
- noticeTitle: chrome.i18n.getMessage("noticeTitle")
- });
- }
+ newState.noticeTitle = chrome.i18n.getMessage("noticeTitle");
+ }
+
+ //reset countdown
+ this.setState(newState, () => {
+ this.noticeRef.current.resetCountdown();
+ });
}
afterVote(segment: SponsorTime, type: number, category: string): void {
diff --git a/src/config.ts b/src/config.ts
index 2a40dbf6..5723db12 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,5 +1,5 @@
import * as CompileConfig from "../config.json";
-import { CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime, StorageChangesObject } from "./types";
+import { CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime, StorageChangesObject, UnEncodedSegmentTimes as UnencodedSegmentTimes } from "./types";
import Utils from "./utils";
const utils = new Utils();
@@ -10,6 +10,7 @@ interface SBConfig {
defaultCategory: string,
whitelistedChannels: string[],
forceChannelCheck: boolean,
+ skipKeybind: string,
startSponsorKeybind: string,
submitKeybind: string,
minutesSaved: number,
@@ -17,7 +18,6 @@ interface SBConfig {
sponsorTimesContributed: number,
submissionCountSinceCategories: number, // New count used to show the "Read The Guidelines!!" message
showTimeWithSkips: boolean,
- unsubmittedWarning: boolean,
disableSkipping: boolean,
trackViewCount: boolean,
dontShowNotice: boolean,
@@ -65,7 +65,7 @@ export interface SBObject {
config: SBConfig;
// Functions
- encodeStoredItem<T>(data: T): T | Array<any>;
+ encodeStoredItem<T>(data: T): T | UnencodedSegmentTimes;
convertJSON(): void;
}
@@ -143,6 +143,7 @@ const Config: SBObject = {
defaultCategory: "chooseACategory",
whitelistedChannels: [],
forceChannelCheck: false,
+ skipKeybind: "Enter",
startSponsorKeybind: ";",
submitKeybind: "'",
minutesSaved: 0,
@@ -150,7 +151,6 @@ const Config: SBObject = {
sponsorTimesContributed: 0,
submissionCountSinceCategories: 0,
showTimeWithSkips: true,
- unsubmittedWarning: true,
disableSkipping: false,
trackViewCount: true,
dontShowNotice: false,
@@ -247,10 +247,10 @@ const Config: SBObject = {
*
* @param data
*/
-function encodeStoredItem<T>(data: T): T | Array<any> {
+function encodeStoredItem<T>(data: T): T | UnencodedSegmentTimes {
// if data is SBMap convert to json for storing
if(!(data instanceof SBMap)) return data;
- return Array.from(data.entries());
+ return Array.from(data.entries()).filter((element) => element[1] === []); // Remove empty entries
}
/**
@@ -265,7 +265,7 @@ function decodeStoredItem<T>(id: string, data: T): T | SBMap<string, SponsorTime
if (Config.defaults[id] instanceof SBMap) {
try {
if (!Array.isArray(data)) return data;
- return new SBMap(id, data);
+ return new SBMap(id, data as UnencodedSegmentTimes);
} catch(e) {
console.error("Failed to parse SBMap: " + id);
}
@@ -395,7 +395,7 @@ function migrateOldFormats(config: SBConfig) {
// Migrate old "sponsorTimes"
if (config["sponsorTimes"]) {
- let jsonData: any = config["sponsorTimes"];
+ let jsonData: unknown = config["sponsorTimes"];
// Check if data is stored in the old format for SBMap (a JSON string)
if (typeof jsonData === "string") {
diff --git a/src/content.ts b/src/content.ts
index aba53f24..9e9332e6 100644
--- a/src/content.ts
+++ b/src/content.ts
@@ -19,11 +19,12 @@ utils.wait(() => Config.config !== null, 5000, 10).then(addCSS);
//was sponsor data found when doing SponsorsLookup
let sponsorDataFound = false;
-let previousVideoID: VideoID = null;
//the actual sponsorTimes if loaded and UUIDs associated with them
let sponsorTimes: SponsorTime[] = null;
//what video id are these sponsors for
let sponsorVideoID: VideoID = null;
+// List of open skip notices
+const skipNotices: SkipNotice[] = [];
// JSON video info
let videoInfo: VideoInfo = null;
@@ -36,11 +37,13 @@ let channelID: string;
let currentSkipSchedule: NodeJS.Timeout = null;
let seekListenerSetUp = false
-/** @type {Array[boolean]} Has the sponsor been skipped */
+/** Has the sponsor been skipped */
let sponsorSkipped: boolean[] = [];
//the video
let video: HTMLVideoElement;
+// List of videos that have had event listeners added to them
+const videoRootsWithEventListeners: HTMLDivElement[] = [];
let onInvidious;
let onMobileYouTube;
@@ -100,6 +103,7 @@ const skipNoticeContentContainer: ContentContainer = () => ({
unskipSponsorTime,
sponsorTimes,
sponsorTimesSubmitting,
+ skipNotices,
v: video,
sponsorVideoID,
reskipSponsorTime,
@@ -198,28 +202,6 @@ if (!Config.configListeners.includes(contentConfigUpdateListener)) {
Config.configListeners.push(contentConfigUpdateListener);
}
-//check for hotkey pressed
-document.onkeydown = function(e: KeyboardEvent){
- const key = e.key;
-
- const video = document.getElementById("movie_player");
-
- const startSponsorKey = Config.config.startSponsorKeybind;
-
- const submitKey = Config.config.submitKeybind;
-
- //is the video in focus, otherwise they could be typing a comment
- if (document.activeElement === video) {
- if(key == startSponsorKey){
- //semicolon
- startSponsorClicked();
- } else if (key == submitKey) {
- //single quote
- submitSponsorTimes();
- }
- }
-}
-
function resetValues() {
lastCheckTime = 0;
lastCheckVideoTime = -1;
@@ -310,25 +292,6 @@ async function videoIDChange(id) {
}
}
- //warn them if they had unsubmitted times
- if (previousVideoID != null) {
- //get the sponsor times from storage
- const sponsorTimes = Config.config.segmentTimes.get(previousVideoID);
- if (sponsorTimes != undefined && sponsorTimes.length > 0 && new URL(document.URL).host !== "music.youtube.com") {
- //warn them that they have unsubmitted sponsor times
- chrome.runtime.sendMessage({
- message: "alertPrevious",
- previousVideoID: previousVideoID
- });
- }
-
- //set the previous video id to the currentID
- previousVideoID = id;
- } else {
- //set the previous id now, don't wait for chrome.storage.get
- previousVideoID = id;
- }
-
//close popup
closeInfoMenu();
@@ -532,6 +495,8 @@ async function sponsorsLookup(id: string) {
return;
}
+ addHotkeyListener();
+
if (!durationListenerSetUp) {
durationListenerSetUp = true;
@@ -1016,7 +981,7 @@ function skipToTime(v: HTMLVideoElement, skipTime: number[], skippingSegments: S
if (openNotice) {
//send out the message saying that a sponsor message was skipped
if (!Config.config.dontShowNotice || !autoSkip) {
- new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer);
+ skipNotices.push(new SkipNotice(skippingSegments, autoSkip, skipNoticeContentContainer));
}
}
@@ -1562,6 +1527,41 @@ function getSegmentsMessage(sponsorTimes: SponsorTime[]): string {
return sponsorTimesMessage;
}
+function addHotkeyListener(): boolean {
+ const videoRoot = document.getElementById("movie_player") as HTMLDivElement;
+
+ if (!videoRootsWithEventListeners.includes(videoRoot)) {
+ videoRoot.addEventListener("keydown", hotkeyListener);
+ videoRootsWithEventListeners.push(videoRoot);
+ return true;
+ }
+
+ return false;
+}
+
+function hotkeyListener(e: KeyboardEvent): void {
+ const key = e.key;
+
+ const skipKey = Config.config.skipKeybind;
+ const startSponsorKey = Config.config.startSponsorKeybind;
+ const submitKey = Config.config.submitKeybind;
+
+ switch (key) {
+ case skipKey:
+ if (skipNotices.length > 0) {
+ const latestSkipNotice = skipNotices[skipNotices.length - 1];
+ latestSkipNotice.toggleSkip.call(latestSkipNotice);
+ }
+ break;
+ case startSponsorKey:
+ startSponsorClicked();
+ break;
+ case submitKey:
+ submitSponsorTimes();
+ break;
+ }
+}
+
/**
* Is this an unlisted YouTube video.
* Assumes that the the privacy info is available.
diff --git a/src/render/SkipNotice.tsx b/src/render/SkipNotice.tsx
index ac66cae4..526d2d1c 100644
--- a/src/render/SkipNotice.tsx
+++ b/src/render/SkipNotice.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as ReactDOM from "react-dom";
-import SkipNoticeComponent from "../components/SkipNoticeComponent";
+import SkipNoticeComponent, { SkipNoticeAction } from "../components/SkipNoticeComponent";
import { SponsorTime, ContentContainer } from "../types";
class SkipNotice {
@@ -15,6 +15,8 @@ class SkipNotice {
skipNoticeRef: React.MutableRefObject<SkipNoticeComponent>;
constructor(segments: SponsorTime[], autoSkip = false, contentContainer: ContentContainer) {
+ this.skipNoticeRef = React.createRef();
+
this.segments = segments;
this.autoSkip = autoSkip;
this.contentContainer = contentContainer;
@@ -67,6 +69,13 @@ class SkipNotice {
ReactDOM.unmountComponentAtNode(this.noticeElement);
this.noticeElement.remove();
+
+ const skipNotices = this.contentContainer().skipNotices;
+ skipNotices.splice(skipNotices.indexOf(this), 1);
+ }
+
+ toggleSkip(): void {
+ this.skipNoticeRef.current.prepAction(SkipNoticeAction.Unskip);
}
}
diff --git a/src/types.ts b/src/types.ts
index 64afe352..dd870f37 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,13 +1,15 @@
import SubmissionNotice from "./render/SubmissionNotice";
import SkipNoticeComponent from "./components/SkipNoticeComponent";
+import SkipNotice from "./render/SkipNotice";
-interface ContentContainer {
+export interface ContentContainer {
(): {
vote: (type: number, UUID: string, category?: string, skipNotice?: SkipNoticeComponent) => void,
dontShowNoticeAgain: () => void,
unskipSponsorTime: (segment: SponsorTime) => void,
sponsorTimes: SponsorTime[],
sponsorTimesSubmitting: SponsorTime[],
+ skipNotices: SkipNotice[],
v: HTMLVideoElement,
sponsorVideoID,
reskipSponsorTime: (segment: SponsorTime) => void,
@@ -22,34 +24,34 @@ interface ContentContainer {
}
}
-interface FetchResponse {
+export interface FetchResponse {
responseText: string,
status: number,
ok: boolean
}
-interface VideoDurationResponse {
+export interface VideoDurationResponse {
duration: number;
}
-enum CategorySkipOption {
+export enum CategorySkipOption {
ShowOverlay,
ManualSkip,
AutoSkip
}
-interface CategorySelection {
+export interface CategorySelection {
name: string;
option: CategorySkipOption
}
-enum SponsorHideType {
+export enum SponsorHideType {
Visible = undefined,
Downvoted = 1,
MinimumDuration
}
-interface SponsorTime {
+export interface SponsorTime {
segment: number[];
UUID: string;
@@ -58,13 +60,13 @@ interface SponsorTime {
hidden?: SponsorHideType;
}
-interface PreviewBarOption {
+export interface PreviewBarOption {
color: string,
opacity: string
}
-interface Registration {
+export interface Registration {
message: string,
id: string,
allFrames: boolean,
@@ -73,12 +75,12 @@ interface Registration {
matches: string[]
}
-interface BackgroundScriptContainer {
+export interface BackgroundScriptContainer {
registerFirefoxContentScript: (opts: Registration) => void,
unregisterFirefoxContentScript: (id: string) => void
}
-interface VideoInfo {
+export interface VideoInfo {
responseContext: {
serviceTrackingParams: Array<{service: string, params: Array<{key: string, value: string}>}>,
webResponseContextExtensionData: {
@@ -154,22 +156,8 @@ interface VideoInfo {
messages: unknown;
}
-type VideoID = string;
-
-type StorageChangesObject = { [key: string]: chrome.storage.StorageChange };
-
-export {
- FetchResponse,
- VideoDurationResponse,
- ContentContainer,
- CategorySelection,
- CategorySkipOption,
- SponsorTime,
- VideoID,
- SponsorHideType,
- PreviewBarOption,
- Registration,
- BackgroundScriptContainer,
- VideoInfo,
- StorageChangesObject,
-};
+export type VideoID = string;
+
+export type StorageChangesObject = { [key: string]: chrome.storage.StorageChange };
+
+export type UnEncodedSegmentTimes = [string, SponsorTime[]][]; \ No newline at end of file