xref: /MusicFree/src/core/persistStatus.ts (revision 819a9075ec97c73412fbf94430d3065e57d52b4e)
1*819a9075Smaotoumaoimport getOrCreateMMKV from "@/utils/getOrCreateMMKV";
2*819a9075Smaotoumaoimport safeParse from "@/utils/safeParse";
3*819a9075Smaotoumaoimport { useEffect, useState } from "react";
4*819a9075Smaotoumao
5*819a9075Smaotoumao// Internal Method
6*819a9075Smaotoumaoconst getStore = () => {
7*819a9075Smaotoumao    return getOrCreateMMKV('App.PersistStatus');
8*819a9075Smaotoumao};
9*819a9075Smaotoumao
10*819a9075Smaotoumaointerface IPersistConfig {
11*819a9075Smaotoumao    /** 当前的音乐 */
12*819a9075Smaotoumao    'music.musicItem': IMusic.IMusicItem;
13*819a9075Smaotoumao    /** 进度 */
14*819a9075Smaotoumao    'music.progress': number;
15*819a9075Smaotoumao    /** 模式 */
16*819a9075Smaotoumao    'music.repeatMode': string;
17*819a9075Smaotoumao    /** 列表 */
18*819a9075Smaotoumao    'music.playList': IMusic.IMusicItem[];
19*819a9075Smaotoumao    /** 速度 */
20*819a9075Smaotoumao    'music.rate': number;
21*819a9075Smaotoumao    /** 音质 */
22*819a9075Smaotoumao    'music.quality': IMusic.IQualityKey;
23*819a9075Smaotoumao    /** app */
24*819a9075Smaotoumao    'app.skipVersion': string;
25*819a9075Smaotoumao    /** 开屏弹窗 */
26*819a9075Smaotoumao    'app.skipBootstrapStorageDialog': boolean;
27*819a9075Smaotoumao    /** 上次更新插件的时间 */
28*819a9075Smaotoumao    'app.pluginUpdateTime': number;
29*819a9075Smaotoumao    /** 歌词-是否启用翻译 */
30*819a9075Smaotoumao    'lyric.showTranslation': boolean;
31*819a9075Smaotoumao    /** 歌词-详情页字体大小 */
32*819a9075Smaotoumao    'lyric.detailFontSize': number;
33*819a9075Smaotoumao}
34*819a9075Smaotoumao
35*819a9075Smaotoumaofunction set<K extends keyof IPersistConfig>(
36*819a9075Smaotoumao    key: K,
37*819a9075Smaotoumao    value: IPersistConfig[K] | undefined,
38*819a9075Smaotoumao) {
39*819a9075Smaotoumao    const store = getStore();
40*819a9075Smaotoumao    if (value === undefined) {
41*819a9075Smaotoumao        store.delete(key);
42*819a9075Smaotoumao    } else {
43*819a9075Smaotoumao        store.set(key, JSON.stringify(value));
44*819a9075Smaotoumao    }
45*819a9075Smaotoumao}
46*819a9075Smaotoumao
47*819a9075Smaotoumaofunction get<K extends keyof IPersistConfig>(key: K): IPersistConfig[K] | null {
48*819a9075Smaotoumao    const store = getStore();
49*819a9075Smaotoumao    const raw = store.getString(key);
50*819a9075Smaotoumao    if (raw) {
51*819a9075Smaotoumao        return safeParse(raw) as IPersistConfig[K];
52*819a9075Smaotoumao    }
53*819a9075Smaotoumao    return null;
54*819a9075Smaotoumao}
55*819a9075Smaotoumao
56*819a9075Smaotoumaofunction useValue<K extends keyof IPersistConfig>(
57*819a9075Smaotoumao    key: K,
58*819a9075Smaotoumao    defaultValue?: IPersistConfig[K],
59*819a9075Smaotoumao): IPersistConfig[K] | null {
60*819a9075Smaotoumao    const [state, setState] = useState<IPersistConfig[K] | null>(
61*819a9075Smaotoumao        get(key) ?? defaultValue ?? null,
62*819a9075Smaotoumao    );
63*819a9075Smaotoumao
64*819a9075Smaotoumao    useEffect(() => {
65*819a9075Smaotoumao        const store = getStore();
66*819a9075Smaotoumao        const sub = store.addOnValueChangedListener(changedKey => {
67*819a9075Smaotoumao            if (key === changedKey) {
68*819a9075Smaotoumao                setState(get(key));
69*819a9075Smaotoumao            }
70*819a9075Smaotoumao        });
71*819a9075Smaotoumao
72*819a9075Smaotoumao        return () => {
73*819a9075Smaotoumao            sub.remove();
74*819a9075Smaotoumao        };
75*819a9075Smaotoumao    }, []);
76*819a9075Smaotoumao
77*819a9075Smaotoumao    return state;
78*819a9075Smaotoumao}
79*819a9075Smaotoumao
80*819a9075Smaotoumaoconst PersistStatus = {
81*819a9075Smaotoumao    get,
82*819a9075Smaotoumao    set,
83*819a9075Smaotoumao    useValue,
84*819a9075Smaotoumao};
85*819a9075Smaotoumao
86*819a9075Smaotoumaoexport default PersistStatus;
87