xref: /MusicFree/src/core/mediaCache.ts (revision 32683ee62b4655ae6d3cb700ae12398eac644f02)
1import { addFileScheme } from "@/utils/fileUtils";
2import getOrCreateMMKV from "@/utils/getOrCreateMMKV";
3import { getMediaKey } from "@/utils/mediaItem";
4import safeParse from "@/utils/safeParse";
5import { exists, unlink } from "react-native-fs";
6
7// Internal Method
8const mediaCacheStore = getOrCreateMMKV('cache.MediaCache', true);
9
10// 最多缓存800条数据
11const maxCacheCount = 800;
12
13/** 获取meta信息 */
14const getMediaCache = (mediaItem: ICommon.IMediaBase) => {
15    if (mediaItem.platform && mediaItem.id) {
16        const cacheMediaItem = mediaCacheStore.getString(
17            getMediaKey(mediaItem),
18        );
19        return cacheMediaItem
20            ? safeParse<ICommon.IMediaBase>(cacheMediaItem)
21            : null;
22    }
23
24    return null;
25};
26
27/** 设置meta信息 */
28const setMediaCache = (mediaItem: ICommon.IMediaBase) => {
29    if (mediaItem.platform && mediaItem.id) {
30        const allKeys = mediaCacheStore.getAllKeys();
31        if (allKeys.length >= maxCacheCount) {
32            // TODO: 随机删一半
33            for (let i = 0; i < maxCacheCount / 2; ++i) {
34                const rawCacheMedia = mediaCacheStore.getString(allKeys[i]);
35                const cacheData = rawCacheMedia
36                    ? safeParse(rawCacheMedia)
37                    : null;
38                clearLocalCaches(cacheData);
39
40                mediaCacheStore.delete(allKeys[i]);
41            }
42        }
43
44        mediaCacheStore.set(getMediaKey(mediaItem), JSON.stringify(mediaItem));
45        return true;
46    }
47
48    return false;
49};
50
51async function clearLocalCaches(cacheData: IMusic.IMusicItemCache) {
52    if (cacheData.$localLyric) {
53        await checkPathAndRemove(cacheData.$localLyric.rawLrc);
54        await checkPathAndRemove(cacheData.$localLyric.translation);
55    }
56}
57
58async function checkPathAndRemove(filePath?: string) {
59    if (!filePath) {
60        return;
61    }
62    filePath = addFileScheme(filePath);
63    if (await exists(filePath)) {
64        unlink(filePath);
65    }
66}
67
68/** 移除缓存信息 */
69const removeMediaCache = (mediaItem: ICommon.IMediaBase) => {
70    if (mediaItem.platform && mediaItem.id) {
71        mediaCacheStore.delete(getMediaKey(mediaItem));
72    }
73
74    return false;
75};
76
77const MediaCache = {
78    getMediaCache,
79    setMediaCache,
80    removeMediaCache,
81};
82
83export default MediaCache;
84