From 277506b3c871ff2ec71580a4df4d96e7ae8a519f Mon Sep 17 00:00:00 2001 From: Tamius Han Date: Tue, 7 May 2024 19:05:10 +0200 Subject: [PATCH] Start implementing run levels --- src/ext/enum/run-level.enum.ts | 5 ++ src/ext/lib/video-data/PlayerData.ts | 73 ++++++++++++++++++++++++-- src/ext/lib/video-data/VideoData.ts | 29 ++++++++++ src/ext/lib/video-transform/Resizer.ts | 10 ++++ 4 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 src/ext/enum/run-level.enum.ts diff --git a/src/ext/enum/run-level.enum.ts b/src/ext/enum/run-level.enum.ts new file mode 100644 index 0000000..24b9db0 --- /dev/null +++ b/src/ext/enum/run-level.enum.ts @@ -0,0 +1,5 @@ +export enum RunLevel { + Off = 0, + UIOnly = 1, + CustomCSSActive = 2 +} diff --git a/src/ext/lib/video-data/PlayerData.ts b/src/ext/lib/video-data/PlayerData.ts index 5b874ee..5c12682 100644 --- a/src/ext/lib/video-data/PlayerData.ts +++ b/src/ext/lib/video-data/PlayerData.ts @@ -12,6 +12,7 @@ import EventBus from '../EventBus'; import UI from '../uwui/UI'; import { SiteSettings } from '../settings/SiteSettings'; import PageInfo from './PageInfo'; +import { RunLevel } from '../../enum/run-level.enum'; if (process.env.CHANNEL !== 'stable'){ console.info("Loading: PlayerData.js"); @@ -35,6 +36,22 @@ interface PlayerDimensions { * If list of names is provided, the function returns dimensions of the first element that contains any name from the list in either * id or class. + * + * + * RUN LEVELS + * Run are there to ensure only the necessary functions run. + * + * * Off: + * * Extension is effectively disabled. However, even in this quasi-disabled state, + * certain functions of the class should still be active. + * 1. Player size monitoring + * (Run level could be set to 'off' due to player being too small) + * 2. Event bus + * (Actions from popup may cause RunLevel to increase) + * + * * UiOnly: + * * Extension should show in-player UI, but it should not inject any + * unnecessary CSS. */ class PlayerData { @@ -56,6 +73,7 @@ class PlayerData { //#endregion //#region flags + runLevel: RunLevel; enabled: boolean; invalid: boolean = false; private periodicallyRefreshPlayerElement: boolean = false; @@ -85,6 +103,9 @@ class PlayerData { 'update-player': [{ function: () => this.getPlayer() }], + 'set-run-level': [{ + function: (runLevel) => this.setRunLevel(runLevel) + }] } //#endregion @@ -163,12 +184,9 @@ class PlayerData { } private reloadPlayerDataConfig(siteConfUpdate) { - console.log('reloading config ...') // this.siteSettings = siteConfUpdate; this.element = this.getPlayer(); - console.log('got player:', this.element); - this.periodicallyRefreshPlayerElement = false; try { this.periodicallyRefreshPlayerElement = this.siteSettings.data.currentDOMConfig.periodicallyRefreshPlayerElement; @@ -177,10 +195,12 @@ class PlayerData { } // because this is often caused by the UI - console.log('tree request:'); this.handlePlayerTreeRequest(); } + /** + * Initializes event bus + */ private initEventBus() { for (const action in this.eventBusCommands) { for (const command of this.eventBusCommands[action]) { @@ -189,6 +209,9 @@ class PlayerData { } } + /** + * Completely stops everything the extension is doing + */ destroy() { document.removeEventListener('fullscreenchange', this.dimensionChangeListener); this.stopChangeDetection(); @@ -210,6 +233,37 @@ class PlayerData { this.ui.enable(); } + /** + * Sets extension runLevel + * @param runLevel + * @returns + */ + setRunLevel(runLevel: RunLevel) { + if (this.runLevel === runLevel) { + return; + } + + // increasing runLevel works differently than decreasing + if (this.runLevel > runLevel) { + if (runLevel < RunLevel.CustomCSSActive) { + this.element.classList.remove(this.playerCssClass); + } + if (runLevel < RunLevel.UIOnly) { + this.ui.disable(); + } + } else { + if (runLevel >= RunLevel.UIOnly) { + this.ui.enable(); + this.startChangeDetection(); + } + if (runLevel >= RunLevel.CustomCSSActive) { + this.element.classList.add(this.playerCssClass); + } + } + + this.runLevel = runLevel; + } + /** * Disables ultrawidify for this video by removing the relevant classes * from the video and player elements. @@ -300,6 +354,10 @@ class PlayerData { // Check if extension is allowed to run in current combination of theater + full screen const canEnable = this.siteSettings.isEnabledForEnvironment(this.isFullscreen, this.isTheaterMode) === ExtensionMode.Enabled; + // TODO: if canEnable is 'true' and runLevel is OFF, we should + // call restoreAr function of resizer and let it figure out the necessary run level. + // Function that restores the last user-set AR may also need to be written. + // Enable/disable if (canEnable) { if (!this.enabled) { @@ -338,7 +396,8 @@ class PlayerData { || newDimensions?.fullscreen != oldDimensions?.fullscreen ){ // If player size changes, we restore aspect ratio - this.videoData.resizer?.restore(); + this.eventBus.send('restore-ar', null); + // this.videoData.resizer?.restore(); } } @@ -347,6 +406,10 @@ class PlayerData { } //#region player element change detection + /** + * Starts change detection. + * @returns + */ startChangeDetection(){ if (this.invalid) { return; diff --git a/src/ext/lib/video-data/VideoData.ts b/src/ext/lib/video-data/VideoData.ts index 6df2be2..204bccf 100644 --- a/src/ext/lib/video-data/VideoData.ts +++ b/src/ext/lib/video-data/VideoData.ts @@ -15,6 +15,7 @@ import EventBus from '../EventBus'; import { SiteSettings } from '../settings/SiteSettings'; import { Ar } from '../../../common/interfaces/ArInterface'; import { ExtensionStatus } from './ExtensionStatus'; +import { RunLevel } from '../../enum/run-level.enum'; /** * VideoData — handles CSS for the video element. @@ -37,6 +38,7 @@ class VideoData { //#region flags arSetupComplete: boolean = false; enabled: boolean; + runLevel: RunLevel; destroyed: boolean = false; invalid: boolean = false; videoStatusOk: boolean = false; @@ -383,6 +385,33 @@ class VideoData { // this.restoreCrop(); } + + setRunLevel(runLevel: RunLevel, options?: {fromPlayer?: boolean}) { + if (this.runLevel === runLevel) { + return; // also no need to propagate to the player + } + + // Run level decreases towards 'off' + if (this.runLevel > runLevel) { + if (runLevel < RunLevel.CustomCSSActive) { + this.video.classList.remove(this.baseCssName); + this.video.classList.remove(this.userCssClassName); + this.enabled = false; + } + } else { // Run level increases towards 'everything runs'* + if (runLevel >= RunLevel.CustomCSSActive) { + this.video.classList.add(this.baseCssName); + this.video.classList.add(this.userCssClassName); + this.enabled = true; + } + } + + this.runLevel = runLevel; + if (!options?.fromPlayer) { + this.player.setRunLevel(runLevel); + } + } + /** * Disables ultrawidify in general. * @param options diff --git a/src/ext/lib/video-transform/Resizer.ts b/src/ext/lib/video-transform/Resizer.ts index acdd15d..eb598d1 100644 --- a/src/ext/lib/video-transform/Resizer.ts +++ b/src/ext/lib/video-transform/Resizer.ts @@ -17,6 +17,7 @@ import EventBus from '../EventBus'; import { _cp } from '../../../common/js/utils'; import Settings from '../Settings'; import { Ar } from '../../../common/interfaces/ArInterface'; +import { RunLevel } from '../../enum/run-level.enum'; if(Debug.debug) { console.log("Loading: Resizer.js"); @@ -120,6 +121,9 @@ class Resizer { }], 'get-ar': [{ function: () => this.eventBus.send('uw-config-broadcast', {type: 'ar', config: this.lastAr}) + }], + 'restore-ar': [{ + function: () => this.restore() }] } //#endregion @@ -242,6 +246,12 @@ class Resizer { return; } + if ([AspectRatioType.Reset].includes(ar.type)) { + this.eventBus.send('set-run-level', RunLevel.UIOnly); + } else { + this.eventBus.send('set-run-level', RunLevel.CustomCSSActive); + } + // handle autodetection stuff if (ar.type === AspectRatioType.Automatic) { this.videoData.arDetector?.start();