Restructure the storage files.
This commit is contained in:
parent
d7ddbe4620
commit
df09098f89
|
@ -1,6 +1,6 @@
|
|||
import {offset, type Offset} from "caret-pos";
|
||||
import {Component} from "preact";
|
||||
import {type UserLabelsData} from "../../storage/common.js";
|
||||
import {type UserLabelsData} from "../../storage/exports.js";
|
||||
import {log, querySelectorAll} from "../../utilities/exports.js";
|
||||
|
||||
type Props = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {type HideVotesData} from "../../storage/common.js";
|
||||
import {type HideVotesData} from "../../storage/exports.js";
|
||||
import {log, querySelectorAll} from "../../utilities/exports.js";
|
||||
|
||||
export function runHideVotesFeature(data: HideVotesData) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
type UserLabelsData,
|
||||
createValueUserLabel,
|
||||
saveUserLabels,
|
||||
} from "../../storage/common.js";
|
||||
} from "../../storage/exports.js";
|
||||
import {
|
||||
createElementFromString,
|
||||
isColorBright,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {log, querySelectorAll} from "../../utilities/exports.js";
|
||||
import {type UsernameColorsData} from "../../storage/common.js";
|
||||
import {type UsernameColorsData} from "../../storage/exports.js";
|
||||
|
||||
export function runUsernameColorsFeature(
|
||||
data: UsernameColorsData,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {type JSX, render} from "preact";
|
||||
import {extractGroups, initializeGlobals, log} from "../utilities/exports.js";
|
||||
import {Feature, fromStorage, Data} from "../storage/common.js";
|
||||
import {Feature, fromStorage, Data} from "../storage/exports.js";
|
||||
import {
|
||||
AutocompleteFeature,
|
||||
BackToTopFeature,
|
||||
|
|
|
@ -4,7 +4,7 @@ import {
|
|||
fromStorage,
|
||||
Feature,
|
||||
type HideVotesData,
|
||||
} from "../../storage/common.js";
|
||||
} from "../../storage/exports.js";
|
||||
import {Setting, type SettingProps} from "./index.js";
|
||||
|
||||
type State = {
|
||||
|
|
|
@ -2,7 +2,7 @@ import {Component, type ComponentChildren, type JSX} from "preact";
|
|||
// eslint-disable-next-line n/file-extension-in-import
|
||||
import {useContext} from "preact/hooks";
|
||||
import {AppContext} from "../context.js";
|
||||
import {type Feature} from "../../storage/common.js";
|
||||
import {type Feature} from "../../storage/exports.js";
|
||||
|
||||
export type SettingProps = {
|
||||
children: ComponentChildren;
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
type UsernameColor,
|
||||
Feature,
|
||||
fromStorage,
|
||||
} from "../../storage/common.js";
|
||||
} from "../../storage/exports.js";
|
||||
import {Setting, type SettingProps} from "./index.js";
|
||||
|
||||
type State = {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {createContext} from "preact";
|
||||
import {type Feature} from "../storage/common.js";
|
||||
import {type Feature} from "../storage/exports.js";
|
||||
|
||||
type AppContextValues = {
|
||||
setActiveFeature: (feature: Feature) => void;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Feature} from "../storage/common.js";
|
||||
import {Feature} from "../storage/exports.js";
|
||||
import {
|
||||
AboutSetting,
|
||||
AnonymizeUsernamesSetting,
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
createReportTemplate,
|
||||
initializeGlobals,
|
||||
} from "../utilities/exports.js";
|
||||
import {type Feature, Data, fromStorage} from "../storage/common.js";
|
||||
import {type Feature, Data, fromStorage} from "../storage/exports.js";
|
||||
import {AppContext} from "./context.js";
|
||||
import {features} from "./features.js";
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
Feature,
|
||||
createValueUserLabel,
|
||||
saveUserLabels,
|
||||
} from "../storage/common.js";
|
||||
} from "../storage/exports.js";
|
||||
import "../scss/index.scss";
|
||||
import "../scss/user-label-editor.scss";
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
export enum Feature {
|
||||
AnonymizeUsernames = "anonymize-usernames",
|
||||
Autocomplete = "autocomplete",
|
||||
BackToTop = "back-to-top",
|
||||
Debug = "debug",
|
||||
HideVotes = "hide-votes",
|
||||
JumpToNewComment = "jump-to-new-comment",
|
||||
MarkdownToolbar = "markdown-toolbar",
|
||||
ThemedLogo = "themed-logo",
|
||||
UserLabels = "user-labels",
|
||||
UsernameColors = "username-colors",
|
||||
}
|
||||
|
||||
export enum Data {
|
||||
EnabledFeatures = "enabled-features",
|
||||
KnownGroups = "known-groups",
|
||||
LatestActiveFeatureTab = "latest-active-feature-tab",
|
||||
Version = "data-version",
|
||||
}
|
|
@ -1,25 +1,10 @@
|
|||
import {createValue, type Value} from "@holllo/webextension-storage";
|
||||
import browser from "webextension-polyfill";
|
||||
import {collectUserLabels} from "./user-label.js";
|
||||
import {Data, Feature} from "./enums.js";
|
||||
|
||||
export enum Feature {
|
||||
AnonymizeUsernames = "anonymize-usernames",
|
||||
Autocomplete = "autocomplete",
|
||||
BackToTop = "back-to-top",
|
||||
Debug = "debug",
|
||||
HideVotes = "hide-votes",
|
||||
JumpToNewComment = "jump-to-new-comment",
|
||||
MarkdownToolbar = "markdown-toolbar",
|
||||
ThemedLogo = "themed-logo",
|
||||
UserLabels = "user-labels",
|
||||
UsernameColors = "username-colors",
|
||||
}
|
||||
|
||||
export enum Data {
|
||||
EnabledFeatures = "enabled-features",
|
||||
KnownGroups = "known-groups",
|
||||
LatestActiveFeatureTab = "latest-active-feature-tab",
|
||||
Version = "data-version",
|
||||
}
|
||||
export * from "./user-label.js";
|
||||
export * from "./enums.js";
|
||||
|
||||
export type HideVotesData = {
|
||||
otherComments: boolean;
|
||||
|
@ -28,16 +13,6 @@ export type HideVotesData = {
|
|||
ownTopics: boolean;
|
||||
};
|
||||
|
||||
export type UserLabel = {
|
||||
color: string;
|
||||
id: number;
|
||||
priority: number;
|
||||
text: string;
|
||||
username: string;
|
||||
};
|
||||
|
||||
export type UserLabelsData = Array<Value<UserLabel>>;
|
||||
|
||||
export type UsernameColor = {
|
||||
color: string;
|
||||
id: number;
|
||||
|
@ -46,56 +21,6 @@ export type UsernameColor = {
|
|||
|
||||
export type UsernameColorsData = UsernameColor[];
|
||||
|
||||
/**
|
||||
* Create a {@link Value}-wrapped {@link UserLabel}.
|
||||
*/
|
||||
export async function createValueUserLabel(
|
||||
userLabel: UserLabel,
|
||||
): Promise<UserLabelsData[number]> {
|
||||
return createValue<UserLabel>({
|
||||
deserialize: (input) => JSON.parse(input) as UserLabel,
|
||||
serialize: (input) => JSON.stringify(input),
|
||||
key: `${Feature.UserLabels}-${userLabel.id}`,
|
||||
value: userLabel,
|
||||
storage: browser.storage.sync,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all user labels from storage and combine them into a single array.
|
||||
*/
|
||||
export async function collectUserLabels(): Promise<UserLabelsData> {
|
||||
const storage = await browser.storage.sync.get();
|
||||
const userLabels = [];
|
||||
for (const [key, value] of Object.entries(storage)) {
|
||||
if (!key.startsWith(Feature.UserLabels)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
userLabels.push(
|
||||
await createValueUserLabel(JSON.parse(value as string) as UserLabel),
|
||||
);
|
||||
}
|
||||
|
||||
return userLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all user labels to storage under individual keys.
|
||||
*
|
||||
* They are stored under individual keys so that we don't run into storage quota
|
||||
* limits. If it was stored under a single key we would only be able to fit
|
||||
* around 80-100 labels before hitting the limit.
|
||||
* @param userLabels The user labels array to save.
|
||||
*/
|
||||
export async function saveUserLabels(
|
||||
userLabels: UserLabelsData,
|
||||
): Promise<void> {
|
||||
for (const label of userLabels) {
|
||||
await label.save();
|
||||
}
|
||||
}
|
||||
|
||||
export const storageValues = {
|
||||
[Data.EnabledFeatures]: createValue({
|
||||
deserialize: (input) => new Set(JSON.parse(input) as Feature[]),
|
||||
|
@ -137,7 +62,6 @@ export const storageValues = {
|
|||
},
|
||||
storage: browser.storage.sync,
|
||||
}),
|
||||
// eslint-disable-next-line unicorn/prefer-top-level-await
|
||||
[Feature.UserLabels]: collectUserLabels(),
|
||||
[Feature.UsernameColors]: createValue({
|
||||
deserialize: (input) => JSON.parse(input) as UsernameColorsData,
|
|
@ -1,6 +1,6 @@
|
|||
import browser from "webextension-polyfill";
|
||||
import {setup} from "@holllo/test";
|
||||
import {Data, Feature} from "../common.js";
|
||||
import {Data, Feature} from "../exports.js";
|
||||
import {migrations} from "./migrations.js";
|
||||
import {v112Sample} from "./v1-1-2.js";
|
||||
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import {setup} from "@holllo/test";
|
||||
import {type Migration} from "@holllo/migration-helper";
|
||||
import browser from "webextension-polyfill";
|
||||
import {
|
||||
Data,
|
||||
Feature,
|
||||
createValueUserLabel,
|
||||
fromStorage,
|
||||
saveUserLabels,
|
||||
} from "../common.js";
|
||||
} from "../exports.js";
|
||||
import {v112DeserializeData, v112Sample, type V112Settings} from "./v1-1-2.js";
|
||||
|
||||
export const migrations: Array<Migration<string>> = [
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
import {createValue, type Value} from "@holllo/webextension-storage";
|
||||
import browser from "webextension-polyfill";
|
||||
import {Feature} from "./enums.js";
|
||||
|
||||
export type UserLabel = {
|
||||
color: string;
|
||||
id: number;
|
||||
priority: number;
|
||||
text: string;
|
||||
username: string;
|
||||
};
|
||||
|
||||
export type UserLabelsData = Array<Value<UserLabel>>;
|
||||
|
||||
/**
|
||||
* Create a {@link Value}-wrapped {@link UserLabel}.
|
||||
*/
|
||||
export async function createValueUserLabel(
|
||||
userLabel: UserLabel,
|
||||
): Promise<UserLabelsData[number]> {
|
||||
return createValue<UserLabel>({
|
||||
deserialize: (input) => JSON.parse(input) as UserLabel,
|
||||
serialize: (input) => JSON.stringify(input),
|
||||
key: `${Feature.UserLabels}-${userLabel.id}`,
|
||||
value: userLabel,
|
||||
storage: browser.storage.sync,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all user labels from storage and combine them into a single array.
|
||||
*/
|
||||
export async function collectUserLabels(): Promise<UserLabelsData> {
|
||||
const storage = await browser.storage.sync.get();
|
||||
const userLabels = [];
|
||||
for (const [key, value] of Object.entries(storage)) {
|
||||
if (!key.startsWith(Feature.UserLabels)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
userLabels.push(
|
||||
await createValueUserLabel(JSON.parse(value as string) as UserLabel),
|
||||
);
|
||||
}
|
||||
|
||||
return userLabels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save all user labels to storage under individual keys.
|
||||
*
|
||||
* They are stored under individual keys so that we don't run into storage quota
|
||||
* limits. If it was stored under a single key we would only be able to fit
|
||||
* around 80-100 labels before hitting the limit.
|
||||
* @param userLabels The user labels array to save.
|
||||
*/
|
||||
export async function saveUserLabels(
|
||||
userLabels: UserLabelsData,
|
||||
): Promise<void> {
|
||||
for (const label of userLabels) {
|
||||
await label.save();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue