Compare commits
10 Commits
5f3562fe5b
...
518e09e3cb
Author | SHA1 | Date | |
---|---|---|---|
518e09e3cb | |||
ad632b0680 | |||
73aa925067 | |||
391b0ac7ab | |||
ae2bb7afcd | |||
0681c3ae08 | |||
4aa96bb288 | |||
b24739d70d | |||
dffe8e055a | |||
adadc8bb3e |
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ultrawidify",
|
"name": "ultrawidify",
|
||||||
"version": "6.2.5",
|
"version": "6.2.6",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ultrawidify",
|
"name": "ultrawidify",
|
||||||
"version": "6.2.5",
|
"version": "6.2.6",
|
||||||
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
|
"description": "Aspect ratio fixer for youtube and other sites, with automatic aspect ratio detection. Supports ultrawide and other ratios.",
|
||||||
"author": "Tamius Han <tamius.han@gmail.com>",
|
"author": "Tamius Han <tamius.han@gmail.com>",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -12,6 +12,13 @@ export enum ExtensionEnvironment {
|
|||||||
Fullscreen = 'fullscreen',
|
Fullscreen = 'fullscreen',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DevUiConfig {
|
||||||
|
aardDebugOverlay: {
|
||||||
|
showOnStartup: boolean,
|
||||||
|
showDetectionDetails: boolean,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface KeyboardShortcutInterface {
|
export interface KeyboardShortcutInterface {
|
||||||
key?: string,
|
key?: string,
|
||||||
code?: string,
|
code?: string,
|
||||||
@ -161,11 +168,16 @@ export interface AardSettings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface DevSettings {
|
||||||
|
loadFromSnapshot: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
interface SettingsInterface {
|
interface SettingsInterface {
|
||||||
_updateFlags?: {
|
_updateFlags?: {
|
||||||
requireReload?: SettingsReloadFlags,
|
requireReload?: SettingsReloadFlags,
|
||||||
forSite?: string
|
forSite?: string
|
||||||
}
|
}
|
||||||
|
dev: DevSettings,
|
||||||
|
|
||||||
arDetect: AardSettings,
|
arDetect: AardSettings,
|
||||||
|
|
||||||
@ -185,6 +197,7 @@ interface SettingsInterface {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
devMode?: boolean,
|
devMode?: boolean,
|
||||||
|
dev: DevUiConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
restrictions?: RestrictionsSettings;
|
restrictions?: RestrictionsSettings;
|
||||||
|
@ -144,11 +144,13 @@
|
|||||||
Site compatibility:
|
Site compatibility:
|
||||||
<SupportLevelIndicator
|
<SupportLevelIndicator
|
||||||
:siteSupportLevel="siteSupportLevel"
|
:siteSupportLevel="siteSupportLevel"
|
||||||
|
supportLevelStyle="font-size: 0.69rem !important;"
|
||||||
|
tooltipStyle="font-size: 0.8rem;"
|
||||||
>
|
>
|
||||||
</SupportLevelIndicator>
|
</SupportLevelIndicator>
|
||||||
<div v-if="statusFlags.hasDrm" class="aard-blocked">
|
<div v-if="statusFlags.hasDrm" class="aard-blocked">
|
||||||
Autodetection potentially<br/>
|
Autodetection blocked<br/>
|
||||||
unavailable due to <a style="color: #fff" href="https://en.wikipedia.org/wiki/Digital_rights_management" target="_blank">DRM</a>.
|
by <a style="color: #fff" href="https://en.wikipedia.org/wiki/Digital_rights_management" target="_blank">DRM</a>.
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="statusFlags.aardErrors?.cors" class="aard-blocked">
|
<div v-else-if="statusFlags.aardErrors?.cors" class="aard-blocked">
|
||||||
Autodetection blocked<br/>
|
Autodetection blocked<br/>
|
||||||
@ -156,7 +158,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else-if="statusFlags.aardErrors?.webglError" class="aard-blocked">
|
<div v-else-if="statusFlags.aardErrors?.webglError" class="aard-blocked">
|
||||||
Autodetection unavailable<br/>
|
Autodetection unavailable<br/>
|
||||||
due to webgl error.
|
(webgl error)
|
||||||
</div>
|
</div>
|
||||||
</GhettoContextMenuItem>
|
</GhettoContextMenuItem>
|
||||||
</div>
|
</div>
|
||||||
@ -483,7 +485,8 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
acknowledgeNewFeature(featureKey) {
|
acknowledgeNewFeature(featureKey) {
|
||||||
delete this.settings.active.newFeatureTracker[featureKey];
|
this.settings.active.newFeatureTracker[featureKey].show = 0;
|
||||||
|
this.settings.active.newFeatureTracker[featureKey].acknowledged = true;
|
||||||
this.settings.saveWithoutReload();
|
this.settings.saveWithoutReload();
|
||||||
},
|
},
|
||||||
newFeatureViewUpdate(featureKey) {
|
newFeatureViewUpdate(featureKey) {
|
||||||
@ -721,6 +724,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.aard-blocked {
|
.aard-blocked {
|
||||||
|
font-size: 0.8rem;
|
||||||
color: #fa6;
|
color: #fa6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<div class="w-[1/2]" style="width: 50%">
|
<div class="w-[1/2]" style="width: 50%">
|
||||||
<h2>Report a problem</h2>
|
<h2>Report a problem</h2>
|
||||||
<p>
|
<p>
|
||||||
You may report <strike>undocumented features</strike> bugs using one of the following options (in order of preference):
|
Please report <strike>undocumented features</strike> bugs using one of the following options (in order of preference):
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li>
|
<li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li>
|
||||||
|
@ -269,8 +269,27 @@
|
|||||||
<p>
|
<p>
|
||||||
<b>Debug options</b>
|
<b>Debug options</b>
|
||||||
</p>
|
</p>
|
||||||
<div>
|
<div class="flex flex-row">
|
||||||
<button @click="eventBus.sendToTunnel('aard-enable-debug', true)">Show debug overlay</button>
|
<div>
|
||||||
|
<div>
|
||||||
|
<button @click="eventBus.sendToTunnel('aard-enable-debug', true)">Show debug overlay</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="label">Show debug overlay on startup</div>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="settings.active.ui.dev.aardDebugOverlay.showOnStartup"
|
||||||
|
@change="settings.saveWithoutReload"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<JsonEditor
|
||||||
|
v-model="settingsJson"
|
||||||
|
>
|
||||||
|
</JsonEditor>
|
||||||
|
<button @click="saveDebugUiSettings">Save debug UI settings</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -289,14 +308,15 @@ import AspectRatioType from '../../../common/enums/AspectRatioType.enum';
|
|||||||
import StretchType from '../../../common/enums/StretchType.enum';
|
import StretchType from '../../../common/enums/StretchType.enum';
|
||||||
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
|
import CropModePersistence from '../../../common/enums/CropModePersistence.enum';
|
||||||
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
|
import AlignmentOptionsControlComponent from './AlignmentOptionsControlComponent.vue';
|
||||||
|
import JsonEditor from '@csui/src/components/JsonEditor';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
components: {
|
||||||
return {
|
ShortcutButton,
|
||||||
exec: null,
|
EditShortcutButton,
|
||||||
performanceData: {},
|
Button,
|
||||||
graphRefreshInterval: undefined,
|
AlignmentOptionsControlComponent,
|
||||||
}
|
JsonEditor
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
],
|
],
|
||||||
@ -306,6 +326,16 @@ export default {
|
|||||||
'eventBus',
|
'eventBus',
|
||||||
'site'
|
'site'
|
||||||
],
|
],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
exec: null,
|
||||||
|
performanceData: {},
|
||||||
|
graphRefreshInterval: undefined,
|
||||||
|
settingsJson: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.eventBus.subscribe(
|
this.eventBus.subscribe(
|
||||||
'uw-config-broadcast',
|
'uw-config-broadcast',
|
||||||
@ -315,24 +345,15 @@ export default {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
destroyed() {
|
|
||||||
this.eventBus.unsubscribeAll(this);
|
|
||||||
},
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.eventBus.sendToTunnel('get-aard-timing');
|
this.eventBus.sendToTunnel('get-aard-timing');
|
||||||
this.graphRefreshInterval = setInterval(() => this.eventBus.sendToTunnel('get-aard-timing'), 500);
|
this.graphRefreshInterval = setInterval(() => this.eventBus.sendToTunnel('get-aard-timing'), 500);
|
||||||
|
this.resetSettingsEditor();
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
|
this.eventBus.unsubscribeAll(this);
|
||||||
clearInterval(this.graphRefreshInterval);
|
clearInterval(this.graphRefreshInterval);
|
||||||
},
|
},
|
||||||
components: {
|
|
||||||
ShortcutButton,
|
|
||||||
EditShortcutButton,
|
|
||||||
Button,
|
|
||||||
AlignmentOptionsControlComponent
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
async openOptionsPage() {
|
async openOptionsPage() {
|
||||||
BrowserDetect.runtime.openOptionsPage();
|
BrowserDetect.runtime.openOptionsPage();
|
||||||
@ -349,7 +370,15 @@ export default {
|
|||||||
this.$nextTick( () => this.$forceUpdate() );
|
this.$nextTick( () => this.$forceUpdate() );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
resetSettingsEditor() {
|
||||||
|
this.settingsJson = JSON.parse(JSON.stringify(this.settings?.active.ui.dev.aardDebugOverlay ?? {}));
|
||||||
|
},
|
||||||
|
saveDebugUiSettings() {
|
||||||
|
this.settings.active.ui.dev.aardDebugOverlay = JSON.parse(JSON.stringify(this.settingsJson));
|
||||||
|
this.settings.saveWithoutReload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@
|
|||||||
class="danger"
|
class="danger"
|
||||||
:class="{'disabled': !allowSettingsEditing}"
|
:class="{'disabled': !allowSettingsEditing}"
|
||||||
:disabled="!allowSettingsEditing"
|
:disabled="!allowSettingsEditing"
|
||||||
@click="saveSettingsChanges"
|
@click="() => saveSettingsChanges()"
|
||||||
>
|
>
|
||||||
Save
|
Save
|
||||||
</button>
|
</button>
|
||||||
@ -129,6 +129,31 @@
|
|||||||
>
|
>
|
||||||
</JsonEditor>
|
</JsonEditor>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h2>Settings migration report</h2>
|
||||||
|
<pre>
|
||||||
|
{{settings.migrationReport}}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h2>Settings snapshots</h2>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div v-for="(snapshot, index) of settingsSnapshots" :key="snapshot.createdAt">
|
||||||
|
<small>{{snapshot.createdAt.toISOString()}}</small>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<div class="grow">
|
||||||
|
{{snapshot.name}}
|
||||||
|
</div>
|
||||||
|
<div v-if="settings.isAutomatic">(auto)</div>
|
||||||
|
<div v-if="settings.isAutomatic && settings.isProtected">(protected)</div>
|
||||||
|
<div v-if="settings.default">(default)</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button @click="() => markDefaultSnapshot(index)"><template v-if="settings.isDefault">Revoke default</template><template v-else>Make default</template></button>
|
||||||
|
<button v-if="settings.isAutomatic" @click="() => toggleSnapshotProtection(index)">Toggle protection</button>
|
||||||
|
<button @click="() => deleteSnapshot(index)">Delete snapshot</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -151,6 +176,7 @@ export default {
|
|||||||
allowSettingsEditing: false,
|
allowSettingsEditing: false,
|
||||||
editorSaveFinished: false,
|
editorSaveFinished: false,
|
||||||
settingsJson: {},
|
settingsJson: {},
|
||||||
|
settingsSnapshots: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
@ -236,10 +262,18 @@ export default {
|
|||||||
this.resetSettingsEditor();
|
this.resetSettingsEditor();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettingsChanges() {
|
async saveSettingsChanges() {
|
||||||
if (this.allowSettingsEditing) {
|
if (this.allowSettingsEditing) {
|
||||||
|
const currentVersion = this.settings.active?.version;
|
||||||
this.settings.active = this.settingsJson;
|
this.settings.active = this.settingsJson;
|
||||||
this.settings.saveWithoutReload();
|
|
||||||
|
if (currentVersion !== this.settingsJson.version) {
|
||||||
|
await this.settings.save({forcePreserveVersion: true});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
await this.settings.saveWithoutReload();
|
||||||
|
}
|
||||||
|
|
||||||
this.resetSettingsEditor();
|
this.resetSettingsEditor();
|
||||||
this.editorSaveFinished = true;
|
this.editorSaveFinished = true;
|
||||||
|
|
||||||
@ -251,10 +285,32 @@ export default {
|
|||||||
|
|
||||||
resetSettingsEditor() {
|
resetSettingsEditor() {
|
||||||
this.settingsJson = JSON.parse(JSON.stringify(this.settings?.active ?? {}));
|
this.settingsJson = JSON.parse(JSON.stringify(this.settings?.active ?? {}));
|
||||||
}
|
},
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
|
||||||
|
|
||||||
|
//#region settings snapshot management
|
||||||
|
async loadSettingsSnapshots() {
|
||||||
|
this.settingsSnapshots = await this.settings.snapshotManager.listSnapshots();
|
||||||
|
},
|
||||||
|
|
||||||
|
async markDefaultSnapshot(index) {
|
||||||
|
await this.settings.snapshotManager.setDefaultSnapshot(index, !this.settingsSnapshots[index].isDefault);
|
||||||
|
await this.loadSettingsSnapshots();
|
||||||
|
this.settings.active.dev.loadFromSnapshot = this.settingsSnapshots[index].isDefault;
|
||||||
|
this.saveSettingsChanges();
|
||||||
|
},
|
||||||
|
|
||||||
|
async toggleSnapshotProtection(index) {
|
||||||
|
await this.settings.snapshotManager.setSnapshotAsProtected(index, !this.settingsSnapshots[index].isProtected);
|
||||||
|
await this.loadSettingsSnapshots();
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteSnapshot(index) {
|
||||||
|
await this.settings.snapshotManager.deleteSnapshot(index);
|
||||||
|
await this.loadSettingsSnapshots();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,23 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col w-full h-full gap-2">
|
<div class="flex flex-col w-full h-full gap-2">
|
||||||
<div class="flex flex-row gap-8 bg-black flex-wrap">
|
<div class="flex flex-row gap-8 bg-black flex-wrap w-full">
|
||||||
<div class="min-w-[400px] max-w-[520px] grow-1 shrink-1">
|
<div class="min-w-[400px] max-w-[520px] grow shrink">
|
||||||
<h1>What's new</h1>
|
<h1>What's new</h1>
|
||||||
<!-- <p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md" target="_blank">is available here</a>.</p> -->
|
<!-- <p>Full changelog for older versions <a href="https://github.com/tamius-han/ultrawidify/blob/master/CHANGELOG.md" target="_blank">is available here</a>.</p> -->
|
||||||
|
|
||||||
<h2>6.2.5</h2>
|
<h2>6.2.6</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>'Show UI' button was moved to popup header. Extension popup now defaults to 'crop options' tab</li>
|
<li>Automatic aspect ratio detection: do not apply negative aspect ratios</li>
|
||||||
<li>Fixed the bug where current extension settings wouldn't be displayed correctly in the popup</li>
|
<li>Keyboard zoom now works</li>
|
||||||
<li>Fixed the issue where extension options using the "Extension default" mode would always be disabled</li>
|
<li><code>www.youtube-nocookie.com</code> has been added to the "officially supported" list</li>
|
||||||
<li>Added the ability to import and export settings (ft. developer mode editor)</li>
|
<li>Fixed the bug where UI would sometimes refuse to stay hidden</li>
|
||||||
<li>Added some toys not intended for general audience (Aard now has debug tools).</li>
|
|
||||||
<li>Fixed an issue where aspect ratio wouldn't get calculated correctly on youtube videos with native aspect ratios other than 16:9</li>
|
|
||||||
<li>Fixed an issue that would crash the extension if video element didn't have a player element associated with it</li>
|
|
||||||
<li>Fixed an issue where extension sometimes wouldn't work if video element was grafted/re-parented to a different element</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="min-w-[400px] max-w-[520px] grow-1 shrink-1">
|
<div style="width: 1rem; height: 0px;"></div>
|
||||||
|
<div class="min-w-[400px] max-w-[520px] grow shrink">
|
||||||
|
<h2>Report a problem</h2>
|
||||||
|
<p>
|
||||||
|
Please report <strike>undocumented features</strike> bugs using one of the following options (in order of preference):
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li> <a target="_blank" href="https://github.com/tamius-han/ultrawidify/issues"><b>Github (preferred)</b></a><br/></li>
|
||||||
|
<li>Email: <a target="_blank" :href="mailtoLink">tamius.han@gmail.com</a></li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
When reporting bugs, please include extension version, whether you installed the extension from, and description of your problem.
|
||||||
|
</p>
|
||||||
|
<p> </p>
|
||||||
|
<p> </p>
|
||||||
<h2>Thank you monies</h2>
|
<h2>Thank you monies</h2>
|
||||||
<p>
|
<p>
|
||||||
If you think I deserve money for the work I did up to this point, you can bankroll my caffeine addiction.
|
If you think I deserve money for the work I did up to this point, you can bankroll my caffeine addiction.
|
||||||
@ -30,11 +40,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import BrowserDetect from '@src/ext/conf/BrowserDetect';
|
||||||
|
|
||||||
export default({
|
export default({
|
||||||
props: [
|
props: [
|
||||||
'settings'
|
'settings'
|
||||||
],
|
],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
BrowserDetect: BrowserDetect,
|
||||||
|
// reminder — webextension-polyfill doesn't seem to work in vue!
|
||||||
|
addonVersion: BrowserDetect.firefox ? chrome.runtime.getManifest().version : chrome.runtime.getManifest().version,
|
||||||
|
addonSource: BrowserDetect.processEnvVersion,
|
||||||
|
mailtoLink: '',
|
||||||
|
redditLink: '',
|
||||||
|
showEasterEgg: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.settings.active.whatsNewChecked = true;
|
this.settings.active.whatsNewChecked = true;
|
||||||
this.settings.saveWithoutReload();
|
this.settings.saveWithoutReload();
|
||||||
@ -49,6 +71,10 @@ export default({
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.grow {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
p, li {
|
p, li {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,44 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="siteSupportLevel === 'official'" class="site-support official">
|
<div v-if="siteSupportLevel === 'official'" class="site-support official" :style="supportLevelStyle">
|
||||||
<mdicon name="check-decagram" />
|
<mdicon name="check-decagram" />
|
||||||
<div v-if="!small">Verified</div>
|
<div v-if="!small">Verified</div>
|
||||||
<div class="tooltip">
|
<div class="tooltip" :style="tooltipStyle">
|
||||||
<template v-if="small">Verified — </template>
|
<template v-if="small">Verified — </template>
|
||||||
The extension is being tested and should work on this site.
|
The extension is being tested and should work on this site.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="siteSupportLevel === 'community'" class="site-support community">
|
<div v-if="siteSupportLevel === 'community'" class="site-support community" :style="supportLevelStyle">
|
||||||
<mdicon name="account-group" />
|
<mdicon name="account-group" />
|
||||||
<div v-if="!small">Community</div>
|
<div v-if="!small">Community</div>
|
||||||
<div class="tooltip">
|
<div class="tooltip" :style="tooltipStyle">
|
||||||
<template v-if="small">Community — </template>
|
<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/>
|
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
|
Tamius (the dev) does not test the extension on this site, probably because it requires a subscription or
|
||||||
is geoblocked.
|
is geoblocked.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="siteSupportLevel === 'no-support' || siteSupportLevel === 'unknown'" class="site-support no-support">
|
<div v-if="siteSupportLevel === 'no-support' || siteSupportLevel === 'unknown'" class="site-support no-support" :style="supportLevelStyle">
|
||||||
<mdicon name="help-circle-outline" />
|
<mdicon name="help-circle-outline" />
|
||||||
<div v-if="!small">Unknown</div>
|
<div v-if="!small">Unknown</div>
|
||||||
<div class="tooltip">
|
<div class="tooltip" :style="tooltipStyle">
|
||||||
<template v-if="small">Unknown — </template>
|
<template v-if="small">Unknown — </template>
|
||||||
Not officially supported. Extension will try to fix things, but no promises.<br/><br/>
|
Not officially supported. Extension will try to fix things, but no promises.<br/><br/>
|
||||||
Tamius (the dev) does not test the extension on this site for various reasons
|
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).
|
(unaware, not using the site, language barrier, geoblocking, paid services Tam doesn't use).
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="siteSupportLevel === 'user-added' || siteSupportLevel === 'user-defined'" class="site-support user-added">
|
<div v-if="siteSupportLevel === 'user-added' || siteSupportLevel === 'user-defined'" class="site-support user-added" :style="supportLevelStyle">
|
||||||
<mdicon name="account" />
|
<mdicon name="account" />
|
||||||
<div v-if="!small">Modified by you</div>
|
<div v-if="!small">Modified by you</div>
|
||||||
<div class="tooltip">
|
<div class="tooltip" :style="tooltipStyle">
|
||||||
<template v-if="small">Modified by you — </template>
|
<template v-if="small">Modified by you — </template>
|
||||||
You have manually changed settings for this site. The extension is doing what you told it to do.
|
You have manually changed settings for this site. The extension is doing what you told it to do.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="siteSupportLevel === 'officially-disabled'" class="site-support officially-disabled">
|
<div v-if="siteSupportLevel === 'officially-disabled'" class="site-support officially-disabled" :style="supportLevelStyle">
|
||||||
<mdicon class="site-support no-support" name="checkbox-marked-circle" />
|
<mdicon class="site-support no-support" name="checkbox-marked-circle" />
|
||||||
<div v-if="!small">Not supported</div>
|
<div v-if="!small">Not supported</div>
|
||||||
<div class="tooltip">
|
<div class="tooltip" :style="tooltipStyle">
|
||||||
<template v-if="small">Not supported — </template>
|
<template v-if="small">Not supported — </template>
|
||||||
Extension is known to not work with this site.
|
Extension is known to not work with this site.
|
||||||
</div>
|
</div>
|
||||||
@ -50,6 +50,8 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
siteSupportLevel: String,
|
siteSupportLevel: String,
|
||||||
small: Boolean,
|
small: Boolean,
|
||||||
|
supportLevelStyle: String,
|
||||||
|
tooltipStyle: String,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -21,7 +21,6 @@ const ExtensionConfPatch = [
|
|||||||
normal: ExtensionMode.Default,
|
normal: ExtensionMode.Default,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const uiEnabled =
|
|
||||||
userOptions.sites['@global'].enableUI = {
|
userOptions.sites['@global'].enableUI = {
|
||||||
fullscreen: userOptions.ui.inPlayer.enabled ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
fullscreen: userOptions.ui.inPlayer.enabled ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||||
theater: ExtensionMode.Enabled,
|
theater: ExtensionMode.Enabled,
|
||||||
@ -83,6 +82,16 @@ const ExtensionConfPatch = [
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
delete (userOptions as any).actions;
|
delete (userOptions as any).actions;
|
||||||
|
|
||||||
|
userOptions.dev = {
|
||||||
|
loadFromSnapshot: false
|
||||||
|
};
|
||||||
|
userOptions.ui.dev = {
|
||||||
|
aardDebugOverlay: {
|
||||||
|
showOnStartup: false,
|
||||||
|
showDetectionDetails: true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -14,6 +14,10 @@ if(Debug.debug)
|
|||||||
console.log("Loading: ExtensionConf.js");
|
console.log("Loading: ExtensionConf.js");
|
||||||
|
|
||||||
const ExtensionConf: SettingsInterface = {
|
const ExtensionConf: SettingsInterface = {
|
||||||
|
dev: {
|
||||||
|
loadFromSnapshot: false,
|
||||||
|
},
|
||||||
|
|
||||||
arDetect: {
|
arDetect: {
|
||||||
aardType: 'auto',
|
aardType: 'auto',
|
||||||
|
|
||||||
@ -127,6 +131,12 @@ const ExtensionConf: SettingsInterface = {
|
|||||||
offsetX: -50,
|
offsetX: -50,
|
||||||
offsetY: 0
|
offsetY: 0
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
dev: {
|
||||||
|
aardDebugOverlay: {
|
||||||
|
showOnStartup: false,
|
||||||
|
showDetectionDetails: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -722,6 +732,46 @@ const ExtensionConf: SettingsInterface = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"www.youtube-nocookie.com": {
|
||||||
|
enable: {
|
||||||
|
fullscreen: ExtensionMode.Enabled,
|
||||||
|
theater: ExtensionMode.Enabled,
|
||||||
|
normal: ExtensionMode.Enabled,
|
||||||
|
},
|
||||||
|
enableAard: {
|
||||||
|
fullscreen: ExtensionMode.Enabled,
|
||||||
|
theater: ExtensionMode.Enabled,
|
||||||
|
normal: ExtensionMode.Enabled,
|
||||||
|
},
|
||||||
|
enableKeyboard: {
|
||||||
|
fullscreen: ExtensionMode.Enabled,
|
||||||
|
theater: ExtensionMode.Enabled,
|
||||||
|
normal: ExtensionMode.Enabled
|
||||||
|
},
|
||||||
|
enableUI: {
|
||||||
|
fullscreen: ExtensionMode.Enabled,
|
||||||
|
theater: ExtensionMode.Enabled,
|
||||||
|
normal: ExtensionMode.Disabled
|
||||||
|
},
|
||||||
|
|
||||||
|
override: false, // ignore value localStorage in favour of this
|
||||||
|
type: 'official', // is officially supported? (Alternatives are 'community' and 'user-defined')
|
||||||
|
defaultType: 'official', // if user mucks around with settings, type changes to 'user-defined'.
|
||||||
|
// We still want to know what the original type was, hence defaultType
|
||||||
|
|
||||||
|
activeDOMConfig: 'official',
|
||||||
|
DOMConfig: {
|
||||||
|
'official': {
|
||||||
|
type: 'official',
|
||||||
|
elements: {
|
||||||
|
player: {
|
||||||
|
manual: true,
|
||||||
|
querySelectors: "#movie_player, #player, #c4-player",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"www.netflix.com" : {
|
"www.netflix.com" : {
|
||||||
enable: {
|
enable: {
|
||||||
fullscreen: ExtensionMode.Enabled,
|
fullscreen: ExtensionMode.Enabled,
|
||||||
|
@ -12,11 +12,15 @@ import Logger from './Logger';
|
|||||||
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||||
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||||
import { SiteSettings } from './settings/SiteSettings';
|
import { SiteSettings } from './settings/SiteSettings';
|
||||||
|
import { SettingsSnapshotManager } from './settings/SettingsSnapshotManager';
|
||||||
|
|
||||||
if(process.env.CHANNEL !== 'stable'){
|
if(process.env.CHANNEL !== 'stable'){
|
||||||
console.info("Loading Settings");
|
console.info("Loading Settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SetSettingsOptions {
|
||||||
|
forcePreserveVersion?: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
//#region flags
|
//#region flags
|
||||||
@ -41,6 +45,17 @@ class Settings {
|
|||||||
afterSettingsChangedCallbacks: (() => void)[] = [];
|
afterSettingsChangedCallbacks: (() => void)[] = [];
|
||||||
|
|
||||||
private sortedPatches: any[];
|
private sortedPatches: any[];
|
||||||
|
|
||||||
|
|
||||||
|
public snapshotManager: SettingsSnapshotManager;
|
||||||
|
|
||||||
|
private _migrationReport: string = '';
|
||||||
|
private set migrationReport(report: string) {
|
||||||
|
this._migrationReport = report;
|
||||||
|
}
|
||||||
|
public get migrationReport(): string {
|
||||||
|
return this._migrationReport;
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
@ -50,11 +65,14 @@ class Settings {
|
|||||||
this.afterSettingsSaved = options?.afterSettingsSaved;
|
this.afterSettingsSaved = options?.afterSettingsSaved;
|
||||||
this.active = options?.activeSettings ?? undefined;
|
this.active = options?.activeSettings ?? undefined;
|
||||||
this.default = ExtensionConf;
|
this.default = ExtensionConf;
|
||||||
|
this.snapshotManager = new SettingsSnapshotManager();
|
||||||
|
|
||||||
this.default['version'] = this.getExtensionVersion();
|
this.default['version'] = this.getExtensionVersion();
|
||||||
|
|
||||||
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
||||||
|
|
||||||
this.sortedPatches = this.sortConfPatches(ExtensionConfPatch);
|
this.sortedPatches = this.sortConfPatches(ExtensionConfPatch);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private storageChangeListener(changes, area) {
|
private storageChangeListener(changes, area) {
|
||||||
@ -186,6 +204,18 @@ class Settings {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save current settings object
|
||||||
|
const currentSettings = this.active;
|
||||||
|
|
||||||
|
this.snapshotManager.createSnapshot(
|
||||||
|
JSON.parse(JSON.stringify(currentSettings)),
|
||||||
|
{
|
||||||
|
label: 'Pre-migration snapshot',
|
||||||
|
isAutomatic: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// apply all remaining patches
|
// apply all remaining patches
|
||||||
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${this.sortedPatches.length - index} settings patches to apply`);
|
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${this.sortedPatches.length - index} settings patches to apply`);
|
||||||
while (index < this.sortedPatches.length) {
|
while (index < this.sortedPatches.length) {
|
||||||
@ -209,7 +239,16 @@ class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
const settings = await this.get();
|
let settings = await this.get();
|
||||||
|
|
||||||
|
if (settings?.dev?.loadFromSnapshot) {
|
||||||
|
this.logger?.log('info', 'settings', '[Settings::init] Dev mode is enabled, Loading settings from snapshot:', settings.dev.loadFromSnapshot);
|
||||||
|
const snapshot = await this.snapshotManager.getSnapshot();
|
||||||
|
if (snapshot) {
|
||||||
|
settings = snapshot.settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.version = this.getExtensionVersion();
|
this.version = this.getExtensionVersion();
|
||||||
|
|
||||||
// |—> on first setup, settings is undefined & settings.version is haram
|
// |—> on first setup, settings is undefined & settings.version is haram
|
||||||
@ -282,7 +321,7 @@ class Settings {
|
|||||||
return this.active;
|
return this.active;
|
||||||
}
|
}
|
||||||
|
|
||||||
async get() {
|
async get(): Promise<SettingsInterface | undefined> {
|
||||||
let ret;
|
let ret;
|
||||||
|
|
||||||
ret = await chrome.storage.local.get('uwSettings');
|
ret = await chrome.storage.local.get('uwSettings');
|
||||||
@ -290,13 +329,13 @@ class Settings {
|
|||||||
this.logger?.log('info', 'settings', 'Got settings:', ret && ret.uwSettings && JSON.parse(ret.uwSettings));
|
this.logger?.log('info', 'settings', 'Got settings:', ret && ret.uwSettings && JSON.parse(ret.uwSettings));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return JSON.parse(ret.uwSettings);
|
return JSON.parse(ret.uwSettings) as SettingsInterface;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async set(extensionConf, options?) {
|
async set(extensionConf, options?: SetSettingsOptions) {
|
||||||
if (!options || !options.forcePreserveVersion) {
|
if (!options || !options.forcePreserveVersion) {
|
||||||
extensionConf.version = this.version;
|
extensionConf.version = this.version;
|
||||||
}
|
}
|
||||||
@ -344,7 +383,7 @@ class Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async save(options?) {
|
async save(options?: SetSettingsOptions) {
|
||||||
if (Debug.debug && Debug.storage) {
|
if (Debug.debug && Debug.storage) {
|
||||||
console.log("[Settings::save] Saving active settings:", this.active);
|
console.log("[Settings::save] Saving active settings:", this.active);
|
||||||
}
|
}
|
||||||
@ -354,10 +393,10 @@ class Settings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async saveWithoutReload() {
|
async saveWithoutReload(options?: SetSettingsOptions) {
|
||||||
this.active.preventReload = true;
|
this.active.preventReload = true;
|
||||||
this.active.lastModified = new Date();
|
this.active.lastModified = new Date();
|
||||||
await this.set(this.active);
|
await this.set(this.active, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async rollback() {
|
async rollback() {
|
||||||
|
@ -219,7 +219,6 @@ import { AardTimers, initAardTimers } from './interfaces/aard-timers.interface';
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export class Aard {
|
export class Aard {
|
||||||
|
|
||||||
//#region configuration parameters
|
//#region configuration parameters
|
||||||
private logger: Logger;
|
private logger: Logger;
|
||||||
private videoData: VideoData;
|
private videoData: VideoData;
|
||||||
@ -269,6 +268,7 @@ export class Aard {
|
|||||||
|
|
||||||
private debugConfig: any = {};
|
private debugConfig: any = {};
|
||||||
private timer: AardTimer;
|
private timer: AardTimer;
|
||||||
|
private lastAnimationFrameTime: number = Infinity;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region getters
|
//#region getters
|
||||||
@ -304,8 +304,7 @@ export class Aard {
|
|||||||
// we can tick manually, for debugging
|
// we can tick manually, for debugging
|
||||||
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
|
this.logger.log('info', 'init', `[ArDetector::ctor] creating new ArDetector. arid: ${this.arid}`);
|
||||||
|
|
||||||
this.timer = new AardTimer()
|
this.timer = new AardTimer();
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,6 +336,14 @@ export class Aard {
|
|||||||
// console.error('FALIED TO CREATE DEBUGG CANVAS', e);
|
// console.error('FALIED TO CREATE DEBUGG CANVAS', e);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.settings.active.ui.dev?.aardDebugOverlay?.showOnStartup) {
|
||||||
|
this.showDebugCanvas();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`[uw::aard] failed to create debug UI:`, e);
|
||||||
|
}
|
||||||
|
|
||||||
this.startCheck();
|
this.startCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,6 +414,7 @@ export class Aard {
|
|||||||
* Checks whether autodetection can run
|
* Checks whether autodetection can run
|
||||||
*/
|
*/
|
||||||
startCheck() {
|
startCheck() {
|
||||||
|
console.log('aard - starting checks')
|
||||||
if (!this.videoData.player) {
|
if (!this.videoData.player) {
|
||||||
console.warn('Player not detected!');
|
console.warn('Player not detected!');
|
||||||
console.log('--- video data: ---\n', this.videoData);
|
console.log('--- video data: ---\n', this.videoData);
|
||||||
@ -453,7 +461,6 @@ export class Aard {
|
|||||||
this.verticalTestResults = initAardTestResults(this.settings.active.arDetect);
|
this.verticalTestResults = initAardTestResults(this.settings.active.arDetect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.main();
|
this.main();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -648,7 +655,7 @@ export class Aard {
|
|||||||
do {
|
do {
|
||||||
if (this.testResults.notLetterbox) {
|
if (this.testResults.notLetterbox) {
|
||||||
// console.log('————not letterbox')
|
// console.log('————not letterbox')
|
||||||
console.warn('DETECTED NOT LETTERBOX! (resetting)')
|
// console.warn('DETECTED NOT LETTERBOX! (resetting)')
|
||||||
this.timer.arChanged();
|
this.timer.arChanged();
|
||||||
this.updateAspectRatio(this.defaultAr);
|
this.updateAspectRatio(this.defaultAr);
|
||||||
break;
|
break;
|
||||||
@ -659,7 +666,7 @@ export class Aard {
|
|||||||
// console.info('aspect ratio not certain:', this.testResults.aspectRatioUncertainReason);
|
// console.info('aspect ratio not certain:', this.testResults.aspectRatioUncertainReason);
|
||||||
// console.warn('check finished:', JSON.parse(JSON.stringify(this.testResults)), JSON.parse(JSON.stringify(this.canvasSamples)), '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n');
|
// console.warn('check finished:', JSON.parse(JSON.stringify(this.testResults)), JSON.parse(JSON.stringify(this.canvasSamples)), '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n');
|
||||||
|
|
||||||
console.warn('ASPECT RATIO UNCERTAIN, GUARD LINE INVALIDATED (resetting)')
|
// console.warn('ASPECT RATIO UNCERTAIN, GUARD LINE INVALIDATED (resetting)')
|
||||||
this.timer.arChanged();
|
this.timer.arChanged();
|
||||||
this.updateAspectRatio(this.defaultAr);
|
this.updateAspectRatio(this.defaultAr);
|
||||||
|
|
||||||
@ -669,18 +676,24 @@ export class Aard {
|
|||||||
// TODO: emit debug values if debugging is enabled
|
// TODO: emit debug values if debugging is enabled
|
||||||
this.testResults.isFinished = true;
|
this.testResults.isFinished = true;
|
||||||
|
|
||||||
console.warn(
|
// console.warn(
|
||||||
`[${(+new Date() % 10000) / 100} | ${this.arid}]`,'check finished — aspect ratio updated:', this.testResults.aspectRatioUpdated,
|
// `[${(+new Date() % 10000) / 100} | ${this.arid}]`,'check finished — aspect ratio updated:', this.testResults.aspectRatioUpdated,
|
||||||
'\ndetected ar:', this.testResults.activeAspectRatio, '->', this.getAr(),
|
// '\ndetected ar:', this.testResults.activeAspectRatio, '->', this.getAr(),
|
||||||
'\nis video playing?', this.getVideoPlaybackState() === VideoPlaybackState.Playing,
|
// '\nis video playing?', this.getVideoPlaybackState() === VideoPlaybackState.Playing,
|
||||||
'\n\n', JSON.parse(JSON.stringify(this.testResults)), JSON.parse(JSON.stringify(this.canvasSamples)), '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n');
|
// '\n\n', JSON.parse(JSON.stringify(this.testResults)), JSON.parse(JSON.stringify(this.canvasSamples)), '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n');
|
||||||
|
|
||||||
// if edge width changed, emit update event.
|
// if edge width changed, emit update event.
|
||||||
// except aspectRatioUpdated doesn't get set reliably, so we just call update every time, and update
|
// except aspectRatioUpdated doesn't get set reliably, so we just call update every time, and update
|
||||||
// if detected aspect ratio is different from the current aspect ratio
|
// if detected aspect ratio is different from the current aspect ratio
|
||||||
// if (this.testResults.aspectRatioUpdated) {
|
// if (this.testResults.aspectRatioUpdated) {
|
||||||
// this.timer.arChanged();
|
// this.timer.arChanged();
|
||||||
this.updateAspectRatio();
|
const finalAr = this.getAr();
|
||||||
|
if (finalAr > 0) {
|
||||||
|
this.updateAspectRatio(finalAr);
|
||||||
|
} else {
|
||||||
|
this.testResults.aspectRatioInvalid = true;
|
||||||
|
this.testResults.aspectRatioInvalidReason = finalAr.toFixed(3);
|
||||||
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if we got "no letterbox" OR aspectRatioUpdated
|
// if we got "no letterbox" OR aspectRatioUpdated
|
||||||
|
@ -7,9 +7,15 @@ export class AardDebugUi {
|
|||||||
uiAnchorElement: HTMLDivElement;
|
uiAnchorElement: HTMLDivElement;
|
||||||
pauseOnArCheck: boolean = false;
|
pauseOnArCheck: boolean = false;
|
||||||
|
|
||||||
|
uiVisibility: any = {};
|
||||||
|
|
||||||
constructor(aard: any) {
|
constructor(aard: any) {
|
||||||
this.aard = aard;
|
this.aard = aard;
|
||||||
|
|
||||||
|
this.uiVisibility = {
|
||||||
|
detectionDetails: aard.settings.active.ui.dev.aardDebugOverlay.showDetectionDetails
|
||||||
|
};
|
||||||
|
|
||||||
(window as any).ultrawidify_uw_aard_debug_tools = {
|
(window as any).ultrawidify_uw_aard_debug_tools = {
|
||||||
enableStopOnChange: () => this.changePauseOnCheck(true),
|
enableStopOnChange: () => this.changePauseOnCheck(true),
|
||||||
disableStopOnChange: () => this.changePauseOnCheck(false),
|
disableStopOnChange: () => this.changePauseOnCheck(false),
|
||||||
@ -26,7 +32,13 @@ export class AardDebugUi {
|
|||||||
position: fixed; top: 0; left: 0; width: 100vw; height: 100dvh; display: flex; flex-direction: column; pointer-events: none; z-index: 9999; font-size: 16px; font-family: 'Overpass Mono', monospace;
|
position: fixed; top: 0; left: 0; width: 100vw; height: 100dvh; display: flex; flex-direction: column; pointer-events: none; z-index: 9999; font-size: 16px; font-family: 'Overpass Mono', monospace;
|
||||||
">
|
">
|
||||||
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; backdrop-filter: blur(0.5rem) brightness(0.5);">
|
<div style="width: 100%; display: flex; flex-direction: row; justify-content: space-between; backdrop-filter: blur(0.5rem) brightness(0.5);">
|
||||||
<div style="padding: 1rem; color: #fff"><h1>Aard debug overlay</h1></div>
|
<div style="padding: 1rem; color: #fff">
|
||||||
|
<h1>Aard debug overlay</h1>
|
||||||
|
</div>
|
||||||
|
<div style="pointer-events: all; display: flex; flex-direction: column; margin-right: 1rem;">
|
||||||
|
<button id="uw-aard-debug_show-detection-details">Show det. details</button>
|
||||||
|
<button id="uw-aard-debug_hide-detection-details">Hide det. details</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
#uw-aard-debug_performance-container #uw-aard-debug_performance-popup {
|
#uw-aard-debug_performance-container #uw-aard-debug_performance-popup {
|
||||||
@ -62,7 +74,9 @@ export class AardDebugUi {
|
|||||||
<button id="uw-aard-debug-ui_close-overlay">Close overlay</button>
|
<button id="uw-aard-debug-ui_close-overlay">Close overlay</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="display: flex; flex-direction: row; width: 100%">
|
|
||||||
|
|
||||||
|
<div id="uw-aard-debug-ui_body" style="display: flex; flex-direction: row; width: 100%">
|
||||||
<div style="">
|
<div style="">
|
||||||
<div id="uw-aard-debug_aard-sample-canvas" style="min-width: 640px"></div>
|
<div id="uw-aard-debug_aard-sample-canvas" style="min-width: 640px"></div>
|
||||||
<div style="background: black; color: #fff"; font-size: 24px;">AARD IN</div>
|
<div style="background: black; color: #fff"; font-size: 24px;">AARD IN</div>
|
||||||
@ -129,6 +143,10 @@ export class AardDebugUi {
|
|||||||
document.getElementById('uw-aard-debug-ui_enable-step').onclick = () => this.aard.step();
|
document.getElementById('uw-aard-debug-ui_enable-step').onclick = () => this.aard.step();
|
||||||
document.getElementById('uw-aard-debug-ui_enable-step-nocache').onclick = () => this.aard.step({noCache: true});
|
document.getElementById('uw-aard-debug-ui_enable-step-nocache').onclick = () => this.aard.step({noCache: true});
|
||||||
document.getElementById('uw-aard-debug-ui_close-overlay').onclick = () => (this.aard as any).hideDebugCanvas();
|
document.getElementById('uw-aard-debug-ui_close-overlay').onclick = () => (this.aard as any).hideDebugCanvas();
|
||||||
|
document.getElementById('uw-aard-debug_show-detection-details').onclick = () => {this.uiVisibility.detectionDetails = true; this.setOverlayVisibility();};
|
||||||
|
document.getElementById('uw-aard-debug_hide-detection-details').onclick = () => {this.uiVisibility.detectionDetails = false; this.setOverlayVisibility();};
|
||||||
|
|
||||||
|
this.setOverlayVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
changePauseOnCheck(pauseOnChange: boolean) {
|
changePauseOnCheck(pauseOnChange: boolean) {
|
||||||
@ -352,7 +370,8 @@ export class AardDebugUi {
|
|||||||
out = `${out}
|
out = `${out}
|
||||||
|
|
||||||
-- UNCERTAIN FLAGS
|
-- UNCERTAIN FLAGS
|
||||||
AR: ${testResults.aspectRatioUncertain} (reason: ${testResults.aspectRatioUncertainReason ?? 'n/a'}); top row: ${testResults.topRowUncertain}; bottom row: ${testResults.bottomRowUncertain}
|
AR: ${testResults.aspectRatioUncertain} (reason: ${testResults.aspectRatioUncertainReason ?? 'n/a'}); top row: ${testResults.topRowUncertain}; bottom row: ${testResults.bottomRowUncertain}${
|
||||||
|
testResults.aspectRatioInvalid ? `\nINVALID_AR (reason: ${testResults.aspectRatioInvalidReason ?? 'n/a'})` : ''}
|
||||||
|
|
||||||
-- GUARD & IMAGE LINE
|
-- GUARD & IMAGE LINE
|
||||||
bottom guard: ${testResults.guardLine.bottom} image: ${testResults.guardLine.invalidated ? 'n/a' : testResults.imageLine.bottom}
|
bottom guard: ${testResults.guardLine.bottom} image: ${testResults.guardLine.invalidated ? 'n/a' : testResults.imageLine.bottom}
|
||||||
@ -388,5 +407,10 @@ export class AardDebugUi {
|
|||||||
resultsDiv.textContent = out;
|
resultsDiv.textContent = out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setOverlayVisibility() {
|
||||||
|
document.getElementById('uw-aard-debug-ui_body').style.display = this.uiVisibility.detectionDetails ? 'flex' : 'none';
|
||||||
|
document.getElementById('uw-aard-debug_hide-detection-details').style.display = this.uiVisibility.detectionDetails ? '' : 'none';
|
||||||
|
document.getElementById('uw-aard-debug_show-detection-details').style.display = this.uiVisibility.detectionDetails ? 'none' : '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,9 @@ export interface AardTestResults {
|
|||||||
letterboxWidth: number,
|
letterboxWidth: number,
|
||||||
letterboxOffset: number,
|
letterboxOffset: number,
|
||||||
logoDetected: [boolean, boolean, boolean, boolean]
|
logoDetected: [boolean, boolean, boolean, boolean]
|
||||||
|
aspectRatioInvalid: boolean
|
||||||
aspectRatioUncertainReason?: string
|
aspectRatioUncertainReason?: string
|
||||||
|
aspectRatioInvalidReason?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initAardTestResults(settings: AardSettings): AardTestResults {
|
export function initAardTestResults(settings: AardSettings): AardTestResults {
|
||||||
@ -81,7 +83,8 @@ export function initAardTestResults(settings: AardSettings): AardTestResults {
|
|||||||
activeAspectRatio: 0,
|
activeAspectRatio: 0,
|
||||||
letterboxWidth: 0,
|
letterboxWidth: 0,
|
||||||
letterboxOffset: 0,
|
letterboxOffset: 0,
|
||||||
logoDetected: [false, false, false, false]
|
logoDetected: [false, false, false, false],
|
||||||
|
aspectRatioInvalid: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,4 +123,5 @@ export function resetAardTestResults(results: AardTestResults): void {
|
|||||||
results.aspectRatioUncertainReason = null;
|
results.aspectRatioUncertainReason = null;
|
||||||
results.topRowUncertain = false;
|
results.topRowUncertain = false;
|
||||||
results.bottomRowUncertain = false;
|
results.bottomRowUncertain = false;
|
||||||
|
results.aspectRatioInvalid = false;
|
||||||
}
|
}
|
||||||
|
106
src/ext/lib/settings/SettingsSnapshotManager.ts
Normal file
106
src/ext/lib/settings/SettingsSnapshotManager.ts
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
import { settings } from 'cluster'
|
||||||
|
import SettingsInterface from '@src/common/interfaces/SettingsInterface';
|
||||||
|
|
||||||
|
|
||||||
|
export interface SettingsSnapshot {
|
||||||
|
isAutomatic?: boolean;
|
||||||
|
isProtected?: boolean;
|
||||||
|
isDefault?: boolean;
|
||||||
|
forVersion: string;
|
||||||
|
label: string;
|
||||||
|
settings: SettingsInterface;
|
||||||
|
createdAt: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SettingsSnapshotOptions {
|
||||||
|
isAutomatic?: boolean,
|
||||||
|
isProtected?: boolean,
|
||||||
|
isDefault?: boolean,
|
||||||
|
label?: string,
|
||||||
|
forVersion?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SettingsSnapshotManager {
|
||||||
|
private MAX_AUTOMATIC_SNAPSHOTS = 5;
|
||||||
|
|
||||||
|
async getSnapshot(index?: number) {
|
||||||
|
const snapshots = await this.listSnapshots();
|
||||||
|
|
||||||
|
if (!index) {
|
||||||
|
return snapshots.find(x => x.isDefault);
|
||||||
|
} else {
|
||||||
|
if (index < 0 || index >= snapshots.length) {
|
||||||
|
throw new Error('Invalid index');
|
||||||
|
}
|
||||||
|
return snapshots[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async createSnapshot(settings: SettingsInterface, options?: SettingsSnapshotOptions) {
|
||||||
|
const snapshot = {
|
||||||
|
...options,
|
||||||
|
label: options.label ?? 'Automatic snapshot',
|
||||||
|
forVersion: options.forVersion || settings.version,
|
||||||
|
settings: JSON.parse(JSON.stringify(settings)),
|
||||||
|
createdAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const snapshots = await this.listSnapshots();
|
||||||
|
const automaticSnapshots = snapshots.filter((s) => s.isAutomatic && !s.isProtected);
|
||||||
|
|
||||||
|
if (options.isAutomatic && automaticSnapshots.length >= this.MAX_AUTOMATIC_SNAPSHOTS) {
|
||||||
|
const firstAutomaticIndex = snapshots.findIndex((s) => s.isAutomatic && !s.isProtected);
|
||||||
|
snapshots.splice(firstAutomaticIndex, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshots.push(snapshot);
|
||||||
|
this.set(snapshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
async setDefaultSnapshot(index: number, isDefault: boolean) {
|
||||||
|
const snapshots = await this.listSnapshots();
|
||||||
|
if (index < 0 || index >= snapshots.length) {
|
||||||
|
throw new Error('Invalid index');
|
||||||
|
}
|
||||||
|
if (isDefault) {
|
||||||
|
for (const snapshot of snapshots) {
|
||||||
|
snapshot.isDefault = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snapshots[index].isDefault = isDefault;
|
||||||
|
this.set(snapshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
async markSnapshotAsProtected(index: number, isProtected: boolean) {
|
||||||
|
const snapshots = await this.listSnapshots();
|
||||||
|
if (index < 0 || index >= snapshots.length) {
|
||||||
|
throw new Error('Invalid index');
|
||||||
|
}
|
||||||
|
snapshots[index].isProtected = isProtected;
|
||||||
|
this.set(snapshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteSnapshot(index: number) {
|
||||||
|
const snapshots = await this.listSnapshots();
|
||||||
|
if (index < 0 || index >= snapshots.length) {
|
||||||
|
throw new Error('Invalid index');
|
||||||
|
}
|
||||||
|
snapshots.splice(index, 1);
|
||||||
|
this.set(snapshots);
|
||||||
|
}
|
||||||
|
|
||||||
|
async listSnapshots(): Promise<SettingsSnapshot[]> {
|
||||||
|
const ret = await chrome.storage.local.get('uwSettings-snapshots');
|
||||||
|
try {
|
||||||
|
JSON.parse(ret['uwSettings-snapshots']) as SettingsSnapshot[];
|
||||||
|
} catch (e) {
|
||||||
|
return [] as SettingsSnapshot[];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async set(snapshots: SettingsSnapshot[]) {
|
||||||
|
await chrome.storage.local.set({
|
||||||
|
'uwSettings-snapshots': JSON.stringify(snapshots),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
import ExtensionMode from '../../../common/enums/ExtensionMode.enum';
|
||||||
import { EventBusConnector } from '../EventBus';
|
import { EventBusConnector } from '../EventBus';
|
||||||
|
|
||||||
if (process.env.CHANNEL !== 'stable'){
|
if (process.env.CHANNEL !== 'stable'){
|
||||||
@ -29,6 +30,7 @@ class UI {
|
|||||||
this.saveState = undefined;
|
this.saveState = undefined;
|
||||||
this.playerData = uiConfig.playerData;
|
this.playerData = uiConfig.playerData;
|
||||||
this.uiSettings = uiConfig.uiSettings;
|
this.uiSettings = uiConfig.uiSettings;
|
||||||
|
this.siteSettings = uiConfig.siteSettings;
|
||||||
|
|
||||||
this.iframeErrorCount = 0;
|
this.iframeErrorCount = 0;
|
||||||
this.iframeConfirmed = false;
|
this.iframeConfirmed = false;
|
||||||
@ -43,10 +45,28 @@ class UI {
|
|||||||
this.extensionBase = chrome.runtime.getURL('').replace(/\/$/, "");
|
this.extensionBase = chrome.runtime.getURL('').replace(/\/$/, "");
|
||||||
|
|
||||||
// UI will be initialized when setUiVisibility is called
|
// UI will be initialized when setUiVisibility is called
|
||||||
|
console.log('ui config:', uiConfig);
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canRun() {
|
||||||
|
if (this.isGlobal) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.siteSettings?.data.enableUI.fullscreen === ExtensionMode.Enabled
|
||||||
|
|| this.siteSettings?.data.enableUI.theater === ExtensionMode.Enabled
|
||||||
|
|| this.siteSettings?.data.enableUI.normal === ExtensionMode.Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
|
if (!this.canRun()) {
|
||||||
|
console.log('ui config: canRun returned false', this.siteSettings?.data.enableUI.fullscreen === ExtensionMode.Enabled, this.siteSettings?.data.enableUI.theater === ExtensionMode.Enabled, this.siteSettings?.data.enableUI.normal === ExtensionMode.Enabled)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('ui config: canRun returned truie', this.siteSettings?.data.enableUI.fullscreen === ExtensionMode.Enabled, this.siteSettings?.data.enableUI.theater === ExtensionMode.Enabled, this.siteSettings?.data.enableUI.normal === ExtensionMode.Enabled)
|
||||||
|
|
||||||
|
|
||||||
this.initUIContainer();
|
this.initUIContainer();
|
||||||
this.loadIframe();
|
this.loadIframe();
|
||||||
this.initMessaging();
|
this.initMessaging();
|
||||||
@ -315,6 +335,10 @@ class UI {
|
|||||||
canShowUI: false,
|
canShowUI: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.playerData?.environment && this.siteSettings.data.enableUI[this.playerData?.environment] !== ExtensionMode.Enabled) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.playerData?.dimensions) {
|
if (this.playerData?.dimensions) {
|
||||||
result.playerDimensions = this.playerData.dimensions;
|
result.playerDimensions = this.playerData.dimensions;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,8 @@ class PlayerData {
|
|||||||
parentElement: this.element,
|
parentElement: this.element,
|
||||||
eventBus: this.eventBus,
|
eventBus: this.eventBus,
|
||||||
playerData: this,
|
playerData: this,
|
||||||
uiSettings: this.videoData.settings.active.ui
|
uiSettings: this.videoData.settings.active.ui,
|
||||||
|
siteSettings: this.siteSettings,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -615,7 +616,8 @@ class PlayerData {
|
|||||||
parentElement: this.element,
|
parentElement: this.element,
|
||||||
eventBus: this.eventBus,
|
eventBus: this.eventBus,
|
||||||
playerData: this,
|
playerData: this,
|
||||||
uiSettings: this.videoData.settings.active.ui
|
uiSettings: this.videoData.settings.active.ui,
|
||||||
|
siteSettings: this.siteSettings,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -627,8 +629,6 @@ class PlayerData {
|
|||||||
* Finds and returns HTML element of the player
|
* Finds and returns HTML element of the player
|
||||||
*/
|
*/
|
||||||
private getPlayer(options?: {verbose?: boolean}): HTMLElement {
|
private getPlayer(options?: {verbose?: boolean}): HTMLElement {
|
||||||
const host = window.location.hostname;
|
|
||||||
let element = this.videoElement.parentNode;
|
|
||||||
const videoWidth = this.videoElement.offsetWidth;
|
const videoWidth = this.videoElement.offsetWidth;
|
||||||
const videoHeight = this.videoElement.offsetHeight;
|
const videoHeight = this.videoElement.offsetHeight;
|
||||||
let playerCandidate;
|
let playerCandidate;
|
||||||
@ -649,7 +649,6 @@ class PlayerData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if mode is given, we follow the preference
|
// if mode is given, we follow the preference
|
||||||
|
|
||||||
if (this.siteSettings.data.currentDOMConfig?.elements?.player?.manual && this.siteSettings.data.currentDOMConfig?.elements?.player?.mode) {
|
if (this.siteSettings.data.currentDOMConfig?.elements?.player?.manual && this.siteSettings.data.currentDOMConfig?.elements?.player?.mode) {
|
||||||
if (this.siteSettings.data.currentDOMConfig?.elements?.player?.mode === 'qs') {
|
if (this.siteSettings.data.currentDOMConfig?.elements?.player?.mode === 'qs') {
|
||||||
playerCandidate = this.getPlayerQs(playerQs, elementStack, videoWidth, videoHeight);
|
playerCandidate = this.getPlayerQs(playerQs, elementStack, videoWidth, videoHeight);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "Ultrawidify",
|
"name": "Ultrawidify",
|
||||||
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
"description": "Removes black bars on ultrawide videos and offers advanced options to fix aspect ratio.",
|
||||||
"version": "6.2.5",
|
"version": "6.2.6",
|
||||||
"icons": {
|
"icons": {
|
||||||
"32":"res/icons/uw-32.png",
|
"32":"res/icons/uw-32.png",
|
||||||
"64":"res/icons/uw-64.png"
|
"64":"res/icons/uw-64.png"
|
||||||
|
Loading…
Reference in New Issue
Block a user