Rework storage values to use a single function.
This commit is contained in:
parent
2e0ea98225
commit
866d823820
|
@ -1,8 +1,5 @@
|
||||||
import Shepherd from "shepherd.js";
|
import Shepherd from "shepherd.js";
|
||||||
import {
|
import {fromStorage, StorageKey} from "../storage/common.js";
|
||||||
addCompletedTour,
|
|
||||||
createIntroductionUnderstood,
|
|
||||||
} from "../storage/common.js";
|
|
||||||
import {
|
import {
|
||||||
allTours,
|
allTours,
|
||||||
introductionTour,
|
introductionTour,
|
||||||
|
@ -12,7 +9,9 @@ import {
|
||||||
|
|
||||||
/** The main entry point for the content script. */
|
/** The main entry point for the content script. */
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
const introductionUnderstood = await createIntroductionUnderstood();
|
const introductionUnderstood = await fromStorage(
|
||||||
|
StorageKey.IntroductionUnderstood,
|
||||||
|
);
|
||||||
|
|
||||||
// Get the anchor without the leading #.
|
// Get the anchor without the leading #.
|
||||||
const anchor = window.location.hash.slice(1);
|
const anchor = window.location.hash.slice(1);
|
||||||
|
@ -121,7 +120,9 @@ function startTour(data: TourData, runMainAgainAfterComplete: boolean): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the tour as completed.
|
// 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) {
|
if (runMainAgainAfterComplete) {
|
||||||
await main();
|
await main();
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import {Component, type JSX} from "preact";
|
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 {allTours} from "../../tours/exports.js";
|
||||||
import {Tour} from "./tour.js";
|
import {Tour} from "./tour.js";
|
||||||
|
|
||||||
type Props = Record<string, unknown>;
|
type Props = Record<string, unknown>;
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
toursCompleted: Awaited<ReturnType<typeof createToursCompleted>>["value"];
|
toursCompleted: Awaited<StorageValues[StorageKey.ToursCompleted]>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Tours extends Component<Props, State> {
|
export class Tours extends Component<Props, State> {
|
||||||
|
@ -14,20 +18,23 @@ export class Tours extends Component<Props, State> {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
toursCompleted: new Set(),
|
toursCompleted: undefined!,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount(): Promise<void> {
|
async componentDidMount(): Promise<void> {
|
||||||
const toursCompleted = await createToursCompleted();
|
const toursCompleted = await fromStorage(StorageKey.ToursCompleted);
|
||||||
this.setState({toursCompleted: toursCompleted.value});
|
this.setState({toursCompleted});
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
const {toursCompleted} = this.state;
|
const {toursCompleted} = this.state;
|
||||||
|
if (toursCompleted === undefined) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
const tours = allTours.map((tour) => (
|
const tours = allTours.map((tour) => (
|
||||||
<Tour hasBeenCompleted={toursCompleted.has(tour.id)} tour={tour} />
|
<Tour hasBeenCompleted={toursCompleted.value.has(tour.id)} tour={tour} />
|
||||||
));
|
));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,33 +2,39 @@ import browser from "webextension-polyfill";
|
||||||
import {createValue} from "@holllo/webextension-storage";
|
import {createValue} from "@holllo/webextension-storage";
|
||||||
import {type TourId} from "../tours/exports.js";
|
import {type TourId} from "../tours/exports.js";
|
||||||
|
|
||||||
|
/** All available storage keys. */
|
||||||
export enum StorageKey {
|
export enum StorageKey {
|
||||||
IntroductionUnderstood = "introduction-understood",
|
IntroductionUnderstood = "introduction-understood",
|
||||||
ToursCompleted = "tours-completed",
|
ToursCompleted = "tours-completed",
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createIntroductionUnderstood() {
|
/** All values we want to save in storage. */
|
||||||
return createValue<boolean>({
|
const storageValues = {
|
||||||
|
[StorageKey.IntroductionUnderstood]: createValue<boolean>({
|
||||||
deserialize: (input) => input === "true",
|
deserialize: (input) => input === "true",
|
||||||
serialize: (input) => JSON.stringify(input),
|
serialize: (input) => JSON.stringify(input),
|
||||||
key: StorageKey.IntroductionUnderstood,
|
key: StorageKey.IntroductionUnderstood,
|
||||||
storage: browser.storage.local,
|
storage: browser.storage.local,
|
||||||
value: false,
|
value: false,
|
||||||
});
|
}),
|
||||||
}
|
[StorageKey.ToursCompleted]: createValue<Set<TourId>>({
|
||||||
|
|
||||||
export async function createToursCompleted() {
|
|
||||||
return createValue<Set<TourId>>({
|
|
||||||
deserialize: (input) => new Set(JSON.parse(input) as TourId[]),
|
deserialize: (input) => new Set(JSON.parse(input) as TourId[]),
|
||||||
serialize: (input) => JSON.stringify(Array.from(input)),
|
serialize: (input) => JSON.stringify(Array.from(input)),
|
||||||
key: StorageKey.ToursCompleted,
|
key: StorageKey.ToursCompleted,
|
||||||
storage: browser.storage.local,
|
storage: browser.storage.local,
|
||||||
value: new Set([]),
|
value: new Set([]),
|
||||||
});
|
}),
|
||||||
}
|
};
|
||||||
|
|
||||||
export async function addCompletedTour(tourId: TourId): Promise<void> {
|
/** Alias to get the inferred type shape of {@link storageValues}. */
|
||||||
const toursCompleted = await createToursCompleted();
|
export type StorageValues = typeof storageValues;
|
||||||
toursCompleted.value.add(tourId);
|
|
||||||
await toursCompleted.save();
|
/**
|
||||||
|
* 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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {TourId, type TourData} from "./types.js";
|
||||||
import {openOptionsPageFromBackground, renderInContainer} from "./utilities.js";
|
import {openOptionsPageFromBackground, renderInContainer} from "./utilities.js";
|
||||||
|
|
||||||
|
@ -103,7 +103,9 @@ const steps: TourData["steps"] = [
|
||||||
classes: "btn",
|
classes: "btn",
|
||||||
text: "I understand",
|
text: "I understand",
|
||||||
async action() {
|
async action() {
|
||||||
const introductionUnderstood = await createIntroductionUnderstood();
|
const introductionUnderstood = await fromStorage(
|
||||||
|
StorageKey.IntroductionUnderstood,
|
||||||
|
);
|
||||||
introductionUnderstood.value = true;
|
introductionUnderstood.value = true;
|
||||||
await introductionUnderstood.save();
|
await introductionUnderstood.save();
|
||||||
this.complete();
|
this.complete();
|
||||||
|
|
Loading…
Reference in New Issue