mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-08 12:37:05 +03:00
Add submitting for highlight category
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
"serverAddress": "https://sponsor.ajay.app",
|
||||
"testingServerAddress": "https://sponsor.ajay.app/test",
|
||||
"serverAddressComment": "This specifies the default SponsorBlock server to connect to",
|
||||
"categoryList": ["sponsor", "selfpromo", "interaction", "intro", "outro", "preview", "music_offtopic"]
|
||||
"categoryList": ["sponsor", "selfpromo", "interaction", "intro", "outro", "preview", "music_offtopic", "highlight"]
|
||||
}
|
||||
|
||||
@@ -335,9 +335,6 @@
|
||||
"createdBy": {
|
||||
"message": "Created By"
|
||||
},
|
||||
"autoSkip": {
|
||||
"message": "Auto Skip"
|
||||
},
|
||||
"showSkipNotice": {
|
||||
"message": "Show Notice After A Segment Is Skipped"
|
||||
},
|
||||
@@ -534,14 +531,20 @@
|
||||
"category_music_offtopic_short": {
|
||||
"message": "Non-Music"
|
||||
},
|
||||
"category_highlight": {
|
||||
"message": "Highlight"
|
||||
},
|
||||
"category_highlight_description": {
|
||||
"message": "The part of the video that most people are looking for. Similar to \"Video starts at x\" comments."
|
||||
},
|
||||
"category_livestream_messages": {
|
||||
"message": "Livestream: Donation/Message Readings"
|
||||
},
|
||||
"category_livestream_messages_short": {
|
||||
"message": "Message Reading"
|
||||
},
|
||||
"disable": {
|
||||
"message": "Disable"
|
||||
"autoSkip": {
|
||||
"message": "Auto Skip"
|
||||
},
|
||||
"manualSkip": {
|
||||
"message": "Manual Skip"
|
||||
@@ -549,6 +552,18 @@
|
||||
"showOverlay": {
|
||||
"message": "Show In Seek Bar"
|
||||
},
|
||||
"disable": {
|
||||
"message": "Disable"
|
||||
},
|
||||
"autoSkip_POI": {
|
||||
"message": "Auto skip to the start"
|
||||
},
|
||||
"manualSkip_POI": {
|
||||
"message": "Ask when video loads"
|
||||
},
|
||||
"showOverlay_POI": {
|
||||
"message": "Show In Seek Bar"
|
||||
},
|
||||
"colorFormatIncorrect": {
|
||||
"message": "Your color is formatted incorrectly. It should be a 3 or 6 digit hex code with a number sign at the beginning."
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from "react";
|
||||
|
||||
import * as CompileConfig from "../../config.json";
|
||||
import { Category } from "../types";
|
||||
import CategorySkipOptionsComponent from "./CategorySkipOptionsComponent";
|
||||
|
||||
export interface CategoryChooserProps {
|
||||
@@ -58,7 +59,7 @@ class CategoryChooserComponent extends React.Component<CategoryChooserProps, Cat
|
||||
|
||||
for (const category of CompileConfig.categoryList) {
|
||||
elements.push(
|
||||
<CategorySkipOptionsComponent category={category}
|
||||
<CategorySkipOptionsComponent category={category as Category}
|
||||
key={category}>
|
||||
</CategorySkipOptionsComponent>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import * as React from "react";
|
||||
|
||||
import Config from "../config"
|
||||
import { CategorySkipOption } from "../types";
|
||||
import { Category, CategorySkipOption } from "../types";
|
||||
|
||||
import Utils from "../utils";
|
||||
const utils = new Utils();
|
||||
|
||||
export interface CategorySkipOptionsProps {
|
||||
category: string;
|
||||
category: Category;
|
||||
defaultColor?: string;
|
||||
defaultPreviewColor?: string;
|
||||
}
|
||||
@@ -146,10 +149,13 @@ class CategorySkipOptionsComponent extends React.Component<CategorySkipOptionsPr
|
||||
|
||||
const optionNames = ["disable", "showOverlay", "manualSkip", "autoSkip"];
|
||||
|
||||
console.log(utils.getCategoryActionType(this.props.category))
|
||||
|
||||
for (const optionName of optionNames) {
|
||||
elements.push(
|
||||
<option key={optionName} value={optionName}>
|
||||
{chrome.i18n.getMessage(optionName)}
|
||||
{chrome.i18n.getMessage(optionName !== "disable" ? optionName + utils.getCategoryActionType(this.props.category)
|
||||
: optionName)}
|
||||
</option>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import * as React from "react";
|
||||
import * as CompileConfig from "../../config.json";
|
||||
import Config from "../config"
|
||||
import { ContentContainer, SponsorHideType, SponsorTime } from "../types";
|
||||
import { Category, ContentContainer, CategoryActionType, SponsorHideType, SponsorTime } from "../types";
|
||||
import NoticeComponent from "./NoticeComponent";
|
||||
import NoticeTextSelectionComponent from "./NoticeTextSectionComponent";
|
||||
|
||||
import Utils from "../utils";
|
||||
const utils = new Utils();
|
||||
|
||||
export enum SkipNoticeAction {
|
||||
None,
|
||||
Upvote,
|
||||
@@ -342,7 +345,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||
this.contentContainer().vote(0, this.segments[index].UUID, undefined, this);
|
||||
break;
|
||||
case SkipNoticeAction.CategoryVote:
|
||||
this.contentContainer().vote(undefined, this.segments[index].UUID, this.categoryOptionRef.current.value, this)
|
||||
this.contentContainer().vote(undefined, this.segments[index].UUID, this.categoryOptionRef.current.value as Category, this)
|
||||
break;
|
||||
case SkipNoticeAction.Unskip:
|
||||
this.state.unskipCallback(index);
|
||||
@@ -389,7 +392,8 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||
getCategoryOptions(): React.ReactElement[] {
|
||||
const elements = [];
|
||||
|
||||
for (const category of Config.config.categorySelections) {
|
||||
const categories = Config.config.categorySelections.filter((cat => utils.getCategoryActionType(cat.name as Category) === CategoryActionType.Skippable));
|
||||
for (const category of categories) {
|
||||
elements.push(
|
||||
<option value={category.name}
|
||||
key={category.name}>
|
||||
@@ -476,7 +480,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||
});
|
||||
}
|
||||
|
||||
afterVote(segment: SponsorTime, type: number, category: string): void {
|
||||
afterVote(segment: SponsorTime, type: number, category: Category): void {
|
||||
this.addVoteButtonInfo(chrome.i18n.getMessage("voted"));
|
||||
|
||||
if (type === 0) {
|
||||
|
||||
@@ -4,7 +4,7 @@ import Config from "../config";
|
||||
import * as CompileConfig from "../../config.json";
|
||||
|
||||
import Utils from "../utils";
|
||||
import { ContentContainer, SponsorTime } from "../types";
|
||||
import { Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
|
||||
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";
|
||||
const utils = new Utils();
|
||||
|
||||
@@ -16,6 +16,7 @@ export interface SponsorTimeEditProps {
|
||||
contentContainer: ContentContainer,
|
||||
|
||||
submissionNotice: SubmissionNoticeComponent;
|
||||
categoryList?: Category[];
|
||||
}
|
||||
|
||||
export interface SponsorTimeEditState {
|
||||
@@ -106,13 +107,15 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
onChange={(e) => {
|
||||
const sponsorTimeEdits = this.state.sponsorTimeEdits;
|
||||
sponsorTimeEdits[0] = e.target.value;
|
||||
if (utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTimeEdits[1] = e.target.value;
|
||||
|
||||
this.setState({sponsorTimeEdits});
|
||||
|
||||
this.saveEditTimes();
|
||||
}}>
|
||||
</input>
|
||||
|
||||
{utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable ? (
|
||||
<span>
|
||||
<span>
|
||||
{" " + chrome.i18n.getMessage("to") + " "}
|
||||
</span>
|
||||
@@ -143,6 +146,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
onClick={() => this.setTimeToEnd()}>
|
||||
{chrome.i18n.getMessage("bracketEnd")}
|
||||
</span>
|
||||
</span>
|
||||
): ""}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
@@ -151,7 +156,8 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
className="sponsorTimeDisplay"
|
||||
onClick={this.toggleEditTime.bind(this)}>
|
||||
{utils.getFormattedTime(segment[0], true) +
|
||||
((!isNaN(segment[1])) ? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
|
||||
((!isNaN(segment[1]) && utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable)
|
||||
? " " + chrome.i18n.getMessage("to") + " " + utils.getFormattedTime(segment[1], true) : "")}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -190,7 +196,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
{chrome.i18n.getMessage("delete")}
|
||||
</span>
|
||||
|
||||
{(!isNaN(segment[1])) ? (
|
||||
{(!isNaN(segment[1]) && utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.Skippable) ? (
|
||||
<span id={"sponsorTimePreviewButton" + this.idSuffix}
|
||||
className="sponsorTimeEditButton"
|
||||
onClick={this.previewTime.bind(this)}>
|
||||
@@ -225,7 +231,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
</option>
|
||||
)];
|
||||
|
||||
for (const category of CompileConfig.categoryList) {
|
||||
for (const category of (this.props.categoryList ?? CompileConfig.categoryList)) {
|
||||
elements.push(
|
||||
<option value={category}
|
||||
key={category}>
|
||||
@@ -253,6 +259,10 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
return;
|
||||
}
|
||||
|
||||
if (utils.getCategoryActionType(event.target.value as Category) === CategoryActionType.POI) {
|
||||
this.setTimeTo(1, null);
|
||||
}
|
||||
|
||||
this.saveEditTimes();
|
||||
}
|
||||
|
||||
@@ -264,11 +274,16 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
this.setTimeTo(1, this.props.contentContainer().v.duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index
|
||||
* @param time If null, will set time to the first index's time
|
||||
*/
|
||||
setTimeTo(index: number, time: number): void {
|
||||
const sponsorTime = this.props.contentContainer().sponsorTimesSubmitting[this.props.index];
|
||||
if (time === null) time = sponsorTime.segment[0];
|
||||
|
||||
sponsorTime.segment[index] =
|
||||
time;
|
||||
sponsorTime.segment[index] = time;
|
||||
if (utils.getCategoryActionType(sponsorTime.category) === CategoryActionType.POI) sponsorTime.segment[1] = time;
|
||||
|
||||
this.setState({
|
||||
sponsorTimeEdits: this.getFormattedSponsorTimesEdits(sponsorTime)
|
||||
@@ -312,7 +327,7 @@ class SponsorTimeEditComponent extends React.Component<SponsorTimeEditProps, Spo
|
||||
}
|
||||
}
|
||||
|
||||
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value;
|
||||
sponsorTimesSubmitting[this.props.index].category = this.categoryOptionRef.current.value as Category;
|
||||
|
||||
Config.config.segmentTimes.set(this.props.contentContainer().sponsorVideoID, sponsorTimesSubmitting);
|
||||
|
||||
|
||||
126
src/config.ts
126
src/config.ts
@@ -1,13 +1,10 @@
|
||||
import * as CompileConfig from "../config.json";
|
||||
import { CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime, StorageChangesObject, UnEncodedSegmentTimes as UnencodedSegmentTimes } from "./types";
|
||||
|
||||
import Utils from "./utils";
|
||||
const utils = new Utils();
|
||||
import { Category, CategorySelection, CategorySkipOption, PreviewBarOption, SponsorTime, StorageChangesObject, UnEncodedSegmentTimes as UnencodedSegmentTimes } from "./types";
|
||||
|
||||
interface SBConfig {
|
||||
userID: string,
|
||||
segmentTimes: SBMap<string, SponsorTime[]>,
|
||||
defaultCategory: string,
|
||||
defaultCategory: Category,
|
||||
whitelistedChannels: string[],
|
||||
forceChannelCheck: boolean,
|
||||
skipKeybind: string,
|
||||
@@ -57,6 +54,8 @@ interface SBConfig {
|
||||
"preview-preview": PreviewBarOption,
|
||||
"music_offtopic": PreviewBarOption,
|
||||
"preview-music_offtopic": PreviewBarOption,
|
||||
"highlight": PreviewBarOption,
|
||||
"preview-highlight": PreviewBarOption,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +141,7 @@ const Config: SBObject = {
|
||||
defaults: {
|
||||
userID: null,
|
||||
segmentTimes: new SBMap("segmentTimes"),
|
||||
defaultCategory: "chooseACategory",
|
||||
defaultCategory: "chooseACategory" as Category,
|
||||
whitelistedChannels: [],
|
||||
forceChannelCheck: false,
|
||||
skipKeybind: "Enter",
|
||||
@@ -173,7 +172,7 @@ const Config: SBObject = {
|
||||
refetchWhenNotFound: true,
|
||||
|
||||
categorySelections: [{
|
||||
name: "sponsor",
|
||||
name: "sponsor" as Category,
|
||||
option: CategorySkipOption.AutoSkip
|
||||
}],
|
||||
|
||||
@@ -238,6 +237,14 @@ const Config: SBObject = {
|
||||
"preview-music_offtopic": {
|
||||
color: "#a6634a",
|
||||
opacity: "0.7"
|
||||
},
|
||||
"highlight": {
|
||||
color: "#ff1684",
|
||||
opacity: "0.7"
|
||||
},
|
||||
"preview-highlight": {
|
||||
color: "#9b044c",
|
||||
opacity: "0.7"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -334,108 +341,15 @@ function fetchConfig(): Promise<void> {
|
||||
}
|
||||
|
||||
function migrateOldFormats(config: SBConfig) {
|
||||
if (config["disableAutoSkip"]) {
|
||||
for (const selection of config.categorySelections) {
|
||||
if (selection.name === "sponsor") {
|
||||
selection.option = CategorySkipOption.ManualSkip;
|
||||
if (!config["highlightCategoryAdded"] && !config.categorySelections.some((s) => s.name === "highlight")) {
|
||||
config["highlightCategoryAdded"] = true;
|
||||
|
||||
chrome.storage.sync.remove("disableAutoSkip");
|
||||
}
|
||||
}
|
||||
}
|
||||
config.categorySelections.push({
|
||||
name: "highlight" as Category,
|
||||
option: CategorySkipOption.AutoSkip
|
||||
});
|
||||
|
||||
// Auto vote removal
|
||||
if (config["autoUpvote"]) {
|
||||
chrome.storage.sync.remove("autoUpvote");
|
||||
}
|
||||
// mobileUpdateShowCount removal
|
||||
if (config["mobileUpdateShowCount"] !== undefined) {
|
||||
chrome.storage.sync.remove("mobileUpdateShowCount");
|
||||
}
|
||||
// categoryUpdateShowCount removal
|
||||
if (config["categoryUpdateShowCount"] !== undefined) {
|
||||
chrome.storage.sync.remove("categoryUpdateShowCount");
|
||||
}
|
||||
|
||||
// Channel URLS
|
||||
if (config.whitelistedChannels.length > 0 &&
|
||||
(config.whitelistedChannels[0] == null || config.whitelistedChannels[0].includes("/"))) {
|
||||
const channelURLFixer = async() => {
|
||||
const 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
|
||||
const 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.whitelistedChannels = newChannelList;
|
||||
}
|
||||
|
||||
channelURLFixer();
|
||||
}
|
||||
|
||||
// Check if off-topic category needs to be removed
|
||||
for (let i = 0; i < config.categorySelections.length; i++) {
|
||||
if (config.categorySelections[i].name === "offtopic") {
|
||||
config.categorySelections.splice(i, 1);
|
||||
// Call set listener
|
||||
config.categorySelections = config.categorySelections;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate old "sponsorTimes"
|
||||
if (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") {
|
||||
try {
|
||||
jsonData = JSON.parse(jsonData);
|
||||
} catch(e) {
|
||||
// Continue normally (out of this if statement)
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise junk data
|
||||
if (Array.isArray(jsonData)) {
|
||||
const oldMap = new Map(jsonData);
|
||||
oldMap.forEach((sponsorTimes: number[][], key) => {
|
||||
const 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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Config from "./config";
|
||||
|
||||
import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, FetchResponse, VideoInfo, StorageChangesObject } from "./types";
|
||||
import { SponsorTime, CategorySkipOption, VideoID, SponsorHideType, FetchResponse, VideoInfo, StorageChangesObject, CategoryActionType, SegmentUUID, Category } from "./types";
|
||||
|
||||
import { ContentContainer } from "./types";
|
||||
import Utils from "./utils";
|
||||
@@ -691,14 +691,16 @@ function startSkipScheduleCheckingForStartSponsors() {
|
||||
// See if there are any starting sponsors
|
||||
let startingSponsor = -1;
|
||||
for (const time of sponsorTimes) {
|
||||
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime) {
|
||||
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime
|
||||
&& utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
||||
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) {
|
||||
if (time.segment[0] <= video.currentTime && time.segment[0] > startingSponsor && time.segment[1] > video.currentTime
|
||||
&& utils.getCategoryActionType(time.category) === CategoryActionType.Skippable) {
|
||||
startingSponsor = time.segment[0];
|
||||
break;
|
||||
}
|
||||
@@ -959,7 +961,8 @@ function getStartTimes(sponsorTimes: SponsorTime[], includeIntersectingSegments:
|
||||
|| ((includeNonIntersectingSegments && sponsorTimes[i].segment[0] >= minimum)
|
||||
|| (includeIntersectingSegments && sponsorTimes[i].segment[0] < minimum && sponsorTimes[i].segment[1] > minimum)))
|
||||
&& (!onlySkippableSponsors || utils.getCategorySelection(sponsorTimes[i].category).option !== CategorySkipOption.ShowOverlay)
|
||||
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)) {
|
||||
&& (!hideHiddenSponsors || sponsorTimes[i].hidden === SponsorHideType.Visible)
|
||||
&& utils.getCategoryActionType(sponsorTimes[i].category) === CategoryActionType.Skippable) {
|
||||
|
||||
startTimes.push(sponsorTimes[i].segment[0]);
|
||||
}
|
||||
@@ -1031,11 +1034,9 @@ function skipToTime(v: HTMLVideoElement, skipTime: number[], skippingSegments: S
|
||||
}
|
||||
|
||||
function unskipSponsorTime(segment: SponsorTime) {
|
||||
if (sponsorTimes != null) {
|
||||
//add a tiny bit of time to make sure it is not skipped again
|
||||
video.currentTime = segment.segment[0] + 0.001;
|
||||
}
|
||||
}
|
||||
|
||||
function reskipSponsorTime(segment: SponsorTime) {
|
||||
video.currentTime = segment.segment[1];
|
||||
@@ -1353,7 +1354,7 @@ function clearSponsorTimes() {
|
||||
}
|
||||
|
||||
//if skipNotice is null, it will not affect the UI
|
||||
function vote(type: number, UUID: string, category?: string, skipNotice?: SkipNoticeComponent) {
|
||||
function vote(type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent) {
|
||||
if (skipNotice !== null && skipNotice !== undefined) {
|
||||
//add loading info
|
||||
skipNotice.addVoteButtonInfo.bind(skipNotice)(chrome.i18n.getMessage("Loading"))
|
||||
|
||||
@@ -198,7 +198,7 @@ class PreviewBar {
|
||||
if (!this.onMobileYouTube) bar.style.opacity = Config.config.barTypes[barSegmentType].opacity;
|
||||
|
||||
bar.style.position = "absolute";
|
||||
bar.style.width = this.timeToPercentage(segment[1] - segment[0]);
|
||||
if (segment[1] - segment[0] > 0) bar.style.width = this.timeToPercentage(segment[1] - segment[0]);
|
||||
bar.style.left = this.timeToPercentage(segment[0]);
|
||||
|
||||
return bar;
|
||||
|
||||
18
src/types.ts
18
src/types.ts
@@ -4,7 +4,7 @@ import SkipNotice from "./render/SkipNotice";
|
||||
|
||||
export interface ContentContainer {
|
||||
(): {
|
||||
vote: (type: number, UUID: string, category?: string, skipNotice?: SkipNoticeComponent) => void,
|
||||
vote: (type: number, UUID: SegmentUUID, category?: Category, skipNotice?: SkipNoticeComponent) => void,
|
||||
dontShowNoticeAgain: () => void,
|
||||
unskipSponsorTime: (segment: SponsorTime) => void,
|
||||
sponsorTimes: SponsorTime[],
|
||||
@@ -41,7 +41,7 @@ export enum CategorySkipOption {
|
||||
}
|
||||
|
||||
export interface CategorySelection {
|
||||
name: string;
|
||||
name: Category;
|
||||
option: CategorySkipOption
|
||||
}
|
||||
|
||||
@@ -51,11 +51,19 @@ export enum SponsorHideType {
|
||||
MinimumDuration
|
||||
}
|
||||
|
||||
export enum CategoryActionType {
|
||||
Skippable = "", // Strings are used to find proper language configs
|
||||
POI = "_POI"
|
||||
}
|
||||
|
||||
export type SegmentUUID = string & { __segmentUUIDBrand: unknown };
|
||||
export type Category = string & { __categoryBrand: unknown };
|
||||
|
||||
export interface SponsorTime {
|
||||
segment: number[];
|
||||
UUID: string;
|
||||
UUID: SegmentUUID;
|
||||
|
||||
category: string;
|
||||
category: Category;
|
||||
|
||||
hidden?: SponsorHideType;
|
||||
}
|
||||
@@ -145,7 +153,7 @@ export interface VideoInfo {
|
||||
isUnlisted: boolean,
|
||||
hasYpcMetadata: boolean,
|
||||
viewCount: string,
|
||||
category: string,
|
||||
category: Category,
|
||||
publishDate: string,
|
||||
ownerChannelName: string,
|
||||
uploadDate: string,
|
||||
|
||||
11
src/utils.ts
11
src/utils.ts
@@ -1,5 +1,5 @@
|
||||
import Config from "./config";
|
||||
import { CategorySelection, SponsorTime, FetchResponse, BackgroundScriptContainer, Registration } from "./types";
|
||||
import { CategorySelection, SponsorTime, FetchResponse, BackgroundScriptContainer, Registration, Category, CategoryActionType } from "./types";
|
||||
|
||||
import * as CompileConfig from "../config.json";
|
||||
|
||||
@@ -43,6 +43,15 @@ export default class Utils {
|
||||
});
|
||||
}
|
||||
|
||||
getCategoryActionType(category: Category): CategoryActionType {
|
||||
switch (category) {
|
||||
case "highlight":
|
||||
return CategoryActionType.POI;
|
||||
default:
|
||||
return CategoryActionType.Skippable;
|
||||
}
|
||||
}
|
||||
|
||||
containsPermission(permissions: chrome.permissions.Permissions): Promise<boolean> {
|
||||
return new Promise((resolve) => {
|
||||
chrome.permissions.contains(permissions, resolve)
|
||||
|
||||
Reference in New Issue
Block a user