1import { 2 internalSerializeKey, 3 localPluginPlatform, 4 sortIndexSymbol, 5 timeStampSymbol, 6} from '@/constants/commonConst'; 7import MediaMeta from '@/core/mediaMeta'; 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 await MediaMeta.update(musicItem, { 144 associatedLrc: linkto, 145 }); 146 await MediaMeta.update(linkto, [ 147 ['lrc', linkto.lrc], 148 ['$.local.localLrc', linkto.$?.local?.localLrc], 149 ]); 150} 151 152export function sortByTimestampAndIndex(array: any[], newArray = false) { 153 if (newArray) { 154 array = [...array]; 155 } 156 return array.sort((a, b) => { 157 const ts = a[timeStampSymbol] - b[timeStampSymbol]; 158 if (ts !== 0) { 159 return ts; 160 } 161 return a[sortIndexSymbol] - b[sortIndexSymbol]; 162 }); 163} 164