xref: /MusicFree/src/core/persistStatus.ts (revision 05b0ff92d077d5daf0c485c7d4c4f3f8a17a34c8)
1819a9075Smaotoumaoimport getOrCreateMMKV from "@/utils/getOrCreateMMKV";
2819a9075Smaotoumaoimport safeParse from "@/utils/safeParse";
3819a9075Smaotoumaoimport { useEffect, useState } from "react";
4819a9075Smaotoumao
5819a9075Smaotoumao// Internal Method
6819a9075Smaotoumaoconst getStore = () => {
7819a9075Smaotoumao    return getOrCreateMMKV('App.PersistStatus');
8819a9075Smaotoumao};
9819a9075Smaotoumao
10*05b0ff92Smaotoumaointerface IPersistStatus {
11819a9075Smaotoumao    /** 当前的音乐 */
12819a9075Smaotoumao    'music.musicItem': IMusic.IMusicItem;
13819a9075Smaotoumao    /** 进度 */
14819a9075Smaotoumao    'music.progress': number;
15819a9075Smaotoumao    /** 模式 */
16819a9075Smaotoumao    'music.repeatMode': string;
17819a9075Smaotoumao    /** 列表 */
18819a9075Smaotoumao    'music.playList': IMusic.IMusicItem[];
19819a9075Smaotoumao    /** 速度 */
20819a9075Smaotoumao    'music.rate': number;
21819a9075Smaotoumao    /** 音质 */
22819a9075Smaotoumao    'music.quality': IMusic.IQualityKey;
23819a9075Smaotoumao    /** app */
24819a9075Smaotoumao    'app.skipVersion': string;
25819a9075Smaotoumao    /** 开屏弹窗 */
26819a9075Smaotoumao    'app.skipBootstrapStorageDialog': boolean;
27819a9075Smaotoumao    /** 上次更新插件的时间 */
28819a9075Smaotoumao    'app.pluginUpdateTime': number;
29819a9075Smaotoumao    /** 歌词-是否启用翻译 */
30819a9075Smaotoumao    'lyric.showTranslation': boolean;
31819a9075Smaotoumao    /** 歌词-详情页字体大小 */
32819a9075Smaotoumao    'lyric.detailFontSize': number;
33819a9075Smaotoumao}
34819a9075Smaotoumao
35*05b0ff92Smaotoumaofunction set<K extends keyof IPersistStatus>(
36819a9075Smaotoumao    key: K,
37*05b0ff92Smaotoumao    value: IPersistStatus[K] | undefined,
38819a9075Smaotoumao) {
39819a9075Smaotoumao    const store = getStore();
40819a9075Smaotoumao    if (value === undefined) {
41819a9075Smaotoumao        store.delete(key);
42819a9075Smaotoumao    } else {
43819a9075Smaotoumao        store.set(key, JSON.stringify(value));
44819a9075Smaotoumao    }
45819a9075Smaotoumao}
46819a9075Smaotoumao
47*05b0ff92Smaotoumaofunction get<K extends keyof IPersistStatus>(key: K): IPersistStatus[K] | null {
48819a9075Smaotoumao    const store = getStore();
49819a9075Smaotoumao    const raw = store.getString(key);
50819a9075Smaotoumao    if (raw) {
51*05b0ff92Smaotoumao        return safeParse(raw) as IPersistStatus[K];
52819a9075Smaotoumao    }
53819a9075Smaotoumao    return null;
54819a9075Smaotoumao}
55819a9075Smaotoumao
56*05b0ff92Smaotoumaofunction useValue<K extends keyof IPersistStatus>(
57819a9075Smaotoumao    key: K,
58*05b0ff92Smaotoumao    defaultValue?: IPersistStatus[K],
59*05b0ff92Smaotoumao): IPersistStatus[K] | null {
60*05b0ff92Smaotoumao    const [state, setState] = useState<IPersistStatus[K] | null>(
61819a9075Smaotoumao        get(key) ?? defaultValue ?? null,
62819a9075Smaotoumao    );
63819a9075Smaotoumao
64819a9075Smaotoumao    useEffect(() => {
65819a9075Smaotoumao        const store = getStore();
66819a9075Smaotoumao        const sub = store.addOnValueChangedListener(changedKey => {
67819a9075Smaotoumao            if (key === changedKey) {
68819a9075Smaotoumao                setState(get(key));
69819a9075Smaotoumao            }
70819a9075Smaotoumao        });
71819a9075Smaotoumao
72819a9075Smaotoumao        return () => {
73819a9075Smaotoumao            sub.remove();
74819a9075Smaotoumao        };
75819a9075Smaotoumao    }, []);
76819a9075Smaotoumao
77819a9075Smaotoumao    return state;
78819a9075Smaotoumao}
79819a9075Smaotoumao
80819a9075Smaotoumaoconst PersistStatus = {
81819a9075Smaotoumao    get,
82819a9075Smaotoumao    set,
83819a9075Smaotoumao    useValue,
84819a9075Smaotoumao};
85819a9075Smaotoumao
86819a9075Smaotoumaoexport default PersistStatus;
87