diff --git a/src/common/utils/common.ts b/src/common/utils/common.ts index 000e99f8..6671cb03 100644 --- a/src/common/utils/common.ts +++ b/src/common/utils/common.ts @@ -180,3 +180,25 @@ export const encodePath = (path: string) => { // https://github.com/lyswhut/lx-music-desktop/issues/963 return path.replaceAll('%', '%25') } + + +export const arrPush = (list: T[], newList: T[]) => { + for (let i = 0; i * 1000 < newList.length; i++) { + list.push(...newList.slice(i * 1000, (i + 1) * 1000)) + } + return list +} + +export const arrUnshift = (list: T[], newList: T[]) => { + for (let i = 0; i * 1000 < newList.length; i++) { + list.splice(i * 1000, 0, ...newList.slice(i * 1000, (i + 1) * 1000)) + } + return list +} + +export const arrPushByPosition = (list: T[], newList: T[], position: number) => { + for (let i = 0; i * 1000 < newList.length; i++) { + list.splice(position + i * 1000, 0, ...newList.slice(i * 1000, (i + 1) * 1000)) + } + return list +} diff --git a/src/main/worker/dbService/modules/download/index.ts b/src/main/worker/dbService/modules/download/index.ts index 5ec966dd..81417fe5 100644 --- a/src/main/worker/dbService/modules/download/index.ts +++ b/src/main/worker/dbService/modules/download/index.ts @@ -1,3 +1,4 @@ +import { arrPush, arrUnshift } from '@common/utils/common' import { queryDownloadList, inertDownloadList, @@ -69,14 +70,14 @@ export const downloadInfoSave = (downloadInfos: LX.Download.ListItem[], addMusic if (!list) initDownloadList() if (addMusicLocationType == 'top') { let newList = [...list] - newList.unshift(...downloadInfos) + arrUnshift(newList, downloadInfos) inertDownloadList(toDBDownloadInfo(downloadInfos), newList.slice(downloadInfos.length - 1).map((info, index) => { return { id: info.id, position: index } })) list = newList } else { inertDownloadList(toDBDownloadInfo(downloadInfos, list.length), []) - list.push(...downloadInfos) + arrPush(list, downloadInfos) } } @@ -103,12 +104,12 @@ export const downloadInfoUpdate = (lists: LX.Download.ListItem[]) => { export const downloadInfoRemove = (ids: string[]) => { deleteDownloadList(ids) if (list) { - for (let i = list.length; i--;) { - let idx = ids.indexOf(list[i].id) - if (idx < 0) continue - list.splice(i, 1) - ids.splice(idx, 1) - } + const listSet = new Set() + for (const item of list) listSet.add(item.id) + for (const id of ids) listSet.delete(id) + const newList = list.filter(task => listSet.has(task.id)) + list.splice(0, list.length) + for (const item of newList) list.push(item) } } diff --git a/src/main/worker/dbService/modules/list/index.ts b/src/main/worker/dbService/modules/list/index.ts index 94197857..a9841e7d 100644 --- a/src/main/worker/dbService/modules/list/index.ts +++ b/src/main/worker/dbService/modules/list/index.ts @@ -1,4 +1,5 @@ import { LIST_IDS } from '@common/constants' +import { arrPush, arrPushByPosition, arrUnshift } from '@common/utils/common' import { deleteUserLists, inertUserLists, @@ -180,7 +181,10 @@ export const getListMusics = (listId: string): LX.Music.MusicInfo[] => { export const musicOverwrite = (listId: string, musicInfos: LX.Music.MusicInfo[]) => { let targetList = getListMusics(listId) overwriteMusicInfo(listId, toDBMusicInfo(musicInfos, listId)) - if (targetList) targetList.splice(0, targetList.length, ...musicInfos) + if (targetList) { + targetList.splice(0, targetList.length) + arrPush(targetList, musicInfos) + } } /** @@ -203,12 +207,12 @@ export const musicsAdd = (listId: string, musicInfos: LX.Music.MusicInfo[], addM switch (addMusicLocationType) { case 'top': insertMusicInfoListAndRefreshOrder(toDBMusicInfo(musicInfos, listId), listId, toDBMusicInfo(targetList, listId, musicInfos.length)) - targetList.unshift(...musicInfos) + arrUnshift(targetList, musicInfos) break case 'bottom': default: insertMusicInfoList(toDBMusicInfo(musicInfos, listId, targetList.length)) - targetList.push(...musicInfos) + arrPush(targetList, musicInfos) break } } @@ -221,15 +225,13 @@ export const musicsAdd = (listId: string, musicInfos: LX.Music.MusicInfo[], addM export const musicsRemove = (listId: string, ids: string[]) => { let targetList = getListMusics(listId) if (!targetList.length) return - ids = [...ids] removeMusicInfos(listId, ids) - for (let i = targetList.length - 1; i > -1; i--) { - const item = targetList[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - ids.splice(index, 1) - targetList.splice(i, 1) - } + const listSet = new Set() + for (const item of targetList) listSet.add(item.id) + for (const id of ids) listSet.delete(id) + const newList = targetList.filter(mInfo => listSet.has(mInfo.id)) + targetList.splice(0, targetList.length) + arrPush(targetList, newList) } /** @@ -245,32 +247,32 @@ export const musicsMove = (fromId: string, toId: string, musicInfos: LX.Music.Mu const ids = musicInfos.map(musicInfo => musicInfo.id) - const map = new Map() - for (const item of toList) map.set(item.id, item) + let listSet = new Set() + for (const item of toList) listSet.add(item.id) musicInfos = musicInfos.filter(item => { - if (map.has(item.id)) return false - map.set(item.id, item) + if (listSet.has(item.id)) return false + listSet.add(item.id) return true }) switch (addMusicLocationType) { case 'top': moveMusicInfoAndRefreshOrder(fromId, ids, toId, toDBMusicInfo(musicInfos, toId), toDBMusicInfo(toList, toId, musicInfos.length)) - toList.unshift(...musicInfos) + arrUnshift(toList, musicInfos) break case 'bottom': default: moveMusicInfo(fromId, ids, toDBMusicInfo(musicInfos, toId, toList.length)) - toList.push(...musicInfos) + arrPush(toList, musicInfos) break } - for (let i = fromList.length - 1; i > -1; i--) { - const item = fromList[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - ids.splice(index, 1) - fromList.splice(i, 1) - } + + listSet = new Set() + for (const item of fromList) listSet.add(item.id) + for (const id of ids) listSet.delete(id) + const newList = fromList.filter(mInfo => listSet.has(mInfo.id)) + fromList.splice(0, fromList.length) + arrPush(fromList, newList) } /** @@ -320,15 +322,17 @@ export const musicsPositionUpdate = (listId: string, position: number, ids: stri let targetList = getListMusics(listId) if (!targetList.length) return - const newTargetList = [...targetList] - const infos = Array(ids.length) - for (let i = newTargetList.length; i--;) { - const item = newTargetList[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - infos.splice(index, 1, newTargetList.splice(i, 1)[0]) + let newTargetList = [...targetList] + + const infos: LX.Music.MusicInfo[] = [] + const map = new Map() + for (const item of newTargetList) map.set(item.id, item) + for (const id of ids) { + infos.push(map.get(id) as LX.Music.MusicInfo) + map.delete(id) } - newTargetList.splice(Math.min(position, newTargetList.length), 0, ...infos) + newTargetList = newTargetList.filter(mInfo => map.has(mInfo.id)) + arrPushByPosition(newTargetList, infos, Math.min(position, newTargetList.length)) updateMusicInfoOrder(listId, newTargetList.map((info, index) => { return { @@ -358,7 +362,7 @@ export const listDataOverwrite = (myListData: MakeOptional { dbLists.push({ ...listInfo, position: index }) - dbMusicInfos.push(...toDBMusicInfo(list, listInfo.id)) + arrPush(dbMusicInfos, toDBMusicInfo(list, listInfo.id)) }) overwriteListData(dbLists, dbMusicInfos) diff --git a/src/renderer/store/download/action.ts b/src/renderer/store/download/action.ts index 6f3fda9e..d4121d37 100644 --- a/src/renderer/store/download/action.ts +++ b/src/renderer/store/download/action.ts @@ -13,7 +13,7 @@ import { getMusicUrl, getPicUrl, getLyricInfo } from '@renderer/core/music/onlin import { appSetting } from '../setting' import { qualityList } from '..' import { proxyCallback } from '@renderer/worker/utils' -import { joinPath } from '@renderer/utils' +import { arrPush, arrUnshift, joinPath } from '@renderer/utils' import { DOWNLOAD_STATUS } from '@common/constants' const waitingUpdateTasks = new Map() @@ -48,7 +48,7 @@ export const getDownloadList = async(): Promise => { break } } - downloadList.push(...list) + arrPush(downloadList, list) } return downloadList } @@ -59,9 +59,9 @@ const addTasks = async(list: LX.Download.ListItem[]) => { await downloadTasksCreate(list.map(i => toRaw(i)), addMusicLocationType) if (addMusicLocationType === 'top') { - downloadList.unshift(...list) + arrUnshift(downloadList, list) } else { - downloadList.push(...list) + arrPush(downloadList, list) } window.app_event.downloadListUpdate() } @@ -367,18 +367,21 @@ export const pauseDownloadTasks = async(list: LX.Download.ListItem[]) => { */ export const removeDownloadTasks = async(ids: string[]) => { await downloadTasksRemove(ids) - ids = [...ids] - for (let i = downloadList.length; i--;) { - const item = downloadList[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - ids.splice(index, 1) - downloadList.splice(i, 1) - if (runingTask.has(item.id)) { - void window.lx.worker.download.removeTask(item.id) - runingTask.delete(item.id) + + const listSet = new Set() + for (const item of downloadList) listSet.add(item.id) + for (const id of ids) listSet.delete(id) + const newList = downloadList.filter(task => { + if (runingTask.has(task.id)) { + void window.lx.worker.download.removeTask(task.id) + runingTask.delete(task.id) } - } + return listSet.has(task.id) + }) + downloadList.splice(0, downloadList.length) + arrPush(downloadList, newList) + + void checkStartTask() window.app_event.downloadListUpdate() } diff --git a/src/renderer/store/list/listManage/action.ts b/src/renderer/store/list/listManage/action.ts index 9f5247d1..c7213ce3 100644 --- a/src/renderer/store/list/listManage/action.ts +++ b/src/renderer/store/list/listManage/action.ts @@ -8,6 +8,7 @@ import { } from './state' import { overwriteListPosition, overwriteListUpdateInfo, removeListPosition, removeListUpdateInfo } from '@renderer/utils/data' import { LIST_IDS } from '@common/constants' +import { arrPush, arrUnshift } from '@common/utils/common' export const setUserLists = (lists: LX.List.UserListInfo[]) => { userLists.splice(0, userLists.length, ...lists) @@ -25,7 +26,8 @@ const overwriteMusicList = (id: string, list: LX.Music.MusicInfo[]) => { markRawList(list) let targetList = allMusicList.get(id) if (targetList) { - targetList.splice(0, targetList.length, ...list) + targetList.splice(0, targetList.length) + arrPush(targetList, list) } else { allMusicList.set(id, shallowReactive(list)) } @@ -179,16 +181,18 @@ export const userListsUpdatePosition = (position: number, ids: string[]) => { const updateLists: LX.List.UserListInfo[] = [] - for (let i = newUserLists.length; i--;) { - if (ids.includes(newUserLists[i].id)) { - const list = newUserLists.splice(i, 1)[0] - list.locationUpdateTime = Date.now() - updateLists.push(list) - } + // const targetItem = list[position] + const map = new Map() + for (const item of newUserLists) map.set(item.id, item) + for (const id of ids) { + const listInfo = map.get(id) as LX.List.UserListInfo + listInfo.locationUpdateTime = Date.now() + updateLists.push(listInfo) + map.delete(id) } - position = Math.min(newUserLists.length, position) + newUserLists.splice(0, newUserLists.length, ...newUserLists.filter(mInfo => map.has(mInfo.id))) + newUserLists.splice(Math.min(position, newUserLists.length), 0, ...updateLists) - newUserLists.splice(position, 0, ...updateLists) setUserLists(newUserLists) } @@ -212,11 +216,11 @@ export const listMusicAdd = (id: string, musicInfos: LX.Music.MusicInfo[], addMu }) switch (addMusicLocationType) { case 'top': - targetList.unshift(...musicInfos) + arrUnshift(targetList, musicInfos) break case 'bottom': default: - targetList.push(...musicInfos) + arrPush(targetList, musicInfos) break } @@ -234,14 +238,13 @@ export const listMusicRemove = (listId: string, ids: string[]): string[] => { let targetList = allMusicList.get(listId) if (!targetList) return listId == loveList.id ? [listId] : [] - ids = [...ids] - for (let i = targetList.length - 1; i > -1; i--) { - const item = targetList[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - ids.splice(index, 1) - targetList.splice(i, 1) - } + const listSet = new Set() + for (const item of targetList) listSet.add(item.id) + for (const id of ids) listSet.delete(id) + const newList = targetList.filter(mInfo => listSet.has(mInfo.id)) + targetList.splice(0, targetList.length) + arrPush(targetList, newList) + return [listId] } @@ -284,7 +287,9 @@ export const listMusicUpdatePosition = async(listId: string, position: number, i const list = await window.lx.worker.main.createSortedList(toRaw(targetList), position, ids) markRawList(list) - targetList.splice(0, targetList.length, ...list) + targetList.splice(0, targetList.length) + arrPush(targetList, list) + // console.timeEnd('ts') return [listId] } diff --git a/src/renderer/store/player/action.ts b/src/renderer/store/player/action.ts index b2513b77..a8c5ead4 100644 --- a/src/renderer/store/player/action.ts +++ b/src/renderer/store/player/action.ts @@ -19,6 +19,7 @@ import { setProgress } from './playProgress' import { playNext } from '@renderer/core/player' import { LIST_IDS } from '@common/constants' import { toRaw } from '@common/utils/vueTools' +import { arrPush, arrUnshift } from '@common/utils/common' type PlayerMusicInfoKeys = keyof typeof musicInfo @@ -231,8 +232,8 @@ export const addTempPlayList = (list: LX.Player.TempPlayListItem[]) => { } return true }) - if (topList.length) tempPlayList.unshift(...topList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) - if (bottomList.length) tempPlayList.push(...bottomList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) + if (topList.length) arrUnshift(tempPlayList, topList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) + if (bottomList.length) arrPush(tempPlayList, bottomList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) if (!playMusicInfo.musicInfo) void playNext() } diff --git a/src/renderer/worker/main/list.ts b/src/renderer/worker/main/list.ts index f0dab6cb..81de6b88 100644 --- a/src/renderer/worker/main/list.ts +++ b/src/renderer/worker/main/list.ts @@ -1,6 +1,6 @@ // import { throttle } from '@common/utils' -import { filterFileName, sortInsert, similar } from '@common/utils/common' +import { filterFileName, sortInsert, similar, arrPushByPosition } from '@common/utils/common' import { joinPath, saveStrToFile } from '@common/utils/nodejs' import { createLocalMusicInfo } from '@renderer/utils/music' @@ -212,14 +212,15 @@ export const searchListMusic = (list: LX.Music.MusicInfo[], text: string) => { * @returns */ export const createSortedList = (list: LX.Music.MusicInfo[], position: number, ids: string[]) => { - const infos = Array(ids.length) - for (let i = list.length; i--;) { - const item = list[i] - const index = ids.indexOf(item.id) - if (index < 0) continue - infos.splice(index, 1, list.splice(i, 1)[0]) + const infos: LX.Music.MusicInfo[] = [] + const map = new Map() + for (const item of list) map.set(item.id, item) + for (const id of ids) { + infos.push(map.get(id) as LX.Music.MusicInfo) + map.delete(id) } - list.splice(Math.min(position, list.length), 0, ...infos) + list = list.filter(mInfo => map.has(mInfo.id)) + arrPushByPosition(list, infos, Math.min(position, list.length)) return list }