ultrawidify/src/ext/lib/settings/SettingsSnapshotManager.ts

153 lines
4.2 KiB
TypeScript

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 SnapshotManagerSettings {
maxAutomaticSnapshots: number,
minVersions: number,
}
const SNAPSHOT_MANAGER_CONF = 'uwSettings-snapshot-manager-conf';
export class SettingsSnapshotManager {
config: SnapshotManagerSettings;
async init() {
const ret = await chrome.storage.local.get(SNAPSHOT_MANAGER_CONF) as string;
try {
this.config = JSON.parse(ret[SNAPSHOT_MANAGER_CONF]);
} catch (e) {
this.config = {
maxAutomaticSnapshots: 10,
minVersions: 5
};
}
}
async saveConf() {
await chrome.storage.local.set({
[SNAPSHOT_MANAGER_CONF]: JSON.stringify(this.config)
});
}
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(snapshot: Partial<SettingsSnapshot> & {settings: SettingsInterface}) {
if (!snapshot.createdAt) {
snapshot.createdAt = new Date()
}
if (!snapshot.forVersion) {
snapshot.forVersion = snapshot.settings.version;
}
if (!snapshot.label) {
snapshot.label = "Unknown snapshot"
}
const snapshots = await this.listSnapshots();
const automaticSnapshots = snapshots
.filter((s) => s.isAutomatic && !s.isProtected)
.sort((a: SettingsSnapshot, b: SettingsSnapshot) => a.settings.version === b.settings.version ? 0 : a.settings.version < b.settings.version ? -1 : 1);
let minVersionCount = 0;
let lastVersion;
for (const snap of automaticSnapshots) {
if (lastVersion !== snap.settings.version) {
minVersionCount++;
lastVersion = snap.settings.version;
}
}
if (snapshot.isAutomatic && automaticSnapshots.length >= this.config.maxAutomaticSnapshots && minVersionCount > this.config.minVersions) {
const firstAutomaticIndex = snapshots.findIndex((s) => s.isAutomatic && !s.isProtected);
snapshots.splice(firstAutomaticIndex, 1);
}
snapshots.push(snapshot as SettingsSnapshot);
this.set(snapshots);
}
async updateSnapshot(snapshot: SettingsSnapshot) {
const snapshots = await this.listSnapshots();
const i = snapshots.findIndex((x: SettingsSnapshot) => x.createdAt === snapshot.createdAt);
try {
snapshots[i] = snapshot;
this.set(snapshots);
} catch (e) {
console.error('uw::SettingsSnapshotManager::updateSnapshot — failed to update snapshot.', {e, i, snapshot, 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 {
const json = JSON.parse(ret['uwSettings-snapshots'] as string) as SettingsSnapshot[];
return json;
} catch (e) {
return [] as SettingsSnapshot[];
}
}
private async set(snapshots: SettingsSnapshot[] = []) {
await chrome.storage.local.set({
'uwSettings-snapshots': JSON.stringify(snapshots),
});
}
}