commit
1cf0f2dd0b
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -6,6 +6,25 @@ Project versioning adheres to [Semantic Versioning](http://semver.org/).
|
|||
Commit convention is based on [Conventional Commits](http://conventionalcommits.org).
|
||||
Change log format is based on [Keep a Changelog](http://keepachangelog.com/).
|
||||
|
||||
## [1.15.1](https://github.com/lyswhut/lx-music-desktop/compare/v1.15.0...v1.15.1) - 2021-11-09
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化我的列表、下载列表等列表的滚动流畅度
|
||||
- 优化下载功能的批量添加、删除、暂停任务时的流畅度,现在进行这些操作应该不会再觉得卡顿了
|
||||
- 支持启动软件时恢复播放下载列表里的歌曲
|
||||
- 添加媒体播放进度条的信息设置
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复某些情况下获取URL失败时会意外切歌的问题
|
||||
- 修复了某些情况下会列表同步失败,导致连接断开无限重连或一直卡在 `syncing...` 的问题
|
||||
- 修复列表数据过大导致同步失败的问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新electron到v15.3.1(这修复了媒体控制失效的问题)
|
||||
|
||||
## [1.15.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.14.1...v1.15.0) - 2021-10-29
|
||||
|
||||
### 新增
|
||||
|
|
4
FAQ.md
4
FAQ.md
|
@ -56,6 +56,8 @@
|
|||
|
||||
播放在线列表内的歌曲需要将它们都添加到我的列表才能播放,你可以全选列表内的歌曲然后添加到现有列表或者新创建的列表,然后去播放该列表内的歌曲。
|
||||
|
||||
从v1.10.0起,你可以右击排行榜名字的弹出菜单中直接播放或收藏整个排行榜的歌曲。
|
||||
|
||||
## 无法打开外部歌单
|
||||
|
||||
不支持跨源打开歌单,请**确认**你需要打开的歌单平台是否与软件标签所写的**歌单源**对应(不一样的话请通过右上角切换歌单源);<br>
|
||||
|
@ -142,7 +144,7 @@
|
|||
|
||||
注:v1.6.0及之后的版本才支持`-dha`参数
|
||||
|
||||
## Window 7 下软件启动后,界面无法显示
|
||||
## Windows 7 下软件启动后,界面无法显示
|
||||
|
||||
对于软件启动后,可以在任务栏看到软件,但软件界面在桌面上无任何显示,或者整个界面偶尔闪烁的情况。<br>
|
||||
原始问题看:<https://github.com/electron/electron/issues/19569#issuecomment-522231083><br>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "1.15.0",
|
||||
"version": "1.15.1",
|
||||
"description": "一个免费的音乐查找助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
|
@ -167,31 +167,31 @@
|
|||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.15.8",
|
||||
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.16.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-modules-umd": "^7.14.5",
|
||||
"@babel/plugin-transform-runtime": "^7.15.8",
|
||||
"@babel/plugin-transform-modules-umd": "^7.16.0",
|
||||
"@babel/plugin-transform-runtime": "^7.16.0",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/preset-env": "^7.15.8",
|
||||
"@babel/preset-env": "^7.16.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.2.3",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"browserslist": "^4.17.5",
|
||||
"browserslist": "^4.17.6",
|
||||
"cfonts": "^2.10.0",
|
||||
"chalk": "^4.1.2",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^9.0.1",
|
||||
"core-js": "^3.19.0",
|
||||
"core-js": "^3.19.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^6.5.0",
|
||||
"css-minimizer-webpack-plugin": "^3.1.1",
|
||||
"css-loader": "^6.5.1",
|
||||
"css-minimizer-webpack-plugin": "^3.1.2",
|
||||
"del": "^6.0.0",
|
||||
"electron": "^15.3.0",
|
||||
"electron": "^15.3.1",
|
||||
"electron-builder": "^22.11.7",
|
||||
"electron-debug": "^3.2.0",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-to-chromium": "^1.3.884",
|
||||
"electron-to-chromium": "^1.3.891",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-standard": "^16.0.3",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
|
@ -208,7 +208,7 @@
|
|||
"less-loader": "^10.2.0",
|
||||
"less-plugin-clean-css": "^1.5.1",
|
||||
"markdown-it": "^12.2.0",
|
||||
"mini-css-extract-plugin": "^2.4.3",
|
||||
"mini-css-extract-plugin": "^2.4.4",
|
||||
"node-loader": "^2.0.0",
|
||||
"postcss": "^8.3.11",
|
||||
"postcss-loader": "^6.2.0",
|
||||
|
@ -219,11 +219,11 @@
|
|||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"spinnies": "^0.5.1",
|
||||
"terser-webpack-plugin": "^5.2.4",
|
||||
"terser-webpack-plugin": "^5.2.5",
|
||||
"url-loader": "^4.1.1",
|
||||
"vue-loader": "^15.9.8",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"webpack": "^5.60.0",
|
||||
"webpack": "^5.62.1",
|
||||
"webpack-cli": "^4.9.1",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-hot-middleware": "^2.25.1",
|
||||
|
@ -240,14 +240,14 @@
|
|||
"iconv-lite": "^0.6.3",
|
||||
"image-size": "^1.0.0",
|
||||
"koa": "^2.13.4",
|
||||
"long": "^5.0.1",
|
||||
"long": "^5.1.0",
|
||||
"needle": "^3.0.0",
|
||||
"node-id3": "^0.2.3",
|
||||
"request": "^2.88.2",
|
||||
"socket.io": "^4.3.1",
|
||||
"socket.io": "^4.3.2",
|
||||
"utf-8-validate": "^5.0.7",
|
||||
"vue": "^2.6.14",
|
||||
"vue-i18n": "^8.26.5",
|
||||
"vue-i18n": "^8.26.7",
|
||||
"vue-router": "^3.5.3",
|
||||
"vuex": "^3.6.2"
|
||||
}
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
### 新增
|
||||
|
||||
- 添加黑色托盘图标
|
||||
- 自定义源新增`version`字段,新增`utils.buffer.bufToString`方法
|
||||
|
||||
### 优化
|
||||
|
||||
- 大幅优化我的列表、下载、歌单、排行榜列表性能,现在即使同一列表内的歌曲很多时也不会卡顿了
|
||||
- 优化列表同步代码逻辑
|
||||
- 优化开关评论时的动画性能
|
||||
- 优化进入、离开播放详情页的性能
|
||||
- 兼容桌面歌词以触摸的方式移动、调整大小
|
||||
- 调整图标尺寸
|
||||
- 优化我的列表、下载列表等列表的滚动流畅度
|
||||
- 优化下载功能的批量添加、删除、暂停任务时的流畅度,现在进行这些操作应该不会再觉得卡顿了
|
||||
- 支持启动软件时恢复播放下载列表里的歌曲
|
||||
- 添加媒体播放进度条的信息设置
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复kg源的歌单链接无法打开的问题
|
||||
- 修复同一首歌的URL、歌词等同时需要换源时的处理问题
|
||||
- 修复某些情况下获取URL失败时会意外切歌的问题
|
||||
- 修复了某些情况下会列表同步失败,导致连接断开无限重连或一直卡在 `syncing...` 的问题
|
||||
- 修复列表数据过大导致同步失败的问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新 Electron 到 v15.3.0
|
||||
- 更新electron到v15.3.1(这修复了媒体控制失效的问题)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -153,8 +153,6 @@ exports.initSetting = isShowErrorAlert => {
|
|||
// 迁移列表滚动位置设置 ~0.18.3
|
||||
if (setting.list.scroll) {
|
||||
let scroll = setting.list.scroll
|
||||
// electronStore_list.set('defaultList.location', scroll.locations.default || 0)
|
||||
// electronStore_list.set('loveList.location', scroll.locations.love || 0)
|
||||
electronStore_config.delete('setting.list.scroll')
|
||||
electronStore_config.set('setting.list.isSaveScrollLocation', scroll.enable)
|
||||
delete setting.list.scroll
|
||||
|
|
|
@ -46,7 +46,7 @@ const { isMac, isLinux, initHotKey } = require('../common/utils')
|
|||
// https://github.com/electron/electron/issues/18397
|
||||
// 开发模式下为true时 多次引入native模块会导致渲染进程卡死
|
||||
// https://github.com/electron/electron/issues/22791
|
||||
app.allowRendererProcessReuse = !isDev
|
||||
// app.allowRendererProcessReuse = !isDev
|
||||
|
||||
|
||||
app.on('web-contents-created', (event, contents) => {
|
||||
|
|
|
@ -72,7 +72,7 @@ const handleStartServer = (port = 9527) => new Promise((resolve, reject) => {
|
|||
serveClient: false,
|
||||
connectTimeout: 10000,
|
||||
pingTimeout: 30000,
|
||||
maxHttpBufferSize: 3e6,
|
||||
maxHttpBufferSize: 1e9, // 1G
|
||||
allowRequest: authConnection,
|
||||
transports: ['websocket'],
|
||||
})
|
||||
|
|
|
@ -11,6 +11,22 @@ let io
|
|||
let syncingId = null
|
||||
const wait = (time = 1000) => new Promise((resolve, reject) => setTimeout(resolve, time))
|
||||
|
||||
const patchListData = listData => {
|
||||
return Object.assign({}, {
|
||||
defaultList: {
|
||||
id: 'default',
|
||||
name: '试听列表',
|
||||
list: [],
|
||||
},
|
||||
loveList: {
|
||||
id: 'love',
|
||||
name: '我的收藏',
|
||||
list: [],
|
||||
},
|
||||
userList: [],
|
||||
}, listData)
|
||||
}
|
||||
|
||||
const getRemoteListData = socket => new Promise((resolve, reject) => {
|
||||
console.log('getRemoteListData')
|
||||
const handleError = reason => {
|
||||
|
@ -23,7 +39,7 @@ const getRemoteListData = socket => new Promise((resolve, reject) => {
|
|||
const data = JSON.parse(decryptMsg(socket.data.keyInfo, enData))
|
||||
if (!data) return reject(new Error('Get remote list data failed'))
|
||||
if (data.action != 'getData') return
|
||||
resolve(data.data)
|
||||
resolve(patchListData(data.data))
|
||||
}
|
||||
|
||||
socket.on('disconnect', handleError)
|
||||
|
@ -35,7 +51,7 @@ const getLocalListData = () => new Promise((resolve, reject) => {
|
|||
const handleSuccess = ({ action, data }) => {
|
||||
if (action !== 'getData') return
|
||||
global.lx_event.sync.off(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
|
||||
resolve(data)
|
||||
resolve(patchListData(data))
|
||||
}
|
||||
global.lx_event.sync.on(SYNC_EVENT_NAMES.sync_handle_list, handleSuccess)
|
||||
global.lx_event.sync.sync_list({
|
||||
|
@ -87,10 +103,10 @@ const updateSnapshot = (path, data) => {
|
|||
}
|
||||
|
||||
|
||||
const createListDataObj = listData => {
|
||||
const listDataObj = {}
|
||||
for (const list of listData.userList) listDataObj[list.id] = list
|
||||
return listDataObj
|
||||
const createUserListDataObj = listData => {
|
||||
const userListDataObj = {}
|
||||
for (const list of listData.userList) userListDataObj[list.id] = list
|
||||
return userListDataObj
|
||||
}
|
||||
|
||||
const handleMergeList = (sourceList, targetList, addMusicLocationType) => {
|
||||
|
@ -137,11 +153,11 @@ const mergeList = (sourceListData, targetListData) => {
|
|||
newListData.defaultList = handleMergeList(sourceListData.defaultList, targetListData.defaultList, addMusicLocationType)
|
||||
newListData.loveList = handleMergeList(sourceListData.loveList, targetListData.loveList, addMusicLocationType)
|
||||
|
||||
const listDataObj = createListDataObj(sourceListData)
|
||||
const userListDataObj = createUserListDataObj(sourceListData)
|
||||
newListData.userList = [...sourceListData.userList]
|
||||
|
||||
for (const list of targetListData.userList) {
|
||||
const targetList = listDataObj[list.id]
|
||||
const targetList = userListDataObj[list.id]
|
||||
if (targetList) {
|
||||
targetList.list = handleMergeList(targetList, list, addMusicLocationType).list
|
||||
} else {
|
||||
|
@ -156,11 +172,11 @@ const overwriteList = (sourceListData, targetListData) => {
|
|||
newListData.defaultList = sourceListData.defaultList
|
||||
newListData.loveList = sourceListData.loveList
|
||||
|
||||
const listDataObj = createListDataObj(sourceListData)
|
||||
const userListDataObj = createUserListDataObj(sourceListData)
|
||||
newListData.userList = [...sourceListData.userList]
|
||||
|
||||
for (const list of targetListData.userList) {
|
||||
const targetList = listDataObj[list.id]
|
||||
const targetList = userListDataObj[list.id]
|
||||
if (targetList) continue
|
||||
newListData.userList.push(list)
|
||||
}
|
||||
|
@ -259,8 +275,10 @@ const mergeListDataFromSnapshot = (sourceList, targetList, snapshotList, addMusi
|
|||
const targetListItemIds = new Set()
|
||||
for (const m of sourceList.list) sourceListItemIds.add(m.songmid)
|
||||
for (const m of targetList.list) targetListItemIds.add(m.songmid)
|
||||
for (const m of snapshotList.list) {
|
||||
if (!sourceListItemIds.has(m.songmid) || !targetListItemIds.has(m.songmid)) removedListIds.add(m.songmid)
|
||||
if (snapshotList) {
|
||||
for (const m of snapshotList.list) {
|
||||
if (!sourceListItemIds.has(m.songmid) || !targetListItemIds.has(m.songmid)) removedListIds.add(m.songmid)
|
||||
}
|
||||
}
|
||||
|
||||
let newList
|
||||
|
@ -294,13 +312,12 @@ const mergeListDataFromSnapshot = (sourceList, targetList, snapshotList, addMusi
|
|||
const handleMergeListDataFromSnapshot = async(socket, snapshot) => {
|
||||
const addMusicLocationType = global.appSetting.list.addMusicLocationType
|
||||
const [remoteListData, localListData] = await Promise.all([getRemoteListData(socket), getLocalListData()])
|
||||
console.log('handleMergeListDataFromSnapshot', 'remoteListData, localListData')
|
||||
const newListData = {}
|
||||
newListData.defaultList = mergeListDataFromSnapshot(localListData.defaultList, remoteListData.defaultList, snapshot.defaultList, addMusicLocationType)
|
||||
newListData.loveList = mergeListDataFromSnapshot(localListData.loveList, remoteListData.loveList, snapshot.loveList, addMusicLocationType)
|
||||
const localUserListData = createListDataObj(localListData)
|
||||
const remoteUserListData = createListDataObj(remoteListData)
|
||||
const snapshotUserListData = createListDataObj(snapshot)
|
||||
const localUserListData = createUserListDataObj(localListData)
|
||||
const remoteUserListData = createUserListDataObj(remoteListData)
|
||||
const snapshotUserListData = createUserListDataObj(snapshot)
|
||||
const removedListIds = new Set()
|
||||
const localUserListIds = new Set()
|
||||
const remoteUserListIds = new Set()
|
||||
|
@ -367,7 +384,7 @@ const syncList = async socket => {
|
|||
}
|
||||
console.log('isSyncRequired', isSyncRequired)
|
||||
if (isSyncRequired) return handleSyncList(socket)
|
||||
return handleMergeListDataFromSnapshot(socket, fileData)
|
||||
return handleMergeListDataFromSnapshot(socket, patchListData(fileData))
|
||||
}
|
||||
|
||||
const checkSyncQueue = async() => {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
},
|
||||
|
@ -399,10 +404,17 @@ export default {
|
|||
if (!info) return
|
||||
if (info.index < 0) return
|
||||
if (info.listId) {
|
||||
const list = window.allList[info.listId]
|
||||
// console.log(list)
|
||||
if (!list || !list.list[info.index]) return
|
||||
info.list = list.list
|
||||
if (info.listId == 'download') {
|
||||
const list = this.downloadList
|
||||
// console.log(list)
|
||||
if (!list || !list[info.index]) return
|
||||
info.list = list
|
||||
} else {
|
||||
const list = window.allList[info.listId]
|
||||
// console.log(list)
|
||||
if (!list || !list.list[info.index]) return
|
||||
info.list = list.list
|
||||
}
|
||||
}
|
||||
if (!info.list || !info.list[info.index]) return
|
||||
window.restorePlayInfo = info
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
@ -416,6 +417,8 @@ export default {
|
|||
if (!this.targetSong.interval && this.listId != 'download') {
|
||||
this.updateMusicInfo({ listId: this.listId, id: this.targetSong.songmid, musicInfo: this.targetSong, data: { interval: formatPlayTime2(this.maxPlayTime) } })
|
||||
}
|
||||
|
||||
this.updatePositionState()
|
||||
})
|
||||
audio.addEventListener('loadstart', () => {
|
||||
console.log('loadstart')
|
||||
|
@ -430,6 +433,7 @@ export default {
|
|||
audio.currentTime = playTime
|
||||
}
|
||||
this.clearBufferTimeout()
|
||||
this.updatePositionState()
|
||||
|
||||
// if (this.musicInfo.lrc) window.lrc.play(audio.currentTime * 1000)
|
||||
this.status = this.statusText = ''
|
||||
|
@ -483,9 +487,8 @@ export default {
|
|||
},
|
||||
async play() {
|
||||
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,24 +500,26 @@ 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)
|
||||
} 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
|
||||
this.musicInfo.album = targetSong.albumName
|
||||
this.setUrl(targetSong)
|
||||
this.setImg(targetSong)
|
||||
this.setLrc(targetSong)
|
||||
}
|
||||
|
||||
this.updateMediaSessionInfo()
|
||||
this.setImg(targetSong)
|
||||
this.setLrc(targetSong)
|
||||
this.handleUpdateWinLyricInfo('music_info', {
|
||||
songmid: this.musicInfo.songmid,
|
||||
singer: this.musicInfo.singer,
|
||||
|
@ -592,11 +597,25 @@ export default {
|
|||
window.getComputedStyle(this.$refs.dom_progress, null).width,
|
||||
)
|
||||
},
|
||||
togglePlay() {
|
||||
async togglePlay() {
|
||||
if (!audio.src) {
|
||||
if (this.restorePlayTime != null) {
|
||||
// if (!this.assertApiSupport(this.targetSong.source)) return this.playNext()
|
||||
this.setUrl(this.targetSong)
|
||||
if (this.listId == 'download') {
|
||||
const filePath = path.join(this.setting.download.savePath, this.targetSong.fileName)
|
||||
// console.log(filePath)
|
||||
if (!await checkPath(filePath) || !this.targetSong.isComplate || /\.ape$/.test(filePath)) {
|
||||
if (this.list.length == 1) {
|
||||
this.handleRemoveMusic()
|
||||
} else {
|
||||
this.playNext()
|
||||
}
|
||||
return
|
||||
}
|
||||
audio.src = filePath
|
||||
} else {
|
||||
// if (!this.assertApiSupport(this.targetSong.source)) return this.playNext()
|
||||
this.setUrl(this.targetSong)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -634,6 +653,7 @@ export default {
|
|||
audio.src = this.musicInfo.url = url
|
||||
}).catch(err => {
|
||||
// console.log('err', err.message)
|
||||
if (targetSong !== this.targetSong || this.isPlay) return
|
||||
if (err.message == requestMsg.cancelRequest) return
|
||||
if (!isRetryed) return this.setUrl(targetSong, isRefresh, true)
|
||||
this.status = this.statusText = err.message
|
||||
|
@ -676,8 +696,10 @@ export default {
|
|||
})
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
if (targetSong.songmid !== this.musicInfo.songmid) return
|
||||
this.status = this.statusText = this.$t('core.player.lyric_error')
|
||||
}).finally(() => {
|
||||
if (targetSong.songmid !== this.musicInfo.songmid) return
|
||||
this.handleUpdateWinLyricInfo('lyric', { lrc: this.musicInfo.lrc, tlrc: this.musicInfo.tlrc, lxlrc: this.musicInfo.lxlrc })
|
||||
this.setLyric()
|
||||
})
|
||||
|
@ -701,6 +723,7 @@ export default {
|
|||
this.lyric.text = 0
|
||||
this.handleUpdateWinLyricInfo('lines', [])
|
||||
this.handleUpdateWinLyricInfo('line', 0)
|
||||
this.currentMusicInfo = {}
|
||||
},
|
||||
sendProgressEvent(status, mode) {
|
||||
// console.log(status)
|
||||
|
@ -757,7 +780,7 @@ export default {
|
|||
this.setProgressWidth()
|
||||
},
|
||||
handleToMusicLocation() {
|
||||
if (!this.listId || this.listId == '__temp__' || this.listId == 'download') return
|
||||
if (!this.listId || this.listId == '__temp__' || this.listId == 'download' || !this.currentMusicInfo.songmid) return
|
||||
if (this.playIndex == -1) return
|
||||
this.$router.push({
|
||||
path: 'list',
|
||||
|
@ -768,7 +791,7 @@ export default {
|
|||
})
|
||||
},
|
||||
showPlayerDetail() {
|
||||
if (!this.targetSong) return
|
||||
if (!this.currentMusicInfo.songmid) return
|
||||
this.isShowPlayerDetail = true
|
||||
},
|
||||
handleTransitionEnd(e) {
|
||||
|
@ -912,8 +935,18 @@ export default {
|
|||
if (!this.musicInfo.songmid) return
|
||||
this.isShowAddMusicTo = true
|
||||
},
|
||||
handleRestorePlay(restorePlayInfo) {
|
||||
let musicInfo = this.list[restorePlayInfo.index]
|
||||
async handleRestorePlay(restorePlayInfo) {
|
||||
let musicInfo
|
||||
|
||||
if (this.listId == 'download') {
|
||||
this.currentMusicInfo = musicInfo = window.downloadListFullMap.get(this.list[restorePlayInfo.index].key).musicInfo
|
||||
// console.log(filePath)
|
||||
} else {
|
||||
// if (!this.assertApiSupport(targetSong.source)) return this.playNext()
|
||||
musicInfo = this.list[restorePlayInfo.index]
|
||||
this.currentMusicInfo = musicInfo
|
||||
}
|
||||
|
||||
this.musicInfo.songmid = musicInfo.songmid
|
||||
this.musicInfo.singer = musicInfo.singer
|
||||
this.musicInfo.name = musicInfo.name
|
||||
|
@ -936,13 +969,20 @@ 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)
|
||||
},
|
||||
updatePositionState() {
|
||||
navigator.mediaSession.setPositionState({
|
||||
duration: audio.duration,
|
||||
playbackRate: audio.playbackRate,
|
||||
position: audio.currentTime,
|
||||
})
|
||||
},
|
||||
registerMediaSessionHandler() {
|
||||
// navigator.mediaSession.setActionHandler('play', () => {
|
||||
// if (this.isPlay || !this.playMusicInfo) return
|
||||
|
|
|
@ -24,9 +24,9 @@ div(:class="$style.songList")
|
|||
span.select {{item.name}}
|
||||
span.badge.badge-theme-success(:class="[$style.labelQuality, $style.noSelect]" v-if="item._types.ape || item._types.flac || item._types.wav") {{$t('material.song_list.lossless')}}
|
||||
span.badge.badge-theme-info(:class="[$style.labelQuality, $style.noSelect]" v-else-if="item._types['320k']") {{$t('material.song_list.high_quality')}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r3 }")
|
||||
div.list-item-cell(:style="{ width: rowWidth.r3 }" :tips="item.singer")
|
||||
span.select {{item.singer}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r4 }")
|
||||
div.list-item-cell(:style="{ width: rowWidth.r4 }" :tips="item.albumName")
|
||||
span.select {{item.albumName}}
|
||||
div.list-item-cell(:style="{ width: rowWidth.r5 }")
|
||||
span(:class="[$style.time, $style.noSelect]") {{item.interval || '--/--'}}
|
||||
|
|
|
@ -82,7 +82,7 @@ export default {
|
|||
},
|
||||
outsideNum: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
default: 1,
|
||||
},
|
||||
itemHeight: {
|
||||
type: Number,
|
||||
|
@ -101,7 +101,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
views: [],
|
||||
isWaitingUpdate: false,
|
||||
startIndex: -1,
|
||||
endIndex: -1,
|
||||
scrollTop: 0,
|
||||
|
@ -138,16 +137,15 @@ export default {
|
|||
this.updateView()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$refs.dom_scrollContainer.removeEventListener('scroll', this.onScroll)
|
||||
if (this.cancelScroll) this.cancelScroll()
|
||||
},
|
||||
methods: {
|
||||
onScroll(event) {
|
||||
if (this.isWaitingUpdate) return
|
||||
this.isWaitingUpdate = true
|
||||
window.requestAnimationFrame(() => {
|
||||
this.updateView()
|
||||
this.isWaitingUpdate = false
|
||||
})
|
||||
const currentScrollTop = this.$refs.dom_scrollContainer.scrollTop
|
||||
if (Math.abs(currentScrollTop - this.scrollTop) > this.itemHeight * this.outsideNum * 0.6) {
|
||||
this.updateView(currentScrollTop)
|
||||
}
|
||||
this.$emit('scroll', event)
|
||||
},
|
||||
|
||||
|
@ -168,17 +166,18 @@ export default {
|
|||
return list
|
||||
},
|
||||
|
||||
updateView() {
|
||||
const currentScrollTop = this.$refs.dom_scrollContainer.scrollTop
|
||||
updateView(currentScrollTop = this.$refs.dom_scrollContainer.scrollTop) {
|
||||
// const currentScrollTop = this.$refs.dom_scrollContainer.scrollTop
|
||||
const currentStartIndex = Math.floor(currentScrollTop / this.itemHeight)
|
||||
const currentEndIndex = currentStartIndex + Math.ceil(this.$refs.dom_scrollContainer.clientHeight / this.itemHeight)
|
||||
const scrollContainerHeight = this.$refs.dom_scrollContainer.clientHeight
|
||||
const currentEndIndex = currentStartIndex + Math.ceil(scrollContainerHeight / this.itemHeight)
|
||||
const continuous = currentStartIndex <= this.endIndex && currentEndIndex >= this.startIndex
|
||||
const currentStartRenderIndex = Math.max(Math.floor(currentScrollTop / this.itemHeight) - this.outsideNum, 0)
|
||||
const currentEndRenderIndex = currentStartIndex + Math.ceil(this.$refs.dom_scrollContainer.clientHeight / this.itemHeight) + this.outsideNum
|
||||
const currentEndRenderIndex = currentStartIndex + Math.ceil(scrollContainerHeight / this.itemHeight) + this.outsideNum
|
||||
// console.log(continuous)
|
||||
// debugger
|
||||
if (continuous) {
|
||||
if (Math.abs(currentScrollTop - this.scrollTop) < this.itemHeight * this.outsideNum * 0.6) return
|
||||
// if (Math.abs(currentScrollTop - this.scrollTop) < this.itemHeight * this.outsideNum * 0.6) return
|
||||
// console.log('update')
|
||||
if (currentScrollTop > this.scrollTop) { // scroll down
|
||||
// console.log('scroll down')
|
||||
|
@ -229,8 +228,8 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
scrollToIndex(index, offset = 0, animate = false, callback = () => {}) {
|
||||
return this.scrollTo(Math.max(index * this.itemHeight + offset, 0), animate, callback)
|
||||
scrollToIndex(index, offset = 0, animate = false) {
|
||||
return this.scrollTo(Math.max(index * this.itemHeight + offset, 0), animate)
|
||||
},
|
||||
|
||||
getScrollTop() {
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -28,19 +28,16 @@ const state = {
|
|||
id: 'default',
|
||||
name: '试听列表',
|
||||
list: [],
|
||||
location: 0,
|
||||
},
|
||||
loveList: {
|
||||
id: 'love',
|
||||
name: '我的收藏',
|
||||
list: [],
|
||||
location: 0,
|
||||
},
|
||||
tempList: {
|
||||
id: 'temp',
|
||||
name: '临时列表',
|
||||
list: [],
|
||||
location: 0,
|
||||
},
|
||||
userList: [],
|
||||
}
|
||||
|
@ -75,8 +72,8 @@ const actions = {
|
|||
// mitations
|
||||
const mutations = {
|
||||
initList(state, { defaultList, loveList, userList }) {
|
||||
if (defaultList != null) Object.assign(state.defaultList, { list: defaultList.list, location: defaultList.location })
|
||||
if (loveList != null) Object.assign(state.loveList, { list: loveList.list, location: loveList.location })
|
||||
if (defaultList != null) Object.assign(state.defaultList, { list: defaultList.list })
|
||||
if (loveList != null) Object.assign(state.loveList, { list: loveList.list })
|
||||
if (userList != null) state.userList = userList
|
||||
allListInit(state.defaultList, state.loveList, state.userList)
|
||||
state.isInitedList = true
|
||||
|
@ -104,18 +101,17 @@ const mutations = {
|
|||
state.userList = userList
|
||||
allListInit(state.defaultList, state.loveList, state.userList)
|
||||
},
|
||||
setList(state, { id, list, name, location, source, sourceListId, isSync }) {
|
||||
setList(state, { id, list, name, source, sourceListId, isSync }) {
|
||||
const targetList = allList[id]
|
||||
if (targetList) {
|
||||
if (name && targetList.name === name) {
|
||||
if (!isSync) {
|
||||
window.eventHub.$emit(eventSyncName.send_action_list, {
|
||||
action: 'set_list',
|
||||
data: { id, list, name, location, source, sourceListId },
|
||||
data: { id, list, name, source, sourceListId },
|
||||
})
|
||||
}
|
||||
targetList.list.splice(0, targetList.list.length, ...list)
|
||||
targetList.location = location
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -124,14 +120,13 @@ const mutations = {
|
|||
if (!isSync) {
|
||||
window.eventHub.$emit(eventSyncName.send_action_list, {
|
||||
action: 'set_list',
|
||||
data: { id, list, name, location, source, sourceListId },
|
||||
data: { id, list, name, source, sourceListId },
|
||||
})
|
||||
}
|
||||
let newList = {
|
||||
name,
|
||||
id,
|
||||
list,
|
||||
location,
|
||||
source,
|
||||
sourceListId,
|
||||
}
|
||||
|
@ -316,7 +311,6 @@ const mutations = {
|
|||
name,
|
||||
id,
|
||||
list: [],
|
||||
location: 0,
|
||||
source,
|
||||
sourceListId,
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ const filterList = async({ playedList, listInfo, savePath, commit }) => {
|
|||
canPlayList.push(item)
|
||||
|
||||
// 排除已播放音乐
|
||||
let index = filteredPlayedList.findIndex(m => (m.songmid || m.musicInfo.songmid) == item.musicInfo.songmid)
|
||||
let index = filteredPlayedList.findIndex(m => m.songmid == item.songmid)
|
||||
if (index > -1) {
|
||||
filteredPlayedList.splice(index, 1)
|
||||
continue
|
||||
|
@ -51,7 +51,7 @@ const filterList = async({ playedList, listInfo, savePath, commit }) => {
|
|||
// if (!assertApiSupport(s.source)) return false
|
||||
canPlayList.push(s)
|
||||
|
||||
let index = filteredPlayedList.findIndex(m => (m.songmid || m.musicInfo.songmid) == s.songmid)
|
||||
let index = filteredPlayedList.findIndex(m => m.songmid == s.songmid)
|
||||
if (index > -1) {
|
||||
filteredPlayedList.splice(index, 1)
|
||||
return false
|
||||
|
@ -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
|
||||
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,
|
||||
|
@ -265,16 +275,16 @@ const actions = {
|
|||
let currentSongmid
|
||||
if (state.playMusicInfo.isTempPlay) {
|
||||
const musicInfo = currentList[playInfo.listPlayIndex]
|
||||
if (musicInfo) currentSongmid = musicInfo.songmid || musicInfo.musicInfo.songmid
|
||||
if (musicInfo) currentSongmid = musicInfo.songmid
|
||||
} else {
|
||||
currentSongmid = state.playMusicInfo.musicInfo.songmid || state.playMusicInfo.musicInfo.musicInfo.songmid
|
||||
currentSongmid = state.playMusicInfo.musicInfo.songmid
|
||||
}
|
||||
// 从已播放列表移除播放列表已删除的歌曲
|
||||
let index
|
||||
for (index = state.playedList.findIndex(m => (m.musicInfo.songmid || m.musicInfo.musicInfo.songmid) === currentSongmid) - 1; index > -1; index--) {
|
||||
for (index = state.playedList.findIndex(m => m.musicInfo.songmid === currentSongmid) - 1; index > -1; index--) {
|
||||
const playMusicInfo = state.playedList[index]
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid || playMusicInfo.musicInfo.musicInfo.songmid
|
||||
if (playMusicInfo.listId == currentListId && !currentList.some(m => (m.songmid || m.musicInfo.songmid) === currentSongmid)) {
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid
|
||||
if (playMusicInfo.listId == currentListId && !currentList.some(m => m.songmid === currentSongmid)) {
|
||||
commit('removePlayedList', index)
|
||||
continue
|
||||
}
|
||||
|
@ -341,16 +351,16 @@ const actions = {
|
|||
let currentSongmid
|
||||
if (state.playMusicInfo.isTempPlay) {
|
||||
const musicInfo = currentList[playInfo.listPlayIndex]
|
||||
if (musicInfo) currentSongmid = musicInfo.songmid || musicInfo.musicInfo.songmid
|
||||
if (musicInfo) currentSongmid = musicInfo.songmid
|
||||
} else {
|
||||
currentSongmid = state.playMusicInfo.musicInfo.songmid || state.playMusicInfo.musicInfo.musicInfo.songmid
|
||||
currentSongmid = state.playMusicInfo.musicInfo.songmid
|
||||
}
|
||||
// 从已播放列表移除播放列表已删除的歌曲
|
||||
let index
|
||||
for (index = state.playedList.findIndex(m => (m.musicInfo.songmid || m.musicInfo.musicInfo.songmid) === currentSongmid) + 1; index < state.playedList.length; index++) {
|
||||
for (index = state.playedList.findIndex(m => m.musicInfo.songmid === currentSongmid) + 1; index < state.playedList.length; index++) {
|
||||
const playMusicInfo = state.playedList[index]
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid || playMusicInfo.musicInfo.musicInfo.songmid
|
||||
if (playMusicInfo.listId == currentListId && !currentList.some(m => (m.songmid || m.musicInfo.songmid) === currentSongmid)) {
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid
|
||||
if (playMusicInfo.listId == currentListId && !currentList.some(m => m.songmid === currentSongmid)) {
|
||||
commit('removePlayedList', index)
|
||||
continue
|
||||
}
|
||||
|
@ -473,8 +483,8 @@ const mutations = {
|
|||
} else {
|
||||
let listId = playMusicInfo.listId
|
||||
if (listId != '__temp__' && !playMusicInfo.isTempPlay && listId === state.listInfo.id) {
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid || playMusicInfo.musicInfo.musicInfo.songmid
|
||||
playIndex = state.listInfo.list.findIndex(m => (m.songmid || m.musicInfo.songmid) == currentSongmid)
|
||||
const currentSongmid = playMusicInfo.musicInfo.songmid
|
||||
playIndex = state.listInfo.list.findIndex(m => m.songmid == currentSongmid)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -43,12 +43,12 @@
|
|||
:class="[{ [$style.active]: isPlayList && playInfo.playIndex === index }, { selected: selectedIndex == index }, { active: selectdListDetailData.includes(item) }, { [$style.disabled]: !assertApiSupport(item.source) }]"
|
||||
@contextmenu="handleListItemRigthClick($event, index)")
|
||||
div.list-item-cell.nobreak.center(style="flex: 0 0 5%; padding-left: 3px; padding-right: 3px;" :class="$style.noSelect" @click.stop) {{index + 1}}
|
||||
div.list-item-cell.auto.break(:tips="item.name")
|
||||
div.list-item-cell.auto(:tips="item.name")
|
||||
span.select {{item.name}}
|
||||
span(:class="[$style.labelSource, $style.noSelect]" v-if="isShowSource") {{item.source}}
|
||||
div.list-item-cell.break(style="flex: 0 0 22%;")
|
||||
div.list-item-cell(style="flex: 0 0 22%;" :tips="item.singer")
|
||||
span.select {{item.singer}}
|
||||
div.list-item-cell.break(style="flex: 0 0 22%;")
|
||||
div.list-item-cell(style="flex: 0 0 22%;" :tips="item.albumName")
|
||||
span.select {{item.albumName}}
|
||||
div.list-item-cell(style="flex: 0 0 9%;")
|
||||
span(:class="[$style.time, $style.noSelect]") {{item.interval || '--/--'}}
|
||||
|
|
Loading…
Reference in New Issue