mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-24 08:28:31 +03:00
@@ -46,7 +46,6 @@
|
||||
],
|
||||
"permissions": [
|
||||
"storage",
|
||||
"notifications",
|
||||
"https://sponsor.ajay.app/*"
|
||||
],
|
||||
"optional_permissions": [
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -81,6 +81,27 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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/>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
44
src/types.ts
44
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;
|
||||
export type VideoID = string;
|
||||
|
||||
type StorageChangesObject = { [key: string]: chrome.storage.StorageChange };
|
||||
export type StorageChangesObject = { [key: string]: chrome.storage.StorageChange };
|
||||
|
||||
export {
|
||||
FetchResponse,
|
||||
VideoDurationResponse,
|
||||
ContentContainer,
|
||||
CategorySelection,
|
||||
CategorySkipOption,
|
||||
SponsorTime,
|
||||
VideoID,
|
||||
SponsorHideType,
|
||||
PreviewBarOption,
|
||||
Registration,
|
||||
BackgroundScriptContainer,
|
||||
VideoInfo,
|
||||
StorageChangesObject,
|
||||
};
|
||||
export type UnEncodedSegmentTimes = [string, SponsorTime[]][];
|
||||
Reference in New Issue
Block a user