diff --git a/src/components/options/AdvancedSkipOptionsComponent.tsx b/src/components/options/AdvancedSkipOptionsComponent.tsx index 374ff1bb..9011956a 100644 --- a/src/components/options/AdvancedSkipOptionsComponent.tsx +++ b/src/components/options/AdvancedSkipOptionsComponent.tsx @@ -1,7 +1,8 @@ import * as React from "react"; import * as CompileConfig from "../../../config.json"; -import Config, { AdvancedSkipRuleSet, SkipRuleAttribute, SkipRuleOperator } from "../../config"; +import Config from "../../config"; +import { AdvancedSkipRuleSet, SkipRuleAttribute, SkipRuleOperator } from "../../utils/skipRule"; import { CategorySkipOption } from "../../types"; let configSaveTimeout: NodeJS.Timeout | null = null; diff --git a/src/config.ts b/src/config.ts index 74bf214d..fbe3f9be 100644 --- a/src/config.ts +++ b/src/config.ts @@ -3,45 +3,7 @@ import * as invidiousList from "../ci/invidiouslist.json"; import { Category, CategorySelection, CategorySkipOption, NoticeVisibilityMode, PreviewBarOption, SponsorTime, VideoID, SponsorHideType } from "./types"; import { Keybind, ProtoConfig, keybindEquals } from "../maze-utils/src/config"; import { HashedValue } from "../maze-utils/src/hash"; - -export interface Permission { - canSubmit: boolean; -} - -export enum SkipRuleAttribute { - StartTime = "startTime", - EndTime = "endTime", - Duration = "duration", - StartTimePercent = "startTimePercent", - EndTimePercent = "endTimePercent", - DurationPercent = "durationPercent", - Category = "category", - Description = "description", - Source = "source" -} - -export enum SkipRuleOperator { - Less = "<", - LessOrEqual = "<=", - Greater = ">", - GreaterOrEqual = ">=", - Equal = "==", - NotEqual = "!=", - Contains = "*=", - Regex = "~=" -} - -export interface AdvancedSkipRule { - attribute: SkipRuleAttribute; - operator: SkipRuleOperator; - value: string | number; -} - -export interface AdvancedSkipRuleSet { - rules: AdvancedSkipRule[]; - skipOption: CategorySkipOption; - comment: string; -} +import { Permission, AdvancedSkipRuleSet } from "./utils/skipRule"; interface SBConfig { userID: string; diff --git a/src/content.ts b/src/content.ts index a8e58fd6..d7b5e12b 100644 --- a/src/content.ts +++ b/src/content.ts @@ -51,7 +51,8 @@ import { asyncRequestToServer } from "./utils/requests"; import { isMobileControlsOpen } from "./utils/mobileUtils"; import { defaultPreviewTime } from "./utils/constants"; import { onVideoPage } from "../maze-utils/src/pageInfo"; -import { getCategoryDefaultSelection, getCategorySelection, getSegmentsForVideo } from "./utils/segmentData"; +import { getSegmentsForVideo } from "./utils/segmentData"; +import { getCategoryDefaultSelection, getCategorySelection } from "./utils/skipRule"; cleanPage(); diff --git a/src/utils/segmentData.ts b/src/utils/segmentData.ts index bd3ec75a..38cf4848 100644 --- a/src/utils/segmentData.ts +++ b/src/utils/segmentData.ts @@ -1,13 +1,12 @@ import { DataCache } from "../../maze-utils/src/cache"; import { getHash, HashedValue } from "../../maze-utils/src/hash"; -import Config, { AdvancedSkipRule, SkipRuleAttribute, SkipRuleOperator } from "../config"; +import Config, { } from "../config"; import * as CompileConfig from "../../config.json"; -import { ActionType, ActionTypes, CategorySelection, CategorySkipOption, SponsorSourceType, SponsorTime, VideoID } from "../types"; +import { ActionType, ActionTypes, CategorySkipOption, SponsorSourceType, SponsorTime, VideoID } from "../types"; import { getHashParams } from "./pageUtils"; import { asyncRequestToServer } from "./requests"; import { extensionUserAgent } from "../../maze-utils/src"; -import { VideoLabelsCacheData } from "./videoLabels"; -import { getVideoDuration } from "../../maze-utils/src/video"; +import { getCategorySelection } from "./skipRule"; const segmentDataCache = new DataCache(() => { return { @@ -105,102 +104,4 @@ function getEnabledActionTypes(forceFullVideo = false): ActionType[] { } return actionTypes; -} - -export function getCategorySelection(segment: SponsorTime | VideoLabelsCacheData): CategorySelection { - for (const ruleSet of Config.local.skipRules) { - if (ruleSet.rules.every((rule) => isSkipRulePassing(segment, rule))) { - return { name: segment.category, option: ruleSet.skipOption } as CategorySelection; - } - } - - for (const selection of Config.config.categorySelections) { - if (selection.name === segment.category) { - return selection; - } - } - return { name: segment.category, option: CategorySkipOption.Disabled} as CategorySelection; -} - -function getSkipRuleValue(segment: SponsorTime | VideoLabelsCacheData, rule: AdvancedSkipRule): string | number | undefined { - switch (rule.attribute) { - case SkipRuleAttribute.StartTime: - return (segment as SponsorTime).segment?.[0]; - case SkipRuleAttribute.EndTime: - return (segment as SponsorTime).segment?.[1]; - case SkipRuleAttribute.Duration: - return (segment as SponsorTime).segment?.[1] - (segment as SponsorTime).segment?.[0]; - case SkipRuleAttribute.StartTimePercent: { - const startTime = (segment as SponsorTime).segment?.[0]; - if (startTime === undefined) return undefined; - - return startTime / getVideoDuration() * 100; - } - case SkipRuleAttribute.EndTimePercent: { - const endTime = (segment as SponsorTime).segment?.[1]; - if (endTime === undefined) return undefined; - - return endTime / getVideoDuration() * 100; - } - case SkipRuleAttribute.DurationPercent: { - const startTime = (segment as SponsorTime).segment?.[0]; - const endTime = (segment as SponsorTime).segment?.[1]; - if (startTime === undefined || endTime === undefined) return undefined; - - return (endTime - startTime) / getVideoDuration() * 100; - } - case SkipRuleAttribute.Category: - return segment.category; - case SkipRuleAttribute.Description: - return (segment as SponsorTime).description || ""; - case SkipRuleAttribute.Source: - switch ((segment as SponsorTime).source) { - case SponsorSourceType.Local: - return "local"; - case SponsorSourceType.YouTube: - return "youtube"; - case SponsorSourceType.Autogenerated: - return "autogenerated"; - case SponsorSourceType.Server: - return "server"; - } - - break; - default: - return undefined; - } -} - -function isSkipRulePassing(segment: SponsorTime | VideoLabelsCacheData, rule: AdvancedSkipRule): boolean { - const value = getSkipRuleValue(segment, rule); - - switch (rule.operator) { - case SkipRuleOperator.Less: - return typeof value === "number" && value < (rule.value as number); - case SkipRuleOperator.LessOrEqual: - return typeof value === "number" && value <= (rule.value as number); - case SkipRuleOperator.Greater: - return typeof value === "number" && value > (rule.value as number); - case SkipRuleOperator.GreaterOrEqual: - return typeof value === "number" && value >= (rule.value as number); - case SkipRuleOperator.Equal: - return value === rule.value; - case SkipRuleOperator.NotEqual: - return value !== rule.value; - case SkipRuleOperator.Contains: - return String(value).toLocaleLowerCase().includes(String(rule.value).toLocaleLowerCase()); - case SkipRuleOperator.Regex: - return new RegExp(rule.value as string).test(String(value)); - default: - return false; - } -} - -export function getCategoryDefaultSelection(category: string): CategorySelection { - for (const selection of Config.config.categorySelections) { - if (selection.name === category) { - return selection; - } - } - return { name: category, option: CategorySkipOption.Disabled} as CategorySelection; } \ No newline at end of file diff --git a/src/utils/skipRule.ts b/src/utils/skipRule.ts new file mode 100644 index 00000000..a6514ac5 --- /dev/null +++ b/src/utils/skipRule.ts @@ -0,0 +1,141 @@ +import { getVideoDuration } from "../../maze-utils/src/video"; +import Config from "../config"; +import { CategorySelection, CategorySkipOption, SponsorSourceType, SponsorTime } from "../types"; +import { VideoLabelsCacheData } from "./videoLabels"; + +export interface Permission { + canSubmit: boolean; +} + +export enum SkipRuleAttribute { + StartTime = "startTime", + EndTime = "endTime", + Duration = "duration", + StartTimePercent = "startTimePercent", + EndTimePercent = "endTimePercent", + DurationPercent = "durationPercent", + Category = "category", + Description = "description", + Source = "source" +} + +export enum SkipRuleOperator { + Less = "<", + LessOrEqual = "<=", + Greater = ">", + GreaterOrEqual = ">=", + Equal = "==", + NotEqual = "!=", + Contains = "*=", + Regex = "~=" +} + +export interface AdvancedSkipRule { + attribute: SkipRuleAttribute; + operator: SkipRuleOperator; + value: string | number; +} + +export interface AdvancedSkipRuleSet { + rules: AdvancedSkipRule[]; + skipOption: CategorySkipOption; + comment: string; +} + +export function getCategorySelection(segment: SponsorTime | VideoLabelsCacheData): CategorySelection { + for (const ruleSet of Config.local.skipRules) { + if (ruleSet.rules.every((rule) => isSkipRulePassing(segment, rule))) { + return { name: segment.category, option: ruleSet.skipOption } as CategorySelection; + } + } + + for (const selection of Config.config.categorySelections) { + if (selection.name === segment.category) { + return selection; + } + } + return { name: segment.category, option: CategorySkipOption.Disabled} as CategorySelection; +} + +function getSkipRuleValue(segment: SponsorTime | VideoLabelsCacheData, rule: AdvancedSkipRule): string | number | undefined { + switch (rule.attribute) { + case SkipRuleAttribute.StartTime: + return (segment as SponsorTime).segment?.[0]; + case SkipRuleAttribute.EndTime: + return (segment as SponsorTime).segment?.[1]; + case SkipRuleAttribute.Duration: + return (segment as SponsorTime).segment?.[1] - (segment as SponsorTime).segment?.[0]; + case SkipRuleAttribute.StartTimePercent: { + const startTime = (segment as SponsorTime).segment?.[0]; + if (startTime === undefined) return undefined; + + return startTime / getVideoDuration() * 100; + } + case SkipRuleAttribute.EndTimePercent: { + const endTime = (segment as SponsorTime).segment?.[1]; + if (endTime === undefined) return undefined; + + return endTime / getVideoDuration() * 100; + } + case SkipRuleAttribute.DurationPercent: { + const startTime = (segment as SponsorTime).segment?.[0]; + const endTime = (segment as SponsorTime).segment?.[1]; + if (startTime === undefined || endTime === undefined) return undefined; + + return (endTime - startTime) / getVideoDuration() * 100; + } + case SkipRuleAttribute.Category: + return segment.category; + case SkipRuleAttribute.Description: + return (segment as SponsorTime).description || ""; + case SkipRuleAttribute.Source: + switch ((segment as SponsorTime).source) { + case SponsorSourceType.Local: + return "local"; + case SponsorSourceType.YouTube: + return "youtube"; + case SponsorSourceType.Autogenerated: + return "autogenerated"; + case SponsorSourceType.Server: + return "server"; + } + + break; + default: + return undefined; + } +} + +function isSkipRulePassing(segment: SponsorTime | VideoLabelsCacheData, rule: AdvancedSkipRule): boolean { + const value = getSkipRuleValue(segment, rule); + + switch (rule.operator) { + case SkipRuleOperator.Less: + return typeof value === "number" && value < (rule.value as number); + case SkipRuleOperator.LessOrEqual: + return typeof value === "number" && value <= (rule.value as number); + case SkipRuleOperator.Greater: + return typeof value === "number" && value > (rule.value as number); + case SkipRuleOperator.GreaterOrEqual: + return typeof value === "number" && value >= (rule.value as number); + case SkipRuleOperator.Equal: + return value === rule.value; + case SkipRuleOperator.NotEqual: + return value !== rule.value; + case SkipRuleOperator.Contains: + return String(value).toLocaleLowerCase().includes(String(rule.value).toLocaleLowerCase()); + case SkipRuleOperator.Regex: + return new RegExp(rule.value as string).test(String(value)); + default: + return false; + } +} + +export function getCategoryDefaultSelection(category: string): CategorySelection { + for (const selection of Config.config.categorySelections) { + if (selection.name === category) { + return selection; + } + } + return { name: category, option: CategorySkipOption.Disabled} as CategorySelection; +} \ No newline at end of file diff --git a/src/utils/videoLabels.ts b/src/utils/videoLabels.ts index 1d15a3fd..67554279 100644 --- a/src/utils/videoLabels.ts +++ b/src/utils/videoLabels.ts @@ -2,7 +2,7 @@ import { Category, CategorySkipOption, VideoID } from "../types"; import { getHash } from "../../maze-utils/src/hash"; import { logWarn } from "./logger"; import { asyncRequestToServer } from "./requests"; -import { getCategorySelection } from "./segmentData"; +import { getCategorySelection } from "./skipRule"; export interface VideoLabelsCacheData { category: Category;