xref: /MusicFree/src/core/trackPlayer/internal/playList.ts (revision 819a9075ec97c73412fbf94430d3065e57d52b4e)
1import PersistStatus from "@/core/persistStatus.ts";
2import { GlobalState } from "@/utils/stateMapper";
3
4/** 音乐队列 */
5const playListStore = new GlobalState<IMusic.IMusicItem[]>([]);
6
7/** 下标映射 */
8let playListIndexMap: Record<string, Record<string, number>> = {};
9
10/**
11 * 设置播放队列
12 * @param newPlayList 新的播放队列
13 * @param shouldSave 是否保存到本地
14 */
15export function setPlayList(
16    newPlayList: IMusic.IMusicItem[],
17    shouldSave = true,
18) {
19    playListStore.setValue(newPlayList);
20    const newIndexMap: Record<string, Record<string, number>> = {};
21    newPlayList.forEach((item, index) => {
22        // 映射中不存在
23        if (!newIndexMap[item.platform]) {
24            newIndexMap[item.platform] = {
25                [item.id]: index,
26            };
27        } else {
28            // 修改映射
29            newIndexMap[item.platform][item.id] = index;
30        }
31    });
32    playListIndexMap = newIndexMap;
33    if (shouldSave) {
34        PersistStatus.set('music.playList', newPlayList);
35    }
36}
37
38/**
39 * 获取当前的播放队列
40 */
41export const getPlayList = playListStore.getValue;
42
43/**
44 * hook
45 */
46export const usePlayList = playListStore.useValue;
47
48/**
49 * 寻找歌曲在播放列表中的下标
50 * @param musicItem 音乐
51 * @returns 下标
52 */
53export function getMusicIndex(musicItem?: IMusic.IMusicItem | null) {
54    if (!musicItem) {
55        return -1;
56    }
57    return playListIndexMap[musicItem.platform]?.[musicItem.id] ?? -1;
58}
59
60/**
61 * 歌曲是否在播放队列中
62 * @param musicItem 音乐
63 * @returns 是否在播放队列中
64 */
65export function isInPlayList(musicItem?: IMusic.IMusicItem | null) {
66    if (!musicItem) {
67        return false;
68    }
69
70    return playListIndexMap[musicItem.platform]?.[musicItem.id] > -1;
71}
72
73/**
74 * 获取第i个位置的歌曲
75 * @param index 下标
76 */
77export function getPlayListMusicAt(index: number): IMusic.IMusicItem | null {
78    const playList = playListStore.getValue();
79    const len = playList.length;
80    if (len === 0) {
81        return null;
82    }
83
84    return playList[(index + len) % len];
85}
86
87/**
88 * 播放队列是否为空
89 * @returns
90 */
91export function isPlayListEmpty() {
92    return playListStore.getValue().length === 0;
93}
94