Move settings to typescript. Add interface for settings object
This commit is contained in:
parent
4fdd6af291
commit
0117d44422
280
src/common/interfaces/SettingsInterface.ts
Normal file
280
src/common/interfaces/SettingsInterface.ts
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
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'
|
||||||
|
|
||||||
|
interface ActionScopeInterface {
|
||||||
|
show: boolean,
|
||||||
|
label?: string, // example override, takes precedence over default label
|
||||||
|
shortcut?: {
|
||||||
|
key?: string,
|
||||||
|
code?: string,
|
||||||
|
ctrlKey?: boolean,
|
||||||
|
metaKey?: boolean,
|
||||||
|
altKey?: boolean,
|
||||||
|
shiftKey?: boolean,
|
||||||
|
onKeyUp?: boolean,
|
||||||
|
onKeyDown?: boolean,
|
||||||
|
onMouseMove?: boolean,
|
||||||
|
}[],
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SettingsInterface {
|
||||||
|
arDetect: {
|
||||||
|
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
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// samplingInterval: 10, // we sample at columns at (width/this) * [ 1 .. this - 1]
|
||||||
|
blackframe: {
|
||||||
|
sufficientColorVariance: number, // calculate difference between average intensity and pixel, for every pixel for every color
|
||||||
|
// component. Average intensity is normalized to where 0 is black and 1 is biggest value for
|
||||||
|
// that component. If sum of differences between normalized average intensity and normalized
|
||||||
|
// component varies more than this % between color components, we can afford to use less strict
|
||||||
|
// cumulative threshold.
|
||||||
|
cumulativeThresholdLax: number,
|
||||||
|
cumulativeThresholdStrict: number,// if we add values of all pixels together and get more than this, the frame is bright enough.
|
||||||
|
// (note: blackframe is 16x9 px -> 144px total. cumulative threshold can be reached fast)
|
||||||
|
blackPixelsCondition: number, // How much pixels must be black (1 all, 0 none) before we consider frame as black. Takes
|
||||||
|
// precedence over cumulative threshold: if blackPixelsCondition is met, the frame is dark
|
||||||
|
// regardless of whether cumulative threshold has been reached.
|
||||||
|
},
|
||||||
|
blackbar: {
|
||||||
|
blackLevel: number, // everything darker than 10/255 across all RGB components is considered black by
|
||||||
|
// default. blackLevel can decrease if we detect darker black.
|
||||||
|
threshold: number, // if pixel is darker than the sum of black level and this value, we count it as black
|
||||||
|
// on 0-255. Needs to be fairly high (8 might not cut it) due to compression
|
||||||
|
// artifacts in the video itself
|
||||||
|
frameThreshold: number, // threshold, but when doing blackframe test
|
||||||
|
imageThreshold: number, // in order to detect pixel as "not black", the pixel must be brighter than
|
||||||
|
// the sum of black level, threshold and this value.
|
||||||
|
gradientThreshold: number, // When trying to determine thickness of the black bars, we take 2 values: position of
|
||||||
|
// the last pixel that's darker than our threshold, and position of the first pixel that's
|
||||||
|
// brighter than our image threshold. If positions are more than this many pixels apart,
|
||||||
|
// we assume we aren't looking at letterbox and thus don't correct the aspect ratio.
|
||||||
|
gradientSampleSize: number, // How far do we look to find the gradient
|
||||||
|
maxGradient: number, // if two neighboring pixels in gradientSampleSize differ by more than this, then we aren't
|
||||||
|
// looking at a gradient
|
||||||
|
gradientNegativeTreshold: number,
|
||||||
|
gradientMaxSD: number, // reserved for future use
|
||||||
|
antiGradientMode: AntiGradientMode
|
||||||
|
},
|
||||||
|
variableBlackbarThresholdOptions: { // In case of poor bitrate videos, jpeg artifacts may cause us issues
|
||||||
|
// FOR FUTURE USE
|
||||||
|
enabled: boolean, // allow increasing blackbar threshold
|
||||||
|
disableArDetectOnMax: boolean, // disable autodetection when threshold goes over max blackbar threshold
|
||||||
|
maxBlackbarThreshold: number, // max threshold (don't increase past this)
|
||||||
|
thresholdStep: number, // when failing to set aspect ratio, increase threshold by this much
|
||||||
|
increaseAfterConsecutiveResets: number // increase if AR resets this many times in a row
|
||||||
|
},
|
||||||
|
sampling: {
|
||||||
|
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
|
||||||
|
},
|
||||||
|
guardLine: { // all pixels on the guardline need to be black, or else we trigger AR recalculation
|
||||||
|
// (if AR fails to be recalculated, we reset AR)
|
||||||
|
enabled: boolean,
|
||||||
|
ignoreEdgeMargin: number, // we ignore anything that pokes over the black line this close to the edge
|
||||||
|
// (relative to width of the sample)
|
||||||
|
imageTestThreshold: number, // when testing for image, this much pixels must be over blackbarThreshold
|
||||||
|
edgeTolerancePx: number, // black edge violation is performed this far from reported 'last black pixel'
|
||||||
|
edgeTolerancePercent: null // unused. same as above, except use % of canvas height instead of pixels
|
||||||
|
},
|
||||||
|
fallbackMode: {
|
||||||
|
enabled: boolean,
|
||||||
|
safetyBorderPx: number, // determines the thickness of safety border in fallback mode
|
||||||
|
noTriggerZonePx: number // if we detect edge less than this many pixels thick, we don't correct.
|
||||||
|
},
|
||||||
|
arSwitchLimiter: { // to be implemented
|
||||||
|
switches: number, // we can switch this many times
|
||||||
|
period: number // per this period
|
||||||
|
},
|
||||||
|
edgeDetection: {
|
||||||
|
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
|
||||||
|
// or watermark.
|
||||||
|
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
|
||||||
|
// 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)
|
||||||
|
},
|
||||||
|
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
|
||||||
|
}
|
||||||
|
},
|
||||||
|
zoom: {
|
||||||
|
minLogZoom: number,
|
||||||
|
maxLogZoom: number,
|
||||||
|
announceDebounce: number // we wait this long before announcing new zoom
|
||||||
|
},
|
||||||
|
miscSettings: {
|
||||||
|
mousePan: {
|
||||||
|
enabled: boolean
|
||||||
|
},
|
||||||
|
mousePanReverseMouse: boolean,
|
||||||
|
defaultAr?: any
|
||||||
|
},
|
||||||
|
stretch: {
|
||||||
|
conditionalDifferencePercent: number // black bars less than this wide will trigger stretch
|
||||||
|
// if mode is set to '1'. 1.0=100%
|
||||||
|
},
|
||||||
|
resizer: {
|
||||||
|
setStyleString: {
|
||||||
|
maxRetries: number,
|
||||||
|
retryTimeout: number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageInfo: {
|
||||||
|
timeouts: {
|
||||||
|
urlCheck: number,
|
||||||
|
rescan: number
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pan?: any,
|
||||||
|
version?: string,
|
||||||
|
preventReload?: boolean,
|
||||||
|
// -----------------------------------------
|
||||||
|
// ::: ACTIONS :::
|
||||||
|
// -----------------------------------------
|
||||||
|
// Nastavitve za ukaze. Zamenja stare nastavitve za bližnične tipke.
|
||||||
|
//
|
||||||
|
// Polje 'shortcut' je tabela, če se slučajno lotimo kdaj delati choordov.
|
||||||
|
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,
|
||||||
|
}[],
|
||||||
|
whatsNewChecked: boolean,
|
||||||
|
// -----------------------------------------
|
||||||
|
// ::: SITE CONFIGURATION :::
|
||||||
|
// -----------------------------------------
|
||||||
|
// Nastavitve za posamezno stran
|
||||||
|
// Config for a given page:
|
||||||
|
//
|
||||||
|
// <hostname> : {
|
||||||
|
// status: <option> // should extension work on this site?
|
||||||
|
// arStatus: <option> // should we do autodetection on this site?
|
||||||
|
//
|
||||||
|
// 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>
|
||||||
|
//
|
||||||
|
// type: <official|community|user> // 'official' — blessed by Tam.
|
||||||
|
// // 'community' — blessed by reddit.
|
||||||
|
// // 'user' — user-defined (not here)
|
||||||
|
// override: <true|false> // override user settings for this site on update
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Veljavne vrednosti za možnosti
|
||||||
|
// Valid values for options:
|
||||||
|
//
|
||||||
|
// status, arStatus, statusEmbedded:
|
||||||
|
//
|
||||||
|
// * 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
|
||||||
|
//
|
||||||
|
sites: {
|
||||||
|
[x: string]: {
|
||||||
|
mode?: ExtensionMode,
|
||||||
|
autoar?: ExtensionMode,
|
||||||
|
autoarFallback?: ExtensionMode,
|
||||||
|
stretch?: StretchType,
|
||||||
|
videoAlignment?: VideoAlignmentType,
|
||||||
|
keyboardShortcutsEnabled?: ExtensionMode,
|
||||||
|
type?: string,
|
||||||
|
override?: boolean,
|
||||||
|
arPersistence?: boolean,
|
||||||
|
actions?: any;
|
||||||
|
|
||||||
|
cropModePersistence?: CropModePersistence;
|
||||||
|
|
||||||
|
DOM?: {
|
||||||
|
player?: {
|
||||||
|
manual?: boolean,
|
||||||
|
querySelectors?: string,
|
||||||
|
additionalCss?: string,
|
||||||
|
useRelativeAncestor?: boolean,
|
||||||
|
videoAncestor?: any,
|
||||||
|
playerNodeCss?: string,
|
||||||
|
periodicallyRefreshPlayerElement?: boolean
|
||||||
|
},
|
||||||
|
video?: {
|
||||||
|
manual?: boolean,
|
||||||
|
querySelectors?: string,
|
||||||
|
additionalCss?: string,
|
||||||
|
useRelativeAncestor?: boolean,
|
||||||
|
playerNodeCss?: string
|
||||||
|
}
|
||||||
|
},
|
||||||
|
css?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SettingsInterface;
|
@ -6,11 +6,12 @@ import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
|||||||
import AntiGradientMode from '../../common/enums/AntiGradientMode.enum';
|
import AntiGradientMode from '../../common/enums/AntiGradientMode.enum';
|
||||||
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||||
|
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||||
|
|
||||||
if(Debug.debug)
|
if(Debug.debug)
|
||||||
console.log("Loading: ExtensionConf.js");
|
console.log("Loading: ExtensionConf.js");
|
||||||
|
|
||||||
var ExtensionConf = {
|
const ExtensionConf: SettingsInterface = {
|
||||||
arDetect: {
|
arDetect: {
|
||||||
disabledReason: "", // if automatic aspect ratio has been disabled, show reason
|
disabledReason: "", // if automatic aspect ratio has been disabled, show reason
|
||||||
allowedMisaligned: 0.05, // top and bottom letterbox thickness can differ by this much.
|
allowedMisaligned: 0.05, // top and bottom letterbox thickness can differ by this much.
|
||||||
@ -373,7 +374,7 @@ var ExtensionConf = {
|
|||||||
label: 'Never persist',
|
label: 'Never persist',
|
||||||
cmd: [{
|
cmd: [{
|
||||||
action: 'set-ar-persistence',
|
action: 'set-ar-persistence',
|
||||||
arg: CropModePersistence.Never,
|
arg: CropModePersistence.Disabled,
|
||||||
}],
|
}],
|
||||||
scopes: {
|
scopes: {
|
||||||
site: {
|
site: {
|
@ -2,18 +2,39 @@ import Debug from '../conf/Debug';
|
|||||||
import currentBrowser from '../conf/BrowserDetect';
|
import currentBrowser from '../conf/BrowserDetect';
|
||||||
import ExtensionConf from '../conf/ExtensionConf';
|
import ExtensionConf from '../conf/ExtensionConf';
|
||||||
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
import ExtensionMode from '../../common/enums/ExtensionMode.enum';
|
||||||
import ObjectCopy from '../lib/ObjectCopy';
|
import ObjectCopy from './ObjectCopy';
|
||||||
import StretchType from '../../common/enums/StretchType.enum';
|
import StretchType from '../../common/enums/StretchType.enum';
|
||||||
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
|
import VideoAlignmentType from '../../common/enums/VideoAlignmentType.enum';
|
||||||
import ExtensionConfPatch from '../conf/ExtConfPatches';
|
import ExtensionConfPatch from '../conf/ExtConfPatches';
|
||||||
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../common/enums/CropModePersistence.enum';
|
||||||
import BrowserDetect from '../conf/BrowserDetect';
|
import BrowserDetect from '../conf/BrowserDetect';
|
||||||
|
import Logger from './Logger';
|
||||||
|
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||||
|
|
||||||
if(process.env.CHANNEL !== 'stable'){
|
if(process.env.CHANNEL !== 'stable'){
|
||||||
console.info("Loading Settings");
|
console.info("Loading Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
|
//#region flags
|
||||||
|
useSync: boolean = false;
|
||||||
|
version: string;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region helper classes
|
||||||
|
logger: Logger;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region data
|
||||||
|
default: SettingsInterface; // default settings
|
||||||
|
active: SettingsInterface; // currently active settings
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region callbacks
|
||||||
|
onSettingsChanged: any;
|
||||||
|
afterSettingsSaved: any;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
// Options: activeSettings, updateCallback, logger
|
// Options: activeSettings, updateCallback, logger
|
||||||
@ -23,14 +44,8 @@ class Settings {
|
|||||||
this.active = options?.activeSettings ?? undefined;
|
this.active = options?.activeSettings ?? undefined;
|
||||||
this.default = ExtensionConf;
|
this.default = ExtensionConf;
|
||||||
this.default['version'] = this.getExtensionVersion();
|
this.default['version'] = this.getExtensionVersion();
|
||||||
this.useSync = false;
|
|
||||||
this.version = undefined;
|
|
||||||
|
|
||||||
if (currentBrowser.firefox) {
|
(BrowserDetect.browserObj as any).storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
||||||
browser.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
|
||||||
} else if (currentBrowser.chrome) {
|
|
||||||
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
storageChangeListener(changes, area) {
|
storageChangeListener(changes, area) {
|
||||||
@ -60,14 +75,10 @@ class Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getExtensionVersion() {
|
static getExtensionVersion(): string {
|
||||||
if (currentBrowser.firefox) {
|
return (BrowserDetect.browserObj as any).runtime.getManifest().version;
|
||||||
return browser.runtime.getManifest().version;
|
|
||||||
} else if (currentBrowser.chrome) {
|
|
||||||
return chrome.runtime.getManifest().version;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
getExtensionVersion() {
|
getExtensionVersion(): string {
|
||||||
return Settings.getExtensionVersion();
|
return Settings.getExtensionVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +107,10 @@ class Settings {
|
|||||||
// also, the fourth digit can start with a letter.
|
// also, the fourth digit can start with a letter.
|
||||||
// versions that start with a letter are ranked lower than
|
// versions that start with a letter are ranked lower than
|
||||||
// versions x.x.x.0
|
// versions x.x.x.0
|
||||||
if (isNaN(+aa[3]) ^ isNaN(+bb[3])) {
|
if (
|
||||||
|
(isNaN(+aa[3]) && !isNaN(+bb[3]))
|
||||||
|
|| (!isNaN(+aa[3]) && isNaN(+bb[3]))
|
||||||
|
) {
|
||||||
return isNaN(+aa[3]) ? -1 : 1;
|
return isNaN(+aa[3]) ? -1 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,14 +283,10 @@ class Settings {
|
|||||||
let ret;
|
let ret;
|
||||||
|
|
||||||
if (currentBrowser.firefox) {
|
if (currentBrowser.firefox) {
|
||||||
ret = await browser.storage.local.get('uwSettings');
|
ret = await (BrowserDetect.browserObj as any).storage.local.get('uwSettings');
|
||||||
} else if (currentBrowser.chrome) {
|
} else if (currentBrowser.anyChromium) {
|
||||||
ret = await new Promise( (resolve, reject) => {
|
ret = await new Promise( (resolve, reject) => {
|
||||||
chrome.storage.local.get('uwSettings', (res) => resolve(res));
|
(BrowserDetect.browserObj as any).storage.local.get('uwSettings', (res) => resolve(res));
|
||||||
});
|
|
||||||
} else if (currentBrowser.edge) {
|
|
||||||
ret = await new Promise( (resolve, reject) => {
|
|
||||||
browser.storage.local.get('uwSettings', (res) => resolve(res));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +322,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async set(extensionConf, options) {
|
async set(extensionConf, options?) {
|
||||||
if (!options || !options.forcePreserveVersion) {
|
if (!options || !options.forcePreserveVersion) {
|
||||||
extensionConf.version = this.version;
|
extensionConf.version = this.version;
|
||||||
}
|
}
|
||||||
@ -321,11 +331,7 @@ class Settings {
|
|||||||
|
|
||||||
this.logger?.log('info', 'settings', "[Settings::set] setting new settings:", extensionConf)
|
this.logger?.log('info', 'settings', "[Settings::set] setting new settings:", extensionConf)
|
||||||
|
|
||||||
if (BrowserDetect.firefox) {
|
return (BrowserDetect.browserObj as any).storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
|
||||||
return browser.storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
|
|
||||||
} else {
|
|
||||||
return chrome.storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async setActive(activeSettings) {
|
async setActive(activeSettings) {
|
||||||
@ -336,7 +342,7 @@ class Settings {
|
|||||||
this.active[prop] = value;
|
this.active[prop] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(options) {
|
async save(options?) {
|
||||||
if (Debug.debug && Debug.storage) {
|
if (Debug.debug && Debug.storage) {
|
||||||
console.log("[Settings::save] Saving active settings:", this.active);
|
console.log("[Settings::save] Saving active settings:", this.active);
|
||||||
}
|
}
|
||||||
@ -539,7 +545,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getDefaultOption(option) {
|
getDefaultOption(option?) {
|
||||||
const allDefault = {
|
const allDefault = {
|
||||||
mode: ExtensionMode.Default,
|
mode: ExtensionMode.Default,
|
||||||
autoar: ExtensionMode.Default,
|
autoar: ExtensionMode.Default,
|
@ -12,24 +12,12 @@ class Comms {
|
|||||||
return browser.runtime.sendMessage(message);
|
return browser.runtime.sendMessage(message);
|
||||||
} else {
|
} else {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try{
|
chrome.runtime.sendMessage(message, function(response){
|
||||||
if(BrowserDetect.edge){
|
// Chrome/js shittiness mitigation — remove this line and an empty array will be returned
|
||||||
browser.runtime.sendMessage(message, function(response){
|
var r = response;
|
||||||
var r = response;
|
resolve(r);
|
||||||
resolve(r);
|
return true;
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
chrome.runtime.sendMessage(message, function(response){
|
|
||||||
// Chrome/js shittiness mitigation — remove this line and an empty array will be returned
|
|
||||||
var r = response;
|
|
||||||
resolve(r);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e){
|
|
||||||
reject(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,55 @@
|
|||||||
import Debug from '../../conf/Debug';
|
import Debug from '../../conf/Debug';
|
||||||
import VideoData from './VideoData';
|
import VideoData from './VideoData';
|
||||||
import RescanReason from './enums/RescanReason';
|
import RescanReason from './enums/RescanReason.enum';
|
||||||
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
||||||
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
|
||||||
|
import Logger from '../Logger';
|
||||||
|
import Settings from '../Settings';
|
||||||
|
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
|
||||||
|
import CommsClient from '../comms/CommsClient';
|
||||||
|
|
||||||
if (process.env.CHANNEL !== 'stable'){
|
if (process.env.CHANNEL !== 'stable'){
|
||||||
console.info("Loading PageInfo");
|
console.info("Loading PageInfo");
|
||||||
}
|
}
|
||||||
|
|
||||||
class PageInfo {
|
class PageInfo {
|
||||||
|
//#region flags
|
||||||
|
readOnly: boolean = false;
|
||||||
|
hasVideos: boolean = false;
|
||||||
|
siteDisabled: boolean = false;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region timers and timeouts
|
||||||
|
rescanTimer: any;
|
||||||
|
urlCheckTimer: any;
|
||||||
|
announceZoomTimeout: any;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region helper objects
|
||||||
|
logger: Logger;
|
||||||
|
settings: Settings;
|
||||||
|
comms: CommsClient;
|
||||||
|
videos: VideoData[] = [];
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
//#region misc stuff
|
||||||
|
lastUrl: string;
|
||||||
|
extensionMode: ExtensionMode;
|
||||||
|
defaultCrop: any;
|
||||||
|
currentCrop: any;
|
||||||
|
actionHandlerInitQueue: any[] = [];
|
||||||
|
currentZoomScale: number = 1;
|
||||||
|
|
||||||
|
actionHandler: any;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
constructor(comms, settings, logger, extensionMode, readOnly = false){
|
constructor(comms, settings, logger, extensionMode, readOnly = false){
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.hasVideos = false;
|
|
||||||
this.siteDisabled = false;
|
|
||||||
this.videos = [];
|
|
||||||
this.settings = settings;
|
this.settings = settings;
|
||||||
this.actionHandlerInitQueue = [];
|
|
||||||
|
|
||||||
this.lastUrl = window.location.href;
|
this.lastUrl = window.location.href;
|
||||||
this.extensionMode = extensionMode;
|
this.extensionMode = extensionMode;
|
||||||
this.readOnly = readOnly;
|
this.readOnly = readOnly;
|
||||||
this.defaultCrop = undefined;
|
|
||||||
this.currentCrop = undefined;
|
|
||||||
|
|
||||||
if (comms){
|
if (comms){
|
||||||
this.comms = comms;
|
this.comms = comms;
|
||||||
@ -54,8 +82,6 @@ class PageInfo {
|
|||||||
|
|
||||||
this.rescan(RescanReason.PERIODIC);
|
this.rescan(RescanReason.PERIODIC);
|
||||||
this.scheduleUrlCheck();
|
this.scheduleUrlCheck();
|
||||||
|
|
||||||
this.currentZoomScale = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async injectCss(cssString) {
|
async injectCss(cssString) {
|
||||||
@ -87,7 +113,7 @@ class PageInfo {
|
|||||||
}
|
}
|
||||||
for (var video of this.videos) {
|
for (var video of this.videos) {
|
||||||
try {
|
try {
|
||||||
this.comms.unregisterVideo(video.id)
|
(this.comms.unregisterVideo as any)(video.vdid)
|
||||||
video.destroy();
|
video.destroy();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.log('error', ['debug', 'init'], '[PageInfo::destroy] unable to destroy video! Error:', e);
|
this.logger.log('error', ['debug', 'init'], '[PageInfo::destroy] unable to destroy video! Error:', e);
|
||||||
@ -95,7 +121,7 @@ class PageInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
playerStyleString = this.settings.active.sites[window.location.hostname].css;
|
const playerStyleString = this.settings.active.sites[window.location.hostname].css;
|
||||||
if (playerStyleString) {
|
if (playerStyleString) {
|
||||||
this.comms.sendMessage({
|
this.comms.sendMessage({
|
||||||
cmd: 'eject-css',
|
cmd: 'eject-css',
|
||||||
@ -132,8 +158,8 @@ class PageInfo {
|
|||||||
|
|
||||||
getVideos(host) {
|
getVideos(host) {
|
||||||
if (this.settings.active.sites[host]?.DOM?.video?.manual
|
if (this.settings.active.sites[host]?.DOM?.video?.manual
|
||||||
&& this.settings.active.sites[host]?.DOM?.video?.querySelector){
|
&& this.settings.active.sites[host]?.DOM?.video?.querySelectors){
|
||||||
const videos = document.querySelectorAll(this.settings.active.sites[host].DOM.video.querySelector);
|
const videos = document.querySelectorAll(this.settings.active.sites[host].DOM.video.querySelectors);
|
||||||
|
|
||||||
if (videos.length) {
|
if (videos.length) {
|
||||||
return videos;
|
return videos;
|
||||||
@ -245,9 +271,11 @@ class PageInfo {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (this.videos.length > 0) {
|
if (this.videos.length > 0) {
|
||||||
this.comms.registerVideo({host: window.location.hostname, location: window.location});
|
// this.comms.registerVideo({host: window.location.hostname, location: window.location});
|
||||||
|
this.comms.registerVideo();
|
||||||
} else {
|
} else {
|
||||||
this.comms.unregisterVideo({host: window.location.hostname, location: window.location});
|
// this.comms.unregisterVideo({host: window.location.hostname, location: window.location});
|
||||||
|
this.comms.unregisterVideo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +414,7 @@ class PageInfo {
|
|||||||
}
|
}
|
||||||
if (playingOnly) {
|
if (playingOnly) {
|
||||||
for(var vd of this.videos){
|
for(var vd of this.videos){
|
||||||
if (video.isPlaying()) {
|
if (vd.isPlaying()) {
|
||||||
vd.startArDetection();
|
vd.startArDetection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -542,7 +570,7 @@ class PageInfo {
|
|||||||
|
|
||||||
announceZoom(scale) {
|
announceZoom(scale) {
|
||||||
if (this.announceZoomTimeout) {
|
if (this.announceZoomTimeout) {
|
||||||
clearTimeout(this.announceZoom);
|
clearTimeout(this.announceZoomTimeout);
|
||||||
}
|
}
|
||||||
this.currentZoomScale = scale;
|
this.currentZoomScale = scale;
|
||||||
const ths = this;
|
const ths = this;
|
||||||
@ -551,7 +579,7 @@ class PageInfo {
|
|||||||
|
|
||||||
setManualTick(manualTick) {
|
setManualTick(manualTick) {
|
||||||
for(var vd of this.videos) {
|
for(var vd of this.videos) {
|
||||||
vd.setManualTick();
|
vd.setManualTick(manualTick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +565,7 @@ class VideoData {
|
|||||||
this.resizer.setLastAr(lastAr);
|
this.resizer.setLastAr(lastAr);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAr(ar, lastAr){
|
setAr(ar, lastAr?){
|
||||||
if (this.invalid) {
|
if (this.invalid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
7
src/ext/lib/video-data/enums/RescanReason.enum.ts
Normal file
7
src/ext/lib/video-data/enums/RescanReason.enum.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
enum RescanReason {
|
||||||
|
PERIODIC = 0,
|
||||||
|
URL_CHANGE = 1,
|
||||||
|
MANUAL = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RescanReason;
|
@ -1,7 +0,0 @@
|
|||||||
var RescanReason = Object.freeze({
|
|
||||||
PERIODIC: 0,
|
|
||||||
URL_CHANGE: 1,
|
|
||||||
MANUAL: 2
|
|
||||||
});
|
|
||||||
|
|
||||||
export default RescanReason;
|
|
@ -68,11 +68,11 @@ class Stretcher {
|
|||||||
actualWidth = newWidth;
|
actualWidth = newWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
var minW = this.conf.player.dimensions.width * (1 - this.settings.active.StretchType.conditionalDifferencePercent);
|
var minW = this.conf.player.dimensions.width * (1 - this.settings.active.stretch.conditionalDifferencePercent);
|
||||||
var maxW = this.conf.player.dimensions.width * (1 + this.settings.active.StretchType.conditionalDifferencePercent);
|
var maxW = this.conf.player.dimensions.width * (1 + this.settings.active.stretch.conditionalDifferencePercent);
|
||||||
|
|
||||||
var minH = this.conf.player.dimensions.height * (1 - this.settings.active.StretchType.conditionalDifferencePercent);
|
var minH = this.conf.player.dimensions.height * (1 - this.settings.active.stretch.conditionalDifferencePercent);
|
||||||
var maxH = this.conf.player.dimensions.height * (1 + this.settings.active.StretchType.conditionalDifferencePercent);
|
var maxH = this.conf.player.dimensions.height * (1 + this.settings.active.stretch.conditionalDifferencePercent);
|
||||||
|
|
||||||
if (actualWidth >= minW && actualWidth <= maxW) {
|
if (actualWidth >= minW && actualWidth <= maxW) {
|
||||||
stretchFactors.xFactor *= this.conf.player.dimensions.width / actualWidth;
|
stretchFactors.xFactor *= this.conf.player.dimensions.width / actualWidth;
|
||||||
|
@ -111,11 +111,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import Donate from '../common/misc/Donate.vue';
|
import Donate from '../common/misc/Donate.vue';
|
||||||
import SuperAdvancedSettings from './SuperAdvancedSettings.vue';
|
import SuperAdvancedSettings from './SuperAdvancedSettings.vue';
|
||||||
import Debug from '../ext/conf/Debug.js';
|
import Debug from '../ext/conf/Debug';
|
||||||
import BrowserDetect from '../ext/conf/BrowserDetect.js';
|
import BrowserDetect from '../ext/conf/BrowserDetect';
|
||||||
import ExtensionConf from '../ext/conf/ExtensionConf.js';
|
import ExtensionConf from '../ext/conf/ExtensionConf';
|
||||||
import ObjectCopy from '../ext/lib/ObjectCopy.js';
|
import ObjectCopy from '../ext/lib/ObjectCopy';
|
||||||
import Settings from '../ext/lib/Settings.js';
|
import Settings from '../ext/lib/Settings';
|
||||||
import GeneralSettings from './GeneralSettings';
|
import GeneralSettings from './GeneralSettings';
|
||||||
import ControlsSettings from './controls-settings/ControlsSettings';
|
import ControlsSettings from './controls-settings/ControlsSettings';
|
||||||
import AddEditActionPopup from './controls-settings/AddEditActionPopup';
|
import AddEditActionPopup from './controls-settings/AddEditActionPopup';
|
||||||
|
Loading…
Reference in New Issue
Block a user