Compare commits
4 Commits
518e09e3cb
...
32c11d1f61
Author | SHA1 | Date | |
---|---|---|---|
32c11d1f61 | |||
5c48747d0f | |||
5a0abb3595 | |||
95b98c9053 |
@ -78,9 +78,7 @@
|
|||||||
</Popup>
|
</Popup>
|
||||||
<button class="flex-grow" @click="exportSettings()">Export settings</button>
|
<button class="flex-grow" @click="exportSettings()">Export settings</button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<ConfirmButton
|
<ConfirmButton
|
||||||
dialogType="danger"
|
dialogType="danger"
|
||||||
@onConfirmed="resetSettings"
|
@onConfirmed="resetSettings"
|
||||||
@ -130,15 +128,10 @@
|
|||||||
</JsonEditor>
|
</JsonEditor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Settings migration report</h2>
|
|
||||||
<pre>
|
|
||||||
{{settings.migrationReport}}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
<h2>Settings snapshots</h2>
|
<h2>Settings snapshots</h2>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<div v-for="(snapshot, index) of settingsSnapshots" :key="snapshot.createdAt">
|
<div v-for="(snapshot, index) of settingsSnapshots" :key="snapshot.createdAt">
|
||||||
<small>{{snapshot.createdAt.toISOString()}}</small>
|
<small>{{new Date(snapshot.createdAt).toISOString()}}</small>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
{{snapshot.name}}
|
{{snapshot.name}}
|
||||||
@ -208,6 +201,7 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.resetSettingsEditor();
|
this.resetSettingsEditor();
|
||||||
|
this.loadSettingsSnapshots();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setTab(tab) {
|
setTab(tab) {
|
||||||
|
@ -134,16 +134,25 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ShortcutButton from '../../../components/ShortcutButton.vue';
|
import ShortcutButton from '@csui/src/components/ShortcutButton.vue';
|
||||||
import EditShortcutButton from '../../../components/EditShortcutButton';
|
import EditShortcutButton from '@csui/src/components/EditShortcutButton';
|
||||||
import EditModeMixin from '../../../utils/EditModeMixin';
|
import EditModeMixin from '@csui/src/utils/EditModeMixin';
|
||||||
import KeyboardShortcutParserMixin from '../../../utils/KeyboardShortcutParserMixin';
|
import KeyboardShortcutParserMixin from '@csui/src/utils/KeyboardShortcutParserMixin';
|
||||||
import CommsMixin from '../../../utils/CommsMixin';
|
import CommsMixin from '@csui/src/utils/CommsMixin';
|
||||||
import AspectRatioType from '../../../../../common/enums/AspectRatioType.enum';
|
import AspectRatioType from '@src/common/enums/AspectRatioType.enum';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ShortcutButton,
|
||||||
|
EditShortcutButton,
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
// ComputeActionsMixin,
|
||||||
|
EditModeMixin,
|
||||||
|
KeyboardShortcutParserMixin,
|
||||||
|
CommsMixin
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
AspectRatioType: AspectRatioType,
|
AspectRatioType: AspectRatioType,
|
||||||
|
|
||||||
@ -156,12 +165,6 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [
|
|
||||||
// ComputeActionsMixin,
|
|
||||||
EditModeMixin,
|
|
||||||
KeyboardShortcutParserMixin,
|
|
||||||
CommsMixin
|
|
||||||
],
|
|
||||||
props: [
|
props: [
|
||||||
'settings', // required for buttons and actions, which are global
|
'settings', // required for buttons and actions, which are global
|
||||||
'siteSettings',
|
'siteSettings',
|
||||||
@ -169,10 +172,6 @@ export default {
|
|||||||
'isEditing',
|
'isEditing',
|
||||||
'allowSettingSiteDefault'
|
'allowSettingSiteDefault'
|
||||||
],
|
],
|
||||||
components: {
|
|
||||||
ShortcutButton,
|
|
||||||
EditShortcutButton,
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
siteDefaultCrop() {
|
siteDefaultCrop() {
|
||||||
if (!this.siteSettings) {
|
if (!this.siteSettings) {
|
||||||
|
@ -50,11 +50,11 @@
|
|||||||
v-model="editModeOptions.stretch.selected.arguments.limit"
|
v-model="editModeOptions.stretch.selected.arguments.limit"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
If vertical borders would take up less than this much of screen width, the image will be stretched. If the borders are too thick, image will not be stretched.
|
If vertical borders would take up less than this much of screen width, the image will be stretched. If the borders are too thick, image will not be stretched.
|
||||||
Value of 1 means 100%. Value of 0.1 means vertical black bars can take up 10% of the width at most. There's no validation on this, use common sense.
|
Value of 1 means 100%. Value of 0.1 means vertical black bars can take up 10% of the width at most. There's no validation on this, use common sense.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- Some options are only shown for type 5 (fixed) stretch -->
|
<!-- Some options are only shown for type 5 (fixed) stretch -->
|
||||||
@ -70,12 +70,12 @@
|
|||||||
@blur="editModeOptions.stretch.selected.label === 'Stretch to ...' ? editModeOptions.stretch.selected.label = `Stretch to ${editModeOptions.stretch.selected.arguments.ratio}` : null"
|
@blur="editModeOptions.stretch.selected.label === 'Stretch to ...' ? editModeOptions.stretch.selected.label = `Stretch to ${editModeOptions.stretch.selected.arguments.ratio}` : null"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
You can enter a ratio in width:height format (e.g. "21:9" or "1:2.39"), or just the factor
|
You can enter a ratio in width:height format (e.g. "21:9" or "1:2.39"), or just the factor
|
||||||
(in this case, "1:2.39" would become "2.39" and "21:9" would become "2.33"). You should enter
|
(in this case, "1:2.39" would become "2.39" and "21:9" would become "2.33"). You should enter
|
||||||
your numbers without quote marks. Number will be converted to factor form on save.
|
your numbers without quote marks. Number will be converted to factor form on save.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="label">
|
<div class="label">
|
||||||
Label:
|
Label:
|
||||||
@ -83,10 +83,10 @@
|
|||||||
<div class="input">
|
<div class="input">
|
||||||
<input v-model="editModeOptions.stretch.selected.label">
|
<input v-model="editModeOptions.stretch.selected.label">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
Label for the button. You can make it say something other than ratio.
|
Label for the button. You can make it say something other than ratio.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- editing keyboard shortcuts is always allowed -->
|
<!-- editing keyboard shortcuts is always allowed -->
|
||||||
@ -99,12 +99,12 @@
|
|||||||
>
|
>
|
||||||
</EditShortcutButton>
|
</EditShortcutButton>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
<b>Note:</b> Your browser and OS already use certain key combinations that involve Ctrl and Meta (Windows) keys — and, to a lesser extent, Alt.
|
<b>Note:</b> Your browser and OS already use certain key combinations that involve Ctrl and Meta (Windows) keys — and, to a lesser extent, Alt.
|
||||||
The extension doesn't (and cannot) check whether the keyboard shortcut you enter is actually free for you to use. The extension also won't override
|
The extension doesn't (and cannot) check whether the keyboard shortcut you enter is actually free for you to use. The extension also won't override
|
||||||
any keyboard shortcuts defined by the site itself.
|
any keyboard shortcuts defined by the site itself.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-row flex-end">
|
<div class="flex flex-row flex-end">
|
||||||
<div
|
<div
|
||||||
|
@ -1,5 +1,132 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
|
|
||||||
|
<div class="sub-panel-content flex flex-row flex-wrap">
|
||||||
|
|
||||||
|
<ShortcutButton
|
||||||
|
v-for="(command, index) of settings?.active.commands.zoom"
|
||||||
|
class="flex b3 button"
|
||||||
|
:class="{active: editMode ? index === editModeOptions?.zoom?.selectedIndex : isActiveZoom(command)}"
|
||||||
|
:key="index"
|
||||||
|
:label="command.label"
|
||||||
|
:shortcut="getKeyboardShortcutLabel(command)"
|
||||||
|
@click="editMode ? editAction(command, index, 'zoom') : execAction(command)"
|
||||||
|
>
|
||||||
|
</ShortcutButton>
|
||||||
|
|
||||||
|
<!-- "Add new" button -->
|
||||||
|
<ShortcutButton
|
||||||
|
v-if="editMode"
|
||||||
|
class="button b3"
|
||||||
|
:class="{active: editMode ? editModeOptions?.crop?.selectedIndex === null : isActiveCrop(command)}"
|
||||||
|
label="Add new"
|
||||||
|
@click="editAction(
|
||||||
|
{action: 'set-ar-zoom', label: 'New aspect ratio', arguments: {type: AspectRatioType.Fixed}},
|
||||||
|
null,
|
||||||
|
'zoom'
|
||||||
|
)"
|
||||||
|
></ShortcutButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="isEditing">
|
||||||
|
<div v-if="editMode && editModeOptions?.zoom?.selected" class="sub-panel-content">
|
||||||
|
<div class="edit-action-area-header">
|
||||||
|
<span class="text-primary">Editing options for:</span> <b>{{editModeOptions?.zoom?.selected?.label}}</b>
|
||||||
|
<template v-if="editModeOptions?.zoom?.selectedIndex === null && editModeOptions?.zoom?.selected?.label !== 'New aspect ratio'">(New ratio)</template>
|
||||||
|
</div>
|
||||||
|
<div class="edit-action-area">
|
||||||
|
<!-- Some options are only shown for type 4 (fixed) zooms -->
|
||||||
|
<template v-if="editModeOptions?.zoom?.selected?.arguments?.type === AspectRatioType.Fixed">
|
||||||
|
<div class="field">
|
||||||
|
<div class="label">
|
||||||
|
Ratio:
|
||||||
|
</div>
|
||||||
|
<div class="input">
|
||||||
|
<!-- We do an ugly in order to avoid spamming functions down at the bottom -->
|
||||||
|
<input
|
||||||
|
v-model="editModeOptions.zoom.selected.arguments.ratio"
|
||||||
|
@blur="editModeOptions.zoom.selected.label === 'New aspect ratio' ? editModeOptions.zoom.selected.label = editModeOptions.zoom.selected.arguments.ratio : null"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
You can enter a ratio in width:height format (e.g. "21:9" or "1:2.39"), or just the factor
|
||||||
|
(in this case, "1:2.39" would become "2.39" and "21:9" would become "2.33"). You should enter
|
||||||
|
your numbers without quote marks. Number will be converted to factor form on save.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="label">
|
||||||
|
Label:
|
||||||
|
</div>
|
||||||
|
<div class="input">
|
||||||
|
<input v-model="editModeOptions.zoom.selected.label">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
Label for the button. You can make it say something other than ratio.
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- editing keyboard shortcuts is always allowed -->
|
||||||
|
<div class="field">
|
||||||
|
<div class="label">Shortcut:</div>
|
||||||
|
<div class="">
|
||||||
|
<EditShortcutButton
|
||||||
|
:shortcut="editModeOptions?.zoom?.selected?.shortcut"
|
||||||
|
@shortcutChanged="updateSelectedShortcut($event, 'zoom')"
|
||||||
|
>
|
||||||
|
</EditShortcutButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="hint">
|
||||||
|
<b>Note:</b> Your browser and OS already use certain key combinations that involve Ctrl and Meta (Windows) keys — and, to a lesser extent, Alt.
|
||||||
|
The extension doesn't (and cannot) check whether the keyboard shortcut you enter is actually free for you to use. The extension also won't override
|
||||||
|
any keyboard shortcuts defined by the site itself.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-row flex-end">
|
||||||
|
<div
|
||||||
|
v-if="editModeOptions?.zoom?.selected?.arguments?.type === AspectRatioType.Fixed && editModeOptions?.zoom?.selectedIndex !== null"
|
||||||
|
class="button"
|
||||||
|
@click="deleteAction('zoom')"
|
||||||
|
>
|
||||||
|
<mdicon name="delete"></mdicon> Delete
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow"></div>
|
||||||
|
<div class="button" @click="cancelEdit('zoom')">Cancel</div>
|
||||||
|
<div class="button" @click="saveShortcut('zoom')">
|
||||||
|
<mdicon name="floppy"></mdicon>
|
||||||
|
|
||||||
|
<template v-if="editModeOptions?.zoom?.selectedIndex === null">Add</template>
|
||||||
|
<template v-else>Save</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <div v-if="siteSettings && allowSettingSiteDefault" class="edit-action-area">
|
||||||
|
<div class="field">
|
||||||
|
<div class="label">Default for this site</div>
|
||||||
|
<div class="select">
|
||||||
|
<select
|
||||||
|
:value="siteDefaultZoom"
|
||||||
|
@change="setDefaultZoom($event, 'site')"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(command, index) of settings?.active.commands.zoom"
|
||||||
|
:key="index"
|
||||||
|
:value="JSON.stringify(command.arguments)"
|
||||||
|
>
|
||||||
|
{{command.label}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
<!--
|
<!--
|
||||||
min, max and value need to be implemented in js as this slider
|
min, max and value need to be implemented in js as this slider
|
||||||
should use logarithmic scale
|
should use logarithmic scale
|
||||||
@ -73,14 +200,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ShortcutButton from '@csui/src/components/ShortcutButton.vue';
|
||||||
|
import EditShortcutButton from '@csui/src/components/EditShortcutButton';
|
||||||
|
import EditModeMixin from '@csui/src/utils/EditModeMixin';
|
||||||
|
import KeyboardShortcutParserMixin from '@csui/src/utils/KeyboardShortcutParserMixin';
|
||||||
|
import CommsMixin from '@csui/src/utils/CommsMixin';
|
||||||
|
import AspectRatioType from '@src/common/enums/AspectRatioType.enum';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
ShortcutButton,
|
||||||
|
EditShortcutButton,
|
||||||
|
},
|
||||||
|
mixins: [
|
||||||
|
// ComputeActionsMixin,
|
||||||
|
EditModeMixin,
|
||||||
|
KeyboardShortcutParserMixin,
|
||||||
|
CommsMixin
|
||||||
|
],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
AspectRatioType,
|
||||||
|
|
||||||
zoomAspectRatioLocked: true,
|
zoomAspectRatioLocked: true,
|
||||||
zoom: {
|
zoom: {
|
||||||
x: 0,
|
x: 0,
|
||||||
@ -96,15 +242,26 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [
|
|
||||||
|
|
||||||
],
|
|
||||||
props: [
|
props: [
|
||||||
'settings', // required for buttons and actions, which are global
|
'settings', // required for buttons and actions, which are global
|
||||||
'siteSettings',
|
'siteSettings',
|
||||||
'eventBus',
|
'eventBus',
|
||||||
'isEditing'
|
'isEditing'
|
||||||
],
|
],
|
||||||
|
created() {
|
||||||
|
if (this.isEditing) {
|
||||||
|
this.enableEditMode();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
isEditing(newValue, oldValue) {
|
||||||
|
if (newValue) {
|
||||||
|
this.enableEditMode();
|
||||||
|
} else {
|
||||||
|
this.disableEditMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getZoomForDisplay(axis) {
|
getZoomForDisplay(axis) {
|
||||||
// zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications
|
// zoom is internally handled logarithmically, because we want to have x0.5, x1, x2, x4 ... magnifications
|
||||||
@ -146,6 +303,9 @@ export default {
|
|||||||
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: axis ?? 'x'});
|
this.eventBus?.sendToTunnel('set-zoom', {zoom: newZoom, axis: axis ?? 'x'});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isActiveZoom(command) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +135,19 @@
|
|||||||
:isEditing="true"
|
:isEditing="true"
|
||||||
></StretchOptionsPanel>
|
></StretchOptionsPanel>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- ZOOM OPTIONS -->
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<h3 class="mth3">ZOOM OPTIONS</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ZoomOptionsPanel
|
||||||
|
:settings="settings"
|
||||||
|
:eventBus="eventBus"
|
||||||
|
:isEditing="true"
|
||||||
|
></ZoomOptionsPanel>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -142,16 +155,18 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Button from '../components/Button.vue'
|
import Button from '@csui/src/components/Button.vue'
|
||||||
import BrowserDetect from '../../../ext/conf/BrowserDetect';
|
import BrowserDetect from '@src/ext/conf/BrowserDetect';
|
||||||
import CropOptionsPanel from './PanelComponents/VideoSettings/CropOptionsPanel.vue'
|
import CropOptionsPanel from '@csui/src/PlayerUiPanels/PanelComponents/VideoSettings/CropOptionsPanel.vue'
|
||||||
import StretchOptionsPanel from './PanelComponents/VideoSettings/StretchOptionsPanel.vue'
|
import StretchOptionsPanel from '@csui/src/PlayerUiPanels/PanelComponents/VideoSettings/StretchOptionsPanel.vue'
|
||||||
|
import ZoomOptionsPanel from '@csui/src/PlayerUiPanels/PanelComponents/VideoSettings/ZoomOptionsPanel.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Button,
|
Button,
|
||||||
CropOptionsPanel,
|
CropOptionsPanel,
|
||||||
StretchOptionsPanel
|
StretchOptionsPanel,
|
||||||
|
ZoomOptionsPanel,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -267,7 +282,7 @@ export default {
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
width: calc(50% - 0.5rem);
|
width: calc(33% - 0.5rem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ 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';
|
import { update } from 'lodash';
|
||||||
|
|
||||||
const ExtensionConfPatch = [
|
const ExtensionConfPatch = Object.freeze([
|
||||||
{
|
{
|
||||||
forVersion: '6.2.4',
|
forVersion: '6.2.4',
|
||||||
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
|
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
|
||||||
@ -35,6 +35,19 @@ const ExtensionConfPatch = [
|
|||||||
}, {
|
}, {
|
||||||
forVersion: '6.2.6',
|
forVersion: '6.2.6',
|
||||||
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
|
updateFn: (userOptions: SettingsInterface, defaultOptions) => {
|
||||||
|
|
||||||
|
console.warn('[ultrawidify] STARTING SETTINGS MIGRATION TO 6.2.6');
|
||||||
|
|
||||||
|
if (!userOptions.commands) {
|
||||||
|
userOptions.commands = {
|
||||||
|
zoom: [],
|
||||||
|
crop: [],
|
||||||
|
stretch: [],
|
||||||
|
pan: [],
|
||||||
|
internal: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
userOptions.commands.zoom = [{
|
userOptions.commands.zoom = [{
|
||||||
action: 'change-zoom',
|
action: 'change-zoom',
|
||||||
label: 'Zoom +5%',
|
label: 'Zoom +5%',
|
||||||
@ -92,9 +105,139 @@ const ExtensionConfPatch = [
|
|||||||
showDetectionDetails: true
|
showDetectionDetails: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const newZoomActions = [{
|
||||||
|
action: 'set-zoom',
|
||||||
|
label: 'Reset zoom',
|
||||||
|
shortcut: {
|
||||||
|
key: 'r',
|
||||||
|
code: 'KeyR',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
|
},
|
||||||
|
internalOnly: true,
|
||||||
|
actionId: 'set-zoom-reset'
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: 'Automatic',
|
||||||
|
comment: 'Automatically detect aspect ratio and zoom accordingly',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Automatic
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'a',
|
||||||
|
code: 'KeyA',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: 'Cycle',
|
||||||
|
comment: 'Cycle through zoom options',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Cycle
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'c',
|
||||||
|
code: 'KeyC',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '21:9',
|
||||||
|
comment: 'Zoom for 21:9 aspect ratio (1:2.39)',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 2.39
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'd',
|
||||||
|
code: 'KeyD',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: false,
|
||||||
|
onKeyDown: true,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '18:9',
|
||||||
|
comment: 'Zoom for 18:9 aspect ratio (1:2)',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 1.78
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 's',
|
||||||
|
code: 'KeyS',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: false,
|
||||||
|
onKeyDown: true,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '32:9',
|
||||||
|
comment: 'Zoom for 32:9 aspect ratio',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 3.56
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
|
const compareShortcuts = (a: any, b: any) => {
|
||||||
|
if (!a || !b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a.key === b.key && b.code === b.code && a.ctrlKey == b.ctrlKey && a.shiftKey == b.shiftKey && a.metaKey == a.metaKey && a.altKey == b.altKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasConflict = (shortcut: any) => {
|
||||||
|
for (const ct in userOptions.commands) {
|
||||||
|
for (const command of userOptions.commands[ct]) {
|
||||||
|
if (compareShortcuts(shortcut, command.shortcut)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const zoomAction of newZoomActions) {
|
||||||
|
if (
|
||||||
|
!userOptions.commands.zoom.find(
|
||||||
|
x => x.action === zoomAction.action
|
||||||
|
&& x.arguments?.type === zoomAction.arguments?.type
|
||||||
|
&& x.arguments?.ratio === zoomAction.arguments?.ratio
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
userOptions.commands.zoom.push({
|
||||||
|
...zoomAction,
|
||||||
|
shortcut: hasConflict(zoomAction.shortcut) ? undefined : zoomAction.shortcut
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
export default ExtensionConfPatch;
|
export default ExtensionConfPatch;
|
||||||
|
@ -401,11 +401,96 @@ const ExtensionConf: SettingsInterface = {
|
|||||||
}, {
|
}, {
|
||||||
action: 'set-zoom',
|
action: 'set-zoom',
|
||||||
label: 'Reset zoom',
|
label: 'Reset zoom',
|
||||||
arguments: {
|
shortcut: {
|
||||||
zoom: 1,
|
key: 'r',
|
||||||
|
code: 'KeyR',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
},
|
},
|
||||||
internalOnly: true,
|
internalOnly: true,
|
||||||
actionId: 'set-zoom-reset'
|
actionId: 'set-zoom-reset'
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: 'Automatic',
|
||||||
|
comment: 'Automatically detect aspect ratio',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Automatic
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'a',
|
||||||
|
code: 'KeyA',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: 'Cycle',
|
||||||
|
comment: 'Cycle through crop options',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Cycle
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'c',
|
||||||
|
code: 'KeyC',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: true,
|
||||||
|
onKeyDown: false,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '21:9',
|
||||||
|
comment: 'Crop for 21:9 aspect ratio (1:2.39)',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 2.39
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 'd',
|
||||||
|
code: 'KeyD',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: false,
|
||||||
|
onKeyDown: true,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '18:9',
|
||||||
|
comment: 'Crop for 18:9 aspect ratio (1:2)',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 1.78
|
||||||
|
},
|
||||||
|
shortcut: {
|
||||||
|
key: 's',
|
||||||
|
code: 'KeyS',
|
||||||
|
ctrlKey: false,
|
||||||
|
metaKey: false,
|
||||||
|
altKey: false,
|
||||||
|
shiftKey: true,
|
||||||
|
onKeyUp: false,
|
||||||
|
onKeyDown: true,
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
action: 'set-ar-zoom',
|
||||||
|
label: '32:9',
|
||||||
|
comment: 'Crop for 32:9 aspect ratio',
|
||||||
|
arguments: {
|
||||||
|
type: AspectRatioType.Fixed,
|
||||||
|
ratio: 3.56
|
||||||
|
},
|
||||||
}],
|
}],
|
||||||
pan: [{
|
pan: [{
|
||||||
action: 'set-alignment',
|
action: 'set-alignment',
|
||||||
|
@ -44,18 +44,9 @@ class Settings {
|
|||||||
onChangedCallbacks: (() => void)[] = [];
|
onChangedCallbacks: (() => void)[] = [];
|
||||||
afterSettingsChangedCallbacks: (() => void)[] = [];
|
afterSettingsChangedCallbacks: (() => void)[] = [];
|
||||||
|
|
||||||
private sortedPatches: any[];
|
|
||||||
|
|
||||||
|
|
||||||
public snapshotManager: SettingsSnapshotManager;
|
public snapshotManager: SettingsSnapshotManager;
|
||||||
|
|
||||||
private _migrationReport: string = '';
|
|
||||||
private set migrationReport(report: string) {
|
|
||||||
this._migrationReport = report;
|
|
||||||
}
|
|
||||||
public get migrationReport(): string {
|
|
||||||
return this._migrationReport;
|
|
||||||
}
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
@ -70,9 +61,6 @@ 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) {
|
||||||
@ -194,7 +182,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private findFirstNecessaryPatch(version) {
|
private findFirstNecessaryPatch(version) {
|
||||||
return this.sortedPatches.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
|
return ExtensionConfPatch.findIndex(x => this.compareExtensionVersions(x.forVersion, version) > 0);
|
||||||
}
|
}
|
||||||
private applySettingsPatches(oldVersion) {
|
private applySettingsPatches(oldVersion) {
|
||||||
let index = this.findFirstNecessaryPatch(oldVersion);
|
let index = this.findFirstNecessaryPatch(oldVersion);
|
||||||
@ -217,20 +205,20 @@ class Settings {
|
|||||||
|
|
||||||
|
|
||||||
// apply all remaining patches
|
// apply all remaining patches
|
||||||
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${this.sortedPatches.length - index} settings patches to apply`);
|
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${ExtensionConfPatch.length - index} settings patches to apply`);
|
||||||
while (index < this.sortedPatches.length) {
|
while (index < ExtensionConfPatch.length) {
|
||||||
const updateFn = this.sortedPatches[index].updateFn;
|
const updateFn = ExtensionConfPatch[index].updateFn;
|
||||||
delete this.sortedPatches[index].forVersion;
|
|
||||||
delete this.sortedPatches[index].updateFn;
|
|
||||||
|
|
||||||
if (Object.keys( this.sortedPatches[index]).length > 0) {
|
|
||||||
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) {
|
||||||
this.logger?.log('error', 'settings', '[Settings::applySettingsPatches] Failed to execute update function. Keeping settings object as-is. Error:', e);
|
this.logger?.log('error', 'settings', '[Settings::applySettingsPatches] Failed to execute update function. Keeping settings object as-is. Error:', e);
|
||||||
|
console.warn(
|
||||||
|
'————————————————————————————————————\n',
|
||||||
|
'Applying patch', index, ' failed :', '\n',
|
||||||
|
e, '\n',
|
||||||
|
'————————————————————————————————————\n',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +242,7 @@ class Settings {
|
|||||||
// |—> on first setup, settings is undefined & settings.version is haram
|
// |—> on first setup, settings is undefined & settings.version is haram
|
||||||
// | since new installs ship with updates by default, no patching is
|
// | since new installs ship with updates by default, no patching is
|
||||||
// | needed. In this case, we assume we're on the current version
|
// | needed. In this case, we assume we're on the current version
|
||||||
const oldVersion = (settings && settings.version) || this.version;
|
const oldVersion = settings?.version ?? this.version;
|
||||||
|
|
||||||
if (settings) {
|
if (settings) {
|
||||||
this.logger?.log('info', 'settings', "[Settings::init] Configuration fetched from storage:", settings,
|
this.logger?.log('info', 'settings', "[Settings::init] Configuration fetched from storage:", settings,
|
||||||
@ -276,6 +264,7 @@ class Settings {
|
|||||||
this.active = this.getDefaultSettings();
|
this.active = this.getDefaultSettings();
|
||||||
this.active.version = this.version;
|
this.active.version = this.version;
|
||||||
await this.save();
|
await this.save();
|
||||||
|
|
||||||
return this.active;
|
return this.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,7 +328,6 @@ class Settings {
|
|||||||
if (!options || !options.forcePreserveVersion) {
|
if (!options || !options.forcePreserveVersion) {
|
||||||
extensionConf.version = this.version;
|
extensionConf.version = this.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger?.log('info', 'settings', "[Settings::set] setting new settings:", extensionConf)
|
this.logger?.log('info', 'settings', "[Settings::set] setting new settings:", extensionConf)
|
||||||
|
|
||||||
return chrome.storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
|
return chrome.storage.local.set( {'uwSettings': JSON.stringify(extensionConf)});
|
||||||
@ -385,7 +373,7 @@ class Settings {
|
|||||||
|
|
||||||
async save(options?: SetSettingsOptions) {
|
async save(options?: SetSettingsOptions) {
|
||||||
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 — save options", options, "; settings:", this.active);
|
||||||
}
|
}
|
||||||
this.active.preventReload = undefined;
|
this.active.preventReload = undefined;
|
||||||
this.active.lastModified = new Date();
|
this.active.lastModified = new Date();
|
||||||
|
@ -92,13 +92,14 @@ export class SettingsSnapshotManager {
|
|||||||
async listSnapshots(): Promise<SettingsSnapshot[]> {
|
async listSnapshots(): Promise<SettingsSnapshot[]> {
|
||||||
const ret = await chrome.storage.local.get('uwSettings-snapshots');
|
const ret = await chrome.storage.local.get('uwSettings-snapshots');
|
||||||
try {
|
try {
|
||||||
JSON.parse(ret['uwSettings-snapshots']) as SettingsSnapshot[];
|
const json = JSON.parse(ret['uwSettings-snapshots']) as SettingsSnapshot[];
|
||||||
|
return json;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return [] as SettingsSnapshot[];
|
return [] as SettingsSnapshot[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async set(snapshots: SettingsSnapshot[]) {
|
private async set(snapshots: SettingsSnapshot[] = []) {
|
||||||
await chrome.storage.local.set({
|
await chrome.storage.local.set({
|
||||||
'uwSettings-snapshots': JSON.stringify(snapshots),
|
'uwSettings-snapshots': JSON.stringify(snapshots),
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user