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 // eslint-disable-next-line eqeqeq 45 return a && b && a.id == b.id && a.platform === b.platform; 46} 47 48/** 查找是否存在 */ 49export function includesMedia( 50 a: ICommon.IMediaBase[] | null | undefined, 51 b: ICommon.IMediaBase | null | undefined, 52) { 53 if (!a || !b) { 54 return false; 55 } 56 return a.findIndex(_ => isSameMediaItem(_, b)) !== -1; 57} 58 59/** 获取复位的mediaItem */ 60export function resetMediaItem<T extends Partial<ICommon.IMediaBase>>( 61 mediaItem: T, 62 platform?: string, 63 newObj?: boolean, 64): T { 65 // 本地音乐不做处理 66 if ( 67 mediaItem.platform === localPluginPlatform || 68 platform === localPluginPlatform 69 ) { 70 return newObj ? {...mediaItem} : mediaItem; 71 } 72 if (!newObj) { 73 mediaItem.platform = platform ?? mediaItem.platform; 74 mediaItem[internalSerializeKey] = undefined; 75 return mediaItem; 76 } else { 77 return produce(mediaItem, _ => { 78 _.platform = platform ?? mediaItem.platform; 79 _[internalSerializeKey] = undefined; 80 }); 81 } 82} 83 84export function mergeProps( 85 mediaItem: ICommon.IMediaBase, 86 props: Record<string, any> | undefined, 87 anotherProps?: Record<string, any> | undefined | null, 88) { 89 return props 90 ? { 91 ...mediaItem, 92 ...props, 93 ...(anotherProps ?? {}), 94 id: mediaItem.id, 95 platform: mediaItem.platform, 96 } 97 : mediaItem; 98} 99 100export enum InternalDataType { 101 LOCALPATH = 'localPath', 102 // 加入歌单时间 103 TIMESTAMP = 'timestamp', 104 // 如果时间相同,辅助排序 105 SORTINDEX = 'sortIndex', 106} 107 108export function setInternalData<T extends ICommon.IMediaBase>( 109 mediaItem: T, 110 key: InternalDataType, 111 value: string | number | undefined | null, 112): T { 113 return produce(mediaItem, draft => { 114 objectPath.set(draft, `${internalSerializeKey}.${key}`, value); 115 }); 116} 117 118export function getInternalData<T>( 119 mediaItem: ICommon.IMediaBase | null | undefined, 120 key: InternalDataType, 121): T | undefined { 122 if (!mediaItem) { 123 return undefined; 124 } 125 return objectPath.get(mediaItem, `${internalSerializeKey}.${key}`); 126} 127 128export function trimInternalData( 129 mediaItem: ICommon.IMediaBase | null | undefined, 130) { 131 if (!mediaItem) { 132 return undefined; 133 } 134 return { 135 ...mediaItem, 136 [internalSerializeKey]: undefined, 137 }; 138} 139 140/** 关联歌词 */ 141export async function associateLrc( 142 musicItem: ICommon.IMediaBase, 143 linkto: ICommon.IMediaBase, 144) { 145 if (!musicItem || !linkto) { 146 throw new Error(''); 147 } 148 149 // 如果相同直接断链 150 MediaMeta.update(musicItem, { 151 associatedLrc: isSameMediaItem(musicItem, linkto) ? undefined : linkto, 152 }); 153} 154 155export function sortByTimestampAndIndex(array: any[], newArray = false) { 156 if (newArray) { 157 array = [...array]; 158 } 159 return array.sort((a, b) => { 160 const ts = a[timeStampSymbol] - b[timeStampSymbol]; 161 if (ts !== 0) { 162 return ts; 163 } 164 return a[sortIndexSymbol] - b[sortIndexSymbol]; 165 }); 166} 167