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