2021-02-09 00:37:54 +01:00
|
|
|
import { Action } from '../../../node_modules/vuex/types/index'
|
|
|
|
import AntiGradientMode from '../enums/AntiGradientMode.enum'
|
|
|
|
import AspectRatioType from '../enums/AspectRatioType.enum'
|
|
|
|
import CropModePersistence from '../enums/CropModePersistence.enum'
|
|
|
|
import ExtensionMode from '../enums/ExtensionMode.enum'
|
|
|
|
import StretchType from '../enums/StretchType.enum'
|
|
|
|
import VideoAlignmentType from '../enums/VideoAlignmentType.enum'
|
|
|
|
|
2021-10-28 22:53:43 +02:00
|
|
|
export interface KeyboardShortcutInterface {
|
|
|
|
key?: string,
|
|
|
|
code?: string,
|
|
|
|
ctrlKey?: boolean,
|
|
|
|
metaKey?: boolean,
|
|
|
|
altKey?: boolean,
|
|
|
|
shiftKey?: boolean,
|
|
|
|
onKeyUp?: boolean,
|
|
|
|
onKeyDown?: boolean,
|
|
|
|
onMouseMove?: boolean,
|
|
|
|
}
|
|
|
|
|
2021-02-09 00:37:54 +01:00
|
|
|
interface ActionScopeInterface {
|
|
|
|
show: boolean,
|
|
|
|
label?: string, // example override, takes precedence over default label
|
2021-10-28 22:53:43 +02:00
|
|
|
shortcut?: KeyboardShortcutInterface[],
|
2021-02-09 00:37:54 +01:00
|
|
|
}
|
|
|
|
|
2021-10-25 23:11:34 +02:00
|
|
|
interface RestrictionsSettings {
|
|
|
|
disableOnSmallPlayers?: boolean; // Whether ultrawidify should disable itself when the player is small
|
|
|
|
minAllowedWidth?: number; // if player is less than this many px wide, ultrawidify will disable itself
|
|
|
|
minAllowedHeight?: number; // if player is less than this many px tall, ultrawidify will disable itself
|
|
|
|
onlyAllowInFullscreen?: boolean; // if enabled, ultrawidify will be disabled when not in full screen regardless of what previous two options say
|
2022-11-22 01:28:04 +01:00
|
|
|
onlyAllowAutodetectionInFullScreen?: boolean; // if enabled, autodetection will only start once in full screen
|
2021-10-25 23:11:34 +02:00
|
|
|
}
|
|
|
|
|
2023-01-07 03:05:17 +01:00
|
|
|
interface ExtensionEnvironmentSettingsInterface {
|
|
|
|
normal: ExtensionMode,
|
|
|
|
theater: ExtensionMode,
|
|
|
|
fullscreen: ExtensionMode,
|
|
|
|
}
|
|
|
|
|
2021-10-28 22:53:43 +02:00
|
|
|
export interface CommandInterface {
|
|
|
|
action: string,
|
|
|
|
label: string,
|
|
|
|
comment?: string,
|
|
|
|
arguments?: any,
|
|
|
|
shortcut?: KeyboardShortcutInterface,
|
|
|
|
internalOnly?: boolean,
|
|
|
|
actionId?: string,
|
|
|
|
}
|
|
|
|
|
2023-07-15 04:03:32 +02:00
|
|
|
export type SettingsReloadComponent = 'PlayerData' | 'VideoData';
|
|
|
|
export type SettingsReloadFlags = true | SettingsReloadComponent;
|
|
|
|
|
2024-10-19 16:04:20 +02:00
|
|
|
export interface AardSettings {
|
2024-12-26 14:58:14 +01:00
|
|
|
aardType: 'webgl' | 'legacy' | 'auto';
|
|
|
|
|
2024-12-30 23:02:55 +01:00
|
|
|
earlyStopOptions: {
|
|
|
|
stopAfterFirstDetection: boolean;
|
|
|
|
stopAfterTimeout: boolean;
|
|
|
|
stopTimeout: number;
|
|
|
|
},
|
|
|
|
|
|
|
|
|
2024-10-19 16:04:20 +02:00
|
|
|
disabledReason: string, // if automatic aspect ratio has been disabled, show reason
|
|
|
|
allowedMisaligned: number, // top and bottom letterbox thickness can differ by this much.
|
|
|
|
// Any more and we don't adjust ar.
|
|
|
|
allowedArVariance: number, // amount by which old ar can differ from the new (1 = 100%)
|
|
|
|
timers: { // autodetection frequency
|
|
|
|
playing: number, // while playing
|
2024-12-30 23:02:55 +01:00
|
|
|
playingReduced: number, // while video/player element has insufficient size
|
2024-10-19 16:04:20 +02:00
|
|
|
paused: number, // while paused
|
|
|
|
error: number, // after error
|
|
|
|
minimumTimeout: number,
|
|
|
|
tickrate: number, // 1 tick every this many milliseconds
|
|
|
|
},
|
|
|
|
autoDisable: { // settings for automatically disabling the extension
|
|
|
|
maxExecutionTime: number, // if execution time of main autodetect loop exceeds this many milliseconds,
|
|
|
|
// we disable it.
|
|
|
|
consecutiveTimeoutCount: number, // we only do it if it happens this many consecutive times
|
|
|
|
|
|
|
|
// FOR FUTURE USE
|
|
|
|
consecutiveArResets: number // if aspect ratio reverts immediately after AR change is applied, we disable everything
|
|
|
|
},
|
|
|
|
canvasDimensions: {
|
|
|
|
blackframeCanvas: { // smaller than sample canvas, blackframe canvas is used to recon for black frames
|
|
|
|
// it's not used to detect aspect ratio by itself, so it can be tiny af
|
|
|
|
width: number,
|
|
|
|
height: number,
|
|
|
|
},
|
|
|
|
sampleCanvas: { // size of image sample for detecting aspect ratio. Bigger size means more accurate results,
|
|
|
|
// at the expense of performance
|
|
|
|
width: number,
|
|
|
|
height: number,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
blackLevels: {
|
|
|
|
defaultBlack: number, // By default, pixels darker than this are considered black.
|
|
|
|
// (If detection algorithm detects darker blacks, black is considered darkest detected pixel)
|
|
|
|
blackTolerance: number, // If pixel is more than this much brighter than blackLevel, it's considered not black
|
|
|
|
// It is not considered a valid image detection if gradient detection is enabled
|
|
|
|
imageDelta: number, // When gradient detection is enabled, pixels this much brighter than black skip gradient detection
|
|
|
|
}
|
|
|
|
sampling: {
|
|
|
|
edgePosition: number; // % of width (max 0.33). Pixels up to this far away from either edge may contain logo.
|
|
|
|
staticCols: number, // we take a column at [0-n]/n-th parts along the width and sample it
|
|
|
|
randomCols: number, // we add this many randomly selected columns to the static columns
|
|
|
|
staticRows: number, // forms grid with staticSampleCols. Determined in the same way. For black frame checks,
|
|
|
|
},
|
|
|
|
|
|
|
|
// pls deprecate and move things used
|
|
|
|
edgeDetection: {
|
|
|
|
slopeTestWidth: number,
|
|
|
|
gradientTestSamples: number, // we check this many pixels below (or above) the suspected edge to check for gradient
|
|
|
|
gradientTestBlackThreshold: number, // if pixel in test sample is brighter than that, we aren't looking at gradient
|
|
|
|
gradientTestDeltaThreshold: number, // if delta between two adjacent pixels in gradient test exceeds this, it's not gradient
|
|
|
|
gradientTestMinDelta: number, // if last pixels of the test sample is less than this brighter than the first -> not gradient
|
|
|
|
|
2024-10-21 01:08:03 +02:00
|
|
|
thresholds: {
|
2024-10-23 01:23:37 +02:00
|
|
|
edgeDetectionLimit: number, // during scanning of the edge, quit after edge gets detected at this many points
|
|
|
|
minQualitySingleEdge: number, // At least one of the detected must reach this quality
|
|
|
|
minQualitySecondEdge: number, // The other edge must reach this quality (must be smaller or equal to single edge quality)
|
2024-10-21 01:08:03 +02:00
|
|
|
}
|
|
|
|
|
2024-12-31 02:50:33 +01:00
|
|
|
maxLetterboxOffset: number, // Upper and lower letterbox can be different by this many (% of height)
|
2024-10-21 01:08:03 +02:00
|
|
|
|
|
|
|
// Previous iteration variables VVVV
|
2024-10-19 16:04:20 +02:00
|
|
|
sampleWidth: number, // we take a sample this wide for edge detection
|
|
|
|
detectionThreshold: number, // sample needs to have this many non-black pixels to be a valid edge
|
|
|
|
confirmationThreshold: number, //
|
|
|
|
singleSideConfirmationThreshold: number, // we need this much edges (out of all samples, not just edges) in order
|
|
|
|
// to confirm an edge in case there's no edges on top or bottom (other
|
|
|
|
// than logo, of course)
|
|
|
|
logoThreshold: number, // if edge candidate sits with count greater than this*all_samples, it can't be logo
|
2024-12-31 02:50:33 +01:00
|
|
|
// or watermark.
|
2024-10-19 16:04:20 +02:00
|
|
|
edgeTolerancePx?: number, // we check for black edge violation this far from detection point
|
|
|
|
edgeTolerancePercent?: number, // we check for black edge detection this % of height from detection point. unused
|
|
|
|
middleIgnoredArea: number, // we ignore this % of canvas height towards edges while detecting aspect ratios
|
|
|
|
minColsForSearch: number, // if we hit the edge of blackbars for all but this many columns (%-wise), we don't
|
2024-12-31 02:50:33 +01:00
|
|
|
// continue with search. It's pointless, because black edge is higher/lower than we
|
|
|
|
// are now. (NOTE: keep this less than 1 in case we implement logo detection)
|
|
|
|
edgeMismatchTolerancePx: number,// corners and center are considered equal if they differ by at most this many px
|
2024-10-19 16:04:20 +02:00
|
|
|
},
|
|
|
|
pillarTest: {
|
|
|
|
ignoreThinPillarsPx: number, // ignore pillars that are less than this many pixels thick.
|
|
|
|
allowMisaligned: number // left and right edge can vary this much (%)
|
|
|
|
},
|
|
|
|
textLineTest: {
|
|
|
|
nonTextPulse: number, // if a single continuous pulse has this many non-black pixels, we aren't dealing
|
|
|
|
// with text. This value is relative to canvas width (%)
|
|
|
|
pulsesToConfirm: number, // this is a threshold to confirm we're seeing text.
|
|
|
|
pulsesToConfirmIfHalfBlack: number, // this is the threshold to confirm we're seeing text if longest black pulse
|
|
|
|
// is over 50% of the canvas width
|
|
|
|
testRowOffset: number // we test this % of height from detected edge
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-09 00:37:54 +01:00
|
|
|
interface SettingsInterface {
|
2023-07-15 04:03:32 +02:00
|
|
|
_updateFlags?: {
|
|
|
|
requireReload?: SettingsReloadFlags,
|
|
|
|
forSite?: string
|
|
|
|
}
|
|
|
|
|
2024-10-19 16:04:20 +02:00
|
|
|
arDetect: AardSettings,
|
2021-10-25 23:11:34 +02:00
|
|
|
|
2024-06-12 20:29:00 +02:00
|
|
|
ui: {
|
|
|
|
inPlayer: {
|
2024-12-17 02:02:49 +01:00
|
|
|
enabled: boolean,
|
2024-12-17 14:19:30 +01:00
|
|
|
enabledFullscreenOnly: boolean,
|
|
|
|
popupAlignment: 'left' | 'right',
|
2024-12-17 02:02:49 +01:00
|
|
|
minEnabledWidth: number, // don't show UI if player is narrower than % of screen width
|
2024-12-28 01:42:13 +01:00
|
|
|
minEnabledHeight: number, // don't show UI if player is narrower than % of screen height
|
2024-12-17 02:02:49 +01:00
|
|
|
activation: 'trigger-zone' | 'player', // what needs to be hovered in order for UI to be visible
|
|
|
|
triggerZoneDimensions: { // how large the trigger zone is (relative to player size)
|
|
|
|
width: number
|
|
|
|
height: number,
|
|
|
|
offsetX: number, // fed to translateX(offsetX + '%'). Valid range [-100, 0]
|
|
|
|
offsetY: number // fed to translateY(offsetY + '%'). Valid range [-100, 100]
|
|
|
|
},
|
2024-06-12 20:29:00 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-25 23:11:34 +02:00
|
|
|
restrictions?: RestrictionsSettings;
|
|
|
|
|
2021-11-23 01:32:42 +01:00
|
|
|
crop: {
|
|
|
|
default: any;
|
|
|
|
},
|
2022-09-27 01:48:08 +02:00
|
|
|
stretch: {
|
|
|
|
default: any;
|
|
|
|
conditionalDifferencePercent: number // black bars less than this wide will trigger stretch
|
|
|
|
// if mode is set to '1'. 1.0=100%
|
|
|
|
},
|
2022-09-28 00:39:49 +02:00
|
|
|
kbm: {
|
2022-09-27 01:48:08 +02:00
|
|
|
enabled: boolean, // if keyboard/mouse handler service will run
|
|
|
|
keyboardEnabled: boolean, // if keyboard shortcuts are processed
|
|
|
|
mouseEnabled: boolean, // if mouse movement is processed
|
|
|
|
}
|
2021-11-23 01:32:42 +01:00
|
|
|
|
2021-02-09 00:37:54 +01:00
|
|
|
zoom: {
|
|
|
|
minLogZoom: number,
|
|
|
|
maxLogZoom: number,
|
|
|
|
announceDebounce: number // we wait this long before announcing new zoom
|
|
|
|
},
|
2021-10-25 23:11:34 +02:00
|
|
|
|
2021-02-09 00:37:54 +01:00
|
|
|
miscSettings: {
|
|
|
|
mousePan: {
|
|
|
|
enabled: boolean
|
|
|
|
},
|
|
|
|
mousePanReverseMouse: boolean,
|
|
|
|
defaultAr?: any
|
|
|
|
},
|
2022-09-27 01:48:08 +02:00
|
|
|
|
2021-02-09 00:37:54 +01:00
|
|
|
resizer: {
|
|
|
|
setStyleString: {
|
|
|
|
maxRetries: number,
|
|
|
|
retryTimeout: number
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pageInfo: {
|
|
|
|
timeouts: {
|
|
|
|
urlCheck: number,
|
|
|
|
rescan: number
|
|
|
|
}
|
|
|
|
},
|
|
|
|
pan?: any,
|
|
|
|
version?: string,
|
|
|
|
preventReload?: boolean,
|
2021-04-04 03:42:18 +02:00
|
|
|
|
|
|
|
// -----------------------------------------
|
|
|
|
// ::: MITIGATIONS :::
|
|
|
|
// -----------------------------------------
|
|
|
|
// Settings for browser bug workarounds.
|
|
|
|
mitigations?: {
|
|
|
|
zoomLimit?: {
|
|
|
|
enabled?: boolean,
|
2021-04-05 03:29:56 +02:00
|
|
|
fullscreenOnly?: boolean,
|
2021-04-04 03:42:18 +02:00
|
|
|
limit?: number,
|
|
|
|
}
|
|
|
|
}
|
2021-02-09 00:37:54 +01:00
|
|
|
// -----------------------------------------
|
|
|
|
// ::: ACTIONS :::
|
|
|
|
// -----------------------------------------
|
|
|
|
// Nastavitve za ukaze. Zamenja stare nastavitve za bližnične tipke.
|
2021-10-25 23:11:34 +02:00
|
|
|
//
|
|
|
|
// Polje 'shortcut' je tabela, če se slučajno lotimo kdaj delati choordov.
|
2021-02-09 00:37:54 +01:00
|
|
|
actions: {
|
|
|
|
name?: string, // name displayed in settings
|
|
|
|
label?: string, // name displayed in ui (can be overridden in scope/playerUi)
|
|
|
|
cmd?: {
|
|
|
|
action: string,
|
|
|
|
arg: any,
|
|
|
|
customArg?: any,
|
|
|
|
persistent?: boolean, // optional, false by default. If true, change doesn't take effect immediately.
|
|
|
|
// Instead, this action saves stuff to settings
|
|
|
|
}[],
|
|
|
|
scopes?: {
|
|
|
|
global?: ActionScopeInterface,
|
|
|
|
site?: ActionScopeInterface,
|
|
|
|
page?: ActionScopeInterface
|
|
|
|
},
|
|
|
|
playerUi?: {
|
|
|
|
show: boolean,
|
|
|
|
path?: string,
|
|
|
|
},
|
|
|
|
userAdded?: boolean,
|
|
|
|
}[],
|
2021-10-28 22:53:43 +02:00
|
|
|
// This object fulfills the same purpose as 'actions', but is written in less retarded and overly
|
|
|
|
// complicated way. Hopefully it'll be easier to maintain it that way.
|
|
|
|
commands?: {
|
|
|
|
crop?: CommandInterface[],
|
|
|
|
stretch?: CommandInterface[],
|
|
|
|
zoom?: CommandInterface[],
|
|
|
|
pan?: CommandInterface[],
|
|
|
|
internal?: CommandInterface[],
|
|
|
|
},
|
2021-02-09 00:37:54 +01:00
|
|
|
whatsNewChecked: boolean,
|
2024-12-17 02:02:49 +01:00
|
|
|
newFeatureTracker: any,
|
2021-02-09 00:37:54 +01:00
|
|
|
// -----------------------------------------
|
|
|
|
// ::: SITE CONFIGURATION :::
|
|
|
|
// -----------------------------------------
|
|
|
|
// Config for a given page:
|
2021-10-25 23:11:34 +02:00
|
|
|
//
|
2021-02-09 00:37:54 +01:00
|
|
|
// <hostname> : {
|
|
|
|
// status: <option> // should extension work on this site?
|
|
|
|
// arStatus: <option> // should we do autodetection on this site?
|
2021-10-25 23:11:34 +02:00
|
|
|
//
|
2021-02-09 00:37:54 +01:00
|
|
|
// defaultAr?: <ratio> // automatically apply this aspect ratio on this side. Use extension defaults if undefined.
|
|
|
|
// stretch? <stretch mode> // automatically stretch video on this site in this manner
|
|
|
|
// videoAlignment? <left|center|right>
|
|
|
|
//
|
2021-10-25 23:11:34 +02:00
|
|
|
// type: <official|community|user> // 'official' — blessed by Tam.
|
2021-02-09 00:37:54 +01:00
|
|
|
// // 'community' — blessed by reddit.
|
|
|
|
// // 'user' — user-defined (not here)
|
|
|
|
// override: <true|false> // override user settings for this site on update
|
2021-10-25 23:11:34 +02:00
|
|
|
// }
|
|
|
|
//
|
2021-02-09 00:37:54 +01:00
|
|
|
// Valid values for options:
|
|
|
|
//
|
|
|
|
// status, arStatus, statusEmbedded:
|
2021-10-25 23:11:34 +02:00
|
|
|
//
|
2021-02-09 00:37:54 +01:00
|
|
|
// * enabled — always allow, full
|
|
|
|
// * basic — allow, but only the basic version without playerData
|
|
|
|
// * default — allow if default is to allow, block if default is to block
|
|
|
|
// * disabled — never allow
|
2021-10-25 23:11:34 +02:00
|
|
|
//
|
2021-02-09 00:37:54 +01:00
|
|
|
sites: {
|
2023-01-07 03:05:17 +01:00
|
|
|
[x: string]: SiteSettingsInterface,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface SiteSettingsInterface {
|
|
|
|
enable: ExtensionEnvironmentSettingsInterface;
|
|
|
|
enableAard: ExtensionEnvironmentSettingsInterface;
|
|
|
|
enableKeyboard: ExtensionEnvironmentSettingsInterface;
|
2025-01-27 02:59:30 +01:00
|
|
|
enableUI: ExtensionEnvironmentSettingsInterface; // Lies! enableUI doesn't use 'theater' property (but uses the other two)
|
2023-01-07 03:05:17 +01:00
|
|
|
|
2023-07-15 01:28:20 +02:00
|
|
|
type?: 'official' | 'community' | 'user-defined' | 'testing' | 'officially-disabled' | 'unknown' | 'modified';
|
|
|
|
defaultType: 'official' | 'community' | 'user-defined' | 'testing' | 'officially-disabled' | 'unknown' | 'modified';
|
2023-01-07 03:05:17 +01:00
|
|
|
|
2023-01-15 22:11:47 +01:00
|
|
|
// must be defined in @global and @empty
|
|
|
|
persistCSA?: CropModePersistence, // CSA - crop, stretch, alignment
|
2023-01-07 03:05:17 +01:00
|
|
|
|
|
|
|
defaults?: { // must be defined in @global and @empty
|
|
|
|
crop?: {type: AspectRatioType, [x: string]: any},
|
2025-01-14 01:44:25 +01:00
|
|
|
stretch?: {type: StretchType, ratio?: number},
|
2023-01-07 18:57:47 +01:00
|
|
|
alignment?: {x: VideoAlignmentType, y: VideoAlignmentType},
|
2021-02-09 00:37:54 +01:00
|
|
|
}
|
2023-01-07 03:05:17 +01:00
|
|
|
|
|
|
|
cropModePersistence?: CropModePersistence;
|
|
|
|
stretchModePersistence?: CropModePersistence;
|
|
|
|
alignmentPersistence?: CropModePersistence;
|
|
|
|
|
2025-01-06 03:05:18 +01:00
|
|
|
playerAutoConfig?: PlayerAutoConfigInterface;
|
2023-01-07 03:05:17 +01:00
|
|
|
|
|
|
|
activeDOMConfig?: string;
|
|
|
|
DOMConfig?: { [x: string]: SiteDOMSettingsInterface };
|
|
|
|
|
|
|
|
// the following script are for extension caching and shouldn't be saved.
|
|
|
|
// if they _are_ saved, they will be overwritten
|
|
|
|
currentDOMConfig?: SiteDOMSettingsInterface;
|
|
|
|
|
|
|
|
// the following fields are for use with extension update script
|
|
|
|
override?: boolean; // whether settings for this site will be overwritten by extension upgrade script
|
|
|
|
}
|
|
|
|
|
2025-01-06 03:05:18 +01:00
|
|
|
export interface PlayerAutoConfigInterface {
|
|
|
|
modified: boolean;
|
|
|
|
initialIndex: number;
|
|
|
|
currentIndex: number;
|
|
|
|
}
|
|
|
|
|
2023-01-07 03:05:17 +01:00
|
|
|
export interface SiteDOMSettingsInterface {
|
2023-07-15 04:03:32 +02:00
|
|
|
type: 'official' | 'community' | 'user-defined' | 'modified' | undefined;
|
2023-01-07 03:05:17 +01:00
|
|
|
elements?: {
|
|
|
|
player?: SiteDOMElementSettingsInterface,
|
|
|
|
video?: SiteDOMElementSettingsInterface,
|
|
|
|
other?: { [x: number]: SiteDOMElementSettingsInterface }
|
|
|
|
};
|
|
|
|
customCss?: string;
|
|
|
|
periodicallyRefreshPlayerElement?: boolean;
|
|
|
|
|
|
|
|
// the following script are for extension caching and shouldn't be saved.
|
|
|
|
// if they _are_ saved, they will be overwritten
|
|
|
|
anchorElementIndex?: number;
|
|
|
|
anchorElement?: HTMLElement;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface SiteDOMElementSettingsInterface {
|
|
|
|
manual?: boolean;
|
|
|
|
querySelectors?: string;
|
|
|
|
index?: number; // previously: useRelativeAncestor + videoAncestor
|
2023-07-15 04:03:32 +02:00
|
|
|
mode?: 'index' | 'qs';
|
2023-01-07 03:05:17 +01:00
|
|
|
nodeCss?: {[x: string]: string};
|
2021-02-09 00:37:54 +01:00
|
|
|
}
|
|
|
|
|
2021-10-25 23:11:34 +02:00
|
|
|
export default SettingsInterface;
|