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