revive zoom

This commit is contained in:
Tamius Han 2025-04-20 16:11:17 +02:00
parent 39f39f23a7
commit 0d7c535a70
6 changed files with 90 additions and 234 deletions

View File

@ -8,201 +8,10 @@ import SettingsInterface from '../../common/interfaces/SettingsInterface';
import { _cp } from '../../common/js/utils'; import { _cp } from '../../common/js/utils';
import CropModePersistence from '../../common/enums/CropModePersistence.enum'; import CropModePersistence from '../../common/enums/CropModePersistence.enum';
import AspectRatioType from '../../common/enums/AspectRatioType.enum'; import AspectRatioType from '../../common/enums/AspectRatioType.enum';
import { update } from 'lodash';
const ExtensionConfPatch = [ const ExtensionConfPatch = [
{ {
forVersion: '6.1.1',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// add new commands
userOptions.commands = defaultOptions.commands;
userOptions.actions = defaultOptions.actions;
}
}, {
// NOTE - when releasing shit, ensure ALL alpha migrations are combined together in one function
forVersion: '6.1.2',
updateFn: (userOptions, defaultOptions) => {
userOptions.commands = defaultOptions.commands;
// migrates old settings regarding whether extension is enabled or not
const copyEnabled = (site) => {
userOptions.sites[site].enable = {
fullscreen: userOptions.sites[site].mode,
theater: userOptions.sites[site].mode,
normal: ExtensionMode.Disabled
};
userOptions.sites[site].enableKeyboard = {
fullscreen: userOptions.sites[site].keyboardShortcutsEnabled,
theater: userOptions.sites[site].keyboardShortcutsEnabled,
normal: ExtensionMode.Disabled
};
userOptions.sites[site].enableAard = {
fullscreen: userOptions.sites[site].autoar,
theater: userOptions.sites[site].autoar,
normal: ExtensionMode.Disabled
};
userOptions.sites[site].stretchModePersistence = userOptions.sites[site].cropModePersistence;
// remove old options
delete userOptions.sites[site].mode;
delete userOptions.sites[site].keyboardShortcutsEnabled;
delete userOptions.sites[site].autoar;
}
// globals get carried over before other sites:
copyEnabled('@global');
// we make another guess about a new option we just added
for (const key in userOptions.sites) {
// we already had this
if (key === '@global') {
continue;
}
copyEnabled(key);
userOptions.sites[key].DOMConfig = _cp(defaultOptions.sites[key].DOMConfig)
// convert old site.DOM to site.DOMConfig[]
if (userOptions.sites[key].type === 'user-defined') {
const DOM = userOptions.sites[key].DOM;
if (DOM) {
userOptions.sites[key].DOMConfig['user-defined'] = {
type: 'user-1',
customCss: DOM?.css,
periodicallyRefreshPlayerElement: DOM?.player?.periodicallyRefreshPlayerElement,
elements: !(DOM?.player) ? undefined : {
player: {
manual: DOM?.player?.manual,
querySelectors: DOM?.player?.useRelativeAncestor ? undefined : DOM?.player?.querySelectors,
index: DOM?.player?.useRelativeAncestor ? DOM?.player?.videoAncestor : undefined,
}
}
}
userOptions.sites[key].activeDOMConfig = 'user-1';
// remove old configuration
delete userOptions.sites[key].DOM;
}
}
}
}
}, {
forVersion: '6.0.3',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
delete (userOptions as any).sites['@global'].persistOption;
delete (userOptions as any).sites['@empty'].persistOption;
userOptions.sites['@global'].persistCSA = CropModePersistence.Disabled;
userOptions.sites['@empty'].persistCSA = CropModePersistence.Disabled;
}
}, {
forVersion: '6.0.4',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// deprecated much?
userOptions.actions.push({
name: 'Cycle aspect ratio',
label: 'Cycle',
cmd: [{
action: 'set-ar',
arg: AspectRatioType.Cycle
}]
});
// userOptions.commands.crop.push({
// action: 'set-ar',
// label: 'Cycle',
// comment: 'Cycle through crop options',
// arguments: {
// type: AspectRatioType.Cycle
// },
// shortcut: {
// key: 'c',
// code: 'KeyC',
// ctrlKey: false,
// metaKey: false,
// altKey: false,
// shiftKey: false,
// onKeyUp: true,
// onKeyDown: false,
// }
// });
// userOptions.commands.crop.push({
// action: 'set-ar',
// label: '32:9',
// comment: 'Crop for 32:9 aspect ratio',
// arguments: {
// type: AspectRatioType.Fixed,
// ratio: 3.56
// },
// })
}
}, {
forVersion: '6.1.5',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
if (!userOptions.sites['@global'].defaults.alignment || !userOptions.sites['@global'].defaults.alignment.x || !userOptions.sites['@global'].defaults.alignment.y) {
userOptions.sites['@global'].defaults.alignment = {
x: VideoAlignmentType.Center,
y: VideoAlignmentType.Center
};
}
userOptions.sites['@empty'].defaults.alignment = {x: VideoAlignmentType.Default, y: VideoAlignmentType.Default};
}
}, {
forVersion: '6.1.1-6',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
for (const site in userOptions.sites) {
userOptions.sites[site].defaultType = userOptions.sites[site].type as any;
}
userOptions.sites['@global'].defaultType = 'unknown';
userOptions.sites['@empty'].defaultType = 'modified';
}
}, {
forVersion: '6.1.2-0',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
// remove custom CSS, as it is no longer needed
for (const site in userOptions.sites) {
for (const domOption in userOptions.sites[site].DOMConfig)
userOptions.sites[site].DOMConfig[domOption].customCss;
}
userOptions.arDetect.aardType = 'auto';
userOptions.ui = {
inPlayer: {
enabled: true, // enable by default on new installs
enabledFullscreenOnly: false,
minEnabledWidth: 0.75,
minEnabledHeight: 0.75,
activation: 'player',
popupAlignment: 'left',
triggerZoneDimensions: {
width: 0.5,
height: 0.5,
offsetX: -50,
offsetY: 0,
}
}
},
userOptions.newFeatureTracker['uw6.ui-popup'] = {show: 10};
}
}, {
forVersion: '6.2.1',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
userOptions.ui = defaultOptions.ui;
userOptions.arDetect = defaultOptions.arDetect;
userOptions.newFeatureTracker = defaultOptions.newFeatureTracker;
}
}, {
forVersion: '6.2.3',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
for (const site in userOptions.sites) {
if (userOptions.sites[site].defaults?.stretch && !userOptions.sites[site].defaults?.stretch.type) {
userOptions.sites[site].defaults.stretch = {type: userOptions.sites[site].defaults?.stretch as any as StretchType};
}
}
}
}, {
forVersion: '6.2.4', forVersion: '6.2.4',
updateFn: (userOptions: SettingsInterface, defaultOptions) => { updateFn: (userOptions: SettingsInterface, defaultOptions) => {
for (const site in userOptions.sites) { for (const site in userOptions.sites) {
@ -224,6 +33,57 @@ const ExtensionConfPatch = [
normal: ExtensionMode.Default, normal: ExtensionMode.Default,
} }
} }
}, {
forVersion: '6.2.6',
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
userOptions.commands.zoom = [{
action: 'change-zoom',
label: 'Zoom +5%',
arguments: {
zoom: 0.05
},
shortcut: {
key: 'z',
code: 'KeyY',
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
onKeyUp: true,
onKeyDown: false,
},
internalOnly: true,
actionId: 'change-zoom-10in'
}, {
action: 'change-zoom',
label: 'Zoom -5%',
arguments: {
zoom: -0.05
},
shortcut: {
key: 'u',
code: 'KeyU',
ctrlKey: false,
metaKey: false,
altKey: false,
shiftKey: false,
onKeyUp: true,
onKeyDown: false,
},
internalOnly: true,
actionId: 'change-zoom-10out'
}, {
action: 'set-zoom',
label: 'Reset zoom',
arguments: {
zoom: 1,
},
internalOnly: true,
actionId: 'set-zoom-reset'
}];
delete (userOptions as any).actions;
}
} }
]; ];

View File

@ -354,9 +354,9 @@ const ExtensionConf: SettingsInterface = {
}], }],
zoom: [{ zoom: [{
action: 'change-zoom', action: 'change-zoom',
label: 'Zoom +10%', label: 'Zoom +5%',
arguments: { arguments: {
zoom: 0.1 zoom: 0.05
}, },
shortcut: { shortcut: {
key: 'z', key: 'z',
@ -372,9 +372,9 @@ const ExtensionConf: SettingsInterface = {
actionId: 'change-zoom-10in' actionId: 'change-zoom-10in'
}, { }, {
action: 'change-zoom', action: 'change-zoom',
label: 'Zoom -10%', label: 'Zoom -5%',
arguments: { arguments: {
zoom: -0.1 zoom: -0.05
}, },
shortcut: { shortcut: {
key: 'u', key: 'u',

View File

@ -39,6 +39,8 @@ class Settings {
onChangedCallbacks: (() => void)[] = []; onChangedCallbacks: (() => void)[] = [];
afterSettingsChangedCallbacks: (() => void)[] = []; afterSettingsChangedCallbacks: (() => void)[] = [];
private sortedPatches: any[];
//#endregion //#endregion
constructor(options) { constructor(options) {
@ -51,6 +53,8 @@ class Settings {
this.default['version'] = this.getExtensionVersion(); this.default['version'] = this.getExtensionVersion();
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)}); chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
this.sortedPatches = this.sortConfPatches(ExtensionConfPatch);
} }
private storageChangeListener(changes, area) { private storageChangeListener(changes, area) {
@ -171,12 +175,11 @@ class Settings {
return patchesIn.sort( (a, b) => this.compareExtensionVersions(a.forVersion, b.forVersion)); return patchesIn.sort( (a, b) => this.compareExtensionVersions(a.forVersion, b.forVersion));
} }
private findFirstNecessaryPatch(version, extconfPatches) { private findFirstNecessaryPatch(version) {
const sorted = this.sortConfPatches(extconfPatches); return this.sortedPatches.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
return sorted.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
} }
private applySettingsPatches(oldVersion, patches) { private applySettingsPatches(oldVersion) {
let index = this.findFirstNecessaryPatch(oldVersion, patches); let index = this.findFirstNecessaryPatch(oldVersion);
if (index === -1) { if (index === -1) {
this.logger?.log('info','settings','[Settings::applySettingsPatches] There are no pending conf patches.'); this.logger?.log('info','settings','[Settings::applySettingsPatches] There are no pending conf patches.');
@ -184,17 +187,16 @@ class Settings {
} }
// apply all remaining patches // apply all remaining patches
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${patches.length - index} settings patches to apply`); this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${this.sortedPatches.length - index} settings patches to apply`);
while (index < patches.length) { while (index < this.sortedPatches.length) {
const updateFn = patches[index].updateFn; const updateFn = this.sortedPatches[index].updateFn;
delete patches[index].forVersion; delete this.sortedPatches[index].forVersion;
delete patches[index].updateFn; delete this.sortedPatches[index].updateFn;
if (Object.keys(patches[index]).length > 0) { if (Object.keys( this.sortedPatches[index]).length > 0) {
ObjectCopy.overwrite(this.active, patches[index]); ObjectCopy.overwrite(this.active, this.sortedPatches[index]);
} }
if (updateFn) { if (updateFn) {
try { try {
updateFn(this.active, this.getDefaultSettings()); updateFn(this.active, this.getDefaultSettings());
} catch (e) { } catch (e) {
@ -222,15 +224,6 @@ class Settings {
); );
} }
// if (Debug.flushStoredSettings) {
// this.logger?.log('info', 'settings', "%c[Settings::init] Debug.flushStoredSettings is true. Using default settings", "background: #d00; color: #ffd");
// Debug.flushStoredSettings = false; // don't do it again this session
// this.active = this.getDefaultSettings();
// this.active.version = this.version;
// this.set(this.active);
// return this.active;
// }
// if there's no settings saved, return default settings. // if there's no settings saved, return default settings.
if(! settings || (Object.keys(settings).length === 0 && settings.constructor === Object)) { if(! settings || (Object.keys(settings).length === 0 && settings.constructor === Object)) {
this.logger?.log( this.logger?.log(
@ -278,7 +271,7 @@ class Settings {
} }
// in case settings in previous version contained a fucky wucky, we overwrite existing settings with a patch // in case settings in previous version contained a fucky wucky, we overwrite existing settings with a patch
this.applySettingsPatches(oldVersion, ExtensionConfPatch); this.applySettingsPatches(oldVersion);
// set 'whatsNewChecked' flag to false when updating, always // set 'whatsNewChecked' flag to false when updating, always
this.active.whatsNewChecked = false; this.active.whatsNewChecked = false;

View File

@ -54,6 +54,10 @@ export class KeyboardHandler extends KbmBase {
init() { init() {
this.logger.log('info', 'debug', "[KeyboardHandler::init] starting init"); this.logger.log('info', 'debug', "[KeyboardHandler::init] starting init");
// reset keypressActions when re-initializing, otherwise keypressActions will
// multiply in an unwanted way
this.keypressActions = [];
// build the action list — but only from actions that have shortcuts assigned // build the action list — but only from actions that have shortcuts assigned
for (const key in this.settings.active.commands) { for (const key in this.settings.active.commands) {
for (const command of this.settings.active.commands[key]) { for (const command of this.settings.active.commands[key]) {
@ -224,7 +228,6 @@ export class KeyboardHandler extends KbmBase {
this.logger.log('info', 'keyboard', "%c[KeyboardHandler::handleKeyup] Trying to find and execute action for event. Actions/event: ", "color: #ff0", this.keypressActions, event); this.logger.log('info', 'keyboard', "%c[KeyboardHandler::handleKeyup] Trying to find and execute action for event. Actions/event: ", "color: #ff0", this.keypressActions, event);
const isLatin = this.isLatin(event.key); const isLatin = this.isLatin(event.key);
for (const command of this.keypressActions) { for (const command of this.keypressActions) {
if (this.isActionMatch(command.shortcut, event, isLatin)) { if (this.isActionMatch(command.shortcut, event, isLatin)) {
this.eventBus.send(command.action, command.arguments); this.eventBus.send(command.action, command.arguments);

View File

@ -121,7 +121,7 @@ class Resizer {
function: (config: any) => this.setZoom(config.zoom, config.axis, config.noAnnounce) function: (config: any) => this.setZoom(config.zoom, config.axis, config.noAnnounce)
}], }],
'change-zoom': [{ 'change-zoom': [{
function: (config: any) => this.zoomStep(config.step) function: (config: any) => this.zoomStep(config.zoom)
}], }],
'get-ar': [{ 'get-ar': [{
function: () => this.eventBus.send('uw-config-broadcast', {type: 'ar', config: this.lastAr}) function: () => this.eventBus.send('uw-config-broadcast', {type: 'ar', config: this.lastAr})
@ -697,7 +697,7 @@ class Resizer {
private _computeOffsetsRecursionGuard: boolean = false; private _computeOffsetsRecursionGuard: boolean = false;
computeOffsets(stretchFactors: VideoDimensions, ar?: Ar){ computeOffsets(stretchFactors: VideoDimensions, ar?: Ar){
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment); this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment, '— stretch factors before processing:', stretchFactors);
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions(); const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();

View File

@ -40,28 +40,29 @@ class Zoom {
* Increases zoom by a given amount. Does not allow per-axis zoom. * Increases zoom by a given amount. Does not allow per-axis zoom.
* Will set zoom level to x axis (+ given amount) if x and y zooms differ. * Will set zoom level to x axis (+ given amount) if x and y zooms differ.
* @param amount * @param amount
* @param axis leave undefined to apply zoom to both axes
*/ */
zoomStep(amount){ zoomStep(amount: number, axis?: 'x' | 'y') {
this.logScale += amount; let newLog = axis === 'y' ? this.logScaleY : this.logScale;
newLog += amount;
newLog = Math.min(Math.max(newLog, this.minScale), this.maxScale);
if (this.logScale <= this.minScale) { // if axis is undefined, both of this statements should trigger)
this.logScale = this.minScale; if (axis !== 'y') {
this.logScale = newLog;
} }
if (this.logScale >= this.maxScale) { if (axis !== 'x') {
this.logScale = this.maxScale; this.logScaleY = newLog;
} }
this.logScaleY = this.logScale;
this.scale = Math.pow(2, this.logScale); this.scale = Math.pow(2, this.logScale);
this.scaleY = Math.pow(2, this.logScaleY);
this.logger.log('info', 'debug', "[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale); this.logger.log('info', 'debug', "[Zoom::zoomStep] changing zoom by", amount, ". New zoom level:", this.scale);
this.processZoom(); this.processZoom();
} }
setZoom(scale: number, axis?: 'x' |'y', noAnnounce?){ setZoom(scale: number, axis?: 'x' |'y', noAnnounce?){
this.logger.log('info', 'debug', "[Zoom::setZoom] Setting zoom to", scale, "!");
// NOTE: SCALE IS NOT LOGARITHMIC // NOTE: SCALE IS NOT LOGARITHMIC
if(scale < Math.pow(2, this.minScale)) { if(scale < Math.pow(2, this.minScale)) {
scale = this.minScale; scale = this.minScale;
@ -85,8 +86,7 @@ class Zoom {
} }
processZoom() { processZoom() {
// this.conf.resizer.toFixedAr(); this.conf.resizer.toFixedAr();
this.conf.resizer.applyScaling({xFactor: this.scale, yFactor: this.scaleY}, {noAnnounce: true}); this.conf.resizer.applyScaling({xFactor: this.scale, yFactor: this.scaleY}, {noAnnounce: true});
} }