commit
0709aa56a4
|
@ -13,10 +13,13 @@ assignees: ''
|
|||
- [ ] 我已搜索issue列表(<https://github.com/lyswhut/lx-music-desktop/issues?utf8=✓&q=>)
|
||||
|
||||
**描述您想要的解决方案**
|
||||
简洁明了地描述您要发生的事情。
|
||||
<!-- 简洁明了地描述您要发生的事情。 -->
|
||||
|
||||
|
||||
**描述您考虑过的替代方案**
|
||||
对您考虑过的所有替代解决方案或功能的简洁明了的描述。
|
||||
<!-- 对您考虑过的所有替代解决方案或功能的简洁明了的描述。 -->
|
||||
|
||||
|
||||
**其他内容**
|
||||
在此处添加有关功能请求的任何其他上下文或屏幕截图(直接把图片拖到编辑框即可添加图片)。
|
||||
<!-- 在此处添加有关功能请求的任何其他上下文或屏幕截图(直接把图片拖到编辑框即可添加图片)。 -->
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@ assignees: ''
|
|||
- [ ] 我已搜索issue列表(<https://github.com/lyswhut/lx-music-desktop/issues?utf8=✓&q=>)
|
||||
|
||||
**描述错误**
|
||||
清楚简洁地说明错误是什么。
|
||||
<!-- 清楚简洁地说明错误是什么。 -->
|
||||
|
||||
|
||||
**重现**
|
||||
重现行为的步骤:
|
||||
|
@ -22,15 +23,20 @@ assignees: ''
|
|||
3.向下滚动到“ ....”
|
||||
4.看到错误
|
||||
|
||||
|
||||
**预期行为**
|
||||
对您期望发生的事情的简洁明了的描述。
|
||||
<!-- 对您期望发生的事情的简洁明了的描述。 -->
|
||||
|
||||
|
||||
**截图**
|
||||
如果适用,请添加屏幕截图以帮助解释您的问题(直接把图片拖到编辑框即可添加图片)。
|
||||
<!-- 如果适用,请添加屏幕截图以帮助解释您的问题(直接把图片拖到编辑框即可添加图片)。 -->
|
||||
|
||||
|
||||
**环境:**
|
||||
-操作系统及版本:[例如:Windows 10 64位 18362.156]
|
||||
-软件安装包及版本:[例如:Windows 64位绿色版 1.0.0]
|
||||
|
||||
|
||||
**其他内容**
|
||||
在此处添加有关该问题的任何其他上下文。
|
||||
<!-- 在此处添加有关该问题的任何其他上下文。 -->
|
||||
|
||||
|
|
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -6,6 +6,23 @@ 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.5.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.4.1...v1.5.0) - 2020-12-13
|
||||
|
||||
### 新增
|
||||
|
||||
- 直接从歌单详情收藏的列表新增同步功能。注意:这将会覆盖本地的目标列表,歌曲将被替换成最新的在线列表
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化软件启动时恢复上一次播放的歌曲进度功能
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复MAC平台上下载歌曲封面嵌入无法显示的问题
|
||||
- 修复MAC平台首次运行软件最小化、关闭控制按钮默认在右边的问题
|
||||
- 修复酷狗源的某些歌曲没有专辑字段导致的列表加载失败问题
|
||||
- 修复某些酷狗源歌单链接无法打开的问题
|
||||
|
||||
## [1.4.1](https://github.com/lyswhut/lx-music-desktop/compare/v1.4.0...v1.4.1) - 2020-11-25
|
||||
|
||||
|
||||
|
|
|
@ -9,9 +9,10 @@ module.exports = {
|
|||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/main'),
|
||||
events: path.join(__dirname, '../../src/main/events'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.json', '.node'],
|
||||
},
|
||||
|
|
|
@ -21,8 +21,11 @@ module.exports = {
|
|||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/renderer'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@static': path.join(__dirname, '../../src/static'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.json', '.vue', '.node'],
|
||||
},
|
||||
|
|
|
@ -21,8 +21,11 @@ module.exports = {
|
|||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.join(__dirname, '../../src/renderer'),
|
||||
common: path.join(__dirname, '../../src/common'),
|
||||
'@main': path.join(__dirname, '../../src/main'),
|
||||
'@renderer': path.join(__dirname, '../../src/renderer'),
|
||||
'@lyric': path.join(__dirname, '../../src/renderer-lyric'),
|
||||
'@static': path.join(__dirname, '../../src/static'),
|
||||
'@common': path.join(__dirname, '../../src/common'),
|
||||
},
|
||||
extensions: ['*', '.js', '.json', '.vue', '.node'],
|
||||
},
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
// This is the line you want to add
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@main": ["src/main"],
|
||||
"@renderer": ["src/renderer"],
|
||||
"@lyric": ["src/renderer-lyric"],
|
||||
"@static": ["src/static"],
|
||||
"@common": ["src/common"],
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules/**/*"]
|
||||
}
|
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "1.4.1",
|
||||
"version": "1.5.0",
|
||||
"description": "一个免费的音乐下载助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
|
@ -34,16 +34,18 @@
|
|||
"publish:gh:linux": "node build-config/pack.js && npm run publish:linux",
|
||||
"publish:linux": "npm run publish:linux:deb && npm run publish:linux:appImage && npm run publish:linux:rpm && npm run publish:linux:pacman",
|
||||
"publish:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage -p onTagOrDraft",
|
||||
"publish:linux:deb": "npm run publish:linux:deb:x64 && npm run publish:linux:deb:x86",
|
||||
"publish:linux:deb": "npm run publish:linux:deb:x64 && npm run publish:linux:deb:x86 && npm run publish:linux:deb:arm64",
|
||||
"publish:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64 -p onTagOrDraft",
|
||||
"publish:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32 -p onTagOrDraft",
|
||||
"publish:linux:deb:arm64": "cross-env ARCH=arm64 electron-builder -l=deb --arm64 -p onTagOrDraft",
|
||||
"publish:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm --x64 -p onTagOrDraft",
|
||||
"publish:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman --x64 -p onTagOrDraft",
|
||||
"pack:linux": "node build-config/pack.js && npm run pack:linux:deb && npm run pack:linux:appImage && npm run pack:linux:rpm && npm run pack:linux:pacman",
|
||||
"pack:linux:appImage": "cross-env ARCH=x64 electron-builder -l=AppImage",
|
||||
"pack:linux:deb": "npm run pack:linux:deb:x64 && npm run pack:linux:deb:x86",
|
||||
"pack:linux:deb": "npm run pack:linux:deb:x64 && npm run pack:linux:deb:x86 && npm run pack:linux:deb:arm64",
|
||||
"pack:linux:deb:x64": "cross-env ARCH=x64 electron-builder -l=deb --x64",
|
||||
"pack:linux:deb:x86": "cross-env ARCH=x86 electron-builder -l=deb --ia32",
|
||||
"pack:linux:deb:arm64": "cross-env ARCH=arm64 electron-builder -l=deb --arm64",
|
||||
"pack:linux:rpm": "cross-env ARCH=x64 electron-builder -l=rpm --x64",
|
||||
"pack:linux:pacman": "cross-env ARCH=x64 electron-builder -l=pacman --x64",
|
||||
"pack:mac": "node build-config/pack.js && electron-builder -m=dmg",
|
||||
|
@ -158,29 +160,29 @@
|
|||
},
|
||||
"homepage": "https://github.com/lyswhut/lx-music-desktop#readme",
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.3",
|
||||
"@babel/core": "^7.12.10",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-modules-umd": "^7.12.1",
|
||||
"@babel/plugin-transform-runtime": "^7.12.1",
|
||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||
"@babel/polyfill": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.1",
|
||||
"@babel/preset-env": "^7.12.10",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-loader": "^8.2.1",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-minify-webpack-plugin": "^0.3.1",
|
||||
"babel-preset-minify": "^0.5.1",
|
||||
"cfonts": "^2.8.6",
|
||||
"cfonts": "^2.9.0",
|
||||
"chalk": "^4.1.0",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^6.3.1",
|
||||
"core-js": "^3.7.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"copy-webpack-plugin": "^6.4.0",
|
||||
"core-js": "^3.8.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^4.3.0",
|
||||
"del": "^6.0.0",
|
||||
"electron": "^9.3.3",
|
||||
"electron-builder": "^22.9.1",
|
||||
"electron-debug": "^3.1.0",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"eslint": "^7.13.0",
|
||||
"eslint": "^7.15.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
|
@ -194,19 +196,19 @@
|
|||
"html-webpack-plugin": "^4.5.0",
|
||||
"less": "^3.12.2",
|
||||
"less-loader": "^7.1.0",
|
||||
"markdown-it": "^12.0.2",
|
||||
"markdown-it": "^12.0.3",
|
||||
"mini-css-extract-plugin": "^0.12.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||
"postcss-loader": "^4.0.4",
|
||||
"postcss-loader": "^4.1.0",
|
||||
"postcss-pxtorem": "^5.1.1",
|
||||
"pug": "^3.0.0",
|
||||
"pug-loader": "^2.4.0",
|
||||
"pug-plain-loader": "^1.0.0",
|
||||
"pug-plain-loader": "^1.1.0",
|
||||
"raw-loader": "^4.0.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"spinnies": "^0.5.1",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^4.3.0",
|
||||
"stylus-loader": "^4.3.1",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"vue-loader": "^15.9.5",
|
||||
|
@ -215,7 +217,7 @@
|
|||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.0",
|
||||
"webpack-hot-middleware": "^2.25.0",
|
||||
"webpack-merge": "^5.4.0"
|
||||
"webpack-merge": "^5.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"crypto-js": "^4.0.0",
|
||||
|
@ -228,12 +230,12 @@
|
|||
"js-htmlencode": "^0.3.0",
|
||||
"lrc-file-parser": "^1.0.5",
|
||||
"needle": "^2.5.2",
|
||||
"node-id3": "^0.1.21",
|
||||
"node-id3": "^0.1.19",
|
||||
"request": "^2.88.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-i18n": "^8.22.1",
|
||||
"vue-i18n": "^8.22.2",
|
||||
"vue-router": "^3.4.9",
|
||||
"vuex": "^3.5.1",
|
||||
"vuex": "^3.6.0",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
### 新增
|
||||
|
||||
- 直接从歌单详情收藏的列表新增同步功能。注意:这将会覆盖本地的目标列表,歌曲将被替换成最新的在线列表
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化软件启动时恢复上一次播放的歌曲进度功能
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复有歌词翻译与无歌词的音乐间切换会导致歌词翻译残留显示的问题
|
||||
- 修复歌曲URL过期时,等待刷新URL的自动切换歌曲时间间隔太短的问题
|
||||
- 修复某些电脑上的某些歌曲没有声音的问题(升级Electron9.3.4导致的,现降级到9.3.3)
|
||||
- 修复MAC平台上下载歌曲封面嵌入无法显示的问题
|
||||
- 修复MAC平台首次运行软件最小化、关闭控制按钮默认在右边的问题
|
||||
- 修复酷狗源的某些歌曲没有专辑字段导致的列表加载失败问题
|
||||
- 修复某些酷狗源歌单链接无法打开的问题
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,5 @@
|
|||
const path = require('path')
|
||||
const os = require('os')
|
||||
const { isMac } = require('./utils')
|
||||
|
||||
const defaultSetting = {
|
||||
version: '1.0.38',
|
||||
|
@ -92,7 +91,7 @@ const defaultSetting = {
|
|||
randomAnimate: true,
|
||||
ignoreVersion: null,
|
||||
isAgreePact: false,
|
||||
controlBtnPosition: isMac ? 'left' : 'right',
|
||||
controlBtnPosition: process.platform === 'darwin' ? 'left' : 'right',
|
||||
}
|
||||
|
||||
const overwriteSetting = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const names = require('../main/events/_name')
|
||||
const names = require('@main/events/_name')
|
||||
const hotKey = {
|
||||
common: {
|
||||
min: {
|
||||
|
|
|
@ -273,7 +273,21 @@ export default {
|
|||
getPlayList().then(({ defaultList, loveList, userList, downloadList }) => {
|
||||
if (!defaultList) defaultList = this.defaultList
|
||||
if (!loveList) loveList = this.loveList
|
||||
if (!userList) userList = this.userList
|
||||
if (userList) {
|
||||
let needSave = false
|
||||
const getListId = id => id.includes('.') ? getListId(id.substring(0, id.lastIndexOf('_'))) : id
|
||||
userList.forEach(l => {
|
||||
if (!l.id.includes('__') || l.source) return
|
||||
let [source, id] = l.id.split('__')
|
||||
id = getListId(id)
|
||||
l.source = source
|
||||
l.sourceListId = id
|
||||
if (!needSave) needSave = true
|
||||
})
|
||||
if (needSave) this.saveUserList(userList)
|
||||
} else {
|
||||
userList = this.userList
|
||||
}
|
||||
|
||||
if (!defaultList.list) defaultList.list = []
|
||||
if (!loveList.list) loveList.list = []
|
||||
|
@ -306,7 +320,9 @@ export default {
|
|||
initPlayInfo() {
|
||||
rendererInvoke(NAMES.mainWindow.get_data, 'playInfo').then(info => {
|
||||
// console.log(info, window.allList)
|
||||
window.restorePlayInfo = null
|
||||
if (!info) return
|
||||
if (info.index < 0) return
|
||||
if (info.listId) {
|
||||
const list = window.allList[info.listId]
|
||||
// console.log(list)
|
||||
|
|
|
@ -244,9 +244,31 @@ export default {
|
|||
watch: {
|
||||
changePlay(n) {
|
||||
if (!n) return
|
||||
this.resetChangePlay()
|
||||
if (window.restorePlayInfo) {
|
||||
let musicInfo = this.targetSong = this.list[window.restorePlayInfo.index]
|
||||
this.musicInfo.songmid = musicInfo.songmid
|
||||
this.musicInfo.singer = musicInfo.singer
|
||||
this.musicInfo.name = musicInfo.name
|
||||
this.musicInfo.album = musicInfo.albumName
|
||||
this.setImg(musicInfo)
|
||||
this.setLrc(musicInfo)
|
||||
this.nowPlayTime = this.restorePlayTime = window.restorePlayInfo.time
|
||||
this.maxPlayTime = window.restorePlayInfo.maxTime || 0
|
||||
this.handleUpdateWinLyricInfo('music_info', {
|
||||
songmid: this.musicInfo.songmid,
|
||||
singer: this.musicInfo.singer,
|
||||
name: this.musicInfo.name,
|
||||
album: this.musicInfo.album,
|
||||
})
|
||||
this.$nextTick(() => {
|
||||
this.sendProgressEvent(this.progress, 'paused')
|
||||
})
|
||||
window.restorePlayInfo = null
|
||||
return
|
||||
}
|
||||
// console.log('changePlay')
|
||||
this.handleRemoveMusic()
|
||||
this.resetChangePlay()
|
||||
if (this.playIndex < 0) return
|
||||
this.stopPlay()
|
||||
this.play()
|
||||
|
@ -295,6 +317,7 @@ export default {
|
|||
if (Math.abs(n - o) > 2) this.isActiveTransition = true
|
||||
this.savePlayInfo({
|
||||
time: n,
|
||||
maxTime: this.maxPlayTime,
|
||||
listId: this.listId,
|
||||
list: this.listId == null ? this.list : null,
|
||||
index: this.playIndex,
|
||||
|
@ -377,12 +400,7 @@ export default {
|
|||
this.clearLoadingTimeout()
|
||||
this.status = this.statusText = this.$t('core.player.loading')
|
||||
this.maxPlayTime = audio.duration
|
||||
if (window.restorePlayInfo) {
|
||||
audio.currentTime = window.restorePlayInfo.time
|
||||
window.restorePlayInfo = null
|
||||
audio.pause()
|
||||
this.stopPlay()
|
||||
} else if (this.restorePlayTime) {
|
||||
if (this.restorePlayTime) {
|
||||
audio.currentTime = this.restorePlayTime
|
||||
this.restorePlayTime = 0
|
||||
}
|
||||
|
@ -651,7 +669,13 @@ export default {
|
|||
)
|
||||
},
|
||||
togglePlay() {
|
||||
if (!audio.src) return
|
||||
if (!audio.src) {
|
||||
if (this.restorePlayTime != null) {
|
||||
if (!this.assertApiSupport(this.targetSong.source)) return this.handleNext()
|
||||
this.setUrl(this.targetSong)
|
||||
}
|
||||
return
|
||||
}
|
||||
if (this.isPlay) {
|
||||
audio.pause()
|
||||
this.clearBufferTimeout()
|
||||
|
@ -801,7 +825,7 @@ export default {
|
|||
// console.log('start load timeout')
|
||||
this.loadingTimeout = setTimeout(() => {
|
||||
this.handleNext()
|
||||
}, 10000)
|
||||
}, 20000)
|
||||
},
|
||||
clearLoadingTimeout() {
|
||||
if (!this.loadingTimeout) return
|
||||
|
@ -810,7 +834,7 @@ export default {
|
|||
this.loadingTimeout = null
|
||||
},
|
||||
startBuffering() {
|
||||
console.error('start t')
|
||||
console.log('start t')
|
||||
if (this.mediaBuffer.timeout) return
|
||||
this.mediaBuffer.timeout = setTimeout(() => {
|
||||
this.mediaBuffer.timeout = null
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"lists_rename": "Rename",
|
||||
"lists_moveup": "Move Up",
|
||||
"lists_movedown": "Move Down",
|
||||
"lists_sync": "Sync",
|
||||
"lists_remove": "Remove",
|
||||
"list_play": "Play",
|
||||
"list_copy_name": "Copy name",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// http://kazupon.github.io/vue-i18n/en/messages.html
|
||||
|
||||
const requireLang = require.context(
|
||||
'@/lang',
|
||||
'@renderer/lang',
|
||||
true,
|
||||
/\.json$/,
|
||||
)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"lists_rename": "重命名",
|
||||
"lists_moveup": "上移",
|
||||
"lists_movedown": "下移",
|
||||
"lists_sync": "同步",
|
||||
"lists_remove": "删除",
|
||||
"list_play": "播放",
|
||||
"list_copy_name": "复制歌曲名",
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"lists_rename": "重命名",
|
||||
"lists_moveup": "上移",
|
||||
"lists_movedown": "下移",
|
||||
"lists_sync": "同步",
|
||||
"lists_remove": "刪除",
|
||||
"list_play": "播放",
|
||||
"list_copy_name": "複製歌曲名",
|
||||
|
|
|
@ -17,7 +17,7 @@ import store from './store'
|
|||
import '../common/error'
|
||||
|
||||
import { getSetting } from './utils'
|
||||
import languageList from '@/lang/languages.json'
|
||||
import languageList from '@renderer/lang/languages.json'
|
||||
import { rendererSend, NAMES } from '../common/ipc'
|
||||
|
||||
sync(store, router)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// Lib imports
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import messages from '@/lang'
|
||||
import messages from '@renderer/lang'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ const mutations = {
|
|||
allListInit(state.defaultList, state.loveList, state.userList)
|
||||
state.isInitedList = true
|
||||
},
|
||||
setList(state, { id, list, name, location }) {
|
||||
setList(state, { id, list, name, location, source, sourceListId }) {
|
||||
const targetList = allList[id]
|
||||
if (targetList) {
|
||||
if (name && targetList.name === name) {
|
||||
|
@ -76,6 +76,8 @@ const mutations = {
|
|||
id,
|
||||
list,
|
||||
location,
|
||||
source,
|
||||
sourceListId,
|
||||
}
|
||||
state.userList.push(newList)
|
||||
allListUpdate(newList)
|
||||
|
@ -145,7 +147,7 @@ const mutations = {
|
|||
if (!targetList) return
|
||||
Object.assign(targetList.list[index], data)
|
||||
},
|
||||
createUserList(state, { name, id = `userlist_${Date.now()}`, list = [] }) {
|
||||
createUserList(state, { name, id = `userlist_${Date.now()}`, list = [], source, sourceListId }) {
|
||||
let newList = state.userList.find(item => item.id === id)
|
||||
if (!newList) {
|
||||
newList = {
|
||||
|
@ -153,6 +155,8 @@ const mutations = {
|
|||
id,
|
||||
list: [],
|
||||
location: 0,
|
||||
source,
|
||||
sourceListId,
|
||||
}
|
||||
state.userList.push(newList)
|
||||
allListUpdate(newList)
|
||||
|
|
|
@ -9,6 +9,15 @@ for (const source of music.sources) {
|
|||
sources.push(source)
|
||||
}
|
||||
|
||||
const filterList = list => {
|
||||
const keys = new Set()
|
||||
return list.filter(item => {
|
||||
if (keys.has(item.songmid)) return false
|
||||
keys.add(item.songmid)
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
// state
|
||||
const state = {
|
||||
tags: {},
|
||||
|
@ -78,11 +87,11 @@ const actions = {
|
|||
return (
|
||||
cache.has(key)
|
||||
? Promise.resolve(cache.get(key))
|
||||
: music[source].songList.getListDetail(id, page)
|
||||
: music[source].songList.getListDetail(id, page).then(result => ({ ...result, list: filterList(result.list) }))
|
||||
).then(result => commit('setListDetail', { result, key, source, id, page }))
|
||||
},
|
||||
getListDetailAll({ state, rootState }, id) {
|
||||
let source = rootState.setting.songList.source
|
||||
getListDetailAll({ state, rootState }, { source, id }) {
|
||||
// console.log(source, id)
|
||||
const loadData = (id, page) => {
|
||||
let key = `sdetail__${source}__${id}__${page}`
|
||||
return cache.has(key)
|
||||
|
@ -93,7 +102,7 @@ const actions = {
|
|||
})
|
||||
}
|
||||
return loadData(id, 1).then(result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
if (result.total <= result.limit) return filterList(result.list)
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const loadDetail = (loadPage = 1) => {
|
||||
|
@ -101,7 +110,7 @@ const actions = {
|
|||
? loadData(id, ++loadPage).then(result => result.list)
|
||||
: loadData(id, ++loadPage).then(result1 => loadDetail(loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
}
|
||||
return loadDetail().then(result2 => [...result.list, ...result2])
|
||||
return loadDetail().then(result2 => [...result.list, ...result2]).then(list => filterList(list))
|
||||
})
|
||||
},
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ const encodeNames = {
|
|||
''': "'",
|
||||
''': "'",
|
||||
}
|
||||
export const decodeName = str => str.replace(/(?:&|<|>|"|'|')/gm, s => encodeNames[s])
|
||||
export const decodeName = (str = '') => str.replace(/(?:&|<|>|"|'|')/gm, s => encodeNames[s])
|
||||
|
||||
const easeInOutQuad = (t, b, c, d) => {
|
||||
t /= d / 2
|
||||
|
|
|
@ -378,7 +378,7 @@ export default {
|
|||
id = id.toString()
|
||||
if (id.includes('special/single/')) {
|
||||
id = id.replace(this.regExps.listDetailLink, '$1')
|
||||
} else if (/http(?:s):/.test(id)) {
|
||||
} else if (/https?:/.test(id)) {
|
||||
return this.getUserListDetail(id.replace(/^.*http/, 'http'), page)
|
||||
} else if (/^\d+$/.test(id)) {
|
||||
return this.getUserListDetailByCode(id)
|
||||
|
|
|
@ -31,7 +31,7 @@ export default {
|
|||
},
|
||||
})
|
||||
const { body, statusCode } = await _requestObj.promise
|
||||
console.log(body)
|
||||
// console.log(body)
|
||||
if (statusCode != 200 || body.returnCode !== '000000') throw new Error('获取评论失败')
|
||||
return { source: 'mg', comments: this.filterComment(body.data.items), total: body.data.itemTotal, page, limit, maxPage: Math.ceil(body.data.itemTotal / limit) || 1 }
|
||||
},
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
span(:class="$style.listsLabel") {{defaultList.name}}
|
||||
li(:class="[$style.listsItem, loveList.id == listId ? $style.active : null]" :tips="loveList.name" @click="handleListToggle(loveList.id)")
|
||||
span(:class="$style.listsLabel") {{loveList.name}}
|
||||
li.user-list(:class="[$style.listsItem, item.id == listId ? $style.active : null, listsData.rightClickItemIndex == index ? $style.clicked : null]" @contextmenu="handleListsItemRigthClick($event, index)" :tips="item.name" v-for="(item, index) in userList" :key="item.id")
|
||||
li.user-list(
|
||||
:class="[$style.listsItem, item.id == listId ? $style.active : null, listsData.rightClickItemIndex == index ? $style.clicked : null, fetchingListStatus[item.id] ? $style.fetching : null]"
|
||||
@contextmenu="handleListsItemRigthClick($event, index)"
|
||||
:tips="item.name" v-for="(item, index) in userList" :key="item.id")
|
||||
span(:class="$style.listsLabel" @click="handleListToggle(item.id, index + 2)") {{item.name}}
|
||||
input.key-bind(:class="$style.listsInput" @contextmenu.stop type="text" @keyup.enter="handleListsSave(index, $event)" @blur="handleListsSave(index, $event)" :value="item.name" :placeholder="item.name")
|
||||
transition(enter-active-class="animated-fast slideInLeft" leave-active-class="animated-fast fadeOut" @after-leave="handleListsNewAfterLeave")
|
||||
|
@ -100,6 +103,7 @@ export default {
|
|||
isShowItemMenu: false,
|
||||
itemMenuControl: {
|
||||
rename: true,
|
||||
sync: false,
|
||||
moveup: true,
|
||||
movedown: true,
|
||||
remove: true,
|
||||
|
@ -131,6 +135,7 @@ export default {
|
|||
isMove: false,
|
||||
isMoveMultiple: false,
|
||||
isVisibleMusicSearch: false,
|
||||
fetchingListStatus: {},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -180,6 +185,11 @@ export default {
|
|||
action: 'rename',
|
||||
disabled: !this.listsData.itemMenuControl.rename,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.list.lists_sync'),
|
||||
action: 'sync',
|
||||
disabled: !this.listsData.itemMenuControl.sync,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.list.lists_moveup'),
|
||||
action: 'moveup',
|
||||
|
@ -309,7 +319,18 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapMutations(['setPrevSelectListId']),
|
||||
...mapMutations('list', ['listRemove', 'listRemoveMultiple', 'setUserListName', 'createUserList', 'moveupUserList', 'movedownUserList', 'removeUserList', 'setListScroll']),
|
||||
...mapMutations('list', [
|
||||
'listRemove',
|
||||
'listRemoveMultiple',
|
||||
'setUserListName',
|
||||
'createUserList',
|
||||
'moveupUserList',
|
||||
'movedownUserList',
|
||||
'removeUserList',
|
||||
'setListScroll',
|
||||
'setList',
|
||||
]),
|
||||
...mapActions('songList', ['getListDetailAll']),
|
||||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('player', {
|
||||
setPlayList: 'setList',
|
||||
|
@ -668,6 +689,8 @@ export default {
|
|||
}).catch(_ => _)
|
||||
},
|
||||
handleListsItemRigthClick(event, index) {
|
||||
const source = this.userList[index].source
|
||||
this.listsData.itemMenuControl.sync = !!source && !!musicSdk[source].songList
|
||||
this.listsData.itemMenuControl.moveup = index > 0
|
||||
this.listsData.itemMenuControl.movedown = index < this.userList.length - 1
|
||||
this.listsData.rightClickItemIndex = index
|
||||
|
@ -714,6 +737,9 @@ export default {
|
|||
dom.querySelector('input').focus()
|
||||
})
|
||||
break
|
||||
case 'sync':
|
||||
this.handleSyncSourceList(index)
|
||||
break
|
||||
case 'moveup':
|
||||
this.moveupUserList(index)
|
||||
break
|
||||
|
@ -814,6 +840,27 @@ export default {
|
|||
break
|
||||
}
|
||||
},
|
||||
fetchList(id, source, sourceListId) {
|
||||
if (this.fetchingListStatus[id] == null) {
|
||||
this.$set(this.fetchingListStatus, id, true)
|
||||
} else {
|
||||
this.fetchingListStatus[id] = true
|
||||
}
|
||||
return this.getListDetailAll({ source, id: sourceListId }).catch(err => {
|
||||
return Promise.reject(err)
|
||||
}).finally(() => {
|
||||
this.fetchingListStatus[id] = false
|
||||
})
|
||||
},
|
||||
async handleSyncSourceList(index) {
|
||||
const targetList = this.userList[index]
|
||||
const list = await this.fetchList(targetList.id, targetList.source, targetList.sourceListId)
|
||||
// console.log(targetList.list.length, list.length)
|
||||
this.setList({
|
||||
...targetList,
|
||||
list,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -880,7 +927,7 @@ export default {
|
|||
.listsItem {
|
||||
position: relative;
|
||||
transition: .3s ease;
|
||||
transition-property: color, background-color;
|
||||
transition-property: color, background-color, opacity;
|
||||
background-color: transparent;
|
||||
&:hover:not(.active) {
|
||||
background-color: @color-theme_2-hover;
|
||||
|
@ -896,6 +943,9 @@ export default {
|
|||
&.clicked {
|
||||
background-color: @color-theme_2-hover;
|
||||
}
|
||||
&.fetching {
|
||||
opacity: .5;
|
||||
}
|
||||
&.editing {
|
||||
padding: 0 10px;
|
||||
background-color: @color-theme_2-hover;
|
||||
|
|
|
@ -296,11 +296,11 @@ import {
|
|||
sizeFormate,
|
||||
setWindowSize,
|
||||
} from '../utils'
|
||||
import { rendererSend, rendererInvoke, NAMES } from '../../common/ipc'
|
||||
import { rendererSend, rendererInvoke, NAMES } from '@common/ipc'
|
||||
import { mergeSetting, isMac } from '../../common/utils'
|
||||
import apiSourceInfo from '../utils/music/api-source-info'
|
||||
import fs from 'fs'
|
||||
import languageList from '@/lang/languages.json'
|
||||
import languageList from '@renderer/lang/languages.json'
|
||||
import { base as eventBaseName } from '../event/names'
|
||||
import * as hotKeys from '../../common/hotKey'
|
||||
import { mainWindow as eventsNameMainWindow, winLyric as eventsNameWinLyric } from '../../main/events/_name'
|
||||
|
|
|
@ -373,6 +373,7 @@ export default {
|
|||
}
|
||||
},
|
||||
handleGetSongListDetail() {
|
||||
if (!this.importSongListText.length) return
|
||||
this.setSelectListInfo({
|
||||
play_count: null,
|
||||
id: this.importSongListText,
|
||||
|
@ -404,14 +405,22 @@ export default {
|
|||
},
|
||||
async fetchList() {
|
||||
this.detailLoading = true
|
||||
const list = await this.getListDetailAll(this.selectListInfo.id)
|
||||
this.detailLoading = false
|
||||
return list
|
||||
return this.getListDetailAll({ source: this.source, id: this.selectListInfo.id }).catch(err => {
|
||||
return Promise.reject(err)
|
||||
}).finally(() => {
|
||||
this.detailLoading = false
|
||||
})
|
||||
},
|
||||
async addSongListDetail() {
|
||||
if (!this.listDetail.info.name) return
|
||||
const list = await this.fetchList()
|
||||
this.createUserList({ name: this.listDetail.info.name, id: `${this.listDetail.source}__${this.listDetail.id}`, list })
|
||||
this.createUserList({
|
||||
name: this.listDetail.info.name,
|
||||
id: `${this.listDetail.source}__${this.listDetail.id}`,
|
||||
list,
|
||||
source: this.listDetail.source,
|
||||
sourceListId: this.listDetail.id,
|
||||
})
|
||||
},
|
||||
async playSongListDetail() {
|
||||
if (!this.listDetail.info.name) return
|
||||
|
|
Loading…
Reference in New Issue