ultrawidify/src/csui/PlayerOverlay.vue

556 lines
15 KiB
Vue
Raw Normal View History

2020-12-15 00:26:19 +01:00
<template>
<div
class="context-spawn uw-ui-trigger"
style="z-index: 1000"
@mouseenter="(ev) => setTriggerZoneActive(true, ev)"
@mouseleave="(ev) => setTriggerZoneActive(false, ev)"
>
<div
class="spawn-container uw-trigger"
:style="triggerZoneStyles"
>
&nbsp;
</div>
</div>
2022-06-11 15:40:36 +02:00
<div
v-if="contextMenuActive || settingsInitialized && uwTriggerZoneVisible && !isGlobal"
class="context-spawn uw-clickable"
style="z-index: 1001"
@mouseenter="preventContextMenuHide()"
@mouseleave="allowContextMenuHide()"
2022-06-11 15:40:36 +02:00
>
<GhettoContextMenu
alignment="right" class="uw-menu"
@mouseenter="newFeatureViewUpdate('uw6.ui-popup')"
>
2024-10-23 01:23:54 +02:00
<template v-slot:activator>
<div class="context-item">
Ultrawidify
</div>
</template>
<slot>
<div class="menu-width">
<GhettoContextMenuItem :disableHover="true" :css="{'ard-blocked': true}">
<div v-if="statusFlags.hasDrm || true" class="smallcaps text-center">
<b>NOTE:</b><br/>
<b>Autodetection<br/>blocked by website</b>
</div>
<div>
</div>
</GhettoContextMenuItem>
2024-10-23 01:23:54 +02:00
<GhettoContextMenu alignment="right">
<template v-slot:activator>
Crop
2024-10-23 01:23:54 +02:00
</template>
<slot>
<GhettoContextMenuOption
v-for="(command, index) of settings?.active.commands.crop"
:key="index"
:label="command.label"
:shortcut="getKeyboardShortcutLabel(command)"
@click="execAction(command)"
>
</GhettoContextMenuOption>
2024-10-23 01:23:54 +02:00
</slot>
</GhettoContextMenu>
<GhettoContextMenu alignment="right">
<template v-slot:activator>
Stretch
2024-10-23 01:23:54 +02:00
</template>
<slot>
<GhettoContextMenuOption
v-for="(command, index) of settings?.active.commands.stretch"
:key="index"
:label="command.label"
:shortcut="getKeyboardShortcutLabel(command)"
@click="execAction(command)"
>
</GhettoContextMenuOption>
2024-10-23 01:23:54 +02:00
</slot>
</GhettoContextMenu>
<GhettoContextMenu alignment="right">
<template v-slot:activator>
<div class="context-item">
Align
</div>
</template>
<slot>
<GhettoContextMenuItem :disableHover="true" :css="{'reduced-padding': true}">
<AlignmentOptionsControlComponent
:eventBus="eventBus"
>
</AlignmentOptionsControlComponent>
</GhettoContextMenuItem>
</slot>
2024-10-23 01:23:54 +02:00
</GhettoContextMenu>
<!-- shortcut for configuring UI -->
<GhettoContextMenuOption
v-if="settings.active.newFeatureTracker?.['uw6.ui-popup']?.show > 0"
2024-12-22 23:07:55 +01:00
@click="showUwWindow('playerUiSettings')"
>
<span style="color: #fa6;">I hate this popup<br/></span>
<span style="font-size: 0.8em">
<span style="text-transform: uppercase; font-size: 0.8em">
2024-12-22 23:07:55 +01:00
<a @click="showUwWindow('playerUiSettings')">
Do something about it
</a> × <a @click="acknowledgeNewFeature('uw6.ui-popup')">keep the popup</a>
</span>
<br/>
<span style="opacity: 0.5">This menu option will show {{settings.active.newFeatureTracker?.['uw6.ui-popup']?.show}} more<br/> times; or until clicked or dismissed.<br/>
Also accessible via <span style="font-variant: small-caps">extension settings</span>.
</span>
</span>
</GhettoContextMenuOption>
<!-- -->
<GhettoContextMenuOption
@click="showUwWindow()"
label="Extension settings"
>
</GhettoContextMenuOption>
<GhettoContextMenuOption
@click="showUwWindow('about')"
label="Not working?"
>
</GhettoContextMenuOption>
2024-10-23 01:23:54 +02:00
</div>
</slot>
</GhettoContextMenu>
</div>
2023-01-06 18:47:42 +01:00
2024-10-23 01:23:54 +02:00
2022-06-11 15:40:36 +02:00
<div
2023-01-06 18:47:42 +01:00
v-if="settingsInitialized && uwWindowVisible"
class="uw-window flex flex-col uw-clickable"
2022-06-11 15:40:36 +02:00
:class="{'fade-out': uwWindowFadeOut}"
>
2023-01-06 18:47:42 +01:00
<PlayerUIWindow
:settings="settings"
:eventBus="eventBus"
:logger="logger"
:in-player="!isGlobal"
2023-01-06 18:47:42 +01:00
:site="site"
:defaultTab="defaultWindowTab"
2023-01-06 18:47:42 +01:00
@close="uwWindowVisible = false"
@preventClose="(event) => uwWindowFadeOutDisabled = event"
></PlayerUIWindow>
2020-12-15 00:26:19 +01:00
</div>
</template>
<script>
2024-10-23 01:23:54 +02:00
import PlayerUIWindow from './src/PlayerUIWindow.vue';
import GhettoContextMenu from './src/components/GhettoContextMenu.vue';
import GhettoContextMenuItem from './src/components/GhettoContextMenuItem.vue';
import GhettoContextMenuOption from './src/components/GhettoContextMenuOption.vue';
import AlignmentOptionsControlComponent from './src/PlayerUiPanels/AlignmentOptionsControlComponent.vue';
import BrowserDetect from '../ext/conf/BrowserDetect';
import Logger from '../ext/lib/Logger';
import Settings from '../ext/lib/Settings';
import EventBus from '../ext/lib/EventBus';
import UIProbeMixin from './src/utils/UIProbeMixin';
import KeyboardShortcutParserMixin from './src/utils/KeyboardShortcutParserMixin';
import CommsMixin from './src/utils/CommsMixin';
2020-12-15 00:26:19 +01:00
export default {
components: {
2024-10-23 01:23:54 +02:00
PlayerUIWindow,
GhettoContextMenu,
GhettoContextMenuItem,
GhettoContextMenuOption,
AlignmentOptionsControlComponent,
2020-12-15 00:26:19 +01:00
},
mixins: [
UIProbeMixin,
KeyboardShortcutParserMixin,
CommsMixin
],
2020-12-15 00:26:19 +01:00
data() {
return {
2022-06-11 15:40:36 +02:00
uwTriggerZoneVisible: false,
uwTriggerZoneTimeout: undefined,
uwTriggerRegionConf: {
left: "10%",
top: "10%",
height: "30%",
width: "30%",
maxWidth: "24rem",
maxHeight: "13.37rem",
},
uwWindowFadeOutDisabled: false,
2022-06-11 15:40:36 +02:00
uwWindowFadeOut: false,
uwWindowCloseTimeout: undefined,
uwWindowVisible: false,
// component properties
settings: {},
2021-10-22 00:30:56 +02:00
BrowserDetect: BrowserDetect,
settingsInitialized: false,
eventBus: new EventBus(),
logger: null,
// NOTE: chromium doesn't allow us to access window.parent.location
// meaning we will have to correct this value from our uwui-probe
// messages ... which is a bummer.
site: null,
origin: '*', // will be set appropriately once the first uwui-probe event is received
lastProbeTs: null,
2024-06-05 01:08:50 +02:00
isGlobal: true,
disabled: false,
contextMenuActive: false,
triggerZoneActive: false,
uiVisible: true,
debugData: {
resizer: {},
player: {},
2020-12-16 01:40:09 +01:00
},
2022-03-28 23:14:52 +02:00
debugDataPrettified: '',
2024-06-05 01:08:50 +02:00
// in global overlay, this property is used to determine
// if closing the window should emit uw-set-ui-state
// event on eventBus
showPlayerUIAfterClose: false,
2022-07-28 00:45:27 +02:00
statusFlags: {
hasDrm: undefined,
},
defaultWindowTab: 'videoSettings',
2022-07-28 00:45:27 +02:00
2024-06-05 01:08:50 +02:00
saveState: {},
2020-12-15 00:26:19 +01:00
};
},
computed: {
// LPT: NO ARROW FUNCTIONS IN COMPUTED,
// IS SUPER HARAM
// THINGS WILL NOT WORK IF YOU USE ARROWS
windowWidth() {
2020-12-16 01:40:09 +01:00
return window.innerWidth;
},
windowHeight() {
2020-12-16 01:40:09 +01:00
return window.innerHeight;
},
2020-12-15 00:26:19 +01:00
},
watch: {
showUi(visible) {
if (visible !== undefined) {
this.uiVisible = visible;
}
},
resizerDebugData(newData) {
this.debugData.resizer = newData;
2020-12-16 01:40:09 +01:00
this.debugDataPrettified = JSON.stringify(this.debugData, null, 2);
},
playerDebugData(newData) {
this.debugData.player = newData;
2020-12-16 01:40:09 +01:00
this.debugDataPrettified = JSON.stringify(this.debugData, null, 2);
2020-12-15 00:26:19 +01:00
}
},
2022-03-20 20:43:49 +01:00
async created() {
this.logger = new Logger();
// this prolly needs to be taken out
await this.logger.init({
allowLogging: true,
});
this.settings = new Settings({afterSettingsSaved: this.updateConfig, logger: this.logger});
await this.settings.init();
this.settingsInitialized = true;
2023-07-10 22:56:26 +02:00
// set up communication with client script.
// NOTE: companion onmousemove is set up in UIProbeMixin
window.addEventListener('message', event => {
this.handleMessage(event);
});
2022-07-30 00:47:11 +02:00
this.eventBus.subscribe('uw-config-broadcast', {function: (data) => {
2022-07-28 00:45:27 +02:00
if (data.type === 'drm-status') {
this.statusFlags.hasDrm = data.hasDrm;
}
2022-07-30 00:47:11 +02:00
}});
this.eventBus.subscribe('uw-set-ui-state', { function: (data) => {
2024-06-05 01:08:50 +02:00
if (data.globalUiVisible !== undefined) {
if (this.isGlobal) {
if (data.globalUiVisible) {
this.showUwWindow();
} else {
this.hideUwWindow(true);
}
// this.showPlayerUIAfterClose = data.showPlayerUIAfterClose;
} else {
// non global UIs are hidden while global overlay
// is visible and vice versa
// this.disabled = data.globalUiVisible;
this.saveState = {
uwWindowVisible: this.uwWindowVisible,
uwWindowFadeOutDisabled: this.uwWindowFadeOutDisabled,
uwWindowFadeOut: this.uwWindowFadeOut
};
this.uwWindowFadeOutDisabled = false;
this.hideUwWindow(true);
}
}
}});
2024-06-05 01:08:50 +02:00
this.eventBus.subscribe(
'uw-restore-ui-state',
{
function: (data) => {
if (this.saveState) {
if (this.saveState.uwWindowVisible) {
this.showUwWindow();
}
this.uwWindowFadeOutDisabled = this.saveState.uwWindowFadeOutDisabled;
this.uwWindowFadeOut = this.saveState.uwWindowFadeOut;
}
this.saveState = {};
}
}
);
this.sendToParentLowLevel('uwui-get-role', null);
this.sendToParentLowLevel('uwui-get-theme', null);
//
2020-12-15 00:26:19 +01:00
},
2020-12-15 00:26:19 +01:00
methods: {
/**
* Gets URL of the browser settings page (i think?)
*/
2020-12-22 03:14:03 +01:00
getUrl(url) {
2020-12-30 15:35:54 +01:00
return BrowserDetect.getURL(url);
},
/**
* Mostly intended to process messages received via window.addEventListener('message').
* This method should include minimal logic instead, it should only route messages
* to the correct function down the line.
*/
handleMessage(event) {
2024-06-05 01:08:50 +02:00
switch (event.data.action) {
case 'uwui-probe':
if (!this.site) {
this.origin = event.origin;
this.site = event.origin.split('//')[1];
}
return this.handleProbe(event.data, event.origin); // handleProbe is defined in UIProbeMixin
case 'uw-bus-tunnel':
return this.handleBusTunnelIn(event.data.payload);
case 'uwui-set-role':
this.isGlobal = event.data.payload.role === 'global';
this.sendToParentLowLevel('uwui-interface-ready', true);
break;
}
},
/**
* Handles trigger zone
*/
handleTriggerZone(mouseInside) {
console.log('handing trigger zone!', mouseInside);
// this.triggerZoneActive = mouseInside;
},
acknowledgeNewFeature(featureKey) {
delete this.settings.active.newFeatureTracker[featureKey];
this.settings.saveWithoutReload();
},
newFeatureViewUpdate(featureKey) {
if (!this.settings.active.newFeatureTracker[featureKey]) {
return;
}
try {
this.settings.active.newFeatureTracker[featureKey].show--;
this.settings.saveWithoutReload();
if (this.settings.active.newFeatureTracker[featureKey]?.show < 0) {
this.acknowledgeNewFeature(featureKey);
}
} catch (e) {
// do nothing
}
},
2024-06-05 01:08:50 +02:00
/**
* Sends message to parent _without_ using event bus.
*/
sendToParentLowLevel(action, payload, lowLevelExtras = {}) {
window.parent.postMessage(
{
action, payload, ...lowLevelExtras
},
'*'
);
},
preventContextMenuHide() {
this.contextMenuActive = true;
},
allowContextMenuHide() {
this.contextMenuActive = false;
},
setTriggerZoneActive(active, event) {
this.triggerZoneActive = active;
},
showUwWindow(tab) {
this.defaultWindowTab = tab; // can be undefined
2022-06-11 15:40:36 +02:00
this.uwWindowFadeOut = false;
this.uwWindowVisible = true;
this.uwTriggerZoneVisible = false;
this.allowContextMenuHide();
2022-07-28 00:45:27 +02:00
// refresh DRM status
this.eventBus.send('get-drm-status');
2024-06-05 01:08:50 +02:00
// if (this.isGlobal) {
// this.sendToParentLowLevel('uwui-clickable', undefined, {clickable: true});
// }
2022-06-11 15:40:36 +02:00
},
2024-06-05 01:08:50 +02:00
hideUwWindow(skipTimeout = false) {
if (this.uwWindowFadeOutDisabled) {
return;
}
2024-06-05 01:08:50 +02:00
const timeout = skipTimeout ? 0 : 1100;
this.uwWindowCloseTimeout = setTimeout(
() => {
this.uwWindowVisible = false;
// Global UI has some extra housekeeping to do when window gets hidden
if (this.isGlobal) {
this.sendToParentLowLevel('uwui-global-window-hidden', {});
}
},
timeout
);
2022-06-11 15:40:36 +02:00
this.uwWindowFadeOut = true;
},
cancelUwWindowHide() {
this.uwWindowFadeOut = false;
clearTimeout(this.uwWindowCloseTimeout);
},
handleBusTunnelIn(payload) {
2024-06-05 01:08:50 +02:00
this.eventBus.send(payload.action, payload.config, payload.routingData);
}
2020-12-15 00:26:19 +01:00
}
}
</script>
<style lang="scss">
.ard-blocked {
color: rgb(219, 125, 48) !important;
background-color: rgba(0,0,0,0.85) !important;
}
</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;
z-index: 999999999999999999;
}
2022-06-11 15:40:36 +02:00
.reduced-padding {
padding: 1rem !important;
}
2022-06-11 15:40:36 +02:00
.uv-hover-trigger-region {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 0.5rem dashed #fff;
color: #fff;
backdrop-filter: blur(0.5rem) brightness(0.5);
}
2023-01-06 18:47:42 +01:00
.uw-window {
position: absolute;
top: 10%;
left: 10%;
z-index: 999999999999999999;
2020-12-16 01:40:09 +01:00
width: 2500px;
height: 1200px;
max-width: 80%;
max-height: 80%;
2020-12-16 01:40:09 +01:00
pointer-events: all !important;
2020-12-16 01:40:09 +01:00
2023-01-06 18:47:42 +01:00
opacity: 1;
backdrop-filter: blur(16px) saturate(120%);
2021-10-22 00:30:56 +02:00
2022-06-11 15:40:36 +02:00
&.fade-out {
opacity: 0;
2023-01-06 18:47:42 +01:00
transition: opacity 0.5s;
transition-delay: 0.5s;
2022-06-11 15:40:36 +02:00
}
}
2020-12-15 00:26:19 +01:00
.gib-bg {
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(16px) saturate(120%);
width: fit-content;
block-size: fit-content;
}
2024-10-23 01:23:54 +02:00
.context-spawn {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
display: flex;
flex-direction: row;
align-content: center;
align-items: center;
// width: 100%;
// height: 100%;
padding: 2rem;
color: #fff;
// .context-item {
// font-size: .95rem;
// padding: 1rem 1.6rem;
// background-color: rgba(0, 0, 0, 0.5);
// backdrop-filter: blur(16px) saturate(120%);
2024-10-23 01:23:54 +02:00
// white-space: nowrap;
// }
// .spawn-container {
// border: 1px solid white;
// }
2024-10-23 01:23:54 +02:00
}
</style>