1
Fork 0

Rework storage values to use a single function.

This commit is contained in:
Bauke 2023-07-02 12:25:48 +02:00
parent 2e0ea98225
commit 866d823820
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
4 changed files with 43 additions and 27 deletions

View File

@ -1,8 +1,5 @@
import Shepherd from "shepherd.js";
import {
addCompletedTour,
createIntroductionUnderstood,
} from "../storage/common.js";
import {fromStorage, StorageKey} from "../storage/common.js";
import {
allTours,
introductionTour,
@ -12,7 +9,9 @@ import {
/** The main entry point for the content script. */
async function main(): Promise<void> {
const introductionUnderstood = await createIntroductionUnderstood();
const introductionUnderstood = await fromStorage(
StorageKey.IntroductionUnderstood,
);
// Get the anchor without the leading #.
const anchor = window.location.hash.slice(1);
@ -121,7 +120,9 @@ function startTour(data: TourData, runMainAgainAfterComplete: boolean): void {
}
// Mark the tour as completed.
await addCompletedTour(data.id);
const completedTours = await fromStorage(StorageKey.ToursCompleted);
completedTours.value.add(data.id);
await completedTours.save();
if (runMainAgainAfterComplete) {
await main();

View File

@ -1,12 +1,16 @@
import {Component, type JSX} from "preact";
import {createToursCompleted} from "../../storage/common.js";
import {
fromStorage,
StorageKey,
type StorageValues,
} from "../../storage/common.js";
import {allTours} from "../../tours/exports.js";
import {Tour} from "./tour.js";
type Props = Record<string, unknown>;
type State = {
toursCompleted: Awaited<ReturnType<typeof createToursCompleted>>["value"];
toursCompleted: Awaited<StorageValues[StorageKey.ToursCompleted]>;
};
export class Tours extends Component<Props, State> {
@ -14,20 +18,23 @@ export class Tours extends Component<Props, State> {
super(props);
this.state = {
toursCompleted: new Set(),
toursCompleted: undefined!,
};
}
async componentDidMount(): Promise<void> {
const toursCompleted = await createToursCompleted();
this.setState({toursCompleted: toursCompleted.value});
const toursCompleted = await fromStorage(StorageKey.ToursCompleted);
this.setState({toursCompleted});
}
render(): JSX.Element {
const {toursCompleted} = this.state;
if (toursCompleted === undefined) {
return <></>;
}
const tours = allTours.map((tour) => (
<Tour hasBeenCompleted={toursCompleted.has(tour.id)} tour={tour} />
<Tour hasBeenCompleted={toursCompleted.value.has(tour.id)} tour={tour} />
));
return (

View File

@ -2,33 +2,39 @@ import browser from "webextension-polyfill";
import {createValue} from "@holllo/webextension-storage";
import {type TourId} from "../tours/exports.js";
/** All available storage keys. */
export enum StorageKey {
IntroductionUnderstood = "introduction-understood",
ToursCompleted = "tours-completed",
}
export async function createIntroductionUnderstood() {
return createValue<boolean>({
/** All values we want to save in storage. */
const storageValues = {
[StorageKey.IntroductionUnderstood]: createValue<boolean>({
deserialize: (input) => input === "true",
serialize: (input) => JSON.stringify(input),
key: StorageKey.IntroductionUnderstood,
storage: browser.storage.local,
value: false,
});
}
export async function createToursCompleted() {
return createValue<Set<TourId>>({
}),
[StorageKey.ToursCompleted]: createValue<Set<TourId>>({
deserialize: (input) => new Set(JSON.parse(input) as TourId[]),
serialize: (input) => JSON.stringify(Array.from(input)),
key: StorageKey.ToursCompleted,
storage: browser.storage.local,
value: new Set([]),
});
}
}),
};
export async function addCompletedTour(tourId: TourId): Promise<void> {
const toursCompleted = await createToursCompleted();
toursCompleted.value.add(tourId);
await toursCompleted.save();
/** Alias to get the inferred type shape of {@link storageValues}. */
export type StorageValues = typeof storageValues;
/**
* Get the stored value for a given key.
* @param key The key to get from storage.
*/
export async function fromStorage<K extends StorageKey>(
key: K,
): Promise<StorageValues[K]> {
return storageValues[key];
}

View File

@ -1,4 +1,4 @@
import {createIntroductionUnderstood} from "../storage/common.js";
import {fromStorage, StorageKey} from "../storage/common.js";
import {TourId, type TourData} from "./types.js";
import {openOptionsPageFromBackground, renderInContainer} from "./utilities.js";
@ -103,7 +103,9 @@ const steps: TourData["steps"] = [
classes: "btn",
text: "I understand",
async action() {
const introductionUnderstood = await createIntroductionUnderstood();
const introductionUnderstood = await fromStorage(
StorageKey.IntroductionUnderstood,
);
introductionUnderstood.value = true;
await introductionUnderstood.save();
this.complete();