WIP on player detection config import
This commit is contained in:
parent
077c7cae15
commit
3f5ab5ecc6
@ -501,11 +501,10 @@ export interface SiteDOMSettingsInterface {
|
||||
}
|
||||
|
||||
export interface PlayerDOMSettingsInterface {
|
||||
playerDetectionMode: PlayerDetectionMode,
|
||||
detectionMode: PlayerDetectionMode,
|
||||
allowAutoFallback: boolean,
|
||||
ancestorIndex?: number,
|
||||
querySelectors?: string,
|
||||
customCSS?: string,
|
||||
}
|
||||
|
||||
export interface SiteDOMElementSettingsInterface {
|
||||
|
||||
@ -341,6 +341,20 @@ const ExtensionConfPatch = Object.freeze([
|
||||
userOptions.sites[site].persistCSA = userOptions.sites[site].persistCSA ?? CropModePersistence.Default;
|
||||
}
|
||||
|
||||
if (userOptions.sites[site].type as any === 'user-added' || userOptions.sites[site].type === 'user-defined') {
|
||||
userOptions.sites[site].type = SiteSupportLevel.UserDefined;
|
||||
}
|
||||
if (userOptions.sites[site].type as any === 'no-support') {
|
||||
userOptions.sites[site].type = SiteSupportLevel.Unknown;
|
||||
}
|
||||
if (userOptions.sites[site].defaultType as any === 'user-added' || userOptions.sites[site].defaultType === 'user-defined') {
|
||||
userOptions.sites[site].type = SiteSupportLevel.UserDefined;
|
||||
}
|
||||
if (userOptions.sites[site].defaultType as any === 'no-support') {
|
||||
userOptions.sites[site].defaultType = SiteSupportLevel.Unknown;
|
||||
}
|
||||
|
||||
|
||||
for (const domConf in siteData.DOMConfig) {
|
||||
logger.log('updateFn', "Updating domconf", domConf);
|
||||
const oldConf = userOptions.sites[site].DOMConfig[domConf] as any;
|
||||
@ -351,22 +365,31 @@ const ExtensionConfPatch = Object.freeze([
|
||||
elements: {}
|
||||
};
|
||||
|
||||
if (newConf.type === 'user-added' || newConf.type === 'user-defined') {
|
||||
newConf.type = SiteSupportLevel.UserDefined;
|
||||
}
|
||||
if (newConf.type === 'no-support') {
|
||||
newConf.type = SiteSupportLevel.Unknown;
|
||||
}
|
||||
|
||||
if (oldConf.elements?.player) {
|
||||
newConf.elements['player'] = {
|
||||
playerDetectionMode: oldConf?.elements?.player?.manual ? (
|
||||
detectionMode: oldConf?.elements?.player?.manual ? (
|
||||
oldConf?.elements?.player?.querySelectors.trim() ? PlayerDetectionMode.QuerySelectors : PlayerDetectionMode.AncestorIndex
|
||||
) : PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
ancestorIndex: oldConf?.elements?.player?.parentIndex,
|
||||
querySelectors: oldConf?.elements?.player?.querySelectors,
|
||||
customCSS: oldConf?.elements?.player?.customCss,
|
||||
}
|
||||
} else {
|
||||
newConf.elements['player'] = {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
}
|
||||
}
|
||||
if (oldConf.customCss) {
|
||||
newConf.customCss = oldConf.customCss;
|
||||
}
|
||||
|
||||
if (oldConf.elements?.video) {
|
||||
newConf.elements['video'] = {
|
||||
@ -394,7 +417,7 @@ const ExtensionConfPatch = Object.freeze([
|
||||
type: SiteSupportLevel.Unknown,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
}
|
||||
}
|
||||
@ -406,18 +429,12 @@ const ExtensionConfPatch = Object.freeze([
|
||||
type: SiteSupportLevel.UserDefined,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1,
|
||||
// querySelectors: '',
|
||||
// customCSS: ''
|
||||
},
|
||||
video: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1,
|
||||
// querySelectors: '',
|
||||
// customCSS: ''
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@ -829,11 +829,10 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.Unknown,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1, // we leave those on undefined,
|
||||
// querySelectors: '',
|
||||
// customCSS: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -863,18 +862,16 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.UserDefined,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1,
|
||||
// querySelectors: '',
|
||||
// customCSS: ''
|
||||
},
|
||||
video: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1,
|
||||
// querySelectors: '',
|
||||
// customCSS: ''
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -899,7 +896,7 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.OfficialSupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: "#movie_player, #player, #c4-player",
|
||||
}
|
||||
@ -927,7 +924,7 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.OfficialSupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: "#movie_player, #player, #c4-player",
|
||||
}
|
||||
@ -950,7 +947,7 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.CommunitySupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.Auto,
|
||||
detectionMode: PlayerDetectionMode.Auto,
|
||||
allowAutoFallback: true,
|
||||
// ancestorIndex: 1,
|
||||
// querySelectors: '',
|
||||
@ -975,12 +972,12 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.OfficialSupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: ".btm-media-player",
|
||||
},
|
||||
video: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: ".btm-media-client-element"
|
||||
}
|
||||
@ -1005,7 +1002,7 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.OfficialSupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: "#movie_player, #player, #c4-player",
|
||||
}
|
||||
@ -1058,7 +1055,7 @@ const ExtensionConf: SettingsInterface = {
|
||||
type: SiteSupportLevel.CommunitySupport,
|
||||
elements: {
|
||||
player: {
|
||||
playerDetectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
detectionMode: PlayerDetectionMode.QuerySelectors,
|
||||
allowAutoFallback: true,
|
||||
querySelectors: "#jwplayer-container"
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
class="popup-overlay"
|
||||
:class="{'dim': dimOverlay}"
|
||||
>
|
||||
<div class="popup-content p-4 border border-stone-700 max-h-[90dvh] max-w-[90dvw]" >
|
||||
<div class="popup-content p-4 border border-stone-700 bg-stone-950 max-h-[90dvh] max-w-[90dvw]" >
|
||||
<div class="h-full flex flex-col w-full">
|
||||
<div v-if="title" class="header grow-0 shrink-0" :class="type">
|
||||
<h3 class="mb-4 mt-0">{{title}}</h3>
|
||||
@ -15,7 +15,7 @@
|
||||
<div v-else class="h-full w-full -mr-4 pr-4 grow shrink overflow-y-auto overflow-x-hidden">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="grow-0 shrink-0 flex row gap-2 justify-end w-full">
|
||||
<div v-if="!clientSideButtons" class="grow-0 shrink-0 flex row gap-2 justify-end w-full">
|
||||
<button
|
||||
class="primary"
|
||||
v-if="confirmButtonText"
|
||||
@ -63,6 +63,10 @@ export default {
|
||||
type: String,
|
||||
default: 'info'
|
||||
},
|
||||
clientSideButtons: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
confirmButtonText: {
|
||||
type: String,
|
||||
required: false,
|
||||
@ -94,6 +98,7 @@ export default {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.header {
|
||||
font-size: 1.33rem;
|
||||
|
||||
|
||||
@ -1,68 +1,95 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="computedSiteSupportLevel === 'official'"
|
||||
class="site-support site-support-level official"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="check-decagram" />
|
||||
<div v-if="!small">Verified</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Verified — </template>
|
||||
The extension is being tested and should work on this site.
|
||||
<div v-if="computedSiteSupportLevel === SiteSupportLevel.OfficialSupport"
|
||||
class="site-support site-support-level official"
|
||||
:class="{'no-tooltip': disableTooltip}"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="check-decagram" />
|
||||
<div v-if="!small">Verified</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Verified — </template>
|
||||
The extension is being tested and should work on this site.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="computedSiteSupportLevel === 'community'" class="site-support site-support-level community" :style="supportLevelStyle">
|
||||
<mdicon name="account-group" />
|
||||
<div v-if="!small">Community</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Community — </template>
|
||||
People say extension works on this site (or have provided help getting the extension to work if it didn't).<br/><br/>
|
||||
Tamius (the dev) does not test the extension on this site, probably because it requires a subscription or
|
||||
is geoblocked.
|
||||
<div v-if="computedSiteSupportLevel === SiteSupportLevel.CommunitySupport"
|
||||
class="site-support site-support-level community"
|
||||
:class="{'no-tooltip': disableTooltip}"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="account-group" />
|
||||
<div v-if="!small">Community</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Community — </template>
|
||||
People say extension works on this site (or have provided help getting the extension to work if it didn't).<br/><br/>
|
||||
Tamius (the dev) does not test the extension on this site, probably because it requires a subscription or
|
||||
is geoblocked.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="computedSiteSupportLevel === 'no-support' || computedSiteSupportLevel === 'unknown'" class="site-support site-support-level no-support" :style="supportLevelStyle">
|
||||
<mdicon name="help-circle-outline" />
|
||||
<div v-if="!small">Untested</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Untested — </template>
|
||||
Extension will try to fix things, but no promises; for you are exploring the uncharted lands.<br/><br/>
|
||||
Tamius (the dev) does not test the extension on this site for various reasons
|
||||
(unaware, not using the site, language barrier, geoblocking, paid services Tam doesn't use).
|
||||
<div v-if="computedSiteSupportLevel === SiteSupportLevel.Unknown"
|
||||
class="site-support site-support-level no-support"
|
||||
:class="{'no-tooltip': disableTooltip}"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="help-circle-outline" />
|
||||
<div v-if="!small">Untested</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Untested — </template>
|
||||
Extension will try to fix things, but no promises; for you are exploring the uncharted lands.<br/><br/>
|
||||
Tamius (the dev) does not test the extension on this site for various reasons
|
||||
(unaware, not using the site, language barrier, geoblocking, paid services Tam doesn't use).
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="computedSiteSupportLevel === 'user-added' || computedSiteSupportLevel === 'user-defined'" class="site-support site-support-level user-added" :style="supportLevelStyle">
|
||||
<mdicon name="account" />
|
||||
<div v-if="!small">Modified by you</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Modified by you — </template>
|
||||
You are on your own. You have manually changed settings for this site. The extension is doing what you told it to do.
|
||||
<div v-if="computedSiteSupportLevel === SiteSupportLevel.UserDefined || computedSiteSupportLevel === SiteSupportLevel.UserModified"
|
||||
class="site-support site-support-level user-added"
|
||||
:class="{'no-tooltip': disableTooltip}"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="account" />
|
||||
<div v-if="!small">Modified by you</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Modified by you — </template>
|
||||
You are on your own. You have manually changed settings for this site. The extension is doing what you told it to do.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="computedSiteSupportLevel === 'officially-disabled'" class="site-support site-support-level officially-disabled" :style="supportLevelStyle">
|
||||
<mdicon name="close-circle" />
|
||||
<div v-if="!small">Blacklisted</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Blacklisted — </template>
|
||||
Extension is known to not work with this site.
|
||||
<div v-if="computedSiteSupportLevel === SiteSupportLevel.BetaSupport">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="computedSiteSupportLevel === 'officially-disabled'"
|
||||
class="site-support site-support-level officially-disabled"
|
||||
:class="{'no-tooltip': disableTooltip}"
|
||||
:style="supportLevelStyle"
|
||||
>
|
||||
<mdicon name="close-circle" />
|
||||
<div v-if="!small">Blacklisted</div>
|
||||
<div class="tooltip" :style="tooltipStyle">
|
||||
<template v-if="small">Blacklisted — </template>
|
||||
Extension is known to not work with this site.
|
||||
</div>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { SiteSupportLevel } from '@src/common/enums/SiteSupportLevel.enum';
|
||||
|
||||
export default defineComponent({
|
||||
data() {
|
||||
return {
|
||||
SiteSupportLevel
|
||||
};
|
||||
},
|
||||
props: {
|
||||
siteSupportLevel: String,
|
||||
siteSettings: Object,
|
||||
small: Boolean,
|
||||
disableTooltip: Boolean,
|
||||
supportLevelStyle: String,
|
||||
tooltipStyle: String,
|
||||
},
|
||||
computed: {
|
||||
computedSiteSupportLevel() {
|
||||
return this.siteSupportLevel ?? (this.siteSettings ? this.siteSettings.data.type ?? 'no-support' : 'waiting');
|
||||
return this.siteSupportLevel ?? (this.siteSettings ? this.siteSettings.data.type ?? SiteSupportLevel.Unknown : 'waiting');
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,6 +102,7 @@ export default defineComponent({
|
||||
.site-support {
|
||||
@apply inline-flex flex-row items-center gap-1 rounded-[0.5rem] relative;
|
||||
|
||||
|
||||
.tooltip {
|
||||
padding: 1rem;
|
||||
display: none;
|
||||
@ -93,6 +121,13 @@ export default defineComponent({
|
||||
word-break: break-word;
|
||||
}
|
||||
&:hover {
|
||||
|
||||
&.no-tooltip {
|
||||
.tooltip {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ export default defineComponent({
|
||||
this.editSnapshot(snapshot);
|
||||
},
|
||||
handleImportedSnapshotError(error: any) {
|
||||
console.error(`[ultrawidify] Failed to upload snapshot. Error:`, e);
|
||||
console.error(`[ultrawidify] Failed to upload snapshot. Error:`, error);
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
@ -330,6 +330,7 @@
|
||||
title="Player detection options"
|
||||
confirmButtonText="Save"
|
||||
cancelButtonText="Cancel"
|
||||
@onCancel="playerDetectionOptionsDialog.visible = false"
|
||||
>
|
||||
<PlayerSelectorAdvancedForm
|
||||
:settings="settings"
|
||||
|
||||
@ -2,15 +2,35 @@
|
||||
<!-- ADVANCED OPTIONS -->
|
||||
<div class="flex flex-col gap-2">
|
||||
<div class="flex flex-row gap-2 justify-end">
|
||||
<button>Load existing config</button>
|
||||
<button>Import from file</button>
|
||||
<button @click="openSelectSnapshotDialog()">Load existing config</button>
|
||||
<UploadJsonFileButton
|
||||
@importedJson="handleImportedSettings"
|
||||
@error="handleSettingsImportError"
|
||||
>
|
||||
Import settings
|
||||
</UploadJsonFileButton>
|
||||
<button>Export config</button>
|
||||
</div>
|
||||
|
||||
<template v-if="DOMConfigData" >
|
||||
<div v-if="loaded" class="w-[690px] max-w-full">
|
||||
|
||||
<div v-if="DOMConfigName" class="field">
|
||||
<div class="label">Current preset name:</div>
|
||||
<div class="flex flex-row gap-2 items-center">
|
||||
{{DOMConfigName}}
|
||||
<SupportLevelIndicator
|
||||
:siteSupportLevel="DOMConfigData.type"
|
||||
:disableTooltip="true"
|
||||
></SupportLevelIndicator>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- #region player element detection -->
|
||||
<div class="field">
|
||||
<div class="label">Player detection:</div>
|
||||
<div class="select">
|
||||
<select v-model="DOMConfigData.elements.player.playerDetectionMode">
|
||||
<select v-model="DOMConfigData.elements.player.detectionMode">
|
||||
<option :value="PlayerDetectionMode.Auto">Automatic</option>
|
||||
<option :value="PlayerDetectionMode.AncestorIndex">Fixed player container offset</option>
|
||||
<option :value="PlayerDetectionMode.QuerySelectors">Query selectors</option>
|
||||
@ -18,48 +38,107 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Use automatic detection for fallback</div>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" v-model="DOMConfigData.elements.player.allowAutoFallback" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Player container offset</div>
|
||||
<div class="input">
|
||||
<input v-model="DOMConfigData.elements.player.ancestorIndex" />
|
||||
<!-- Player container offset ( ancestor index field -->
|
||||
<template v-if="DOMConfigData.elements.player.detectionMode === PlayerDetectionMode.AncestorIndex">
|
||||
<div class="field">
|
||||
<div class="label">Player container offset:</div>
|
||||
<div class="input">
|
||||
<input v-model="DOMConfigData.elements.player.ancestorIndex" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
Defines how far away from video the player container element is. If you don't know what you're doing, start
|
||||
with 1, save settings, and reload the page. If this doesn't fix your problem, increase the number by 1 and
|
||||
repeat the procedure. If no value between 1-16 works, the site may require additional CSS in order to work.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Query selector</div>
|
||||
<div class="input">
|
||||
<input v-model="DOMConfigData.elements.player.querySelectors" />
|
||||
<!-- Query selectors field -->
|
||||
<template v-if="DOMConfigData.elements.player.detectionMode === PlayerDetectionMode.QuerySelectors">
|
||||
<div class="field">
|
||||
<div class="label">Query selectors:</div>
|
||||
<div class="input">
|
||||
<input v-model="DOMConfigData.elements.player.querySelectors" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
You should be at least somewhat proficient with CSS in order to use this option. If you need to provide more
|
||||
than one query selector, use commas to separate them.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Additional CSS for the page</div>
|
||||
<div class="input">
|
||||
<textarea v-model="DOMConfigData.customCSS" />
|
||||
<!-- Use auto-selection for fallback -->
|
||||
<template v-if="DOMConfigData.elements.player.detectionMode !== PlayerDetectionMode.Auto">
|
||||
<div class="field">
|
||||
<div class="label">Use automatic detection for fallback</div>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" v-model="DOMConfigData.elements.player.allowAutoFallback" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
You should be at least somewhat proficient with CSS in order to use this option.
|
||||
If no valid player is found by following these settings, use automatic player detection as a fallback.
|
||||
You should probably keep this option on.
|
||||
</div>
|
||||
</template>
|
||||
<!-- #endregion -->
|
||||
|
||||
<!-- #region video element detection -->
|
||||
<div class="field">
|
||||
<div class="label">Video detection:</div>
|
||||
<div class="select">
|
||||
<select v-model="DOMConfigData.elements.video.detectionMode">
|
||||
<option :value="PlayerDetectionMode.Auto">Automatic</option>
|
||||
<option :value="PlayerDetectionMode.QuerySelectors">Query selectors</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Player container offset / ancestor index field, not valid in video element selection -->
|
||||
<template v-if="DOMConfigData.elements.video.detectionMode === PlayerDetectionMode.AncestorIndex">
|
||||
<div class="field">
|
||||
<div class="label">Yo, that 'video detection' mode is straight up illegal. Change it to something else.</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
<!-- Query selectors field -->
|
||||
<template v-if="DOMConfigData.elements.video.detectionMode === PlayerDetectionMode.QuerySelectors">
|
||||
<div class="field">
|
||||
<div class="label">Query selectors:</div>
|
||||
<div class="input">
|
||||
<input v-model="DOMConfigData.elements.video.querySelectors" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
You should be at least somewhat proficient with CSS in order to use this option. If you need to provide more
|
||||
than one query selector, use commas to separate them.
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Use auto-selection for fallback -->
|
||||
<template v-if="DOMConfigData.elements.video.detectionMode !== PlayerDetectionMode.Auto">
|
||||
<div class="field">
|
||||
<div class="label">Use automatic detection for fallback</div>
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" v-model="DOMConfigData.elements.video.allowAutoFallback" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
If no valid video is found by following these settings, use automatic player detection as a fallback.
|
||||
You should probably keep this option on.
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="field">
|
||||
<div class="label">Additional CSS for the page:</div>
|
||||
<div class="input">
|
||||
<textarea v-model="DOMConfigData.customCss"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hint">
|
||||
CSS that will be injected into the page. You should be at least somewhat proficient with CSS in order to use this option.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<template v-else>
|
||||
No DOM config for this site.
|
||||
</template>
|
||||
@ -67,28 +146,91 @@
|
||||
|
||||
<div class="w-full flex flex-row gap-2 justify-end">
|
||||
<button>Save as</button>
|
||||
<button>Save</button>
|
||||
<button :disabled="DOMConfigName?.startsWith('@')">Save</button>
|
||||
<button>Close</button>
|
||||
</div>
|
||||
|
||||
<!-- PRESET SELECT DIALOG -->
|
||||
<Popup
|
||||
v-if="selectSnapshotDialog.visible"
|
||||
title="Select configuration"
|
||||
@onClose="selectSnapshotDialog.visible = false"
|
||||
>
|
||||
|
||||
<div>Select configuration:</div>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
<div
|
||||
v-for="(value, key) of siteSettings.data.DOMConfig" :key="key"
|
||||
class="
|
||||
px-4 py-2 flex flex-row gap-2 w-full items-center
|
||||
border border-stone-800 hover:bg-stone-800
|
||||
"
|
||||
:class="{'!border-primary-300 text-primary-300': key === siteSettings.data.activeDOMConfig}"
|
||||
@click="selectConfig(key)"
|
||||
>
|
||||
<div>{{key}}</div>
|
||||
<SupportLevelIndicator :siteSupportLevel="value.type" :disableTooltip="true"></SupportLevelIndicator>
|
||||
<div class="grow"></div>
|
||||
<div v-if="key === siteSettings.data.activeDOMConfig" class="">
|
||||
<mdicon name="check-bold" :size="20"></mdicon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
|
||||
<!-- FINISH IMPORT DIALOG -->
|
||||
<Popup
|
||||
v-if="finishImportDialog.visible"
|
||||
:title="finishImportDialog.data.invalidJson ? 'Import failed' : 'Select configuration'"
|
||||
@onClose="finishImportDialog.visible = false"
|
||||
:clientSideButtons="true"
|
||||
>
|
||||
<template v-if="finishImportDialog.data.invalidJson">
|
||||
<div>The selected file appears to be corrupted, as it contains no valid configurations.</div>
|
||||
<div class="flex flex-row justify-end mt-4"><button @click="finishImportDialog.visible = false">OK</button></div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>The following configurations were imported. Resolve any conflicts and select the config you wish to use.</div>
|
||||
<div class="flex flex-col gap-2 py-4">
|
||||
<div
|
||||
v-for="(value, key) of finishImportDialog.data.DOMConfig" :key="key"
|
||||
class="
|
||||
px-4 py-2 flex flex-row gap-2 w-full items-center
|
||||
border border-stone-800 hover:bg-stone-800
|
||||
"
|
||||
:class="{'!border-primary-300 text-primary-300': key === finishImportDialog.data.activeDOMConfig}"
|
||||
>
|
||||
<div>{{key}}</div>
|
||||
<SupportLevelIndicator :siteSupportLevel="value.type" :disableTooltip="true"></SupportLevelIndicator>
|
||||
<div class="grow"></div>
|
||||
<div v-if="key === finishImportDialog.data.activeDOMConfig" class="">
|
||||
<mdicon name="check-bold" :size="20"></mdicon>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popup>
|
||||
|
||||
<!-- EXPORT CONFIG DIALOG -->
|
||||
|
||||
<!-- SAVE AS DIALOG -->
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { SiteSettings } from '@src/ext/lib/settings/SiteSettings';
|
||||
import { PlayerDetectionMode } from '@src/common/enums/PlayerDetectionMode.enum';
|
||||
import UploadJsonFileButton from '@components/common/UploadJsonFileButton.vue';
|
||||
import SupportLevelIndicator from '@components/common/SupportLevelIndicator.vue';
|
||||
|
||||
import Popup from '@components/common/Popup.vue';
|
||||
import { _cp } from '../../../../../common/js/utils';
|
||||
import { _cp } from '@src/common/js/utils';
|
||||
import { SiteDOMSettingsInterface } from '@src/common/interfaces/SettingsInterface';
|
||||
|
||||
|
||||
export default({
|
||||
components: {
|
||||
PlayerDetectionMode,
|
||||
UploadJsonFileButton,
|
||||
SupportLevelIndicator,
|
||||
Popup,
|
||||
},
|
||||
props: [
|
||||
@ -98,8 +240,11 @@ export default({
|
||||
data() {
|
||||
return {
|
||||
PlayerDetectionMode,
|
||||
loaded: false,
|
||||
DOMConfigData: undefined as any,
|
||||
DOMConfigName: undefined as any,
|
||||
selectSnapshotDialog: {visible: false},
|
||||
finishImportDialog: {visible: false}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -113,14 +258,69 @@ export default({
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadSiteSettings(siteSettings: SiteSettings) {
|
||||
loadSiteSettings(siteSettings: SiteSettings, configKey = siteSettings.data.activeDOMConfig) {
|
||||
let DOMConfigData;
|
||||
if (siteSettings.data.DOMConfig) {
|
||||
this.DOMConfigData = siteSettings.data.DOMConfig[siteSettings.data.activeDOMConfig];
|
||||
} else {
|
||||
this.DOMConfigData = _cp(siteSettings.blankSettings.DOMConfig.blank)
|
||||
}
|
||||
}
|
||||
DOMConfigData = siteSettings.data.DOMConfig[configKey];
|
||||
this.DOMConfigName = configKey;
|
||||
|
||||
if (!DOMConfigData.elements) {
|
||||
DOMConfigData.elements = _cp(siteSettings.blankSettings.DOMConfig.empty);
|
||||
}
|
||||
if (!DOMConfigData.elements.player) {
|
||||
DOMConfigData.elements.player = _cp(siteSettings.blankSettings.DOMConfig.empty.elements.player);
|
||||
}
|
||||
if (!DOMConfigData.elements.video) {
|
||||
DOMConfigData.elements.video = _cp(siteSettings.blankSettings.DOMConfig.empty.elements.video);
|
||||
}
|
||||
} else {
|
||||
DOMConfigData = _cp(siteSettings.blankSettings.DOMConfig.empty)
|
||||
}
|
||||
this.DOMConfigData = DOMConfigData;
|
||||
|
||||
this.loaded = true;
|
||||
},
|
||||
|
||||
openSelectSnapshotDialog() {
|
||||
this.selectSnapshotDialog = {
|
||||
visible: true
|
||||
}
|
||||
},
|
||||
|
||||
selectConfig(key: string) {
|
||||
this.loadSiteSettings(this.siteSettings, key);
|
||||
this.siteSettings.set('activeDOMConfig', key);
|
||||
this.selectSnapshotDialog = false;
|
||||
},
|
||||
|
||||
handleImportedSettings(json: {activeDOMConfig?: string, DOMConfig: { [x: string]: SiteDOMSettingsInterface & {overwrite?: boolean}}} | SiteDOMSettingsInterface) {
|
||||
let afterImportDialogData;
|
||||
|
||||
if ((json as any).DOMConfig) {
|
||||
afterImportDialogData = json;
|
||||
} else if ((json as SiteDOMSettingsInterface).type) {
|
||||
const key = `imported-${new Date().toISOString()}`;
|
||||
afterImportDialogData = {
|
||||
activeDOMConfig: key,
|
||||
DOMConfig: {
|
||||
[key]: json as SiteDOMSettingsInterface
|
||||
}
|
||||
}
|
||||
} else {
|
||||
afterImportDialogData = {
|
||||
invalidJson: true
|
||||
}
|
||||
}
|
||||
|
||||
this.finishImportDialog = {
|
||||
data: afterImportDialogData,
|
||||
visible: true
|
||||
};
|
||||
},
|
||||
|
||||
handleSettingsImportError(error) {
|
||||
console.error(`[ultrawidify] Failed to upload snapshot. Error:`, error);
|
||||
},
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -14,5 +14,9 @@
|
||||
&:hover {
|
||||
@apply border-primary-500 text-primary-300;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
@apply pointer-events-none text-stone-500 border-stone-700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,10 @@
|
||||
.input, .range-input {
|
||||
@apply py-1 px-2 bg-black/25 border-b border-white/50 w-full relative;
|
||||
|
||||
&.multiline {
|
||||
@apply border border-stone-500;
|
||||
}
|
||||
|
||||
&:active, &:focus, &:focus-within {
|
||||
@apply border-b-1 border-b-primary-400;
|
||||
}
|
||||
@ -21,6 +25,14 @@
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
textarea {
|
||||
@apply text-sm font-mono border border-stone-800 -my-1 -mb-2 -mx-2 px-2 py-1 pb-2;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.unit {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
@ -115,16 +127,18 @@
|
||||
font-size: 5rem;;
|
||||
}
|
||||
&:hover {
|
||||
@apply text-black bg-primary-400;
|
||||
@apply text-black bg-primary-300;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.hint {
|
||||
@apply text-primary-200/70;
|
||||
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.7;
|
||||
margin-top: 0.25rem;
|
||||
margin-top: -0.33rem;
|
||||
margin-bottom: 0.75rem;
|
||||
margin-left: 5rem;
|
||||
box-sizing:border-box;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user