Compare commits
7 Commits
13cfb9ff14
...
67f848a9ee
Author | SHA1 | Date | |
---|---|---|---|
67f848a9ee | |||
fe336122e0 | |||
6d8d8493a6 | |||
5d7d249fff | |||
35ca030dfb | |||
fab6fb0f5b | |||
3b8fc807f7 |
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div
|
||||
class="context-spawn uw-ui-trigger"
|
||||
style="z-index: 1000"
|
||||
class="context-spawn uw-ui-area"
|
||||
style="z-index: 1000;"
|
||||
v-if="!triggerZoneEditorVisible"
|
||||
>
|
||||
<div
|
||||
class="spawn-container uw-trigger"
|
||||
class="spawn-container uw-ui-trigger debug-2"
|
||||
:style="triggerZoneStyles"
|
||||
@mouseenter="(ev) => setTriggerZoneActive(true, ev)"
|
||||
>
|
||||
|
||||
</div>
|
||||
@ -14,14 +14,14 @@
|
||||
|
||||
<div
|
||||
v-if="contextMenuActive || settingsInitialized && uwTriggerZoneVisible && !isGlobal"
|
||||
class="context-spawn uw-clickable"
|
||||
class="context-spawn uw-clickable uw-ui-area"
|
||||
style="z-index: 1001"
|
||||
@mouseenter="preventContextMenuHide()"
|
||||
@mouseleave="allowContextMenuHide()"
|
||||
|
||||
>
|
||||
<GhettoContextMenu
|
||||
alignment="right" class="uw-menu"
|
||||
@mouseenter="newFeatureViewUpdate('uw6.ui-popup')"
|
||||
@mouseenter="() => {preventContextMenuHide(); newFeatureViewUpdate('uw6.ui-popup')}"
|
||||
@mouseleave="allowContextMenuHide()"
|
||||
>
|
||||
<template v-slot:activator>
|
||||
<div class="context-item">
|
||||
@ -151,7 +151,7 @@
|
||||
|
||||
<div
|
||||
v-if="settingsInitialized && uwWindowVisible"
|
||||
class="uw-window flex flex-col uw-clickable"
|
||||
class="uw-window flex flex-col uw-clickable uw-ui-area"
|
||||
:class="{'fade-out': uwWindowFadeOut}"
|
||||
>
|
||||
<PlayerUIWindow
|
||||
@ -167,17 +167,17 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="context-spawn uw-ui-trigger"
|
||||
style="z-index: 1000;"
|
||||
v-if="triggerZoneEditorVisible"
|
||||
class="context-spawn uw-ui-area"
|
||||
style="z-index: 1000; border: 2px dashed red; overflow: hidden;"
|
||||
>
|
||||
<TriggerZoneEditor
|
||||
class="uw-clickable"
|
||||
:settings="settings"
|
||||
:eventBus="eventBus"
|
||||
:playerDimensions="playerDimensions"
|
||||
>
|
||||
</TriggerZoneEditor>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -228,6 +228,7 @@ export default {
|
||||
uwWindowFadeOut: false,
|
||||
uwWindowCloseTimeout: undefined,
|
||||
uwWindowVisible: false,
|
||||
triggerZoneEditorVisible: false,
|
||||
|
||||
// component properties
|
||||
settings: {},
|
||||
@ -387,6 +388,26 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
this.eventBus.subscribe(
|
||||
'start-trigger-zone-edit',
|
||||
{
|
||||
function: () => {
|
||||
this.triggerZoneEditorVisible = true;
|
||||
this.uwWindowVisible = false;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
this.eventBus.subscribe(
|
||||
'finish-trigger-zone-edit',
|
||||
{
|
||||
function: () => {
|
||||
this.triggerZoneEditorVisible = false;
|
||||
this.showUwWindow('playerUiSettings');
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
this.sendToParentLowLevel('uwui-get-role', null);
|
||||
this.sendToParentLowLevel('uwui-get-theme', null);
|
||||
|
||||
@ -531,13 +552,11 @@ export default {
|
||||
background-color: rgba(0,0,0,0.85) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" src="./src/res-common/panels.scss" scoped module></style>
|
||||
<style lang="scss" src="./src/res-common/common.scss" scoped module></style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import 'res/css/uwui-base.scss';
|
||||
@import 'res/css/colors.scss';
|
||||
@import 'res/css/font/overpass.css';
|
||||
@import 'res/css/font/overpass-mono.css';
|
||||
@import 'res/css/common.scss';
|
||||
@import './src/res-common/_variables';
|
||||
|
||||
.uw-hover {
|
||||
position: absolute;
|
||||
@ -560,7 +579,7 @@ export default {
|
||||
}
|
||||
|
||||
.uw-window {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
|
||||
top: 10%;
|
||||
left: 10%;
|
||||
@ -595,9 +614,15 @@ export default {
|
||||
|
||||
.context-spawn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform: translateY(-50%);
|
||||
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
@ -605,8 +630,6 @@ export default {
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
|
||||
padding: 2rem;
|
||||
|
||||
color: #fff;
|
||||
|
||||
// .context-item {
|
||||
@ -653,4 +676,18 @@ export default {
|
||||
border: 4px solid #fa4;
|
||||
}
|
||||
|
||||
.debug-1 {
|
||||
border: 1px solid yellow;
|
||||
|
||||
&:hover {
|
||||
background-color: rbba(255,255,0,0.5);
|
||||
}
|
||||
}
|
||||
.debug-2 {
|
||||
border: 1px solid blue;
|
||||
|
||||
&:hover {
|
||||
background-color: rbba(0,0,255,.5);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en"; style="position: relative">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="color-scheme" content="light dark">
|
||||
|
@ -1,12 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" style="position: relative">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="color-scheme" content="dark">
|
||||
<title>Ultrawidify - Content Script User Interface (in-player overlay)</title>
|
||||
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||
</head>
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent">
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent;">
|
||||
<div id="app"></div>
|
||||
<script src="csui.js"></script>
|
||||
</body>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" style="position: relative">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="color-scheme" content="light">
|
||||
<title>Ultrawidify - Content Script User Interface (in-player overlay)</title>
|
||||
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||
</head>
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent">
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent;">
|
||||
<div id="app"></div>
|
||||
<script src="csui.js"></script>
|
||||
</body>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" style="position: relative">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Ultrawidify - Content Script User Interface (in-player overlay)</title>
|
||||
<!-- <link rel="stylesheet" href="csui.css"> -->
|
||||
</head>
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent">
|
||||
<body class="uw-ultrawidify-container-root" style="background-color: transparent;">
|
||||
<div id="app"></div>
|
||||
<script src="csui.js"></script>
|
||||
</body>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" style="position: relative">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
|
@ -117,11 +117,11 @@
|
||||
v-if="selectedTab === 'about'"
|
||||
>
|
||||
</AboutPanel>
|
||||
<ResetBackupPanel
|
||||
<!-- <ResetBackupPanel
|
||||
v-if="selectedTab === 'resetBackup'"
|
||||
:settings="settings"
|
||||
>
|
||||
</ResetBackupPanel>
|
||||
</ResetBackupPanel> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -164,14 +164,14 @@ export default {
|
||||
tabs: [
|
||||
// {id: 'videoSettings', label: 'Video settings', icon: 'crop'},
|
||||
{id: 'extensionSettings', label: 'Site and Extension options', icon: 'cogs' },
|
||||
{id: 'playerUiSettings', label: 'In-player interface', icon: 'movie-cog-outline' },
|
||||
{id: 'playerUiSettings', label: 'UI and keyboard', icon: 'movie-cog-outline' },
|
||||
{id: 'playerDetection', label: 'Player detection', icon: 'television-play'},
|
||||
{id: 'autodetectionSettings', label: 'Autodetection options', icon: 'auto-fix'},
|
||||
// {id: 'advancedOptions', label: 'Advanced options', icon: 'cogs' },
|
||||
// {id: 'debugging', label: 'Debugging', icon: 'bug-outline' }
|
||||
{id: 'changelog', label: 'What\'s new', icon: 'alert-decagram' },
|
||||
{id: 'about', label: 'About', icon: 'information-outline'},
|
||||
{id: 'resetBackup', label: 'Reset and backup', icon: 'file-restore-outline'},
|
||||
// {id: 'resetBackup', label: 'Reset and backup', icon: 'file-restore-outline'},
|
||||
],
|
||||
selectedTab: 'extensionSettings',
|
||||
BrowserDetect: BrowserDetect,
|
||||
|
@ -1,9 +1,6 @@
|
||||
<template>
|
||||
<!-- <div class="flex flex-row">
|
||||
<mdicon name="crop" :size="32" />
|
||||
<h1>Crop video:</h1>
|
||||
</div> -->
|
||||
<div class="sub-panel-content flex flex-row flex-wrap">
|
||||
|
||||
<ShortcutButton
|
||||
v-for="(command, index) of settings?.active.commands.crop"
|
||||
class="flex b3 button"
|
||||
@ -19,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}},
|
||||
@ -114,7 +111,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="edit-action-area">
|
||||
<div v-if="siteSettings" class="edit-action-area">
|
||||
<div class="field">
|
||||
<div class="label">Default for this site</div>
|
||||
<div class="select">
|
||||
@ -176,11 +173,19 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
siteDefaultCrop() {
|
||||
if (!this.siteSettings) {
|
||||
return null;
|
||||
}
|
||||
return JSON.stringify(
|
||||
this.siteSettings.data.defaults.crop
|
||||
);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.isEditing) {
|
||||
this.enableEditMode();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isEditing(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
@ -195,6 +200,9 @@ export default {
|
||||
* Sets default crop, for either site or global
|
||||
*/
|
||||
setDefaultCrop($event, scope) {
|
||||
if (!this.siteSettings) {
|
||||
return;
|
||||
}
|
||||
const commandArguments = JSON.parse($event.target.value);
|
||||
|
||||
this.siteSettings.set('defaults.crop', commandArguments);
|
||||
@ -205,7 +213,7 @@ export default {
|
||||
* Determines whether a given crop command is the currently active one
|
||||
*/
|
||||
isActiveCrop(cropCommand) {
|
||||
if (! this.resizerConfig.crop) {
|
||||
if (! this.resizerConfig.crop || !this.siteSettings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="edit-action-area">
|
||||
<div v-if="siteSettings" class="edit-action-area">
|
||||
<div class="field">
|
||||
<div class="label">Default for this site:</div>
|
||||
<div class="select">
|
||||
@ -191,11 +191,19 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
siteDefaultStretch() {
|
||||
if (!this.siteSettings) {
|
||||
return null;
|
||||
}
|
||||
return JSON.stringify(
|
||||
this.siteSettings.data.defaults.stretch
|
||||
);
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.isEditing) {
|
||||
this.enableEditMode();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isEditing(newValue, oldValue) {
|
||||
if (newValue) {
|
||||
@ -210,6 +218,9 @@ export default {
|
||||
* Sets default stretching mode, for either site or global
|
||||
*/
|
||||
setDefaultStretchingMode($event, globalOrSite) {
|
||||
if (!this.siteSettings) {
|
||||
return;
|
||||
}
|
||||
const commandArguments = JSON.parse($event.target.value);
|
||||
this.siteSettings.set('defaults.stretch', commandArguments);
|
||||
},
|
||||
@ -218,7 +229,7 @@ export default {
|
||||
* Determines whether a given stretch command is the currently active one
|
||||
*/
|
||||
isActiveStretch(stretchCommand) {
|
||||
if (! this.resizerConfig.stretch) {
|
||||
if (! this.resizerConfig.stretch || !this.siteSettings) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2,148 +2,100 @@
|
||||
<div class="flex flex-col" style="position: relative; width: 100%;">
|
||||
<!-- The rest of the tab is under 'edit ratios and shortcuts' row -->
|
||||
<div class="flex flex-col" style="width: 100%">
|
||||
|
||||
<h2>Player UI options</h2>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Enable in-player UI</div>
|
||||
<input type="checkbox" v-model="settings.active.ui.inPlayer.enabled" />
|
||||
<div class="flex flex-col compact-form">
|
||||
<div class="field">
|
||||
<div class="label">Enable in-player UI</div>
|
||||
<input type="checkbox" v-model="settings.active.ui.inPlayer.enabled" />
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col field-group compact-form"
|
||||
:class="{disabled: !settings.active.ui.inPlayer.enabled}"
|
||||
>
|
||||
<div class="field">
|
||||
<div class="label">Enable only in full screen</div>
|
||||
<input type="checkbox" v-model="settings.active.ui.inPlayer.enabledFullscreenOnly" />
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Popup activator position:
|
||||
</div>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="settings.active.ui.inPlayer.alignment"
|
||||
@click="setUiOption('alignment', $event)"
|
||||
>
|
||||
<option value="left">Left</option>
|
||||
<option value="right">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Activate in-player UI:
|
||||
</div>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="settings.active.ui.inPlayer.activation"
|
||||
@click="setUiOption('', $event)"
|
||||
>
|
||||
<option value="player">
|
||||
When mouse hovers over player
|
||||
</option>
|
||||
<option value="trigger-zone">
|
||||
When mouse hovers over trigger zone
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field" :class="{disabled: settings.active.ui.inPlayer.activation !== 'trigger-zone'}">
|
||||
<div class="label">Edit trigger zone:</div>
|
||||
<button @click="startTriggerZoneEdit()">Edit</button>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Do not show in-player UI when video player is narrower than (% of screen width)
|
||||
</div>
|
||||
<div>TODO: slider</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-col"
|
||||
:class="{disabled: settings.active.ui.inPlayer.enabled}"
|
||||
>
|
||||
<div class="field">
|
||||
<div class="label">Enable only in full screen</div>
|
||||
<input type="checkbox" v-model="settings.active.ui.inPlayer.enabledFullscreenOnly" />
|
||||
<h2 class="mt2r">Menu options and keyboard shortcuts</h2>
|
||||
<div>
|
||||
Click 'add new' to add a new option. Click a button to edit or remove the keyboard shortcut.
|
||||
</div>
|
||||
<div class="keyboard-settings">
|
||||
<!-- CROP OPTIONS -->
|
||||
<div>
|
||||
<div class="flex flex-row">
|
||||
<h3 class="mth3">CROP OPTIONS</h3>
|
||||
</div>
|
||||
|
||||
<CropOptionsPanel
|
||||
:settings="settings"
|
||||
:eventBus="eventBus"
|
||||
:isEditing="true"
|
||||
>
|
||||
</CropOptionsPanel>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Popup activator position:
|
||||
<!-- STRETCH OPTIONS -->
|
||||
<div>
|
||||
<div class="flex flex-row">
|
||||
<h3 class="mth3">STRETCH OPTIONS</h3>
|
||||
</div>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="settings.active.ui.inPlayer.alignment"
|
||||
@click="setUiOption('alignment', $event)"
|
||||
>
|
||||
<option value="left">Left</option>
|
||||
<option value="right">Right</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Activate in-player UI:
|
||||
</div>
|
||||
<div class="select">
|
||||
<select
|
||||
v-model="settings.active.ui.inPlayer.activation"
|
||||
@click="setUiOption('', $event)"
|
||||
>
|
||||
<option value="player">
|
||||
When mouse hovers over player
|
||||
</option>
|
||||
<option value="trigger-zone">
|
||||
When mouse hovers over trigger zone
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Edit trigger zone:</div>
|
||||
<button>Edit</button>
|
||||
</div>
|
||||
|
||||
<div v-if="settings.active.ui.inPlayer.activation === 'trigger-zone'">
|
||||
<div class="trigger-zone-editor">
|
||||
<div class="heading">
|
||||
<h3>Trigger zone editor</h3>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone width:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.width"
|
||||
class="slider"
|
||||
type="range"
|
||||
min="0.1"
|
||||
max="1"
|
||||
step="0.01"
|
||||
>
|
||||
<input
|
||||
:value="(settings.active.ui.inPlayer.triggerZoneDimensions.width * 100).toFixed(2)"
|
||||
@input="(event) => setTriggerZoneSize('width', event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="hint">
|
||||
Width of the trigger zone (% of player area).
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone height:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.height"
|
||||
type="range"
|
||||
min="0.1"
|
||||
max="1"
|
||||
step="0.01"
|
||||
>
|
||||
<input
|
||||
:value="(settings.active.ui.inPlayer.triggerZoneDimensions.height * 100).toFixed(2)"
|
||||
@input="(event) => setTriggerZoneSize('width', event.target.value)"
|
||||
>
|
||||
</div>
|
||||
<div class="hint">
|
||||
Height of the trigger zone (% of player area).
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone horizontal offset:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetX"
|
||||
type="range"
|
||||
min="-100"
|
||||
max="100"
|
||||
>
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetX"
|
||||
>
|
||||
</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="field">
|
||||
<div class="label">Trigger zone vertical offset:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetY"
|
||||
type="range"
|
||||
min="-100"
|
||||
max="100"
|
||||
>
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetY"
|
||||
>
|
||||
</div>
|
||||
<div class="hint">
|
||||
By default, trigger zone is centered around the button. This option moves trigger zone up and down.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">
|
||||
Do not show in-player UI when video player is narrower than (% of screen width)
|
||||
</div>
|
||||
<div>TODO: slider</div>
|
||||
<StretchOptionsPanel
|
||||
:settings="settings"
|
||||
:eventBus="eventBus"
|
||||
:isEditing="true"
|
||||
></StretchOptionsPanel>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -154,8 +106,15 @@
|
||||
<script>
|
||||
import Button from '../components/Button.vue'
|
||||
import BrowserDetect from '../../../ext/conf/BrowserDetect';
|
||||
import CropOptionsPanel from './PanelComponents/VideoSettings/CropOptionsPanel.vue'
|
||||
import StretchOptionsPanel from './PanelComponents/VideoSettings/StretchOptionsPanel.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Button,
|
||||
CropOptionsPanel,
|
||||
StretchOptionsPanel
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@ -171,32 +130,14 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
components: {
|
||||
Button,
|
||||
},
|
||||
methods: {
|
||||
setUiPage(key, event) {
|
||||
|
||||
},
|
||||
forceNumber(value) {
|
||||
// Change EU format to US if needed
|
||||
// | remove everything after second period if necessary
|
||||
// | | | remove non-numeric characters
|
||||
// | | | |
|
||||
return value.replaceAll(',', '.').split('.', 2).join('.').replace(/[^0-9.]/g, '');
|
||||
|
||||
startTriggerZoneEdit() {
|
||||
this.eventBus.send('start-trigger-zone-edit');
|
||||
},
|
||||
setTriggerZoneSize(key, value) {
|
||||
let size = (+this.forceNumber(value) / 100);
|
||||
|
||||
if (isNaN(+size)) {
|
||||
size = 0.5;
|
||||
}
|
||||
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions[key] = size;
|
||||
this.settings.saveWithoutReload();
|
||||
},
|
||||
|
||||
|
||||
async openOptionsPage() {
|
||||
BrowserDetect.runtime.openOptionsPage();
|
||||
},
|
||||
@ -249,6 +190,39 @@ export default {
|
||||
.field {
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
}
|
||||
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
/* color: #666; */
|
||||
filter: contrast(50%) brightness(40%) grayscale(100%);
|
||||
}
|
||||
|
||||
.compact-form {
|
||||
|
||||
|
||||
> .field, > .field-group {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.keyboard-settings {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
|
||||
> * {
|
||||
width: calc(50% - 0.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
.mt2r {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.mth3 {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,4 +1,6 @@
|
||||
<template>
|
||||
|
||||
<!-- Preview + editor -->
|
||||
<div
|
||||
v-if="settings?.active?.ui"
|
||||
class="active-trigger-area uw-clickable"
|
||||
@ -8,28 +10,137 @@
|
||||
@mousedown="(event) => handleMouseDown('offset', event)"
|
||||
>
|
||||
<div
|
||||
class="uw-clickable tl"
|
||||
class="uw-clickable corner tl"
|
||||
@mousedown.stop="(event) => handleMouseDown('tl', event)"
|
||||
>
|
||||
XX
|
||||
</div>
|
||||
<div
|
||||
class="uw-clickable tr"
|
||||
class="uw-clickable corner tr"
|
||||
@mousedown.stop="(event) => handleMouseDown('tr', event)"
|
||||
>
|
||||
XX
|
||||
</div>
|
||||
<div
|
||||
class="uw-clickable bl"
|
||||
class="uw-clickable corner bl"
|
||||
@mousedown.stop="(event) => handleMouseDown('bl', event)"
|
||||
>
|
||||
XX
|
||||
</div>
|
||||
<div
|
||||
class="uw-clickable br"
|
||||
class="uw-clickable corner br"
|
||||
@mousedown.stop="(event) => handleMouseDown('br', event)"
|
||||
>
|
||||
XX
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sliders -->
|
||||
<div
|
||||
class="trigger-zone-editor-sliders-container"
|
||||
>
|
||||
<div class="panel uw-clickable">
|
||||
<div class="trigger-zone-editor-window">
|
||||
<div class="heading">
|
||||
<h2>Trigger zone editor</h2>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
Trigger zone is represented by this very obvious gold grid. Ultrawidify menu button will only show when mouse enters the area marked by the grid.
|
||||
</p>
|
||||
<p>
|
||||
Note that interacting with the grid area is slightly broken. The distance dragged doesn't correspond with the amount of resizing. I don't plan on
|
||||
fixing that because the amount of effort required to get it working perfectly doesn't correspond with the amount of utility this part of the UI will
|
||||
see. Like, it works well enough and I want to enjoy some of my end-of-year PTO.
|
||||
</p>
|
||||
<p>
|
||||
Sliders work as they should.
|
||||
</p>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone width:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
:value="settings.active.ui.inPlayer.triggerZoneDimensions.width"
|
||||
class="slider"
|
||||
type="range"
|
||||
min="0.1"
|
||||
max="1"
|
||||
step="0.01"
|
||||
@input="(event) => setTriggerZoneOffset('width', event.target.value, true)"
|
||||
>
|
||||
<input
|
||||
:value="triggerZoneWidth"
|
||||
@input="(event) => setTriggerZoneSize('width', event.target.value)"
|
||||
@change="(event) => updateSettings()"
|
||||
>
|
||||
</div>
|
||||
<div class="hint">
|
||||
Width of the trigger zone (% of player area).
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone height:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
:value="settings.active.ui.inPlayer.triggerZoneDimensions.height"
|
||||
type="range"
|
||||
min="0.1"
|
||||
max="1"
|
||||
step="0.01"
|
||||
@input="(event) => setTriggerZoneOffset('height', event.target.value, true)"
|
||||
>
|
||||
<input
|
||||
:value="triggerZoneHeight"
|
||||
@input="(event) => setTriggerZoneSize('height', event.target.value)"
|
||||
@change="(event) => updateSettings()"
|
||||
>
|
||||
</div>
|
||||
<div class="hint">
|
||||
Height of the trigger zone (% of player area).
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label">Trigger zone horizontal offset:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetX"
|
||||
type="range"
|
||||
min="-100"
|
||||
max="100"
|
||||
@input="(event) => setTriggerZoneOffset('offsetX', event.target.value, true)"
|
||||
>
|
||||
<input
|
||||
:value="settings.active.ui.inPlayer.triggerZoneDimensions.offsetX"
|
||||
@input="(event) => setTriggerZoneOffset('offsetX', event.target.value)"
|
||||
@change="(event) => updateSettings()"
|
||||
>
|
||||
</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="field">
|
||||
<div class="label">Trigger zone vertical offset:</div>
|
||||
<div class="input range-input">
|
||||
<input
|
||||
v-model="settings.active.ui.inPlayer.triggerZoneDimensions.offsetY"
|
||||
type="range"
|
||||
min="-100"
|
||||
max="100"
|
||||
@input="(event) => setTriggerZoneOffset('offsetY', event.target.value, true)"
|
||||
>
|
||||
<input
|
||||
:value="settings.active.ui.inPlayer.triggerZoneDimensions.offsetY"
|
||||
@input="(event) => setTriggerZoneOffset('offsetY', event.target.value)"
|
||||
@change="(event) => updateSettings()"
|
||||
>
|
||||
</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="action-row">
|
||||
<button @click="finishTriggerZoneEdit">Finish editing</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -39,11 +150,11 @@
|
||||
export default {
|
||||
props: [
|
||||
'settings',
|
||||
'eventBus',
|
||||
'playerDimensions',
|
||||
],
|
||||
watch: {
|
||||
playerDimensions(newVal, oldVal) {
|
||||
console.log('triggerzone -- dimensions changed!', this.playerDimensions, newVal, oldVal);
|
||||
this.updateTriggerZones();
|
||||
}
|
||||
},
|
||||
@ -58,9 +169,26 @@ export default {
|
||||
created() {
|
||||
document.addEventListener("mouseup", this.handleMouseUp);
|
||||
document.addEventListener("mousemove", this.handleMouseMove);
|
||||
this.updateTriggerZones(false);
|
||||
},
|
||||
computed: {
|
||||
triggerZoneWidth() {
|
||||
const v = this.settings.active.ui.inPlayer.triggerZoneDimensions.width * 100;
|
||||
return this.optionalToFixed(v, 2);
|
||||
},
|
||||
triggerZoneHeight() {
|
||||
const v = this.settings.active.ui.inPlayer.triggerZoneDimensions.height * 100;
|
||||
return this.optionalToFixed(v, 2);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateTriggerZones() {
|
||||
optionalToFixed(v, n) {
|
||||
if ((`${v}`.split('.')[1]?.length ?? 0) > n) {
|
||||
return v.toFixed(2);
|
||||
}
|
||||
return v;
|
||||
},
|
||||
updateTriggerZones(forceRefresh = true) {
|
||||
if (this.playerDimensions && this.settings?.active?.ui?.inPlayer?.triggerZoneDimensions) {
|
||||
this.triggerZoneStyles = {
|
||||
width: `${Math.round(this.playerDimensions.width * this.settings.active.ui.inPlayer.triggerZoneDimensions.width)}px`,
|
||||
@ -68,6 +196,9 @@ export default {
|
||||
transform: `translate(${(this.settings.active.ui.inPlayer.triggerZoneDimensions.offsetX)}%, ${this.settings.active.ui.inPlayer.triggerZoneDimensions.offsetY}%)`,
|
||||
};
|
||||
}
|
||||
// if (forceRefresh) {
|
||||
// this.$forceUpdate();
|
||||
// }
|
||||
},
|
||||
handleMouseDown(corner, event) {
|
||||
this.activeCornerDrag = corner;
|
||||
@ -134,8 +265,8 @@ export default {
|
||||
}
|
||||
|
||||
// ensure everything is properly limited
|
||||
const cw = Math.min(0.95, Math.max(0.125, nw));
|
||||
const ch = Math.min(0.95, Math.max(0.125, nh));
|
||||
const cw = Math.min(1, Math.max(0.125, nw));
|
||||
const ch = Math.min(1, Math.max(0.125, nh));
|
||||
|
||||
// // update properties
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions.width = cw;
|
||||
@ -161,14 +292,63 @@ export default {
|
||||
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions.offsetX = cx;
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions.offsetY = cy;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
//#region slider window
|
||||
forceNumber(value) {
|
||||
// Change EU format to US if needed
|
||||
// | remove everything after second period if necessary
|
||||
// | | | remove non-numeric characters
|
||||
// | | | |
|
||||
return value.replaceAll(',', '.').split('.', 2).join('.').replace(/[^0-9.\-]/g, '');
|
||||
},
|
||||
setTriggerZoneSize(key, value, instantUpdate) {
|
||||
console.log('setting trigger zone size:', key, value);
|
||||
let size = (+this.forceNumber(value) / 100);
|
||||
|
||||
if (isNaN(+size)) {
|
||||
size = 0.5;
|
||||
}
|
||||
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions[key] = size;
|
||||
|
||||
if (instantUpdate) {
|
||||
this.updateSettings();
|
||||
}
|
||||
},
|
||||
setTriggerZoneOffset(key, value, instantUpdate) {
|
||||
let offset = +this.forceNumber(value);
|
||||
|
||||
this.settings.active.ui.inPlayer.triggerZoneDimensions[key] = offset;
|
||||
|
||||
if (instantUpdate) {
|
||||
this.updateSettings();
|
||||
}
|
||||
},
|
||||
updateSettings() {
|
||||
this.settings.saveWithoutReload();
|
||||
this.updateTriggerZones();
|
||||
},
|
||||
|
||||
//#endregion
|
||||
finishTriggerZoneEdit() {
|
||||
this.eventBus.send('finish-trigger-zone-edit');
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="../res-common/panels.scss" scoped module></style>
|
||||
<style lang="scss" src="../res-common/common.scss" scoped module></style>
|
||||
<style lang="scss" scoped>
|
||||
.active-trigger-area {
|
||||
background-image: url('/res/img/grid_512.webp');
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.trigger-zone-editor {
|
||||
@ -176,8 +356,14 @@ export default {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
> * {
|
||||
> .corner {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-color: #000;
|
||||
background-image: url('/res/img/corner-marker_64.webp');
|
||||
background-size: cover;
|
||||
|
||||
}
|
||||
.tr, .tl {
|
||||
top: 0;
|
||||
@ -191,6 +377,86 @@ export default {
|
||||
.tr, .br {
|
||||
right: 0;
|
||||
}
|
||||
.br {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.bl {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.tl {
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.trigger-zone-editor-window {
|
||||
max-width: 69rem;
|
||||
}
|
||||
|
||||
.trigger-zone-editor-sliders-container {
|
||||
position: fixed;
|
||||
width: 100dvw;
|
||||
height: 100dvh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 2000;
|
||||
|
||||
pointer-events: none;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.panel {
|
||||
backdrop-filter: blur(0.5rem) brightness(0.5);
|
||||
color: #ccc;
|
||||
pointer-events: all;
|
||||
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.range-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
max-width: 5rem;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
.trigger-zone-editor {
|
||||
padding-bottom: 2rem;
|
||||
|
||||
.field {
|
||||
margin-bottom: -1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.range-input {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
* {
|
||||
margin-left: 0.5rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
input {
|
||||
max-width: 5rem;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -6,12 +6,16 @@ export default {
|
||||
* the content script.
|
||||
*/
|
||||
document.addEventListener('mousemove', (event) => {
|
||||
this.handleProbe({
|
||||
coords: {
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
}
|
||||
}, this.origin);
|
||||
this.handleProbe(
|
||||
{
|
||||
coords: {
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
},
|
||||
isCompanion: true,
|
||||
},
|
||||
this.origin
|
||||
);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
@ -74,6 +78,7 @@ export default {
|
||||
*/
|
||||
let isClickable = false;
|
||||
let isOverTriggerZone = false;
|
||||
let isOverUIArea = false;
|
||||
const elements = document.elementsFromPoint(eventData.coords.x, eventData.coords.y);
|
||||
|
||||
for (const element of elements) {
|
||||
@ -83,6 +88,9 @@ export default {
|
||||
if (element.classList?.contains('uw-ui-trigger')) {
|
||||
isOverTriggerZone = true;
|
||||
}
|
||||
if (element.classList?.contains('uw-ui-area')) {
|
||||
isOverUIArea = true;
|
||||
}
|
||||
}
|
||||
|
||||
this.triggerZoneActive = isOverTriggerZone;
|
||||
@ -91,18 +99,22 @@ export default {
|
||||
// but don't show the trigger zone behind an active popup
|
||||
if (
|
||||
eventData.canShowUI
|
||||
&& (this.settings.active.ui.inPlayer.activation !== 'player' || isOverTriggerZone)
|
||||
&& (this.settings.active.ui.inPlayer.activation === 'player' ? isOverUIArea : isOverTriggerZone)
|
||||
) {
|
||||
if (! this.uwWindowVisible) {
|
||||
this.uwTriggerZoneVisible = true;
|
||||
clearTimeout(this.uwTriggerZoneTimeout);
|
||||
this.uwTriggerZoneTimeout = setTimeout(
|
||||
() => this.uwTriggerZoneVisible = false,
|
||||
250
|
||||
() => {
|
||||
this.uwTriggerZoneVisible = false;
|
||||
// this.$forceRefresh();
|
||||
},
|
||||
750
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.uwTriggerZoneVisible = false;
|
||||
// console.log('[UI] hiding UI because conditions were not met. canShowUI:', eventData.canShowUI, 'isOverTriggerZone', isOverTriggerZone);
|
||||
// this.uwTriggerZoneVisible = false;
|
||||
}
|
||||
|
||||
window.parent.postMessage(
|
||||
|
@ -106,9 +106,17 @@ class UI {
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = this.uiIframe.getBoundingClientRect();
|
||||
|
||||
const offsets = {
|
||||
top: window.scrollY + rect.top,
|
||||
left: window.scrollX + rect.left
|
||||
};
|
||||
|
||||
const coords = {
|
||||
x: event.pageX - this.uiIframe.offsetLeft,
|
||||
y: event.pageY - this.uiIframe.offsetTop
|
||||
x: event.pageX - offsets.left,
|
||||
y: event.pageY - offsets.top,
|
||||
frameOffset: offsets,
|
||||
};
|
||||
|
||||
const playerData = this.canShowUI(coords);
|
||||
@ -223,12 +231,12 @@ class UI {
|
||||
* * player element ()
|
||||
* * uwui-clickable element
|
||||
*/
|
||||
canShowUI(coords) {
|
||||
canShowUI() {
|
||||
const playerCssClass = 'uw-ultrawidify-player-css';
|
||||
|
||||
const result = {
|
||||
playerDimensions: undefined,
|
||||
canShowUI: false
|
||||
canShowUI: false,
|
||||
}
|
||||
|
||||
if (this.playerData?.dimensions) {
|
||||
@ -243,22 +251,10 @@ class UI {
|
||||
// fullscreen mode unless watching videos)
|
||||
result.playerDimensions.width < window.screen.width * (this.uiSettings.inPlayer.minEnabledWidth ?? 0)
|
||||
) {
|
||||
result.canShowUI = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
const elements = document.elementsFromPoint(coords.x, coords.y);
|
||||
|
||||
for (const element of elements) {
|
||||
if (
|
||||
element instanceof HTMLVideoElement
|
||||
|| element.classList.contains(playerCssClass)
|
||||
) {
|
||||
result.canShowUI = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
result.canShowUI = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
BIN
src/res/img/corner-marker_64.webp
Normal file
BIN
src/res/img/corner-marker_64.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
Loading…
Reference in New Issue
Block a user