2020-12-15 00:26:19 +01:00
|
|
|
<template>
|
2024-06-05 01:08:50 +02:00
|
|
|
|
2022-06-11 15:40:36 +02:00
|
|
|
<div
|
2024-06-02 16:06:26 +02:00
|
|
|
v-if="settingsInitialized && uwTriggerZoneVisible && !isGlobal"
|
2022-06-11 15:40:36 +02:00
|
|
|
class="uw-hover uv-hover-trigger-region uw-clickable"
|
|
|
|
:style="uwTriggerRegionConf"
|
|
|
|
@mouseenter="showUwWindow"
|
|
|
|
>
|
2024-10-23 01:23:54 +02:00
|
|
|
<!-- <h1>Aspect ratio controls</h1>
|
|
|
|
<div>Hover to activate</div> -->
|
|
|
|
[ |> ]
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="context-spawn uw-clickable">
|
|
|
|
|
|
|
|
<GhettoContextMenu alignment="right">
|
|
|
|
<template v-slot:activator>
|
|
|
|
<div class="context-item">
|
|
|
|
Ultrawidify
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<slot>
|
|
|
|
<div class="menu-width">
|
|
|
|
<GhettoContextMenu alignment="right">
|
|
|
|
<template v-slot:activator>
|
|
|
|
<div class="context-item">
|
|
|
|
Crop
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<slot>
|
|
|
|
<div>MEnu item 1</div>
|
|
|
|
<div>Menu item 2</div>
|
|
|
|
<div>Menu item 3</div>
|
|
|
|
</slot>
|
|
|
|
</GhettoContextMenu>
|
|
|
|
<GhettoContextMenu alignment="right">
|
|
|
|
<template v-slot:activator>
|
|
|
|
<div class="context-item">
|
|
|
|
Stretch
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<slot>
|
|
|
|
<div>Menu item 4</div>
|
|
|
|
<div>Menu item 5</div>
|
|
|
|
<div>Menu item 6</div>
|
|
|
|
</slot>
|
|
|
|
</GhettoContextMenu>
|
|
|
|
<GhettoContextMenu alignment="right">
|
|
|
|
<template v-slot:activator>
|
|
|
|
<div class="context-item">
|
|
|
|
Align
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</GhettoContextMenu>
|
|
|
|
<button @click="showUiWindow()">Extension settings</button>
|
|
|
|
<button @click="showUiWindow()">Not working?</button>
|
|
|
|
</div>
|
|
|
|
</slot>
|
|
|
|
</GhettoContextMenu>
|
2020-12-17 01:49:28 +01:00
|
|
|
</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"
|
2024-06-08 03:23:34 +02:00
|
|
|
class="uw-window flex flex-col uw-clickable"
|
2022-06-11 15:40:36 +02:00
|
|
|
:class="{'fade-out': uwWindowFadeOut}"
|
|
|
|
@mouseenter="cancelUwWindowHide"
|
2024-06-05 01:08:50 +02:00
|
|
|
@mouseleave="hideUwWindow()"
|
2022-06-11 15:40:36 +02:00
|
|
|
>
|
2023-01-06 18:47:42 +01:00
|
|
|
<PlayerUIWindow
|
|
|
|
:settings="settings"
|
|
|
|
:eventBus="eventBus"
|
|
|
|
:logger="logger"
|
2024-06-02 16:06:26 +02:00
|
|
|
:in-player="!isGlobal"
|
2023-01-06 18:47:42 +01:00
|
|
|
:site="site"
|
|
|
|
@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';
|
2021-01-21 00:21:15 +01:00
|
|
|
import BrowserDetect from '../ext/conf/BrowserDetect';
|
|
|
|
import Logger from '../ext/lib/Logger';
|
|
|
|
import Settings from '../ext/lib/Settings';
|
2022-03-29 01:53:16 +02:00
|
|
|
import EventBus from '../ext/lib/EventBus';
|
2023-01-04 18:09:01 +01:00
|
|
|
import UIProbeMixin from './src/utils/UIProbeMixin';
|
2020-12-15 00:26:19 +01:00
|
|
|
|
|
|
|
export default {
|
|
|
|
components: {
|
2024-10-23 01:23:54 +02:00
|
|
|
PlayerUIWindow,
|
|
|
|
GhettoContextMenu
|
2020-12-15 00:26:19 +01:00
|
|
|
},
|
2023-01-04 18:09:01 +01:00
|
|
|
mixins: [
|
|
|
|
UIProbeMixin
|
|
|
|
],
|
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",
|
|
|
|
},
|
|
|
|
|
2022-06-15 00:43:36 +02:00
|
|
|
uwWindowFadeOutDisabled: false,
|
2022-06-11 15:40:36 +02:00
|
|
|
uwWindowFadeOut: false,
|
|
|
|
uwWindowCloseTimeout: undefined,
|
|
|
|
uwWindowVisible: false,
|
|
|
|
|
2021-01-21 00:21:15 +01:00
|
|
|
// component properties
|
|
|
|
settings: {},
|
2021-10-22 00:30:56 +02:00
|
|
|
BrowserDetect: BrowserDetect,
|
2021-01-21 00:21:15 +01:00
|
|
|
settingsInitialized: false,
|
2022-03-29 01:53:16 +02:00
|
|
|
eventBus: new EventBus(),
|
2021-01-21 00:21:15 +01:00
|
|
|
logger: null,
|
|
|
|
|
2022-03-21 00:50:03 +01:00
|
|
|
// 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,
|
2022-03-22 01:23:15 +01:00
|
|
|
origin: '*', // will be set appropriately once the first uwui-probe event is received
|
2022-03-20 20:44:50 +01:00
|
|
|
lastProbeTs: null,
|
2021-11-21 02:08:53 +01:00
|
|
|
|
2024-06-05 01:08:50 +02:00
|
|
|
isGlobal: true,
|
|
|
|
disabled: false,
|
2024-06-02 16:06:26 +02:00
|
|
|
|
2020-12-16 00:19:02 +01:00
|
|
|
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,
|
|
|
|
},
|
|
|
|
|
2024-06-05 01:08:50 +02:00
|
|
|
saveState: {},
|
|
|
|
|
2022-03-28 23:14:52 +02:00
|
|
|
selectedTab: 'videoSettings',
|
2020-12-15 00:26:19 +01:00
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
2021-11-21 02:08:53 +01:00
|
|
|
// 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;
|
|
|
|
},
|
2021-11-21 02:08:53 +01:00
|
|
|
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;
|
|
|
|
}
|
2020-12-16 00:19:02 +01:00
|
|
|
},
|
|
|
|
resizerDebugData(newData) {
|
|
|
|
this.debugData.resizer = newData;
|
2020-12-16 01:40:09 +01:00
|
|
|
this.debugDataPrettified = JSON.stringify(this.debugData, null, 2);
|
2020-12-16 00:19:02 +01:00
|
|
|
},
|
|
|
|
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
|
|
|
|
2021-01-21 00:21:15 +01:00
|
|
|
async created() {
|
2022-03-22 01:23:15 +01:00
|
|
|
this.logger = new Logger();
|
2023-01-04 18:09:01 +01:00
|
|
|
|
|
|
|
// this prolly needs to be taken out
|
2022-03-22 01:23:15 +01:00
|
|
|
await this.logger.init({
|
|
|
|
allowLogging: true,
|
|
|
|
});
|
2021-01-21 00:21:15 +01:00
|
|
|
|
2022-03-22 01:23:15 +01:00
|
|
|
this.settings = new Settings({afterSettingsSaved: this.updateConfig, logger: this.logger});
|
|
|
|
await this.settings.init();
|
|
|
|
this.settingsInitialized = true;
|
2021-01-21 00:21:15 +01:00
|
|
|
|
2023-07-10 22:56:26 +02:00
|
|
|
// set up communication with client script.
|
|
|
|
// NOTE: companion onmousemove is set up in UIProbeMixin
|
2022-03-22 01:23:15 +01:00
|
|
|
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
|
|
|
}});
|
2024-06-02 16:06:26 +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-02 16:06:26 +02:00
|
|
|
}
|
|
|
|
}});
|
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
|
|
|
},
|
2022-03-21 00:50:03 +01:00
|
|
|
|
2020-12-15 00:26:19 +01:00
|
|
|
methods: {
|
2022-03-21 00:50:03 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
2020-12-22 23:23:03 +01:00
|
|
|
},
|
2022-03-21 00:50:03 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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;
|
2022-03-21 00:50:03 +01:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
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
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
2022-06-11 15:40:36 +02:00
|
|
|
showUwWindow() {
|
|
|
|
this.uwWindowFadeOut = false;
|
|
|
|
this.uwWindowVisible = true;
|
|
|
|
this.uwTriggerZoneVisible = false;
|
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) {
|
2022-06-15 00:43:36 +02:00
|
|
|
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);
|
|
|
|
},
|
|
|
|
|
2022-03-29 01:53:16 +02:00
|
|
|
handleBusTunnelIn(payload) {
|
2024-06-05 01:08:50 +02:00
|
|
|
this.eventBus.send(payload.action, payload.config, payload.routingData);
|
2022-03-29 01:53:16 +02:00
|
|
|
},
|
|
|
|
|
2022-03-22 01:23:15 +01:00
|
|
|
selectTab(tab) {
|
2022-06-09 01:29:26 +02:00
|
|
|
this.selectedTab = tab;
|
2022-03-21 00:50:03 +01:00
|
|
|
}
|
2020-12-15 00:26:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
<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';
|
2022-03-29 01:53:16 +02:00
|
|
|
@import './src/res-common/_variables';
|
2022-01-29 16:23:40 +01:00
|
|
|
|
2022-06-15 00:43:36 +02:00
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
.uw-hover {
|
|
|
|
position: absolute;
|
|
|
|
z-index: 999999999999999999;
|
|
|
|
}
|
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);
|
2022-01-29 16:23:40 +01:00
|
|
|
}
|
2020-12-17 01:49:28 +01:00
|
|
|
|
2023-01-06 18:47:42 +01:00
|
|
|
.uw-window {
|
2022-01-29 16:23:40 +01:00
|
|
|
position: absolute;
|
2021-10-19 22:49:56 +02:00
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
top: 10%;
|
|
|
|
left: 10%;
|
2020-12-17 01:49:28 +01:00
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
z-index: 999999999999999999;
|
2020-12-16 01:40:09 +01:00
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
width: 2500px;
|
|
|
|
height: 1200px;
|
|
|
|
max-width: 80%;
|
|
|
|
max-height: 80%;
|
2020-12-16 01:40:09 +01:00
|
|
|
|
2022-01-29 16:23:40 +01:00
|
|
|
pointer-events: all !important;
|
2020-12-16 01:40:09 +01:00
|
|
|
|
2023-01-06 18:47:42 +01:00
|
|
|
opacity: 1;
|
2022-01-29 16:23:40 +01:00
|
|
|
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
|
|
|
}
|
2022-01-29 16:23:40 +01:00
|
|
|
}
|
2020-12-15 00:26:19 +01:00
|
|
|
|
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%);
|
|
|
|
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-19 22:49:56 +02:00
|
|
|
</style>
|