From e382f0dba024c23ea61f86bdbe267df7ddfe12dc Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sun, 31 Oct 2021 21:50:57 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=8B=E8=BD=BD=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E7=9A=84=E6=B7=BB=E5=8A=A0=E3=80=81=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E3=80=81=E6=9A=82=E5=81=9C=E4=BB=BB=E5=8A=A1=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E6=B5=81=E7=95=85=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- publish/changeLog.md | 1 + src/renderer/App.vue | 11 +- src/renderer/components/core/Player.vue | 31 +- src/renderer/store/modules/download.js | 473 +++++++++++++++--------- src/renderer/store/modules/player.js | 26 +- src/renderer/views/Download.vue | 15 +- 6 files changed, 358 insertions(+), 199 deletions(-) diff --git a/publish/changeLog.md b/publish/changeLog.md index 27315b88..53f0743f 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,6 +1,7 @@ ### 优化 - 优化我的列表、下载列表等列表的滚动流畅度 +- 优化下载功能的添加、删除、暂停任务时的流畅度,现在进行这些操作应该不会再觉得卡顿了 ### 修复 diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 64645594..789acd1f 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -148,7 +148,7 @@ export default { }, downloadList: { handler(n) { - this.saveDownloadList(n) + this.saveDownloadList(window.downloadListFull) }, deep: true, }, @@ -373,12 +373,17 @@ export default { }, initDownloadList(downloadList) { if (downloadList) { - downloadList.forEach(item => { + downloadList = downloadList.filter(item => item && item.key && item.musicInfo) + for (const item of downloadList) { + if (item.name == null) { + item.name = `${item.musicInfo.name} - ${item.musicInfo.singer}` + item.songmid = item.musicInfo.songmid + } if (item.status == this.downloadStatus.RUN || item.status == this.downloadStatus.WAITING) { item.status = this.downloadStatus.PAUSE item.statusText = '暂停下载' } - }) + } this.updateDownloadList(downloadList) } }, diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue index ae342919..4c78eaa1 100644 --- a/src/renderer/components/core/Player.vue +++ b/src/renderer/components/core/Player.vue @@ -64,14 +64,14 @@ div(:class="$style.player") //- transition(enter-active-class="animated lightSpeedIn" transition(enter-active-class="animated lightSpeedIn" leave-active-class="animated slideOutDown") - core-player-detail(v-if="isShowPlayerDetail" :visible.sync="isShowPlayerDetail" :musicInfo="listId == 'download' ? targetSong.musicInfo : targetSong" + core-player-detail(v-if="isShowPlayerDetail" :visible.sync="isShowPlayerDetail" :musicInfo="currentMusicInfo" :lyric="lyric" :list="list" :listId="listId" :playInfo="{ nowPlayTimeStr, maxPlayTimeStr, progress, nowPlayTime, status }" :isPlay="isPlay" @action="handlePlayDetailAction" :nextTogglePlayName="nextTogglePlayName" @toggle-next-play-mode="toggleNextPlayMode" @add-music-to="addMusicTo") - material-list-add-modal(:show="isShowAddMusicTo" :musicInfo="listId == 'download' ? targetSong.musicInfo : targetSong" @close="isShowAddMusicTo = false") + material-list-add-modal(:show="isShowAddMusicTo" :musicInfo="currentMusicInfo" @close="isShowAddMusicTo = false") svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' style="display: none;") defs g(:id="$style.iconPic") @@ -121,6 +121,7 @@ export default { singer: '', album: '', }, + currentMusicInfo: {}, pregessWidth: 0, lyric: { lines: [], @@ -395,7 +396,7 @@ export default { // console.log(this.retryNum) if (!this.restorePlayTime) this.restorePlayTime = audio.currentTime // 记录出错的播放时间 this.retryNum++ - this.setUrl(this.targetSong, true) + this.setUrl(this.currentMusicInfo, true) this.status = this.statusText = this.$t('core.player.refresh_url') return } @@ -485,7 +486,7 @@ export default { this.clearDelayNextTimeout() this.updateMediaSessionInfo() - const targetSong = this.targetSong + let targetSong = this.targetSong if (this.setting.player.togglePlayMethod == 'random' && !this.playMusicInfo.isTempPlay) this.setPlayedList(this.playMusicInfo) this.retryNum = 0 @@ -497,16 +498,18 @@ export default { if (!await checkPath(filePath) || !targetSong.isComplate || /\.ape$/.test(filePath)) { return this.list.length == 1 ? null : this.playNext() } - this.musicInfo.songmid = targetSong.musicInfo.songmid - this.musicInfo.singer = targetSong.musicInfo.singer - this.musicInfo.name = targetSong.musicInfo.name + this.currentMusicInfo = targetSong = window.downloadListFullMap.get(targetSong.key).musicInfo + this.musicInfo.songmid = targetSong.songmid + this.musicInfo.singer = targetSong.singer + this.musicInfo.name = targetSong.name this.musicInfo.album = targetSong.albumName audio.src = filePath // console.log(filePath) - this.setImg(targetSong.musicInfo) - this.setLrc(targetSong.musicInfo) + this.setImg(targetSong) + this.setLrc(targetSong) } else { // if (!this.assertApiSupport(targetSong.source)) return this.playNext() + this.currentMusicInfo = targetSong this.musicInfo.songmid = targetSong.songmid this.musicInfo.singer = targetSong.singer this.musicInfo.name = targetSong.name @@ -771,7 +774,7 @@ export default { }) }, showPlayerDetail() { - if (!this.targetSong) return + if (!this.currentMusicInfo) return this.isShowPlayerDetail = true }, handleTransitionEnd(e) { @@ -939,11 +942,11 @@ export default { }, updateMediaSessionInfo() { const mediaMetadata = { - title: this.targetSong.name, - artist: this.targetSong.singer, - album: this.targetSong.albumName, + title: this.currentMusicInfo.name, + artist: this.currentMusicInfo.singer, + album: this.currentMusicInfo.albumName, } - if (this.targetSong.img) mediaMetadata.artwork = [{ src: this.targetSong.img }] + if (this.currentMusicInfo.img) mediaMetadata.artwork = [{ src: this.currentMusicInfo.img }] navigator.mediaSession.metadata = new window.MediaMetadata(mediaMetadata) }, registerMediaSessionHandler() { diff --git a/src/renderer/store/modules/download.js b/src/renderer/store/modules/download.js index 2ebe539d..a89039eb 100644 --- a/src/renderer/store/modules/download.js +++ b/src/renderer/store/modules/download.js @@ -16,6 +16,8 @@ import { import { NAMES, rendererInvoke } from '@common/ipc' window.downloadList = [] +window.downloadListFull = [] +window.downloadListFullMap = new Map() // state const state = { list: window.downloadList, @@ -32,7 +34,6 @@ const state = { const dls = {} const tryNum = {} -let isRuningActionTask = false // getters @@ -72,7 +73,7 @@ const getExt = type => { } } -const checkList = (list, musicInfo, type, ext) => list.some(s => s.musicInfo.songmid === musicInfo.songmid && (s.type === type || s.ext === ext)) +const checkList = (list, musicInfo, type, ext) => list.some(s => s.songmid === musicInfo.songmid && (s.type === type || s.ext === ext)) const getStartTask = (list, downloadStatus, maxDownloadNum) => { let downloadCount = 0 @@ -81,82 +82,6 @@ const getStartTask = (list, downloadStatus, maxDownloadNum) => { return downloadCount < maxDownloadNum ? waitList.shift() || null : false } -const awaitRequestAnimationFrame = () => new Promise(resolve => window.requestAnimationFrame(() => resolve())) - -const addTasks = async(store, list, type) => { - if (list.length == 0) return - let num = 3 - while (num-- > 0) { - let item = list.shift() - if (!item) return - store.dispatch('createDownload', { - musicInfo: item, - type: getMusicType(item, type), - }) - } - await awaitRequestAnimationFrame() - await addTasks(store, list, type) -} -const removeTasks = async(store, list) => { - let num = 20 - while (num-- > 0) { - let item = list.pop() - if (!item) return - let index = store.state.list.indexOf(item) - if (index < 0) continue - store.dispatch('removeTask', item) - } - await awaitRequestAnimationFrame() - await removeTasks(store, list) -} - -const startTasks = async(store, list) => { - let num = 5 - while (num-- > 0) { - let item = list.shift() - if (!item) return - if (item.isComplate || item.status == state.downloadStatus.RUN || item.status == state.downloadStatus.WAITING) continue - let index = store.state.list.indexOf(item) - if (index < 0) continue - store.dispatch('startTask', item) - } - await awaitRequestAnimationFrame() - await startTasks(store, list) -} - -const pauseTasks = async(store, list, runs = []) => { - let num = 6 - let index - let stateList = store.state.list - while (num-- > 0) { - let item = list.shift() - if (item) { - if (item.isComplate) continue - switch (item.status) { - case state.downloadStatus.RUN: - runs.push(item) - continue - case state.downloadStatus.WAITING: - index = stateList.indexOf(item) - if (index < 0) return - store.dispatch('pauseTask', item) - continue - default: - continue - } - } else { - for (const item of runs) { - index = stateList.indexOf(item) - if (index < 0) return - await store.dispatch('pauseTask', item) - } - return - } - } - await awaitRequestAnimationFrame() - await pauseTasks(store, list, runs) -} - const handleGetMusicUrl = function(musicInfo, type, retryedSource = [], originMusic) { // console.log(musicInfo.source) if (!originMusic) originMusic = musicInfo @@ -183,6 +108,7 @@ const handleGetMusicUrl = function(musicInfo, type, retryedSource = [], originMu } const getMusicUrl = async function(downloadInfo, isUseOtherSource, isRefresh) { + downloadInfo = window.downloadListFullMap.get(downloadInfo.key) const cachedUrl = await getMusicUrlFormStorage(downloadInfo.musicInfo, downloadInfo.type) if (!downloadInfo.musicInfo._types[downloadInfo.type]) { // 兼容旧版酷我源搜索列表过滤128k音质的bug @@ -288,6 +214,7 @@ const fixKgLyric = lrc => /\[00:\d\d:\d\d.\d+\]/.test(lrc) ? lrc.replace(/(?:\[0 */ const saveMeta = function(downloadInfo, filePath, isUseOtherSource, isEmbedPic, isEmbedLyric) { if (downloadInfo.type === 'ape') return + downloadInfo = window.downloadListFullMap.get(downloadInfo.key) const tasks = [ isEmbedPic ? downloadInfo.musicInfo.img @@ -323,6 +250,7 @@ const saveMeta = function(downloadInfo, filePath, isUseOtherSource, isEmbedPic, * @param {*} filePath */ const downloadLyric = function(downloadInfo, isUseOtherSource, filePath, lrcFormat) { + downloadInfo = window.downloadListFullMap.get(downloadInfo.key) getLyric.call(this, downloadInfo.musicInfo, isUseOtherSource).then(lrcs => { if (lrcs?.lyric) { lrcs.lyric = fixKgLyric(lrcs.lyric) @@ -358,7 +286,7 @@ const refreshUrl = function(commit, downloadInfo, isUseOtherSource) { */ const deleteFile = path => new Promise((resolve, reject) => { fs.access(path, fs.constants.F_OK, err => { - if (err) return reject(err) + if (err) return err.code == 'ENOENT' ? resolve() : reject(err) fs.unlink(path, err => { if (err) return reject(err) resolve() @@ -366,54 +294,91 @@ const deleteFile = path => new Promise((resolve, reject) => { }) }) +const createDownloadInfo = ({ musicInfo, type, list, fileName, savePath }) => { + type = getMusicType(musicInfo, type) + let ext = getExt(type) + const key = `${musicInfo.songmid}${ext}` + if (checkList(list, musicInfo, type, ext)) return null + const downloadInfo = { + isComplate: false, + status: state.downloadStatus.WAITING, + statusText: '待下载', + url: null, + songmid: musicInfo.songmid, + fileName: filterFileName(`${fileName + .replace('歌名', musicInfo.name) + .replace('歌手', musicInfo.singer)}.${ext}`), + progress: { + downloaded: 0, + total: 0, + progress: 0, + }, + type, + ext, + name: `${musicInfo.name} - ${musicInfo.singer}`, + key, + } + downloadInfo.filePath = path.join(savePath, downloadInfo.fileName) + // commit('addTask', downloadInfo) + + // 删除同路径下的同名文件 + deleteFile(downloadInfo.filePath) + // .catch(err => { + // if (err.code !== 'ENOENT') return commit('setStatusText', { downloadInfo, text: '文件删除失败' }) + // }) + + if (dls[downloadInfo.key]) { + const dl = dls[downloadInfo.key] + delete dls[downloadInfo.key] + dl.stop() + } + + return downloadInfo +} + +// let waitingUpdateTasks = {} +// const delayUpdateProgress = throttle(function(commit) { +// commit('setProgressDelay') +// }, 1000) + // actions const actions = { async createDownload({ state, rootState, commit, dispatch }, { musicInfo, type }) { - let ext = getExt(type) - if (checkList(state.list, musicInfo, type, ext)) return - const downloadInfo = { - isComplate: false, - status: state.downloadStatus.WAITING, - statusText: '待下载', - url: null, - // songmid: musicInfo.songmid, - fileName: filterFileName(`${rootState.setting.download.fileName - .replace('歌名', musicInfo.name) - .replace('歌手', musicInfo.singer)}.${ext}`), - progress: { - downloaded: 0, - total: 0, - progress: 0, - }, - type, - ext, + const downloadInfo = createDownloadInfo({ musicInfo, - key: `${musicInfo.songmid}${ext}`, - } - downloadInfo.filePath = path.join(rootState.setting.download.savePath, downloadInfo.fileName) - commit('addTask', downloadInfo) - try { // 删除同路径下的同名文件 - await deleteFile(downloadInfo.filePath) - } catch (err) { - if (err.code !== 'ENOENT') return commit('setStatusText', { downloadInfo, text: '文件删除失败' }) - } - if (dls[downloadInfo.key]) { - dls[downloadInfo.key].stop().finally(() => { - delete dls[downloadInfo.key] - dispatch('startTask', downloadInfo) - }) - } else { - // console.log(downloadInfo) - dispatch('startTask', downloadInfo) + type, + fileName: rootState.setting.download.fileName, + savePath: rootState.setting.download.savePath, + list: state.list, + }) + if (!downloadInfo) return + commit('addTask', { downloadInfo, musicInfo, addMusicLocationType: rootState.setting.list.addMusicLocationType }) + let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + while (result) { + dispatch('startTask', result) + result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) } }, - createDownloadMultiple(store, { list, type }) { - if (!list.length || isRuningActionTask) return - isRuningActionTask = true - return addTasks(store, [...list], type).finally(() => { - isRuningActionTask = false - }) + createDownloadMultiple({ state, rootState, commit, dispatch }, { list, type }) { + if (!list.length) return + const downloadList = [] + for (const musicInfo of list) { + const downloadInfo = createDownloadInfo({ + musicInfo, + type, + fileName: rootState.setting.download.fileName, + savePath: rootState.setting.download.savePath, + list: state.list, + }) + if (downloadInfo) downloadList.push({ downloadInfo, musicInfo }) + } + commit('addTasks', { list: downloadList, addMusicLocationType: rootState.setting.list.addMusicLocationType }) + let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + while (result) { + dispatch('startTask', result) + result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + } }, async handleStartTask({ commit, dispatch, rootState }, downloadInfo) { // 开始任务 @@ -423,7 +388,7 @@ const actions = { await checkPath(rootState.setting.download.savePath) } catch (error) { commit('onError', { downloadInfo, errorMsg: error.message }) - commit('setStatusText', '检查下载目录出错: ' + error.message) + commit('setStatusText', { downloadInfo, text: '检查下载目录出错: ' + error.message }) await dispatch('startTask') return } @@ -447,9 +412,9 @@ const actions = { console.log('on complate') }, onError(err) { - // console.log(err) + console.log(err) if (err.code == 'EPERM') { - commit('onError', { downloadInfo, errorMsg: '歌曲下载目录没有写入权限,请尝试更改歌曲保存路径' }) + commit('onError', { downloadInfo, errorMsg: '歌曲保存位置被占用或没有写入权限,请尝试更改歌曲保存目录或重启软件或重启电脑,错误详情:' + err.message }) return } // console.log(tryNum[downloadInfo.key]) @@ -538,28 +503,38 @@ const actions = { await dispatch('startTask') } }, - removeTasks(store, list) { - let { rootState, state } = store - if (isRuningActionTask) return - isRuningActionTask = true - return removeTasks(store, [...list]).finally(() => { - let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) - while (result) { - store.dispatch('startTask', result) - result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + removeTasks({ rootState, commit, dispatch }, list) { + for (const item of list) { + if (dls[item.key]) { + if (item.status == state.downloadStatus.RUN) { + dls[item.key].stop().finally(() => { + delete dls[item.key] + }) + } else { + delete dls[item.key] + } } - isRuningActionTask = false - }) + if (item.status != state.downloadStatus.COMPLETED) { + deleteFile(item.filePath).catch(_ => _) + } + } + commit('removeTasks', list) + let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + while (result) { + dispatch('startTask', result) + result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + } }, async startTask({ state, rootState, commit, dispatch }, downloadInfo) { // 检查是否可以开始任务 - let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) if (downloadInfo && !downloadInfo.isComplate && downloadInfo.status != state.downloadStatus.RUN) { + const result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) if (result === false) { commit('setStatus', { downloadInfo, status: state.downloadStatus.WAITING }) return } } else { + const result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) if (!result) return downloadInfo = result } @@ -582,52 +557,152 @@ const actions = { await dispatch('handleStartTask', downloadInfo) } }, - startTasks(store, list) { - if (isRuningActionTask) return - isRuningActionTask = true - return startTasks(store, list.filter(item => !(item.isComplate || item.status == state.downloadStatus.RUN || item.status == state.downloadStatus.WAITING))).finally(() => { - isRuningActionTask = false - }) + startTasks({ commit, rootState, dispatch }, list) { + list = list.filter(item => !(item.isComplate || item.status == state.downloadStatus.RUN || item.status == state.downloadStatus.WAITING)) + commit('setStatus', { list, status: state.downloadStatus.WAITING }) + let result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + while (result) { + dispatch('startTask', result) + result = getStartTask(state.list, state.downloadStatus, rootState.setting.download.maxDownloadNum) + } }, - async pauseTask(store, item) { + async pauseTask({ commit }, item) { if (item.isComplate) return let dl = dls[item.key] - if (dl) { - try { - await dl.stop() - } catch (_) {} - } - store.commit('pauseTask', item) + if (dl) dl.stop() + commit('setStatus', { downloadInfo: item, status: state.downloadStatus.PAUSE }) }, - pauseTasks(store, list) { - if (isRuningActionTask) return - isRuningActionTask = true - return pauseTasks(store, [...list]).finally(() => { - isRuningActionTask = false - }) + pauseTasks({ commit, rootState, dispatch }, list) { + const waitingTasks = list.filter(item => item.status == state.downloadStatus.WAITING) + commit('setStatus', { list: waitingTasks, status: state.downloadStatus.PAUSE }) + const runningTasks = list.filter(item => item.status == state.downloadStatus.RUN) + for (const item of runningTasks) { + if (item.isComplate) return + let dl = dls[item.key] + if (dl) dl.stop() + } + commit('setStatus', { list: runningTasks, status: state.downloadStatus.PAUSE }) }, } // mitations const mutations = { - addTask(state, downloadInfo) { - state.list.unshift(downloadInfo) + addTask(state, { downloadInfo, musicInfo, addMusicLocationType }) { + const downloadInfoFull = { ...downloadInfo, musicInfo } + window.downloadListFullMap.set(downloadInfo.key, downloadInfoFull) + switch (addMusicLocationType) { + case 'top': + window.downloadListFull.unshift(downloadInfoFull) + state.list.unshift(downloadInfo) + break + case 'bottom': + default: + window.downloadListFull.push(downloadInfoFull) + state.list.push(downloadInfo) + break + } + }, + addTasks(state, { list, addMusicLocationType }) { + const downloadInfoList = [] + const curDownloadListFull = [] + for (const { downloadInfo, musicInfo } of list) { + downloadInfoList.push(downloadInfo) + curDownloadListFull.push({ ...downloadInfo, musicInfo }) + } + let newList + let newListFull + const map = {} + const fullMap = {} + const ids = [] + switch (addMusicLocationType) { + case 'top': + newList = [...downloadInfoList, ...state.list] + newListFull = [...curDownloadListFull, ...window.downloadListFull] + for (let i = newList.length - 1; i > -1; i--) { + const item = newList[i] + if (map[item.key]) continue + ids.unshift(item.key) + map[item.key] = item + fullMap[item.key] = newListFull[i] + } + break + case 'bottom': + default: + newList = [...state.list, ...downloadInfoList] + newListFull = [...window.downloadListFull, ...curDownloadListFull] + newList.forEach((item, index) => { + if (map[item.key]) return + ids.push(item.key) + map[item.key] = item + fullMap[item.key] = newListFull[index] + }) + break + } + window.downloadListFullMap.clear() + window.downloadListFull = ids.map(id => { + const info = fullMap[id] + window.downloadListFullMap.set(info.key, info) + return info + }) + state.list.splice(0, state.list.length, ...ids.map(id => map[id])) }, removeTask({ list }, downloadInfo) { - list.splice(list.indexOf(downloadInfo), 1) + const index = list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + window.downloadListFull.splice(index, 1) + window.downloadListFullMap.delete(downloadInfo.key) + list.splice(index, 1) + }, + removeTasks(state, list) { + let map = {} + let ids = [] + for (const item of state.list) { + ids.push(item.key) + map[item.key] = item + } + for (const { key } of list) { + if (map[key]) delete map[key] + } + let newList = [] + let newListFull = [] + for (const id of ids) { + if (map[id]) { + newList.push(map[id]) + newListFull.push(window.downloadListFullMap.get(id)) + } + } + + window.downloadListFull = newListFull + window.downloadListFullMap.clear() + for (const item of newListFull) { + window.downloadListFullMap.set(item.key, item) + } + state.list.splice(0, state.list.length, ...newList) }, pauseTask(state, downloadInfo) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.status = state.downloadStatus.PAUSE + downloadInfoFull.statusText = '暂停下载' + downloadInfo.status = state.downloadStatus.PAUSE downloadInfo.statusText = '暂停下载' }, setStatusText(state, { downloadInfo, index, text }) { // 设置状态文本 if (downloadInfo) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + if (downloadInfoFull) downloadInfoFull.statusText = text downloadInfo.statusText = text } else { state.list[index].statusText = text + const downloadInfoFull = window.downloadListFull[index] + if (downloadInfoFull) downloadInfoFull.statusText = text } }, - setStatus(state, { downloadInfo, index, status }) { // 设置状态及状态文本 + setStatus(state, { downloadInfo, index, status, list }) { // 设置状态及状态文本 let text switch (status) { case state.downloadStatus.RUN: @@ -646,43 +721,107 @@ const mutations = { text = '下载完成' break } - if (downloadInfo) { - downloadInfo.statusText = text - downloadInfo.status = status + if (list) { + for (const downloadInfo of list) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.statusText = text + downloadInfoFull.status = status + + downloadInfo.statusText = text + downloadInfo.status = status + } } else { - state.list[index].statusText = text - state.list[index].status = status + if (downloadInfo) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.statusText = text + downloadInfoFull.status = status + + downloadInfo.statusText = text + downloadInfo.status = status + } else { + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.statusText = text + downloadInfoFull.status = status + + state.list[index].statusText = text + state.list[index].status = status + } } }, onCompleted(state, downloadInfo) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + console.log(index) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.isComplate = true + downloadInfoFull.status = state.downloadStatus.COMPLETED + downloadInfoFull.statusText = '下载完成' + + downloadInfo.isComplate = true downloadInfo.status = state.downloadStatus.COMPLETED downloadInfo.statusText = '下载完成' }, onError(state, { downloadInfo, errorMsg }) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.status = state.downloadStatus.ERROR + downloadInfoFull.statusText = errorMsg || '任务出错' + downloadInfo.status = state.downloadStatus.ERROR downloadInfo.statusText = errorMsg || '任务出错' }, onStart(state, downloadInfo) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.status = state.downloadStatus.RUN + downloadInfoFull.statusText = '正在下载' + downloadInfo.status = state.downloadStatus.RUN downloadInfo.statusText = '正在下载' }, onProgress(state, { downloadInfo, status }) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.progress.progress = status.progress + downloadInfoFull.progress.downloaded = status.downloaded + downloadInfoFull.progress.total = status.total + downloadInfo.progress.progress = status.progress downloadInfo.progress.downloaded = status.downloaded downloadInfo.progress.total = status.total }, - setTotal(state, { order, downloadInfo }) { - downloadInfo.order = order - }, updateDownloadList(state, list) { - state.list = window.downloadList = list + window.downloadListFullMap.clear() + const stateList = list.map(downloadInfoFull => { + window.downloadListFullMap.set(downloadInfoFull.key, downloadInfoFull) + const downloadInfo = { ...downloadInfoFull } + delete downloadInfo.musicInfo + return downloadInfo + }) + window.downloadListFull = list + state.list = window.downloadList = stateList }, updateUrl(state, { downloadInfo, url }) { + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.url = url downloadInfo.url = url }, updateFilePath(state, { downloadInfo, filePath }) { if (downloadInfo.filePath === filePath) return + const index = state.list.findIndex(m => m.key == downloadInfo.key) + if (index < 0) return + const downloadInfoFull = window.downloadListFull[index] + downloadInfoFull.filePath = filePath downloadInfo.filePath = filePath }, } diff --git a/src/renderer/store/modules/player.js b/src/renderer/store/modules/player.js index e18ffadd..e7ea4fad 100644 --- a/src/renderer/store/modules/player.js +++ b/src/renderer/store/modules/player.js @@ -155,15 +155,23 @@ const getters = { let listPlayIndex = Math.min(state.playIndex, state.listInfo.list.length - 1) if (listId != '__temp__') { - const currentSongmid = state.playMusicInfo.musicInfo.songmid || state.playMusicInfo.musicInfo.musicInfo.songmid - if (isPlayList) { - playIndex = state.listInfo.list.findIndex(m => (m.songmid || m.musicInfo.songmid) == currentSongmid) - if (!isTempPlay) listPlayIndex = playIndex - } else if (listId == 'download') { - playIndex = window.downloadList.findIndex(m => m.musicInfo.songmid == currentSongmid) + if (state.playMusicInfo.musicInfo.key) { + const currentKey = state.playMusicInfo.musicInfo.key + if (isPlayList) { + playIndex = state.listInfo.list.findIndex(m => m.key == currentKey) + if (!isTempPlay) listPlayIndex = playIndex + } else if (listId == 'download') { + playIndex = window.downloadList.findIndex(m => m.key == currentKey) + } } else { - let list = window.allList[listId] - if (list) playIndex = list.list.findIndex(m => m.songmid == currentSongmid) + const currentSongmid = state.playMusicInfo.musicInfo.songmid || state.playMusicInfo.musicInfo.musicInfo.songmid + if (isPlayList) { + playIndex = state.listInfo.list.findIndex(m => m.songmid == currentSongmid) + if (!isTempPlay) listPlayIndex = playIndex + } else { + let list = window.allList[listId] + if (list) playIndex = list.list.findIndex(m => m.songmid == currentSongmid) + } } } if (listPlayIndex >= 0) prevListPlayIndex = listPlayIndex @@ -186,6 +194,8 @@ const getters = { // isTempPlay, // // musicInfo: state.playMusicInfo.musicInfo, // }) + + console.log(state.playMusicInfo) return { listId, playIndex, diff --git a/src/renderer/views/Download.vue b/src/renderer/views/Download.vue index 0a89dcde..bb9c6bcc 100644 --- a/src/renderer/views/Download.vue +++ b/src/renderer/views/Download.vue @@ -20,10 +20,10 @@ div(:class="$style.download") div.list-item(@click="handleDoubleClick($event, index)" @contextmenu="handleListItemRigthClick($event, index)" :class="[{[$style.active]: playListIndex == index }, { selected: selectedIndex == index }, { active: selectedData.includes(item) }]") div.list-item-cell.nobreak.center(style="width: 5%; padding-left: 3px; padding-right: 3px;" @click.stop) {{index + 1}} - div.list-item-cell.auto - span.select {{item.musicInfo.name}} - {{item.musicInfo.singer}} + div.list-item-cell.auto(:tips="item.name") + span.select {{item.name}} div.list-item-cell(style="width: 20%;") {{item.progress.progress}}% - div.list-item-cell(style="width: 22%;") {{item.statusText}} + div.list-item-cell(style="width: 22%;" :tips="item.statusText") {{item.statusText}} div.list-item-cell(style="width: 10%;") {{item.type && item.type.toUpperCase()}} div.list-item-cell(style="width: 13%; padding-left: 0; padding-right: 0;") material-list-buttons(:index="index" :download-btn="false" :file-btn="item.status != downloadStatus.ERROR" remove-btn @@ -309,7 +309,7 @@ export default { this.handleOpenFolder(item.filePath) break case 'search': - this.handleSearch(item.musicInfo) + this.handleSearch(window.downloadListFullMap.get(item.key).musicInfo) break } }, @@ -350,7 +350,8 @@ export default { this.selectedData = [] }, handleListItemRigthClick(event, index) { - this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[this.showList[index].musicInfo.source].getMusicDetailPageUrl + const downloadInfo = window.downloadListFullMap.get(this.showList[index].key) + this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[downloadInfo.musicInfo.source].getMusicDetailPageUrl let dom_container = event.target.closest('.' + this.$style.download) const getOffsetValue = (target, x = 0, y = 0) => { if (target === dom_container) return { x, y } @@ -442,7 +443,7 @@ export default { break case 'search': item = this.showList[index] - if (item) this.handleSearch(item.musicInfo) + if (item) this.handleSearch(window.downloadListFullMap.get(item.key).musicInfo) break case 'remove': if (this.selectedData.length) { @@ -466,7 +467,7 @@ export default { } break case 'sourceDetail': - item = this.showList[index].musicInfo + item = window.downloadListFullMap.get(this.showList[index].key).musicInfo url = musicSdk[item.source].getMusicDetailPageUrl(item) if (!url) return openUrl(url)