xref: /MusicFree/src/utils/mediaItem.ts (revision 316c909695af8978fd54ffb10af86d9214d66fef)
1import {
2    internalSerializeKey,
3    localPluginPlatform,
4    sortIndexSymbol,
5    timeStampSymbol,
6} from '@/constants/commonConst';
7import MediaMeta from '@/core/mediaExtra';
8import produce from 'immer';
9import objectPath from 'object-path';
10
11/** 获取mediakey */
12export function getMediaKey(mediaItem: ICommon.IMediaBase) {
13    return `${mediaItem.platform}@${mediaItem.id}`;
14}
15
16/** 解析mediakey */
17export function parseMediaKey(key: string): ICommon.IMediaBase {
18    try {
19        const str = JSON.parse(key.trim());
20        let platform, id;
21        if (typeof str === 'string') {
22            [platform, id] = str.split('@');
23        } else {
24            platform = str?.platform;
25            id = str?.id;
26        }
27        if (!platform || !id) {
28            throw new Error('mediakey不完整');
29        }
30        return {
31            platform,
32            id,
33        };
34    } catch (e: any) {
35        throw e;
36    }
37}
38
39/** 比较两media是否相同 */
40export function isSameMediaItem(
41    a: ICommon.IMediaBase | null | undefined,
42    b: ICommon.IMediaBase | null | undefined,
43) {
44    return a && b && a.id == b.id && a.platform === b.platform;
45}
46
47/** 查找是否存在 */
48export function includesMedia(
49    a: ICommon.IMediaBase[] | null | undefined,
50    b: ICommon.IMediaBase | null | undefined,
51) {
52    if (!a || !b) {
53        return false;
54    }
55    return a.findIndex(_ => isSameMediaItem(_, b)) !== -1;
56}
57
58/** 获取复位的mediaItem */
59export function resetMediaItem<T extends Partial<ICommon.IMediaBase>>(
60    mediaItem: T,
61    platform?: string,
62    newObj?: boolean,
63): T {
64    // 本地音乐不做处理
65    if (
66        mediaItem.platform === localPluginPlatform ||
67        platform === localPluginPlatform
68    ) {
69        return newObj ? {...mediaItem} : mediaItem;
70    }
71    if (!newObj) {
72        mediaItem.platform = platform ?? mediaItem.platform;
73        mediaItem[internalSerializeKey] = undefined;
74        return mediaItem;
75    } else {
76        return produce(mediaItem, _ => {
77            _.platform = platform ?? mediaItem.platform;
78            _[internalSerializeKey] = undefined;
79        });
80    }
81}
82
83export function mergeProps(
84    mediaItem: ICommon.IMediaBase,
85    props: Record<string, any> | undefined,
86    anotherProps?: Record<string, any> | undefined | null,
87) {
88    return props
89        ? {
90              ...mediaItem,
91              ...props,
92              ...(anotherProps ?? {}),
93              id: mediaItem.id,
94              platform: mediaItem.platform,
95          }
96        : mediaItem;
97}
98
99export enum InternalDataType {
100    LOCALPATH = 'localPath',
101}
102
103export function setInternalData<T extends ICommon.IMediaBase>(
104    mediaItem: T,
105    key: InternalDataType,
106    value: string | number | undefined | null,
107): T {
108    return produce(mediaItem, draft => {
109        objectPath.set(draft, `${internalSerializeKey}.${key}`, value);
110    });
111}
112
113export function getInternalData<T>(
114    mediaItem: ICommon.IMediaBase | null | undefined,
115    key: InternalDataType,
116): T | undefined {
117    if (!mediaItem) {
118        return undefined;
119    }
120    return objectPath.get(mediaItem, `${internalSerializeKey}.${key}`);
121}
122
123export function trimInternalData(
124    mediaItem: ICommon.IMediaBase | null | undefined,
125) {
126    if (!mediaItem) {
127        return undefined;
128    }
129    return {
130        ...mediaItem,
131        [internalSerializeKey]: undefined,
132    };
133}
134
135/** 关联歌词 */
136export async function associateLrc(
137    musicItem: ICommon.IMediaBase,
138    linkto: ICommon.IMediaBase,
139) {
140    if (!musicItem || !linkto) {
141        throw new Error('');
142    }
143
144    // 如果相同直接断链
145    MediaMeta.update(musicItem, {
146        associatedLrc: isSameMediaItem(musicItem, linkto) ? undefined : linkto,
147    });
148}
149
150export function sortByTimestampAndIndex(array: any[], newArray = false) {
151    if (newArray) {
152        array = [...array];
153    }
154    return array.sort((a, b) => {
155        const ts = a[timeStampSymbol] - b[timeStampSymbol];
156        if (ts !== 0) {
157            return ts;
158        }
159        return a[sortIndexSymbol] - b[sortIndexSymbol];
160    });
161}
162