Allow some cross-domain settings sharing, handle settings inheritance, don't save auto-detected player index
This commit is contained in:
parent
150a0a8a90
commit
e67b5a227f
@ -93,6 +93,7 @@
|
||||
:eventBus="eventBus"
|
||||
:siteSettings="siteSettings"
|
||||
:site="site.host"
|
||||
:frames="activeFrames"
|
||||
>
|
||||
</BaseExtensionSettings>
|
||||
<ChangelogPanel
|
||||
@ -307,6 +308,7 @@ export default {
|
||||
label: this.site.frames[frame].host,
|
||||
host: this.site.frames[frame].host,
|
||||
...this.site.frames[frame],
|
||||
...this.settings.active.sites[this.site.frames[frame].host]
|
||||
})
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
<small>{{ site }}</small>
|
||||
</div>
|
||||
<div
|
||||
v-if="frames"
|
||||
class="tab"
|
||||
:class="{'active': tab === 'embeddedSites'}"
|
||||
@click="setTab(tab = 'embeddedSites')"
|
||||
@ -37,13 +38,12 @@
|
||||
></SiteExtensionSettings>
|
||||
</template>
|
||||
|
||||
<template v-if="tab === 'extensionSettings' && globalSettings">
|
||||
<SiteExtensionSettings
|
||||
<template v-if="frames && tab === 'embeddedSites' && globalSettings">
|
||||
<FrameSiteSettings
|
||||
v-if="settings"
|
||||
:frames="frames"
|
||||
:settings="settings"
|
||||
:siteSettings="globalSettings"
|
||||
:isDefaultConfiguration="true"
|
||||
></SiteExtensionSettings>
|
||||
></FrameSiteSettings>
|
||||
</template>
|
||||
|
||||
<template v-if="tab === 'otherSites'">
|
||||
@ -153,6 +153,7 @@
|
||||
|
||||
<script>
|
||||
import SiteExtensionSettings from './PanelComponents/ExtensionSettings/SiteExtensionSettings.vue';
|
||||
import FrameSiteSettings from './PanelComponents/ExtensionSettings/FrameSiteSettings.vue';
|
||||
import OtherSiteSettings from './PanelComponents/ExtensionSettings/OtherSiteSettings.vue';
|
||||
import Popup from '@csui/src/components/Popup';
|
||||
import ConfirmButton from '@csui/src/components/ConfirmButton';
|
||||
@ -162,6 +163,23 @@ import JsonEditor from '@csui/src/components/JsonEditor';
|
||||
|
||||
|
||||
export default {
|
||||
|
||||
components: {
|
||||
SiteExtensionSettings,
|
||||
OtherSiteSettings,
|
||||
Popup,
|
||||
ConfirmButton,
|
||||
UploadJsonFileButton,
|
||||
JsonEditor,
|
||||
FrameSiteSettings,
|
||||
},
|
||||
mixins: [],
|
||||
props: [
|
||||
'settings',
|
||||
'site',
|
||||
'enableSettingsEditor',
|
||||
'frames',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
tab: 'siteSettings',
|
||||
@ -172,22 +190,6 @@ export default {
|
||||
settingsSnapshots: []
|
||||
}
|
||||
},
|
||||
mixins: [
|
||||
|
||||
],
|
||||
props: [
|
||||
'settings',
|
||||
'site',
|
||||
'enableSettingsEditor'
|
||||
],
|
||||
components: {
|
||||
SiteExtensionSettings,
|
||||
OtherSiteSettings,
|
||||
Popup,
|
||||
ConfirmButton,
|
||||
UploadJsonFileButton,
|
||||
JsonEditor
|
||||
},
|
||||
computed: {
|
||||
globalSettings() {
|
||||
return this.settings?.getSiteSettings('@global') ?? null;
|
||||
|
@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div class="">
|
||||
<template v-if="!selectedSite">
|
||||
<div style="margin: 1rem 0rem" class="w-full">
|
||||
<div class="flex flex-row items-baseline">
|
||||
<div style="margin-right: 1rem">Search for site:</div>
|
||||
<div class="input flex-grow">
|
||||
<input v-model="siteFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="frame of frames" :key="frame.host" @click="selectedSite = frame.host" class="flex flex-col container pointer hoverable" style="margin-top: 4px; padding: 0.5rem 1rem;">
|
||||
<SiteListItem
|
||||
:frame="frame"
|
||||
:settings="settings"
|
||||
></SiteListItem>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="selectedSite">
|
||||
<div class="flex flex-row container" style="align-items: center; color: #dedede; margin-top: 1rem;">
|
||||
<div @click="selectedSite = null" class="pointer button-hover" style=" font-size: 2em; padding: 0.5rem; margin-right: 1em;">
|
||||
←
|
||||
</div>
|
||||
<div>
|
||||
Editing {{ selectedSite === '@global' ? 'default settings' : selectedSite }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<SiteExtensionSettings
|
||||
v-if="selectedSiteSettings"
|
||||
:settings="settings"
|
||||
:siteSettings="selectedSiteSettings"
|
||||
:isDefaultConfiguration="selectedSite === '@global'"
|
||||
></SiteExtensionSettings>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SiteExtensionSettings from './SiteExtensionSettings.vue';
|
||||
import SiteListItem from './SiteListItem.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SiteExtensionSettings,
|
||||
SiteListItem,
|
||||
},
|
||||
props: [
|
||||
'settings',
|
||||
'frames',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
selectedSite: null,
|
||||
siteFilter: '',
|
||||
filteredSites: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sites() {
|
||||
if (!this.settings?.active?.sites) {
|
||||
return [];
|
||||
} else {
|
||||
const sites = [];
|
||||
for (const siteKey in this.settings.active.sites) {
|
||||
if (!siteKey.startsWith('@') && (!this.siteFilter.trim() || siteKey.includes(this.siteFilter))) {
|
||||
sites.push({
|
||||
key: siteKey,
|
||||
...this.settings.active.sites[siteKey]
|
||||
})
|
||||
}
|
||||
};
|
||||
sites.sort((a, b) => {
|
||||
const cmpa = a.key.replace('www.', '');
|
||||
const cmpb = b.key.replace('www.', '');
|
||||
|
||||
return cmpa < cmpb ? -1 : 1;
|
||||
});
|
||||
return sites;
|
||||
}
|
||||
},
|
||||
selectedSiteSettings() {
|
||||
return this.settings?.getSiteSettings(this.selectedSite) ?? null;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="../../../../res/css/flex.scss" scoped></style>
|
||||
<style lang="scss" src="@csui/src/res-common/panels.scss" scoped></style>
|
||||
<style lang="scss" src="@csui/src/res-common/common.scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.hoverable {
|
||||
border: 1px solid #333;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid #fa6;
|
||||
color: rgb(255, 231, 212);
|
||||
background-color: rgba(#fa6, 0.125);
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex flex-row">
|
||||
<div class="flex-grow pointer">
|
||||
<b>{{ frame.host ?? frame.key }}</b>
|
||||
<span :style="getSiteTypeColor(frame.type)">
|
||||
(config: {{frame.type ?? 'unknown'}})
|
||||
</span>
|
||||
</div>
|
||||
<div>Edit</div>
|
||||
</div>
|
||||
<div v-if="this.siteSettings?.usesSettingsFor">
|
||||
<div v-if="this.siteSettings.usesSettingsFor === '@global'">Uses default settings</div>
|
||||
<div v-else>Uses settings for: {{this.siteSettings.usesSettingsFor}}</div>
|
||||
</div>
|
||||
<div class="flex flex-row">
|
||||
<small>
|
||||
Enabled: <span :style="getSiteEnabledColor(frame.host, 'enable')"><small>{{ getSiteEnabledModes(frame.host, 'enable') }}</small></span>;
|
||||
Aard <span :style="getSiteEnabledColor(frame.host, 'enableAard')"><small>{{ getSiteEnabledModes(frame.host, 'enableAard') }}</small></span>;
|
||||
kbd: <span :style="getSiteEnabledColor(frame.host, 'enableKeyboard')"><small>{{ getSiteEnabledModes(frame.host, 'enableKeyboard') }}</small></span>
|
||||
UI: <span :style="getSiteEnabledColor(frame.host, 'enableUI')"><small>{{ getSiteEnabledModes(frame.host, 'enableUI') }}</small></span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ExtensionMode from '../../../../../common/enums/ExtensionMode.enum';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
siteSettings: undefined
|
||||
}
|
||||
},
|
||||
props: [
|
||||
'settings',
|
||||
'frame',
|
||||
],
|
||||
created() {
|
||||
this.siteSettings = this.settings.getSiteSettings(this.frame.host ?? this.frame.key);
|
||||
},
|
||||
methods: {
|
||||
getSiteTypeColor(siteType) {
|
||||
switch (siteType) {
|
||||
case 'official': return 'color: #fa6';
|
||||
case 'community': return 'color: rgb(114, 114, 218)';
|
||||
case 'officially-disabled': return 'color: #f00';
|
||||
case 'testing': return 'color: #d81';
|
||||
default: return 'color: rgb(138, 65, 126)'
|
||||
};
|
||||
},
|
||||
getSiteEnabledColor(site, component) {
|
||||
const status = this.getSiteEnabledModes(site, component);
|
||||
return status === 'disabled' ? 'color: #f00' : 'color: #1f8';
|
||||
},
|
||||
getSiteEnabledModes(site, component) {
|
||||
if (this.siteSettings?.normal === ExtensionMode.Enabled) {
|
||||
return 'always';
|
||||
}
|
||||
if (this.siteSettings?.data[component]?.theater === ExtensionMode.Enabled) {
|
||||
return 'T + FS';
|
||||
}
|
||||
if (this.siteSettings?.data[component]?.fullscreen === ExtensionMode.Enabled) {
|
||||
return 'fullscreen';
|
||||
}
|
||||
return 'disabled';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -163,7 +163,6 @@ export default class UWServer {
|
||||
this.logger.log('error','debug', '[UwServer::injectCss] Error while removing css:', {error: e, css, sender});
|
||||
}
|
||||
}
|
||||
|
||||
async replaceCss(oldCss, newCss, sender) {
|
||||
if (oldCss !== newCss) {
|
||||
this.removeCss(oldCss, sender);
|
||||
@ -215,7 +214,9 @@ export default class UWServer {
|
||||
'siteSettings': undefined,
|
||||
'videoSettings': undefined,
|
||||
}
|
||||
|
||||
//TODO: change extension icon based on whether there's any videos on current page
|
||||
|
||||
}
|
||||
|
||||
registerVideo(sender) {
|
||||
@ -276,14 +277,19 @@ export default class UWServer {
|
||||
}
|
||||
|
||||
async getCurrentSite() {
|
||||
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] received get-current-site ...', 'background-color: #243; color: #4a8');
|
||||
|
||||
const site = await this.getVideoTab();
|
||||
|
||||
// Don't propagate 'INVALID SITE' to the popup.
|
||||
if (site.host === 'INVALID SITE') {
|
||||
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] Host is not valid — no info for current tab.', 'background-color: #243; color: #4a8');
|
||||
return;
|
||||
}
|
||||
|
||||
const tabHostname = await this.getCurrentTabHostname();
|
||||
this.logger.log('info', 'comms', '%c[UWServer::getCurrentSite] Returning data:', 'background-color: #243; color: #4a8', {site, tabHostname});
|
||||
|
||||
|
||||
this.eventBus.send(
|
||||
'set-current-site',
|
||||
@ -356,12 +362,15 @@ export default class UWServer {
|
||||
const activeTab = await this.activeTab;
|
||||
|
||||
if (!activeTab || activeTab.length < 1) {
|
||||
this.logger.log('warn', 'comms', 'There is no active tab for some reason. activeTab:', activeTab);
|
||||
return null;
|
||||
}
|
||||
|
||||
const url = activeTab[0].url;
|
||||
|
||||
if (!url) {
|
||||
console.log('no URL for active tab:', activeTab[0].url);
|
||||
}
|
||||
|
||||
var hostname;
|
||||
|
||||
if (url.indexOf("://") > -1) { //find & remove protocol (http, ftp, etc.) and get hostname
|
||||
|
@ -15,10 +15,17 @@ import VideoAlignmentType from '../../../common/enums/VideoAlignmentType.enum';
|
||||
*/
|
||||
export class SiteSettings {
|
||||
private settings: Settings;
|
||||
private site: string;
|
||||
private _site: string;
|
||||
private set site(x: string) {
|
||||
this._site = x;
|
||||
}
|
||||
public get site() {
|
||||
return this._site;
|
||||
}
|
||||
|
||||
raw: SiteSettingsInterface; // actual settings
|
||||
data: SiteSettingsInterface; // effective settings
|
||||
usesSettingsFor: string | undefined;
|
||||
temporaryData: SiteSettingsInterface;
|
||||
sessionData: SiteSettingsInterface;
|
||||
readonly defaultSettings: SiteSettingsInterface;
|
||||
@ -47,12 +54,56 @@ export class SiteSettings {
|
||||
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)})
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to match websites, even if we're on a different subdomain.
|
||||
* @returns
|
||||
*/
|
||||
private getSettingsForSite() {
|
||||
if (this.settings.active.sites[this.site]) {
|
||||
return {
|
||||
siteSettings: this.settings.active.sites[this.site],
|
||||
usesSettingsFor: undefined
|
||||
};
|
||||
}
|
||||
|
||||
const urlSegments = this.site.split('.').reverse();
|
||||
|
||||
siteLoop:
|
||||
for (const cs in this.settings.active.sites) {
|
||||
const configUrlSegments = cs.split('.').reverse();
|
||||
|
||||
// Match site with wildcard site definitions
|
||||
// Also, if definition starts with 'www', match also other subdomains — e.g. if we have a configuration for
|
||||
// `www.example.com`, this will also match `example.com`, `subdomain.example.com`, `nested.subdomain.example.com` ...
|
||||
if (configUrlSegments[configUrlSegments.length - 1] === '*' || (configUrlSegments[configUrlSegments.length - 1] === 'www')) {
|
||||
|
||||
console.log('ss: comparing', configUrlSegments, urlSegments);
|
||||
for (let i = 0; i < configUrlSegments.length - 1 && i < urlSegments.length; i++) {
|
||||
if (configUrlSegments[i] !== urlSegments[i]) {
|
||||
continue siteLoop;
|
||||
}
|
||||
}
|
||||
return {
|
||||
siteSettings: this.settings.active.sites[cs],
|
||||
usesSettingsFor: cs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
siteSettings: this.settings.active.sites['@global'],
|
||||
usesSettingsFor: '@global'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges defaultSettings into site settings where appropriate.
|
||||
* Alan pls ensure default settings object follows the correct structure
|
||||
*/
|
||||
private compileSettingsObject() {
|
||||
this.data = _cp(this.settings.active.sites[this.site] ?? {})
|
||||
const {siteSettings, usesSettingsFor} = this.getSettingsForSite();
|
||||
this.data = _cp(siteSettings);
|
||||
this.usesSettingsFor = usesSettingsFor;
|
||||
|
||||
if (!this.data) {
|
||||
this.data = _cp(this.defaultSettings);
|
||||
@ -150,8 +201,8 @@ export class SiteSettings {
|
||||
|
||||
// we aren't stepping on any other toes by doing this, since everyone
|
||||
// gets the first change
|
||||
this.settings.active._updateFlags = undefined;
|
||||
this.settings.saveWithoutReload();
|
||||
// this.settings.active._updateFlags = undefined;
|
||||
// this.settings.saveWithoutReload();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -695,10 +695,10 @@ class PlayerData {
|
||||
this.equalish(elementStack[currentIndex].element.offsetWidth, elementStack[nextIndex].element.offsetWidth, 2)
|
||||
&& this.equalish(elementStack[currentIndex].element.offsetHeight, elementStack[nextIndex].element.offsetHeight, 2)
|
||||
) {
|
||||
this.siteSettings.set('playerAutoConfig.initialIndex', this.siteSettings.data.playerAutoConfig.initialIndex + 1, {noSave: true});
|
||||
this.siteSettings.set('playerAutoConfig.modified', true);
|
||||
console.log('updated site settings:', this.siteSettings.data.playerAutoConfig);
|
||||
this.videoData.settings.saveWithoutReload();
|
||||
// this.siteSettings.set('playerAutoConfig.initialIndex', this.siteSettings.data.playerAutoConfig.initialIndex + 1, {noSave: true});
|
||||
// this.siteSettings.set('playerAutoConfig.modified', true);
|
||||
// console.log('updated site settings:', this.siteSettings.data.playerAutoConfig);
|
||||
// this.videoData.settings.saveWithoutReload();
|
||||
|
||||
this.updatePlayer({newElement: elementStack[nextIndex].element});
|
||||
}
|
||||
@ -797,9 +797,9 @@ class PlayerData {
|
||||
bestCandidate = null;
|
||||
} else {
|
||||
bestCandidate.heuristics['autoMatch'] = true;
|
||||
if (this.siteSettings.data.playerAutoConfig?.initialIndex !== bestCandidate.index) {
|
||||
this.siteSettings.set('playerAutoConfig.initialIndex', bestCandidate.index, {reload: false, scripted: true});
|
||||
}
|
||||
// if (this.siteSettings.data.playerAutoConfig?.initialIndex !== bestCandidate.index) {
|
||||
// this.siteSettings.set('playerAutoConfig.initialIndex', bestCandidate.index, {reload: false, scripted: true});
|
||||
// }
|
||||
}
|
||||
|
||||
// BUT WAIT! THERE'S MORE
|
||||
|
Loading…
Reference in New Issue
Block a user