1
Fork 0

Store array items under individual keys (#24).

This commit is contained in:
Bauke 2022-04-06 22:26:30 +02:00
parent 796b988899
commit 8bebc6374e
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
4 changed files with 103 additions and 9 deletions

View File

@ -18,6 +18,7 @@
"caret-pos": "^2.0.0", "caret-pos": "^2.0.0",
"debounce": "^1.2.1", "debounce": "^1.2.1",
"htm": "^3.1.0", "htm": "^3.1.0",
"migration-helper": "^0.1.2",
"modern-normalize": "^1.1.0", "modern-normalize": "^1.1.0",
"platform": "^1.3.6", "platform": "^1.3.6",
"preact": "^10.6.6", "preact": "^10.6.6",

View File

@ -8,6 +8,7 @@ specifiers:
caret-pos: ^2.0.0 caret-pos: ^2.0.0
debounce: ^1.2.1 debounce: ^1.2.1
htm: ^3.1.0 htm: ^3.1.0
migration-helper: ^0.1.2
modern-normalize: ^1.1.0 modern-normalize: ^1.1.0
platform: ^1.3.6 platform: ^1.3.6
postcss: ^8.4.8 postcss: ^8.4.8
@ -27,6 +28,7 @@ dependencies:
caret-pos: 2.0.0 caret-pos: 2.0.0
debounce: 1.2.1 debounce: 1.2.1
htm: 3.1.0 htm: 3.1.0
migration-helper: 0.1.2
modern-normalize: 1.1.0 modern-normalize: 1.1.0
platform: 1.3.6 platform: 1.3.6
preact: 10.6.6 preact: 10.6.6
@ -3795,6 +3797,10 @@ packages:
picomatch: 2.3.1 picomatch: 2.3.1
dev: true dev: true
/migration-helper/0.1.2:
resolution: {integrity: sha512-2ZiOVWqKwGL/hx5xCOXKqfNc7aB6Kz/YC4W/vlVd3v1mmnAl4wQb9jGfBZYnKS8Yc+EBCMYsbAhZJFsqcmqyfg==}
dev: false
/mime-db/1.51.0: /mime-db/1.51.0:
resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==}
engines: {node: '>= 0.6'} engines: {node: '>= 0.6'}

50
source/migrations.ts Normal file
View File

@ -0,0 +1,50 @@
import {Migration} from 'migration-helper';
export const migrations: Array<Migration<string>> = [
{
version: '1.1.2',
async migrate(data: Record<string, any>) {
const migrated: Record<string, any> = {
data: {
hideVotes: data.data.hideVotes as Record<string, boolean>,
knownGroups: data.data.knownGroups as string[],
latestActiveFeatureTab: data.data.latestActiveFeatureTab as string,
},
features: (data.features as Record<string, string>) ?? {},
version: '1.1.2',
};
const userLabels = data.data.userLabels as UserLabel[];
for (const label of userLabels) {
migrated[`userLabel${label.id}`] = label;
}
const usernameColors = data.data.usernameColors as UsernameColor[];
for (const color of usernameColors) {
migrated[`usernameColor${color.id}`] = color;
}
return migrated;
},
},
];
export function deserializeData(data: Record<string, any>): {
userLabels: UserLabel[];
usernameColors: UsernameColor[];
} {
const deserialized: ReturnType<typeof deserializeData> = {
userLabels: [],
usernameColors: [],
};
for (const [key, value] of Object.entries(data)) {
if (key.startsWith('userLabel')) {
deserialized.userLabels.push(value);
} else if (key.startsWith('usernameColor')) {
deserialized.usernameColors.push(value);
}
}
return deserialized;
}

View File

@ -1,20 +1,35 @@
import {migrate} from 'migration-helper';
import browser from 'webextension-polyfill'; import browser from 'webextension-polyfill';
import {migrations, deserializeData} from './migrations.js';
import {log} from './utilities/exports.js'; import {log} from './utilities/exports.js';
export default class Settings { export default class Settings {
public static async fromSyncStorage(): Promise<Settings> { public static async fromSyncStorage(): Promise<Settings> {
const settings = new Settings(); const settings = new Settings();
const defaultsObject = {
data: settings.data, const sync = {
features: settings.features, ...settings,
...(await browser.storage.sync.get(null)),
}; };
const sync = (await browser.storage.sync.get( const migrated = (await migrate(
defaultsObject, sync,
)) as typeof defaultsObject; sync.version ?? settings.version,
settings.data = {...settings.data, ...sync.data}; migrations,
settings.features = {...settings.features, ...sync.features}; )) as Record<string, any>;
const deserialized = deserializeData(migrated);
settings.data = migrated.data as Settings['data'];
settings.data.userLabels = deserialized.userLabels;
settings.data.usernameColors = deserialized.usernameColors;
settings.features = migrated.features as Settings['features'];
settings.version = migrated.version as Settings['version'];
if (sync.version !== settings.version) {
await settings.save();
}
return settings; return settings;
} }
@ -73,6 +88,8 @@ export default class Settings {
usernameColors: boolean; usernameColors: boolean;
}; };
public version: string;
private constructor() { private constructor() {
this.data = { this.data = {
hideVotes: { hideVotes: {
@ -136,6 +153,8 @@ export default class Settings {
userLabels: true, userLabels: true,
usernameColors: false, usernameColors: false,
}; };
this.version = '0.0.0';
} }
public manifest(): TRXManifest { public manifest(): TRXManifest {
@ -147,6 +166,24 @@ export default class Settings {
} }
public async save(): Promise<void> { public async save(): Promise<void> {
await browser.storage.sync.set(this); const sync: Record<string, any> = {
data: {
hideVotes: this.data.hideVotes,
knownGroups: this.data.knownGroups,
latestActiveFeatureTab: this.data.latestActiveFeatureTab,
},
features: this.features,
version: this.version,
};
for (const label of this.data.userLabels) {
sync[`userLabel${label.id}`] = {...label};
}
for (const color of this.data.usernameColors) {
sync[`usernameColor${color.id}`] = {...color};
}
await browser.storage.sync.set(sync);
} }
} }