1740e3947S猫头猫/** 2740e3947S猫头猫 * 歌单管理 3740e3947S猫头猫 */ 4740e3947S猫头猫import {Immer} from 'immer'; 5740e3947S猫头猫import {useEffect, useMemo, useState} from 'react'; 6740e3947S猫头猫import {nanoid} from 'nanoid'; 7740e3947S猫头猫import {isSameMediaItem} from '@/utils/mediaItem'; 8740e3947S猫头猫import storage from '@/core/musicSheet/storage.ts'; 9740e3947S猫头猫import migrate, {migrateV2} from '@/core/musicSheet/migrate.ts'; 10740e3947S猫头猫import {getDefaultStore, useAtomValue} from 'jotai'; 11740e3947S猫头猫import { 12740e3947S猫头猫 musicListMap, 13740e3947S猫头猫 musicSheetsBaseAtom, 14740e3947S猫头猫 starredMusicSheetsAtom, 15740e3947S猫头猫} from '@/core/musicSheet/atoms.ts'; 16740e3947S猫头猫import {SortType} from '@/constants/commonConst.ts'; 17740e3947S猫头猫import SortedMusicList from '@/core/musicSheet/sortedMusicList.ts'; 18740e3947S猫头猫import ee from '@/core/musicSheet/ee.ts'; 19740e3947S猫头猫import Config from '@/core/config.ts'; 20740e3947S猫头猫 21740e3947S猫头猫const produce = new Immer({ 22740e3947S猫头猫 autoFreeze: false, 23740e3947S猫头猫}).produce; 24740e3947S猫头猫 25740e3947S猫头猫const defaultSheet: IMusic.IMusicSheetItemBase = { 26740e3947S猫头猫 id: 'favorite', 27740e3947S猫头猫 coverImg: undefined, 28740e3947S猫头猫 title: '我喜欢', 29740e3947S猫头猫 worksNum: 0, 30740e3947S猫头猫}; 31740e3947S猫头猫 32740e3947S猫头猫async function setup() { 33740e3947S猫头猫 // 升级逻辑 - 从 AsyncStorage 升级到 MMKV 34740e3947S猫头猫 await migrate(); 35740e3947S猫头猫 try { 36740e3947S猫头猫 const allSheets: IMusic.IMusicSheetItemBase[] = storage.getSheets(); 37740e3947S猫头猫 38740e3947S猫头猫 if (!Array.isArray(allSheets)) { 39740e3947S猫头猫 throw new Error('not exist'); 40740e3947S猫头猫 } 41740e3947S猫头猫 42740e3947S猫头猫 let needRestore = false; 43740e3947S猫头猫 if (!allSheets.length) { 44740e3947S猫头猫 allSheets.push({ 45740e3947S猫头猫 ...defaultSheet, 46740e3947S猫头猫 }); 47740e3947S猫头猫 needRestore = true; 48740e3947S猫头猫 } 49740e3947S猫头猫 if (allSheets[0].id !== defaultSheet.id) { 50740e3947S猫头猫 const defaultSheetIndex = allSheets.findIndex( 51740e3947S猫头猫 it => it.id === defaultSheet.id, 52740e3947S猫头猫 ); 53740e3947S猫头猫 54740e3947S猫头猫 if (defaultSheetIndex === -1) { 55740e3947S猫头猫 allSheets.unshift({ 56740e3947S猫头猫 ...defaultSheet, 57740e3947S猫头猫 }); 58740e3947S猫头猫 } else { 59740e3947S猫头猫 const firstSheet = allSheets.splice(defaultSheetIndex, 1); 60740e3947S猫头猫 allSheets.unshift(firstSheet[0]); 61740e3947S猫头猫 } 62740e3947S猫头猫 needRestore = true; 63740e3947S猫头猫 } 64740e3947S猫头猫 65740e3947S猫头猫 if (needRestore) { 66740e3947S猫头猫 await storage.setSheets(allSheets); 67740e3947S猫头猫 } 68740e3947S猫头猫 69740e3947S猫头猫 for (let sheet of allSheets) { 70740e3947S猫头猫 const musicList = storage.getMusicList(sheet.id); 71740e3947S猫头猫 const sortType = storage.getSheetMeta(sheet.id, 'sort') as SortType; 72740e3947S猫头猫 sheet.worksNum = musicList.length; 73740e3947S猫头猫 migrateV2.migrate(sheet.id, musicList); 74740e3947S猫头猫 musicListMap.set( 75740e3947S猫头猫 sheet.id, 76740e3947S猫头猫 new SortedMusicList(musicList, sortType, true), 77740e3947S猫头猫 ); 78740e3947S猫头猫 sheet.worksNum = musicList.length; 79740e3947S猫头猫 ee.emit('UpdateMusicList', { 80740e3947S猫头猫 sheetId: sheet.id, 81740e3947S猫头猫 updateType: 'length', 82740e3947S猫头猫 }); 83740e3947S猫头猫 } 84740e3947S猫头猫 migrateV2.done(); 85740e3947S猫头猫 getDefaultStore().set(musicSheetsBaseAtom, allSheets); 86740e3947S猫头猫 setupStarredMusicSheets(); 87740e3947S猫头猫 } catch (e: any) { 88740e3947S猫头猫 if (e.message === 'not exist') { 89740e3947S猫头猫 await storage.setSheets([defaultSheet]); 90740e3947S猫头猫 await storage.setMusicList(defaultSheet.id, []); 91740e3947S猫头猫 getDefaultStore().set(musicSheetsBaseAtom, [defaultSheet]); 92740e3947S猫头猫 musicListMap.set( 93740e3947S猫头猫 defaultSheet.id, 94740e3947S猫头猫 new SortedMusicList([], SortType.None, true), 95740e3947S猫头猫 ); 96740e3947S猫头猫 } 97740e3947S猫头猫 } 98740e3947S猫头猫} 99740e3947S猫头猫 100740e3947S猫头猫// 获取音乐 101740e3947S猫头猫function getSortedMusicListBySheetId(sheetId: string) { 102740e3947S猫头猫 let musicList: SortedMusicList; 103740e3947S猫头猫 if (!musicListMap.has(sheetId)) { 104740e3947S猫头猫 musicList = new SortedMusicList([], SortType.None, true); 105740e3947S猫头猫 musicListMap.set(sheetId, musicList); 106740e3947S猫头猫 } else { 107740e3947S猫头猫 musicList = musicListMap.get(sheetId)!; 108740e3947S猫头猫 } 109740e3947S猫头猫 110740e3947S猫头猫 return musicList; 111740e3947S猫头猫} 112740e3947S猫头猫 113740e3947S猫头猫/** 114740e3947S猫头猫 * 更新基本信息 115740e3947S猫头猫 * @param sheetId 歌单ID 116740e3947S猫头猫 * @param data 歌单数据 117740e3947S猫头猫 */ 118740e3947S猫头猫async function updateMusicSheetBase( 119740e3947S猫头猫 sheetId: string, 120740e3947S猫头猫 data: Partial<IMusic.IMusicSheetItemBase>, 121740e3947S猫头猫) { 122740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 123740e3947S猫头猫 const targetSheetIndex = musicSheets.findIndex(it => it.id === sheetId); 124740e3947S猫头猫 125740e3947S猫头猫 if (targetSheetIndex === -1) { 126740e3947S猫头猫 return; 127740e3947S猫头猫 } 128740e3947S猫头猫 129740e3947S猫头猫 const newMusicSheets = produce(musicSheets, draft => { 130740e3947S猫头猫 draft[targetSheetIndex] = { 131740e3947S猫头猫 ...draft[targetSheetIndex], 132740e3947S猫头猫 ...data, 133740e3947S猫头猫 id: sheetId, 134740e3947S猫头猫 }; 135740e3947S猫头猫 return draft; 136740e3947S猫头猫 }); 137740e3947S猫头猫 await storage.setSheets(newMusicSheets); 138740e3947S猫头猫 getDefaultStore().set(musicSheetsBaseAtom, newMusicSheets); 139*756bc302S猫头猫 ee.emit('UpdateSheetBasic', { 140*756bc302S猫头猫 sheetId, 141*756bc302S猫头猫 }); 142740e3947S猫头猫} 143740e3947S猫头猫 144740e3947S猫头猫/** 145740e3947S猫头猫 * 新建歌单 146740e3947S猫头猫 * @param title 歌单名称 147740e3947S猫头猫 */ 148740e3947S猫头猫async function addSheet(title: string) { 149740e3947S猫头猫 const newId = nanoid(); 150740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 151740e3947S猫头猫 152740e3947S猫头猫 const newSheets: IMusic.IMusicSheetItemBase[] = [ 153740e3947S猫头猫 musicSheets[0], 154740e3947S猫头猫 { 155740e3947S猫头猫 title, 156740e3947S猫头猫 id: newId, 157740e3947S猫头猫 coverImg: undefined, 158740e3947S猫头猫 worksNum: 0, 159740e3947S猫头猫 createAt: Date.now(), 160740e3947S猫头猫 }, 161740e3947S猫头猫 ...musicSheets.slice(1), 162740e3947S猫头猫 ]; 163740e3947S猫头猫 // 写入存储 164740e3947S猫头猫 await storage.setSheets(newSheets); 165740e3947S猫头猫 await storage.setMusicList(newId, []); 166740e3947S猫头猫 167740e3947S猫头猫 // 更新状态 168740e3947S猫头猫 getDefaultStore().set(musicSheetsBaseAtom, newSheets); 169740e3947S猫头猫 let defaultSortType = Config.get('setting.basic.musicOrderInLocalSheet'); 170740e3947S猫头猫 if ( 171740e3947S猫头猫 defaultSortType && 172740e3947S猫头猫 [ 173740e3947S猫头猫 SortType.Newest, 174740e3947S猫头猫 SortType.Artist, 175740e3947S猫头猫 SortType.Album, 176740e3947S猫头猫 SortType.Oldest, 177740e3947S猫头猫 SortType.Title, 178740e3947S猫头猫 ].includes(defaultSortType) 179740e3947S猫头猫 ) { 180740e3947S猫头猫 storage.setSheetMeta(newId, 'sort', defaultSortType); 181740e3947S猫头猫 } else { 182740e3947S猫头猫 defaultSortType = SortType.None; 183740e3947S猫头猫 } 184740e3947S猫头猫 musicListMap.set(newId, new SortedMusicList([], defaultSortType, true)); 185740e3947S猫头猫 return newId; 186740e3947S猫头猫} 187740e3947S猫头猫 188740e3947S猫头猫async function resumeSheets( 189740e3947S猫头猫 sheets: IMusic.IMusicSheetItem[], 190740e3947S猫头猫 overwrite?: boolean, 191740e3947S猫头猫) { 192740e3947S猫头猫 // 1. 分离默认歌单和其他歌单 193740e3947S猫头猫 const defaultSheetIndex = sheets.findIndex(it => it.id === defaultSheet.id); 194740e3947S猫头猫 195740e3947S猫头猫 let exportedDefaultSheet: IMusic.IMusicSheetItem | null = null; 196740e3947S猫头猫 197740e3947S猫头猫 if (defaultSheetIndex !== -1) { 198740e3947S猫头猫 exportedDefaultSheet = sheets.splice(defaultSheetIndex, 1)[0]; 199740e3947S猫头猫 } 200740e3947S猫头猫 201740e3947S猫头猫 // 逆序恢复,最新创建的在最上方 202740e3947S猫头猫 for (let i = sheets.length - 1; i >= 0; --i) { 203740e3947S猫头猫 const newSheetId = await addSheet(sheets[i].title || ''); 204740e3947S猫头猫 await addMusic(newSheetId, sheets[i].musicList || []); 205740e3947S猫头猫 } 206740e3947S猫头猫 207740e3947S猫头猫 if (overwrite) { 208740e3947S猫头猫 await addMusic(defaultSheet.id, exportedDefaultSheet?.musicList || []); 209740e3947S猫头猫 } else { 210740e3947S猫头猫 const newSheetId = await addSheet( 211740e3947S猫头猫 exportedDefaultSheet?.title || defaultSheet.title!, 212740e3947S猫头猫 ); 213740e3947S猫头猫 await addMusic(newSheetId, exportedDefaultSheet?.musicList || []); 214740e3947S猫头猫 } 215740e3947S猫头猫} 216740e3947S猫头猫 217740e3947S猫头猫function backupSheets() { 218740e3947S猫头猫 const allSheets = getDefaultStore().get(musicSheetsBaseAtom); 219740e3947S猫头猫 return allSheets.map(it => ({ 220740e3947S猫头猫 ...it, 221740e3947S猫头猫 musicList: musicListMap.get(it.id)?.musicList || [], 222740e3947S猫头猫 })) as IMusic.IMusicSheetItem[]; 223740e3947S猫头猫} 224740e3947S猫头猫 225740e3947S猫头猫/** 226740e3947S猫头猫 * 删除歌单 227740e3947S猫头猫 * @param sheetId 歌单id 228740e3947S猫头猫 */ 229740e3947S猫头猫async function removeSheet(sheetId: string) { 230740e3947S猫头猫 // 只能删除非默认歌单 231740e3947S猫头猫 if (sheetId === defaultSheet.id) { 232740e3947S猫头猫 return; 233740e3947S猫头猫 } 234740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 235740e3947S猫头猫 236740e3947S猫头猫 // 删除后的歌单 237740e3947S猫头猫 const newSheets = musicSheets.filter(item => item.id !== sheetId); 238740e3947S猫头猫 239740e3947S猫头猫 // 写入存储 240740e3947S猫头猫 storage.removeMusicList(sheetId); 241740e3947S猫头猫 await storage.setSheets(newSheets); 242740e3947S猫头猫 243740e3947S猫头猫 // 修改状态 244740e3947S猫头猫 getDefaultStore().set(musicSheetsBaseAtom, newSheets); 245740e3947S猫头猫 musicListMap.delete(sheetId); 246740e3947S猫头猫} 247740e3947S猫头猫 248740e3947S猫头猫/** 249740e3947S猫头猫 * 向歌单内添加音乐 250740e3947S猫头猫 * @param sheetId 歌单id 251740e3947S猫头猫 * @param musicItem 音乐 252740e3947S猫头猫 */ 253740e3947S猫头猫async function addMusic( 254740e3947S猫头猫 sheetId: string, 255740e3947S猫头猫 musicItem: IMusic.IMusicItem | Array<IMusic.IMusicItem>, 256740e3947S猫头猫) { 257740e3947S猫头猫 const now = Date.now(); 258740e3947S猫头猫 if (!Array.isArray(musicItem)) { 259740e3947S猫头猫 musicItem = [musicItem]; 260740e3947S猫头猫 } 261740e3947S猫头猫 const taggedMusicItems = musicItem.map((it, index) => ({ 262740e3947S猫头猫 ...it, 263740e3947S猫头猫 $timestamp: now, 264740e3947S猫头猫 $sortIndex: musicItem.length - index, 265740e3947S猫头猫 })); 266740e3947S猫头猫 267740e3947S猫头猫 let musicList = getSortedMusicListBySheetId(sheetId); 268740e3947S猫头猫 269740e3947S猫头猫 const addedCount = musicList.add(taggedMusicItems); 270740e3947S猫头猫 271740e3947S猫头猫 // Update 272740e3947S猫头猫 if (!addedCount) { 273740e3947S猫头猫 return; 274740e3947S猫头猫 } 275740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 276740e3947S猫头猫 if ( 277740e3947S猫头猫 !musicSheets 278740e3947S猫头猫 .find(_ => _.id === sheetId) 279740e3947S猫头猫 ?.coverImg?.startsWith('file://') 280740e3947S猫头猫 ) { 281740e3947S猫头猫 await updateMusicSheetBase(sheetId, { 282740e3947S猫头猫 coverImg: musicList.at(0)?.artwork, 283740e3947S猫头猫 }); 284740e3947S猫头猫 } 285740e3947S猫头猫 286740e3947S猫头猫 // 更新音乐数量 287740e3947S猫头猫 getDefaultStore().set( 288740e3947S猫头猫 musicSheetsBaseAtom, 289740e3947S猫头猫 produce(draft => { 290740e3947S猫头猫 const musicSheet = draft.find(it => it.id === sheetId); 291740e3947S猫头猫 if (musicSheet) { 292740e3947S猫头猫 musicSheet.worksNum = musicList.length; 293740e3947S猫头猫 } 294740e3947S猫头猫 }), 295740e3947S猫头猫 ); 296740e3947S猫头猫 297740e3947S猫头猫 await storage.setMusicList(sheetId, musicList.musicList); 298740e3947S猫头猫 ee.emit('UpdateMusicList', { 299740e3947S猫头猫 sheetId, 300740e3947S猫头猫 updateType: 'length', 301740e3947S猫头猫 }); 302740e3947S猫头猫} 303740e3947S猫头猫 304740e3947S猫头猫async function removeMusicByIndex(sheetId: string, indices: number | number[]) { 305740e3947S猫头猫 if (!Array.isArray(indices)) { 306740e3947S猫头猫 indices = [indices]; 307740e3947S猫头猫 } 308740e3947S猫头猫 309740e3947S猫头猫 const musicList = getSortedMusicListBySheetId(sheetId); 310740e3947S猫头猫 311740e3947S猫头猫 musicList.removeByIndex(indices); 312740e3947S猫头猫 313740e3947S猫头猫 // Update 314740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 315740e3947S猫头猫 if ( 316740e3947S猫头猫 !musicSheets 317740e3947S猫头猫 .find(_ => _.id === sheetId) 318740e3947S猫头猫 ?.coverImg?.startsWith('file://') 319740e3947S猫头猫 ) { 320740e3947S猫头猫 await updateMusicSheetBase(sheetId, { 321740e3947S猫头猫 coverImg: musicList.at(0)?.artwork, 322740e3947S猫头猫 }); 323740e3947S猫头猫 } 324740e3947S猫头猫 // 更新音乐数量 325740e3947S猫头猫 getDefaultStore().set( 326740e3947S猫头猫 musicSheetsBaseAtom, 327740e3947S猫头猫 produce(draft => { 328740e3947S猫头猫 const musicSheet = draft.find(it => it.id === sheetId); 329740e3947S猫头猫 if (musicSheet) { 330740e3947S猫头猫 musicSheet.worksNum = musicList.length; 331740e3947S猫头猫 } 332740e3947S猫头猫 }), 333740e3947S猫头猫 ); 334740e3947S猫头猫 await storage.setMusicList(sheetId, musicList.musicList); 335740e3947S猫头猫 ee.emit('UpdateMusicList', { 336740e3947S猫头猫 sheetId, 337740e3947S猫头猫 updateType: 'length', 338740e3947S猫头猫 }); 339740e3947S猫头猫} 340740e3947S猫头猫 341740e3947S猫头猫async function removeMusic( 342740e3947S猫头猫 sheetId: string, 343740e3947S猫头猫 musicItems: IMusic.IMusicItem | IMusic.IMusicItem[], 344740e3947S猫头猫) { 345740e3947S猫头猫 if (!Array.isArray(musicItems)) { 346740e3947S猫头猫 musicItems = [musicItems]; 347740e3947S猫头猫 } 348740e3947S猫头猫 349740e3947S猫头猫 const musicList = getSortedMusicListBySheetId(sheetId); 350740e3947S猫头猫 musicList.remove(musicItems); 351740e3947S猫头猫 352740e3947S猫头猫 // Update 353740e3947S猫头猫 const musicSheets = getDefaultStore().get(musicSheetsBaseAtom); 354915d90f1S猫头猫 355915d90f1S猫头猫 let patchData: Partial<IMusic.IMusicSheetItemBase> = {}; 356740e3947S猫头猫 if ( 357740e3947S猫头猫 !musicSheets 358740e3947S猫头猫 .find(_ => _.id === sheetId) 359740e3947S猫头猫 ?.coverImg?.startsWith('file://') 360740e3947S猫头猫 ) { 361915d90f1S猫头猫 patchData.coverImg = musicList.at(0)?.artwork; 362915d90f1S猫头猫 } 363915d90f1S猫头猫 patchData.worksNum = musicList.length; 364740e3947S猫头猫 await updateMusicSheetBase(sheetId, { 365740e3947S猫头猫 coverImg: musicList.at(0)?.artwork, 366740e3947S猫头猫 }); 367915d90f1S猫头猫 368740e3947S猫头猫 await storage.setMusicList(sheetId, musicList.musicList); 369740e3947S猫头猫 ee.emit('UpdateMusicList', { 370740e3947S猫头猫 sheetId, 371740e3947S猫头猫 updateType: 'length', 372740e3947S猫头猫 }); 373740e3947S猫头猫} 374740e3947S猫头猫 375740e3947S猫头猫async function setSortType(sheetId: string, sortType: SortType) { 376740e3947S猫头猫 const musicList = getSortedMusicListBySheetId(sheetId); 377740e3947S猫头猫 musicList.setSortType(sortType); 378740e3947S猫头猫 379740e3947S猫头猫 // update 380740e3947S猫头猫 await storage.setMusicList(sheetId, musicList.musicList); 381740e3947S猫头猫 storage.setSheetMeta(sheetId, 'sort', sortType); 382740e3947S猫头猫 ee.emit('UpdateMusicList', { 383740e3947S猫头猫 sheetId, 384740e3947S猫头猫 updateType: 'resort', 385740e3947S猫头猫 }); 386740e3947S猫头猫} 387740e3947S猫头猫 388740e3947S猫头猫async function manualSort( 389740e3947S猫头猫 sheetId: string, 390740e3947S猫头猫 musicListAfterSort: IMusic.IMusicItem[], 391740e3947S猫头猫) { 392740e3947S猫头猫 const musicList = getSortedMusicListBySheetId(sheetId); 393740e3947S猫头猫 musicList.manualSort(musicListAfterSort); 394740e3947S猫头猫 395740e3947S猫头猫 // update 396740e3947S猫头猫 await storage.setMusicList(sheetId, musicList.musicList); 397740e3947S猫头猫 storage.setSheetMeta(sheetId, 'sort', SortType.None); 398740e3947S猫头猫 399740e3947S猫头猫 ee.emit('UpdateMusicList', { 400740e3947S猫头猫 sheetId, 401740e3947S猫头猫 updateType: 'resort', 402740e3947S猫头猫 }); 403740e3947S猫头猫} 404740e3947S猫头猫 405740e3947S猫头猫function useSheetsBase() { 406740e3947S猫头猫 return useAtomValue(musicSheetsBaseAtom); 407740e3947S猫头猫} 408740e3947S猫头猫 409740e3947S猫头猫// sheetId should not change 410740e3947S猫头猫function useSheetItem(sheetId: string) { 411740e3947S猫头猫 const sheetsBase = useAtomValue(musicSheetsBaseAtom); 412740e3947S猫头猫 413740e3947S猫头猫 const [sheetItem, setSheetItem] = useState<IMusic.IMusicSheetItem>({ 414740e3947S猫头猫 ...(sheetsBase.find(it => it.id === sheetId) || 415740e3947S猫头猫 ({} as IMusic.IMusicSheetItemBase)), 416740e3947S猫头猫 musicList: musicListMap.get(sheetId)?.musicList || [], 417740e3947S猫头猫 }); 418740e3947S猫头猫 419740e3947S猫头猫 useEffect(() => { 420740e3947S猫头猫 const onUpdateMusicList = ({sheetId: updatedSheetId}) => { 421740e3947S猫头猫 if (updatedSheetId !== sheetId) { 422740e3947S猫头猫 return; 423740e3947S猫头猫 } 424740e3947S猫头猫 setSheetItem(prev => ({ 425740e3947S猫头猫 ...prev, 426740e3947S猫头猫 musicList: musicListMap.get(sheetId)?.musicList || [], 427740e3947S猫头猫 })); 428740e3947S猫头猫 }; 429*756bc302S猫头猫 430*756bc302S猫头猫 const onUpdateSheetBasic = ({sheetId: updatedSheetId}) => { 431*756bc302S猫头猫 if (updatedSheetId !== sheetId) { 432*756bc302S猫头猫 return; 433*756bc302S猫头猫 } 434*756bc302S猫头猫 setSheetItem(prev => ({ 435*756bc302S猫头猫 ...prev, 436*756bc302S猫头猫 ...(getDefaultStore() 437*756bc302S猫头猫 .get(musicSheetsBaseAtom) 438*756bc302S猫头猫 .find(it => it.id === sheetId) || {}), 439*756bc302S猫头猫 })); 440*756bc302S猫头猫 }; 441740e3947S猫头猫 ee.on('UpdateMusicList', onUpdateMusicList); 442*756bc302S猫头猫 ee.on('UpdateSheetBasic', onUpdateSheetBasic); 443740e3947S猫头猫 444740e3947S猫头猫 return () => { 445740e3947S猫头猫 ee.off('UpdateMusicList', onUpdateMusicList); 446*756bc302S猫头猫 ee.off('UpdateSheetBasic', onUpdateSheetBasic); 447740e3947S猫头猫 }; 448740e3947S猫头猫 }, []); 449740e3947S猫头猫 450740e3947S猫头猫 return sheetItem; 451740e3947S猫头猫} 452740e3947S猫头猫 453740e3947S猫头猫function useFavorite(musicItem: IMusic.IMusicItem | null) { 454740e3947S猫头猫 const [fav, setFav] = useState(false); 455740e3947S猫头猫 456740e3947S猫头猫 useEffect(() => { 457740e3947S猫头猫 const onUpdateMusicList = ({sheetId: updatedSheetId, updateType}) => { 458740e3947S猫头猫 if (updatedSheetId !== defaultSheet.id || updateType === 'resort') { 459740e3947S猫头猫 return; 460740e3947S猫头猫 } 461740e3947S猫头猫 setFav(musicListMap.get(defaultSheet.id)?.has(musicItem) || false); 462740e3947S猫头猫 }; 463740e3947S猫头猫 ee.on('UpdateMusicList', onUpdateMusicList); 464740e3947S猫头猫 465740e3947S猫头猫 setFav(musicListMap.get(defaultSheet.id)?.has(musicItem) || false); 466740e3947S猫头猫 return () => { 467740e3947S猫头猫 ee.off('UpdateMusicList', onUpdateMusicList); 468740e3947S猫头猫 }; 469740e3947S猫头猫 }, [musicItem]); 470740e3947S猫头猫 471740e3947S猫头猫 return fav; 472740e3947S猫头猫} 473740e3947S猫头猫 474740e3947S猫头猫async function setupStarredMusicSheets() { 475740e3947S猫头猫 const starredSheets: IMusic.IMusicSheetItem[] = 476740e3947S猫头猫 storage.getStarredSheets() || []; 477740e3947S猫头猫 getDefaultStore().set(starredMusicSheetsAtom, starredSheets); 478740e3947S猫头猫} 479740e3947S猫头猫 480740e3947S猫头猫async function starMusicSheet(musicSheet: IMusic.IMusicSheetItem) { 481740e3947S猫头猫 const store = getDefaultStore(); 482740e3947S猫头猫 const starredSheets: IMusic.IMusicSheetItem[] = store.get( 483740e3947S猫头猫 starredMusicSheetsAtom, 484740e3947S猫头猫 ); 485740e3947S猫头猫 486740e3947S猫头猫 const newVal = [musicSheet, ...starredSheets]; 487740e3947S猫头猫 488740e3947S猫头猫 store.set(starredMusicSheetsAtom, newVal); 489740e3947S猫头猫 await storage.setStarredSheets(newVal); 490740e3947S猫头猫} 491740e3947S猫头猫 492740e3947S猫头猫async function unstarMusicSheet(musicSheet: IMusic.IMusicSheetItemBase) { 493740e3947S猫头猫 const store = getDefaultStore(); 494740e3947S猫头猫 const starredSheets: IMusic.IMusicSheetItem[] = store.get( 495740e3947S猫头猫 starredMusicSheetsAtom, 496740e3947S猫头猫 ); 497740e3947S猫头猫 498740e3947S猫头猫 const newVal = starredSheets.filter( 499740e3947S猫头猫 it => 500740e3947S猫头猫 !isSameMediaItem( 501740e3947S猫头猫 it as ICommon.IMediaBase, 502740e3947S猫头猫 musicSheet as ICommon.IMediaBase, 503740e3947S猫头猫 ), 504740e3947S猫头猫 ); 505740e3947S猫头猫 store.set(starredMusicSheetsAtom, newVal); 506740e3947S猫头猫 await storage.setStarredSheets(newVal); 507740e3947S猫头猫} 508740e3947S猫头猫 509740e3947S猫头猫function useSheetIsStarred( 510740e3947S猫头猫 musicSheet: IMusic.IMusicSheetItem | null | undefined, 511740e3947S猫头猫) { 512740e3947S猫头猫 // TODO: 类型有问题 513740e3947S猫头猫 const musicSheets = useAtomValue(starredMusicSheetsAtom); 514740e3947S猫头猫 return useMemo(() => { 515740e3947S猫头猫 if (!musicSheet) { 516740e3947S猫头猫 return false; 517740e3947S猫头猫 } 518740e3947S猫头猫 return ( 519740e3947S猫头猫 musicSheets.findIndex(it => 520740e3947S猫头猫 isSameMediaItem( 521740e3947S猫头猫 it as ICommon.IMediaBase, 522740e3947S猫头猫 musicSheet as ICommon.IMediaBase, 523740e3947S猫头猫 ), 524740e3947S猫头猫 ) !== -1 525740e3947S猫头猫 ); 526740e3947S猫头猫 }, [musicSheet, musicSheets]); 527740e3947S猫头猫} 528740e3947S猫头猫 529740e3947S猫头猫function useStarredSheets() { 530740e3947S猫头猫 return useAtomValue(starredMusicSheetsAtom); 531740e3947S猫头猫} 532740e3947S猫头猫 533740e3947S猫头猫/********* MusicSheet Meta ****************/ 534740e3947S猫头猫 535740e3947S猫头猫const MusicSheet = { 536740e3947S猫头猫 setup, 537740e3947S猫头猫 addSheet, 538740e3947S猫头猫 defaultSheet, 539740e3947S猫头猫 addMusic, 540740e3947S猫头猫 removeSheet, 541740e3947S猫头猫 backupSheets, 542740e3947S猫头猫 resumeSheets, 543740e3947S猫头猫 removeMusicByIndex, 544740e3947S猫头猫 removeMusic, 545740e3947S猫头猫 starMusicSheet, 546740e3947S猫头猫 unstarMusicSheet, 547740e3947S猫头猫 useFavorite, 548740e3947S猫头猫 useSheetsBase, 549740e3947S猫头猫 useSheetItem, 550740e3947S猫头猫 setSortType, 551740e3947S猫头猫 useSheetIsStarred, 552740e3947S猫头猫 useStarredSheets, 553740e3947S猫头猫 updateMusicSheetBase, 554740e3947S猫头猫 manualSort, 555740e3947S猫头猫 getSheetMeta: storage.getSheetMeta, 556740e3947S猫头猫}; 557740e3947S猫头猫 558740e3947S猫头猫export default MusicSheet; 559