Settings snapshots
This commit is contained in:
parent
ae2bb7afcd
commit
391b0ac7ab
@ -21,7 +21,6 @@ const ExtensionConfPatch = [
|
||||
normal: ExtensionMode.Default,
|
||||
}
|
||||
}
|
||||
const uiEnabled =
|
||||
userOptions.sites['@global'].enableUI = {
|
||||
fullscreen: userOptions.ui.inPlayer.enabled ? ExtensionMode.Enabled : ExtensionMode.Disabled,
|
||||
theater: ExtensionMode.Enabled,
|
||||
@ -84,6 +83,9 @@ const ExtensionConfPatch = [
|
||||
|
||||
delete (userOptions as any).actions;
|
||||
|
||||
userOptions.dev = {
|
||||
loadFromSnapshot: false
|
||||
};
|
||||
userOptions.ui.dev = {
|
||||
aardDebugOverlay: {
|
||||
showOnStartup: false,
|
||||
|
@ -14,6 +14,10 @@ if(Debug.debug)
|
||||
console.log("Loading: ExtensionConf.js");
|
||||
|
||||
const ExtensionConf: SettingsInterface = {
|
||||
dev: {
|
||||
loadFromSnapshot: false,
|
||||
},
|
||||
|
||||
arDetect: {
|
||||
aardType: 'auto',
|
||||
|
||||
@ -728,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" : {
|
||||
enable: {
|
||||
fullscreen: ExtensionMode.Enabled,
|
||||
|
@ -12,11 +12,15 @@ import Logger from './Logger';
|
||||
import SettingsInterface from '../../common/interfaces/SettingsInterface';
|
||||
import AspectRatioType from '../../common/enums/AspectRatioType.enum';
|
||||
import { SiteSettings } from './settings/SiteSettings';
|
||||
import { SettingsSnapshotManager } from './settings/SettingsSnapshotManager';
|
||||
|
||||
if(process.env.CHANNEL !== 'stable'){
|
||||
console.info("Loading Settings");
|
||||
}
|
||||
|
||||
interface SetSettingsOptions {
|
||||
forcePreserveVersion?: boolean,
|
||||
}
|
||||
|
||||
class Settings {
|
||||
//#region flags
|
||||
@ -41,6 +45,17 @@ class Settings {
|
||||
afterSettingsChangedCallbacks: (() => void)[] = [];
|
||||
|
||||
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
|
||||
|
||||
constructor(options) {
|
||||
@ -50,11 +65,14 @@ class Settings {
|
||||
this.afterSettingsSaved = options?.afterSettingsSaved;
|
||||
this.active = options?.activeSettings ?? undefined;
|
||||
this.default = ExtensionConf;
|
||||
this.snapshotManager = new SettingsSnapshotManager();
|
||||
|
||||
this.default['version'] = this.getExtensionVersion();
|
||||
|
||||
chrome.storage.onChanged.addListener((changes, area) => {this.storageChangeListener(changes, area)});
|
||||
|
||||
this.sortedPatches = this.sortConfPatches(ExtensionConfPatch);
|
||||
|
||||
}
|
||||
|
||||
private storageChangeListener(changes, area) {
|
||||
@ -186,6 +204,18 @@ class Settings {
|
||||
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
|
||||
this.logger?.log('info', 'settings', `[Settings::applySettingsPatches] There are ${this.sortedPatches.length - index} settings patches to apply`);
|
||||
while (index < this.sortedPatches.length) {
|
||||
@ -209,7 +239,16 @@ class Settings {
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// |—> on first setup, settings is undefined & settings.version is haram
|
||||
@ -282,7 +321,7 @@ class Settings {
|
||||
return this.active;
|
||||
}
|
||||
|
||||
async get() {
|
||||
async get(): Promise<SettingsInterface | undefined> {
|
||||
let ret;
|
||||
|
||||
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));
|
||||
|
||||
try {
|
||||
return JSON.parse(ret.uwSettings);
|
||||
return JSON.parse(ret.uwSettings) as SettingsInterface;
|
||||
} catch(e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async set(extensionConf, options?) {
|
||||
async set(extensionConf, options?: SetSettingsOptions) {
|
||||
if (!options || !options.forcePreserveVersion) {
|
||||
extensionConf.version = this.version;
|
||||
}
|
||||
@ -344,7 +383,7 @@ class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
async save(options?) {
|
||||
async save(options?: SetSettingsOptions) {
|
||||
if (Debug.debug && Debug.storage) {
|
||||
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.lastModified = new Date();
|
||||
await this.set(this.active);
|
||||
await this.set(this.active, options);
|
||||
}
|
||||
|
||||
async rollback() {
|
||||
|
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),
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user