Rework settings popup

This commit is contained in:
Tamius Han 2025-01-26 22:09:32 +01:00
parent d322c0909a
commit af9b123e8d
9 changed files with 301 additions and 203 deletions

View File

@ -19,6 +19,13 @@
<h1>
<span class="smallcaps">Ultrawidify</span>: <small>Quick settings</small>
</h1>
<div v-if="site && siteSettings" style="transform: scale(0.75) translateX(-12.5%); margin-bottom: -0.5rem; align-content: center" class="flex flex-row">
<div>site: {{site.host}}</div>
<SupportLevelIndicator
:siteSupportLevel="siteSupportLevel"
>
</SupportLevelIndicator>
</div>
</div>
<div v-if="BrowserDetect?.processEnvChannel !== 'stable'" class="absolute channel-info version-info">
Build channel: {{BrowserDetect?.processEnvChannel}} <br/>
@ -113,6 +120,7 @@ import Settings from '../ext/lib/Settings';
import Logger from '../ext/lib/Logger';
import EventBus from '../ext/lib/EventBus';
import {ChromeShittinessMitigations as CSM} from '../common/js/ChromeShittinessMitigations';
import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue'
export default {
components: {
@ -122,6 +130,7 @@ export default {
PlayerDetectionPanel,
BaseExtensionSettings,
InPlayerUIAdvertisement,
SupportLevelIndicator,
AboutPanel
},
data () {
@ -146,6 +155,11 @@ export default {
],
}
},
computed: {
siteSupportLevel() {
return (this.site && this.siteSettings) ? this.siteSettings.data.type || 'no-support' : 'waiting';
}
},
async created() {
this.logger = new Logger();
await this.logger.init({

View File

@ -103,7 +103,6 @@ body {
}
.label {
padding-top: 1.5rem;
font-size: 1.5rem;
font-variant: small-caps;
font-weight: 600;

View File

@ -138,8 +138,7 @@ import ChangelogPanel from './PlayerUiPanels/ChangelogPanel.vue'
import AboutPanel from '@csui/src/PlayerUiPanels/AboutPanel.vue'
import PlayerUiSettings from './PlayerUiPanels/PlayerUiSettings.vue'
import ResetBackupPanel from './PlayerUiPanels/ResetBackupPanel.vue'
import SupportLevelIndicator from './components/SupportLevelIndicator.vue'
import SupportLevelIndicator from '@csui/src/components/SupportLevelIndicator.vue'
export default {
components: {

View File

@ -3,7 +3,8 @@
<!-- Enable extension -->
<div class="field">
<div class="label">
Enable extension under the following conditions:
Enable <span class="color-emphasis">extension</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
@ -18,7 +19,7 @@
</option>
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled (unless enabled for specific site)
Disabled by default
</option>
</template>
<template v-else>
@ -42,185 +43,224 @@
</div>
</div>
<!-- Enable AARD -->
<div class="field">
<div class="label">
Enable automatic aspect ratio detection under the following conditions:
</div>
<div class="select">
<select
v-model="simpleExtensionSettings.enableAard"
@click="setExtensionMode('enableAard', $event)"
>
<option
v-if="simpleExtensionSettings.enable === 'complex'"
value="complex"
<!-- The rest of the menu is disabled when extension is disabled -->
<div :class="{disabled: simpleExtensionSettings.enable === 'disabled' }">
<!-- Enable AARD -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">automatic aspect ratio detection</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
v-model="simpleExtensionSettings.enableAard"
@click="setExtensionMode('enableAard', $event)"
>
(Site uses advanced settings)
</option>
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled (unless enabled for specific site)
<option
v-if="simpleExtensionSettings.enable === 'complex'"
value="complex"
>
(Site uses advanced settings)
</option>
</template>
<template v-else>
<option value="default">
Use default ()
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled by default
</option>
</template>
<template v-else>
<option value="default">
Use default ()
</option>
<option value="disabled">
Never
</option>
</template>
<option value="fs">
Fullscreen only
</option>
<option value="disabled">
Never
<option value="theater">
Fullscreen and theater mode
</option>
</template>
<option value="fs">
Fullscreen only
</option>
<option value="theater">
Fullscreen and theater mode
</option>
<option value="enabled">
Always
</option>
</select>
<option value="enabled">
Always
</option>
</select>
</div>
</div>
</div>
<!-- Enable keyboard -->
<div class="field">
<div class="label">
Enable keyboard shortcuts under the following conditions
</div>
<div class="select">
<select
v-model="simpleExtensionSettings.enableKeyboard"
@click="setExtensionMode('enableKeyboard', $event)"
>
<option
v-if="simpleExtensionSettings.enable === 'complex'"
value="complex"
<!-- Enable keyboard -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">keyboard shortcuts</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
v-model="simpleExtensionSettings.enableKeyboard"
@click="setExtensionMode('enableKeyboard', $event)"
>
(Site uses advanced settings)
</option>
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled (unless enabled for specific site)
<option
v-if="simpleExtensionSettings.enable === 'complex'"
value="complex"
>
(Site uses advanced settings)
</option>
</template>
<template v-else>
<option value="default">
Use default ()
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled by default
</option>
</template>
<template v-else>
<option value="default">
Use default ()
</option>
<option value="disabled">
Never
</option>
</template>
<option value="fs">
Fullscreen only
</option>
<option value="disabled">
Never
<option value="theater">
Fullscreen and theater mode
</option>
</template>
<option value="fs">
Fullscreen only
</option>
<option value="theater">
Fullscreen and theater mode
</option>
<option value="enabled">
Always
</option>
</select>
<option value="enabled">
Always
</option>
</select>
</div>
</div>
</div>
<!-- Default crop -->
<div class="field">
<div class="label">Default crop:</div>
<div class="select">
<select
v-model="siteDefaultCrop"
@change="setOption('defaults.crop', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
<!-- Enable keyboard -->
<div class="field">
<div class="label">
Enable <span class="color-emphasis">in-player UI</span>
<span class="sub-label"><br/>under the following conditions:</span>
</div>
<div class="select">
<select
v-model="simpleExtensionSettings.enableUI"
@click="setExtensionMode('enableUI', $event)"
>
Use default ({{getCommandValue(settings?.active.commands.crop, siteSettings.data.defaults.crop)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.crop"
:key="index"
:value="JSON.stringify(command.arguments)"
<template v-if="isDefaultConfiguration">
<option value="disabled">
Disabled by default
</option>
</template>
<template v-else>
<option value="default">
Use default ()
</option>
<option value="disabled">
Never
</option>
</template>
<option value="fs">
Fullscreen only
</option>
<option value="theater">
Always where possible
</option>
</select>
</div>
</div>
<!-- Default crop -->
<div class="field">
<div class="label">Default crop:</div>
<div class="select">
<select
v-model="siteDefaultCrop"
@change="setOption('defaults.crop', $event)"
>
{{command.label}}
</option>
</select>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getCommandValue(settings?.active.commands.crop, siteSettings.data.defaults.crop)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.crop"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
<div class="hint">This is how extension will crop video if/when autodetection is disabled. Pick 'Reset' option to keep aspect ratio as-is by default.</div>
</div>
<!-- Default stretch -->
<div class="field">
<div class="label">Default stretch:</div>
<div class="select">
<select
v-model="siteDefaultStretch"
@change="setOption('defaults.stretch', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
<!-- Default stretch -->
<div class="field">
<div class="label">Default stretch:</div>
<div class="select">
<select
v-model="siteDefaultStretch"
@change="setOption('defaults.stretch', $event)"
>
Use default ({{getCommandValue(settings?.active.commands.stretch, siteSettings.data.defaults.stretch)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.stretch"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getCommandValue(settings?.active.commands.stretch, siteSettings.data.defaults.stretch)}})
</option>
<option
v-for="(command, index) of settings?.active.commands.stretch"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
</div>
<!-- Default alignment -->
<div class="field">
<div class="label">Default alignment:</div>
<div class="select">
<select
v-model="siteDefaultAlignment"
@change="setOption('defaults.alignment', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
<!-- Default alignment -->
<div class="field">
<div class="label">Default alignment:</div>
<div class="select">
<select
v-model="siteDefaultAlignment"
@change="setOption('defaults.alignment', $event)"
>
Use default ({{getAlignmentLabel(siteSettings.data.defaults.alignment)}})
</option>
<option
v-for="(command, index) of alignmentOptions"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
<option
v-if="!isDefaultConfiguration"
:value="JSON.stringify({useDefault: true})"
>
Use default ({{getAlignmentLabel(siteSettings.data.defaults.alignment)}})
</option>
<option
v-for="(command, index) of alignmentOptions"
:key="index"
:value="JSON.stringify(command.arguments)"
>
{{command.label}}
</option>
</select>
</div>
</div>
</div>
<!-- Crop, et. al. Persistence -->
<div class="field">
<div class="label">Persist crop, stretch, and alignment between videos</div>
<div class="select">
<select
v-model="siteDefaultCropPersistence"
@click="setOption('persistCSA', $event)"
>
<option
v-if="!isDefaultConfiguration"
:value="CropModePersistence.Default"
<!-- Crop, et. al. Persistence -->
<div class="field">
<div class="label">Persist crop, stretch, and alignment between videos</div>
<div class="select">
<select
v-model="siteDefaultCropPersistence"
@click="setOption('persistCSA', $event)"
>
Use default ({{defaultPersistanceLabel}})
</option>
<option :value="CropModePersistence.Disabled">Disabled</option>
<option :value="CropModePersistence.UntilPageReload">Until page reload</option>
<option :value="CropModePersistence.CurrentSession">Current session</option>
<option :value="CropModePersistence.Forever">Always persist</option>
</select>
<option
v-if="!isDefaultConfiguration"
:value="CropModePersistence.Default"
>
Use default ({{defaultPersistanceLabel}})
</option>
<option :value="CropModePersistence.Disabled">Disabled</option>
<option :value="CropModePersistence.UntilPageReload">Until page reload</option>
<option :value="CropModePersistence.CurrentSession">Current session</option>
<option :value="CropModePersistence.Forever">Always persist</option>
</select>
</div>
</div>
</div>
</div>
@ -401,13 +441,20 @@ export default {
commandArguments = undefined;
}
console.log('saving settings ...');
await this.siteSettings.set(option, commandArguments, {reload: false});
console.log('settings saved.');
// changing alignment options doesn't trigger re-compute, so we need to do it ourselves.
// note that this re-computes siteDefaultAlignment even when setting other options, but
// it's _too late AM_ and hit to performance probably isn't bad enough to warrant
// spending time on a more correct solution tomorrow
this._computedWatchers.siteDefaultAlignment.run();
// we also need to force re-compute all watchers, otherwise UI will lag behind
// actual state of settings until reload
this._computedWatchers?.simpleExtensionSettings?.run();
this._computedWatchers?.siteDefaultCrop?.run();
this._computedWatchers?.siteDefaultStretch?.run();
this._computedWatchers?.siteDefaultAlignment?.run();
this._computedWatchers?.siteDefaultCropPersistence?.run();
this._computedWatchers?.defaultPersistanceLabel?.run();
console.log('watchers recomputed');
this.$nextTick( () => this.$forceUpdate());
},

View File

@ -16,7 +16,7 @@
<ShortcutButton
v-if="editMode"
class="button b3"
:class="{active: editMode ? editModeOptions?.crop?.selectedIndex === null : isActiveCrop(command)}"
:class="{active: editMode ? editModeOptions?.crop?.selectedIndex === null : isActiveCrop(command)}"
label="Add new"
@click="editAction(
{action: 'set-ar', label: 'New aspect ratio', arguments: {type: AspectRatioType.Fixed}},
@ -54,12 +54,13 @@
@blur="editModeOptions.crop.selected.label === 'New aspect ratio' ? editModeOptions.crop.selected.label = editModeOptions.crop.selected.arguments.ratio : null"
>
</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>
<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:
@ -67,9 +68,9 @@
<div class="input">
<input v-model="editModeOptions.crop.selected.label">
</div>
<div class="hint">
Label for the button. You can make it say something other than ratio.
</div>
</div>
<div class="hint">
Label for the button. You can make it say something other than ratio.
</div>
</template>
@ -83,11 +84,11 @@
>
</EditShortcutButton>
</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>
<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">

View File

@ -73,10 +73,11 @@
@change="(event) => updateSettings(true)"
>
</div>
<div class="hint">
Width of the trigger zone (% of player area).
</div>
</div>
<div class="hint">
Width of the trigger zone (% of player area).
</div>
<div class="field">
<div class="label">Trigger zone height:</div>
<div class="input range-input">
@ -95,10 +96,11 @@
@change="(event) => updateSettings(true)"
>
</div>
<div class="hint">
Height of the trigger zone (% of player area).
</div>
</div>
<div class="hint">
Height of the trigger zone (% of player area).
</div>
<div class="field">
<div class="label">Trigger zone horizontal offset:</div>
<div class="input range-input">
@ -116,10 +118,11 @@
@change="(event) => updateSettings(true)"
>
</div>
<div class="hint">
By default, trigger zone is centered around the button. This option moves trigger zone left and right.
</div>
</div>
<div class="hint">
By default, trigger zone is centered around the button. This option moves trigger zone left and right.
</div>
<div class="field">
<div class="label">Trigger zone vertical offset:</div>
<div class="input range-input">
@ -137,9 +140,9 @@
@change="(event) => updateSettings(true)"
>
</div>
<div class="hint">
By default, trigger zone is centered around the button. This option moves trigger zone up and down.
</div>
</div>
<div class="hint">
By default, trigger zone is centered around the button. This option moves trigger zone up and down.
</div>
<div class="action-row">

View File

@ -1,5 +1,16 @@
<template>
<div class="flex flex-col" style="padding-bottom: 20px">
<!--
Extension is disabled for a given site when it's disabled in full screen, since
current settings do not allow the extension to only be disabled while in full screen
-->
<template v-if="siteSettings.isEnabledForEnvironment(false, true) === ExtensionMode.Disabled">
<div class="info">
Extension is not enabled for this site.
</div>
</template>
<div class="flex flex-row">
<mdicon name="crop" :size="24" />&nbsp;&nbsp;
<h1>Crop video:</h1>
@ -40,11 +51,13 @@
import CropOptionsPanel from '../../PlayerUiPanels/PanelComponents/VideoSettings/CropOptionsPanel';
import StretchOptionsPanel from '../../PlayerUiPanels/PanelComponents/VideoSettings/StretchOptionsPanel.vue';
import ZoomOptionsPanel from '../../PlayerUiPanels/PanelComponents/VideoSettings/ZoomOptionsPanel.vue';
import ExtensionMode from '@src/common/enums/ExtensionMode.enum.ts';
export default {
data() {
return {
exec: null,
ExtensionMode: ExtensionMode,
};
},
mixins: [

View File

@ -115,7 +115,9 @@ button, .button {
.field {
display: flex;
flex-direction: row;
flex-wrap: wrap;
box-sizing: border-box;
width: 100%;
max-width: 100%;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
@ -129,28 +131,39 @@ button, .button {
.label {
flex: 0 0 25%;
min-width: 16rem;
text-align: right;
padding-right: 1rem;
.color-emphasis {
color: #fa6;
}
.sub-label {
font-size: 0.9em;
opacity: 0.69;
}
}
.input, .range-input {
flex: 0 0 70%;
flex-grow: 1;
flex-shrink: 1;
max-width: 24rem;
}
.hint {
padding-left: calc(25% + 1rem);
font-size: 0.8rem;
opacity: 0.7;
margin-top: 0.25rem;
width: 100%;
.has-hint {
display: flex;
flex-direction: column;
}
.select {
flex-grow: 1;
flex-shrink: 1;
select {
background: rgba($blackBg, $hoverTransparentOpacity);
color: #fff;
border: 0px solid transparent;
// border: 0px solid transparent;
border: 1px solid rgba(255, 171, 102, 0.42);
padding: 0.5rem 1rem 0.25rem;
outline: none;
@ -160,6 +173,15 @@ button, .button {
}
}
}
.hint {
font-size: 0.8rem;
opacity: 0.7;
margin-top: 0.25rem;
margin-bottom: 0.75rem;
margin-left: 5rem;
// width: 100%;
box-sizing:border-box;
}
.options-bar {
position: absolute;

View File

@ -224,7 +224,7 @@ export class SiteSettings {
* @param isFullscreen
* @returns ExtensionMode
*/
isEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
isEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean): ExtensionMode {
const env = this._getEnvironment(isTheater, isFullscreen);
return this.data.enable[env];
}
@ -235,7 +235,7 @@ export class SiteSettings {
* @param isFullscreen
* @returns
*/
isAardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
isAardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean): ExtensionMode {
const env = this._getEnvironment(isTheater, isFullscreen);
return this.data.enableAard[env];
}
@ -246,7 +246,7 @@ export class SiteSettings {
* @param isFullscreen
* @returns
*/
isKeyboardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean) {
isKeyboardEnabledForEnvironment(isTheater: boolean, isFullscreen: boolean): ExtensionMode {
const env = this._getEnvironment(isTheater, isFullscreen);
return this.data.enableKeyboard[env];
}