1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
import React from "react";
import { z } from "zod";
export const DEFAULT_BADGE_CACHE_EXPIRE_MS = 60 * 60 * 1000; // 1 hour
export const DEFAULT_SHOW_COUNT_BADGE = false;
const zSettingsSchema = z.object({
apiKey: z.string(),
apiKeyId: z.string().optional(),
address: z.string(),
theme: z.enum(["light", "dark", "system"]).optional().default("system"),
showCountBadge: z.boolean().default(DEFAULT_SHOW_COUNT_BADGE),
useBadgeCache: z.boolean().default(true),
badgeCacheExpireMs: z.number().min(0).default(DEFAULT_BADGE_CACHE_EXPIRE_MS),
});
const DEFAULT_SETTINGS: Settings = {
apiKey: "",
address: "",
theme: "system",
showCountBadge: DEFAULT_SHOW_COUNT_BADGE,
useBadgeCache: true,
badgeCacheExpireMs: DEFAULT_BADGE_CACHE_EXPIRE_MS,
};
export type Settings = z.infer<typeof zSettingsSchema>;
const STORAGE = chrome.storage.sync;
export default function usePluginSettings() {
const [settings, setSettingsInternal] =
React.useState<Settings>(DEFAULT_SETTINGS);
const [isInit, setIsInit] = React.useState(false);
React.useEffect(() => {
if (!isInit) {
getPluginSettings().then((settings) => {
setSettingsInternal(settings);
setIsInit(true);
});
}
const onChange = (
changes: Record<string, chrome.storage.StorageChange>,
) => {
if (changes.settings === undefined) {
return;
}
const parsedSettings = zSettingsSchema.safeParse(
changes.settings.newValue,
);
if (parsedSettings.success) {
setSettingsInternal(parsedSettings.data);
}
};
STORAGE.onChanged.addListener(onChange);
return () => {
STORAGE.onChanged.removeListener(onChange);
};
}, []);
const setSettings = async (s: (_: Settings) => Settings) => {
const newVal = s(settings);
await STORAGE.set({ settings: newVal });
};
return { settings, setSettings, isPending: isInit };
}
export async function getPluginSettings() {
const parsedSettings = zSettingsSchema.safeParse(
(await STORAGE.get("settings")).settings,
);
if (parsedSettings.success) {
return parsedSettings.data;
} else {
return DEFAULT_SETTINGS;
}
}
export function subscribeToSettingsChanges(
callback: (settings: Settings) => void,
) {
STORAGE.onChanged.addListener((changes) => {
if (changes.settings === undefined) {
return;
}
const parsedSettings = zSettingsSchema.safeParse(changes.settings.newValue);
if (parsedSettings.success) {
callback(parsedSettings.data);
} else {
callback(DEFAULT_SETTINGS);
}
});
}
|