Store array items under individual keys (#24).
This commit is contained in:
parent
796b988899
commit
8bebc6374e
|
@ -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",
|
||||||
|
|
|
@ -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'}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue