commit
bb411a365c
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -6,6 +6,29 @@ 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.7.0](https://github.com/lyswhut/lx-music-desktop/compare/v1.6.1...v1.7.0) - 2021-01-30
|
||||
|
||||
### 新增
|
||||
|
||||
- 搜索界面新增搜索状态的提示
|
||||
- 新增“稍后播放”功能,可在歌曲列表右键菜单使用
|
||||
- 新增“记住播放进度”功能的控制,该功能默认不再开启,可到播放设置-记住播放进度开启
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化播放歌曲换源匹配
|
||||
- 优化设置界面设置项的展示
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复快速切换歌曲时, 会出现播放的歌曲和界面展示的歌曲不一致的问题
|
||||
- 修复了一个由版本更新日志显示导致的潜在远程代码执行攻击漏洞,该漏洞影响v1.6.1及之前的所有版本,请务必更新到最新版本
|
||||
- 修复xm搜索源验证问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新electron到9.4.2
|
||||
|
||||
## [1.6.1](https://github.com/lyswhut/lx-music-desktop/compare/v1.6.0...v1.6.1) - 2021-01-13
|
||||
|
||||
### 优化
|
||||
|
|
|
@ -62,7 +62,7 @@ npm run dev
|
|||
npm run pack:dir
|
||||
|
||||
# 构建安装包(Windows版)
|
||||
npm run pack
|
||||
npm run pack:win
|
||||
|
||||
# 构建安装包(Mac版)
|
||||
npm run pack:mac
|
||||
|
|
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "lx-music-desktop",
|
||||
"version": "1.6.1",
|
||||
"description": "一个免费的音乐下载助手",
|
||||
"version": "1.7.0",
|
||||
"description": "一个免费的音乐查找助手",
|
||||
"main": "./dist/electron/main.js",
|
||||
"productName": "lx-music-desktop",
|
||||
"scripts": {
|
||||
"pack": "node build-config/pack.js && npm run pack:win",
|
||||
"pack:win": "npm run pack:win:setup:x86_64 && npm run pack:win:7z",
|
||||
"pack": "node build-config/pack.js && npm run pack:win:setup:x64",
|
||||
"pack:win": "node build-config/pack.js && npm run pack:win:setup:x86_64 && npm run pack:win:7z",
|
||||
"pack:win:setup:x86_64": "cross-env TARGET=win_安装版 ARCH=x86_64 electron-builder -w=nsis --x64 --ia32",
|
||||
"pack:win:setup:x64": "cross-env TARGET=win_安装版 ARCH=x64 electron-builder -w=nsis --x64",
|
||||
"pack:win:setup:x86": "cross-env TARGET=win_安装版 ARCH=x86 electron-builder -w=nsis --ia32",
|
||||
|
@ -173,16 +173,16 @@
|
|||
"cfonts": "^2.9.1",
|
||||
"chalk": "^4.1.0",
|
||||
"changelog-parser": "^2.8.0",
|
||||
"copy-webpack-plugin": "^6.4.0",
|
||||
"core-js": "^3.8.2",
|
||||
"copy-webpack-plugin": "^6.4.1",
|
||||
"core-js": "^3.8.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^4.3.0",
|
||||
"del": "^6.0.0",
|
||||
"electron": "^9.3.3",
|
||||
"electron": "^9.4.2",
|
||||
"electron-builder": "^22.9.1",
|
||||
"electron-debug": "^3.2.0",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"eslint": "^7.17.0",
|
||||
"eslint": "^7.18.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-formatter-friendly": "^7.0.0",
|
||||
"eslint-loader": "^4.0.2",
|
||||
|
@ -194,12 +194,12 @@
|
|||
"file-loader": "^6.2.0",
|
||||
"friendly-errors-webpack-plugin": "^1.7.0",
|
||||
"html-webpack-plugin": "^4.5.1",
|
||||
"less": "^3.12.2",
|
||||
"less-loader": "^7.2.1",
|
||||
"less": "^3.13.1",
|
||||
"less-loader": "^7.3.0",
|
||||
"markdown-it": "^12.0.4",
|
||||
"mini-css-extract-plugin": "^0.12.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||
"postcss-loader": "^4.1.0",
|
||||
"postcss-loader": "^4.2.0",
|
||||
"postcss-pxtorem": "^5.1.1",
|
||||
"pug": "^3.0.0",
|
||||
"pug-loader": "^2.4.0",
|
||||
|
@ -208,14 +208,14 @@
|
|||
"rimraf": "^3.0.2",
|
||||
"spinnies": "^0.5.1",
|
||||
"stylus": "^0.54.8",
|
||||
"stylus-loader": "^4.3.1",
|
||||
"stylus-loader": "^4.3.3",
|
||||
"terser-webpack-plugin": "^4.2.3",
|
||||
"url-loader": "^4.1.1",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"webpack": "^4.44.2",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.1",
|
||||
"webpack-dev-server": "^3.11.2",
|
||||
"webpack-hot-middleware": "^2.25.0",
|
||||
"webpack-merge": "^5.7.3"
|
||||
},
|
||||
|
@ -233,9 +233,9 @@
|
|||
"node-id3": "^0.2.2",
|
||||
"request": "^2.88.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-i18n": "^8.22.3",
|
||||
"vue-router": "^3.4.9",
|
||||
"vuex": "^3.6.0",
|
||||
"vue-i18n": "^8.22.4",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,20 @@
|
|||
### 新增
|
||||
|
||||
- 搜索界面新增搜索状态的提示
|
||||
- 新增“稍后播放”功能,可在歌曲列表右键菜单使用
|
||||
- 新增“记住播放进度”功能的控制,该功能默认不再开启,可到播放设置-记住播放进度开启
|
||||
|
||||
### 优化
|
||||
|
||||
- 改进自动换源时的歌曲匹配
|
||||
- 优化播放歌曲换源匹配
|
||||
- 优化设置界面设置项的展示
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复某些情况下自动换源的时间过长时会终止换源自动切歌的问题
|
||||
- 修复自动换源导致的搜索列表每页变成10条数据的问题
|
||||
- 降级electron到9.3.3修复部分系统没有声音的问题
|
||||
- 修复快速切换歌曲时, 会出现播放的歌曲和界面展示的歌曲不一致的问题
|
||||
- 修复了一个由版本更新日志显示导致的潜在远程代码执行攻击漏洞,该漏洞影响v1.6.1及之前的所有版本,请务必更新到最新版本
|
||||
- 修复xm搜索源验证问题
|
||||
|
||||
### 其他
|
||||
|
||||
- 更新electron到9.4.2
|
||||
|
|
|
@ -45,6 +45,7 @@ module.exports = async newVerNum => {
|
|||
})
|
||||
version.version = newVerNum
|
||||
version.desc = newChangeLog
|
||||
// version.desc = newMDChangeLog.replace(/(?:^|(\n))#{1,6} (.+)\n/g, '$1$2').trim()
|
||||
pkg.version = newVerNum
|
||||
|
||||
console.log(chalk.blue('new version: ') + chalk.green(newVerNum))
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,7 @@ const path = require('path')
|
|||
const os = require('os')
|
||||
|
||||
const defaultSetting = {
|
||||
version: '1.0.38',
|
||||
version: '1.0.39',
|
||||
player: {
|
||||
togglePlayMethod: 'listLoop',
|
||||
highQuality: false,
|
||||
|
@ -12,6 +12,7 @@ const defaultSetting = {
|
|||
mediaDeviceId: 'default',
|
||||
isMediaDeviceRemovedStopPlay: false,
|
||||
isShowLyricTransition: true,
|
||||
isSavePlayTime: false,
|
||||
},
|
||||
desktopLyric: {
|
||||
enable: false,
|
||||
|
|
|
@ -54,6 +54,7 @@ app.on('web-contents-created', (event, contents) => {
|
|||
event.preventDefault()
|
||||
if (/^devtools/.test(navigationUrl)) return
|
||||
console.log(navigationUrl)
|
||||
if (!/^https?:\/\//.test(navigationUrl)) return
|
||||
await shell.openExternal(navigationUrl)
|
||||
})
|
||||
contents.on('will-attach-webview', (event, webPreferences, params) => {
|
||||
|
|
|
@ -32,22 +32,35 @@ mainHandle(ipcMainWindowNames.handle_xm_verify_open, (event, url) => new Promise
|
|||
disableHtmlFullscreenWindowResize: true,
|
||||
},
|
||||
})
|
||||
view.webContents.on('did-finish-load', () => {
|
||||
if (/punish\?/.test(view.webContents.getURL())) return
|
||||
let ses = view.webContents.session
|
||||
ses.cookies.get({ name: 'x5sec' })
|
||||
.then(async([x5sec]) => {
|
||||
// view.webContents.on('did-finish-load', () => {
|
||||
// if (/punish\?/.test(view.webContents.getURL())) return
|
||||
// let ses = view.webContents.session
|
||||
// ses.cookies.get({ name: 'x5sec' })
|
||||
// .then(async([x5sec]) => {
|
||||
// isActioned = true
|
||||
// await closeView()
|
||||
// if (!x5sec) return reject(new Error('get x5sec failed'))
|
||||
// resolve(x5sec.value)
|
||||
// }).catch(async err => {
|
||||
// isActioned = true
|
||||
// await closeView()
|
||||
// reject(err)
|
||||
// })
|
||||
// })
|
||||
view.webContents.session.webRequest.onCompleted({ urls: ['*://www.xiami.com/*'] }, details => {
|
||||
if (/\/_____tmd_____\/slide\?/.test(details.url)) {
|
||||
for (const item of details.responseHeaders['set-cookie']) {
|
||||
if (!/^x5sec=/.test(item)) continue
|
||||
const x5sec = /x5sec=(\w+);.+$/.exec(item)
|
||||
isActioned = true
|
||||
await closeView()
|
||||
if (!x5sec) return reject(new Error('get x5sec failed'))
|
||||
resolve(x5sec.value)
|
||||
}).catch(async err => {
|
||||
isActioned = true
|
||||
await closeView()
|
||||
reject(err)
|
||||
})
|
||||
closeView().finally(() => {
|
||||
if (!x5sec) return reject(new Error('get x5sec failed'))
|
||||
resolve(x5sec[1])
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// console.log(url)
|
||||
global.modules.mainWindow.setBrowserView(view)
|
||||
const windowSizeInfo = getWindowSizeInfo(global.appSetting)
|
||||
view.setBounds({ x: (windowSizeInfo.width - 380) / 2, y: ((windowSizeInfo.height - 320 + 52) / 2), width: 380, height: 320 })
|
||||
|
|
|
@ -871,6 +871,41 @@
|
|||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
@keyframes hinge {
|
||||
0% {
|
||||
-webkit-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
20%,
|
||||
60% {
|
||||
-webkit-transform: rotate3d(0, 0, 1, 80deg);
|
||||
transform: rotate3d(0, 0, 1, 80deg);
|
||||
-webkit-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
40%,
|
||||
80% {
|
||||
-webkit-transform: rotate3d(0, 0, 1, 60deg);
|
||||
transform: rotate3d(0, 0, 1, 60deg);
|
||||
-webkit-transform-origin: top left;
|
||||
transform-origin: top left;
|
||||
-webkit-animation-timing-function: ease-in-out;
|
||||
animation-timing-function: ease-in-out;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: translate3d(0, 700px, 0);
|
||||
transform: translate3d(0, 700px, 0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.flipInX {
|
||||
backface-visibility: visible !important;
|
||||
|
|
|
@ -34,7 +34,7 @@ div(:class="$style.player")
|
|||
div(:class="$style.titleBtn" @click='addMusicTo' :tips="$t('core.player.add_music_to')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='80%' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-add-2')
|
||||
//- div(:class="$style.playBtn" @click='handleNext' tips="音量")
|
||||
//- div(:class="$style.playBtn" @click='playNext' tips="音量")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 291.063 291.064' space='preserve')
|
||||
use(xlink:href='#icon-sound')
|
||||
|
||||
|
@ -49,7 +49,7 @@ div(:class="$style.player")
|
|||
span(style="margin: 0 5px;") /
|
||||
span {{maxPlayTimeStr}}
|
||||
div(:class="$style.right")
|
||||
div(:class="$style.playBtn" @click='handlePrev' :tips="$t('core.player.prev')" style="transform: rotate(180deg);")
|
||||
div(:class="$style.playBtn" @click='playPrev' :tips="$t('core.player.prev')" style="transform: rotate(180deg);")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 220.847 220.847' space='preserve')
|
||||
use(xlink:href='#icon-nextMusic')
|
||||
div(:class="$style.playBtn" :tips="isPlay ? $t('core.player.pause') : $t('core.player.play')" @click='togglePlay')
|
||||
|
@ -57,7 +57,7 @@ div(:class="$style.player")
|
|||
use(xlink:href='#icon-pause')
|
||||
svg(v-else version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 170 170' space='preserve')
|
||||
use(xlink:href='#icon-play')
|
||||
div(:class="$style.playBtn" @click='handleNext' :tips="$t('core.player.next')")
|
||||
div(:class="$style.playBtn" @click='playNext' :tips="$t('core.player.next')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 220.847 220.847' space='preserve')
|
||||
use(xlink:href='#icon-nextMusic')
|
||||
//- transition(enter-active-class="animated lightSpeedIn"
|
||||
|
@ -90,7 +90,6 @@ import { rendererSend, rendererOn, NAMES } from '../../../common/ipc'
|
|||
import { formatPlayTime2, getRandom, checkPath, setTitle, clipboardWriteText, debounce, throttle, assertApiSupport } from '../../utils'
|
||||
import { mapGetters, mapActions, mapMutations } from 'vuex'
|
||||
import { requestMsg } from '../../utils/message'
|
||||
import { isMac } from '../../../common/utils'
|
||||
import { player as eventPlayerNames } from '../../../common/hotKey'
|
||||
import musicSdk from '@renderer/utils/music'
|
||||
import path from 'path'
|
||||
|
@ -107,7 +106,6 @@ const playNextModes = [
|
|||
export default {
|
||||
data() {
|
||||
return {
|
||||
show: true,
|
||||
volume: 0,
|
||||
nowPlayTime: 0,
|
||||
maxPlayTime: 0,
|
||||
|
@ -123,7 +121,6 @@ export default {
|
|||
singer: '',
|
||||
album: '',
|
||||
},
|
||||
targetSong: null,
|
||||
pregessWidth: 0,
|
||||
lyric: {
|
||||
lines: [],
|
||||
|
@ -133,7 +130,6 @@ export default {
|
|||
delayNextTimeout: null,
|
||||
restorePlayTime: 0,
|
||||
retryNum: 0,
|
||||
isMac,
|
||||
volumeEvent: {
|
||||
isMsDown: false,
|
||||
msDownX: 0,
|
||||
|
@ -149,10 +145,19 @@ export default {
|
|||
},
|
||||
computed: {
|
||||
...mapGetters(['setting']),
|
||||
...mapGetters('player', ['list', 'playIndex', 'changePlay', 'listId', 'isShowPlayerDetail', 'playedList']),
|
||||
...mapGetters('player', ['list', 'changePlay', 'playMusicInfo', 'isShowPlayerDetail', 'playInfo', 'playedList']),
|
||||
// pic() {
|
||||
// return this.musicInfo.img ? this.musicInfo.img : ''
|
||||
// },
|
||||
listId() { // 当前播放歌曲的列表ID
|
||||
return this.playInfo.listId
|
||||
},
|
||||
playIndex() { // 当前播放歌曲所在列表的 播放列表的播放位置
|
||||
return this.playInfo.playIndex
|
||||
},
|
||||
targetSong() {
|
||||
return this.playInfo.musicInfo
|
||||
},
|
||||
title() {
|
||||
return this.musicInfo.name
|
||||
? this.setting.download.fileName.replace('歌名', this.musicInfo.name).replace('歌手', this.musicInfo.singer)
|
||||
|
@ -247,38 +252,19 @@ export default {
|
|||
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')
|
||||
})
|
||||
if (this.setting.player.togglePlayMethod == 'random') this.setPlayedList(musicInfo)
|
||||
this.handleRestorePlay(window.restorePlayInfo)
|
||||
window.restorePlayInfo = null
|
||||
return
|
||||
}
|
||||
// console.log('changePlay')
|
||||
this.handleRemoveMusic()
|
||||
if (this.playIndex < 0) return
|
||||
this.stopPlay()
|
||||
if (!this.playInfo.musicInfo) return
|
||||
this.play()
|
||||
},
|
||||
'setting.player.togglePlayMethod'(n) {
|
||||
audio.loop = n === 'singleLoop'
|
||||
if (this.playedList.length) this.clearPlayedList()
|
||||
if (n == 'random' && this.playIndex > -1) this.setPlayedList(this.list[this.playIndex])
|
||||
if (n == 'random') this.setPlayedList(this.playMusicInfo)
|
||||
},
|
||||
'setting.player.isMute'(n) {
|
||||
audio.muted = n
|
||||
|
@ -297,13 +283,13 @@ export default {
|
|||
if (index < 0) {
|
||||
// console.log(this.playIndex)
|
||||
if (n.length) {
|
||||
this.fixPlayIndex(this.playIndex - 1)
|
||||
this.handleNext()
|
||||
this.setPlayIndex(this.playInfo.listPlayIndex - 1)
|
||||
this.playNext()
|
||||
} else {
|
||||
this.setPlayIndex(-1)
|
||||
this.setPlayMusicInfo(null)
|
||||
}
|
||||
} else {
|
||||
this.fixPlayIndex(index)
|
||||
this.setPlayIndex(index)
|
||||
}
|
||||
// console.log(this.playIndex)
|
||||
}
|
||||
|
@ -317,26 +303,37 @@ export default {
|
|||
},
|
||||
nowPlayTime(n, o) {
|
||||
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,
|
||||
})
|
||||
if (this.setting.player.isSavePlayTime && !this.playInfo.isTempPlay) {
|
||||
this.savePlayInfo({
|
||||
time: n,
|
||||
maxTime: this.maxPlayTime,
|
||||
listId: this.listId,
|
||||
list: this.listId == null ? this.list : null,
|
||||
index: this.playIndex,
|
||||
})
|
||||
}
|
||||
},
|
||||
maxPlayTime(maxPlayTime) {
|
||||
if (!this.playInfo.isTempPlay) {
|
||||
this.savePlayInfo({
|
||||
time: this.nowPlayTime,
|
||||
maxTime: maxPlayTime,
|
||||
listId: this.listId,
|
||||
list: this.listId == null ? this.list : null,
|
||||
index: this.playIndex,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions('player', ['getUrl', 'getPic', 'getLrc']),
|
||||
...mapActions('player', ['getUrl', 'getPic', 'getLrc', 'playPrev', 'playNext']),
|
||||
...mapMutations('player', [
|
||||
'setPlayMusicInfo',
|
||||
'setPlayIndex',
|
||||
'fixPlayIndex',
|
||||
'resetChangePlay',
|
||||
'visiblePlayerDetail',
|
||||
'clearPlayedList',
|
||||
'setPlayedList',
|
||||
'removePlayedList',
|
||||
'setList',
|
||||
]),
|
||||
...mapMutations(['setVolume', 'setPlayNextMode', 'setVisibleDesktopLyric', 'setLockDesktopLyric']),
|
||||
...mapMutations('list', ['updateMusicInfo']),
|
||||
|
@ -345,8 +342,8 @@ export default {
|
|||
let eventHub = window.eventHub
|
||||
let name = action == 'on' ? '$on' : '$off'
|
||||
eventHub[name](eventPlayerNames.toggle_play.action, this.togglePlay)
|
||||
eventHub[name](eventPlayerNames.next.action, this.handleNext)
|
||||
eventHub[name](eventPlayerNames.prev.action, this.handlePrev)
|
||||
eventHub[name](eventPlayerNames.next.action, this.playNext)
|
||||
eventHub[name](eventPlayerNames.prev.action, this.playPrev)
|
||||
eventHub[name](eventPlayerNames.volume_up.action, this.handleSetVolumeUp)
|
||||
eventHub[name](eventPlayerNames.volume_down.action, this.handleSetVolumeDown)
|
||||
eventHub[name](eventPlayerNames.volume_mute.action, this.handleSetVolumeMute)
|
||||
|
@ -377,7 +374,7 @@ export default {
|
|||
console.log('播放完毕')
|
||||
this.stopPlay()
|
||||
this.status = this.statusText = this.$t('core.player.end')
|
||||
this.handleNext()
|
||||
this.playNext()
|
||||
})
|
||||
audio.addEventListener('error', () => {
|
||||
// console.log('code', audio.error)
|
||||
|
@ -389,7 +386,7 @@ export default {
|
|||
// console.log(this.retryNum)
|
||||
if (!this.restorePlayTime) this.restorePlayTime = audio.currentTime // 记录出错的播放时间
|
||||
this.retryNum++
|
||||
this.setUrl(this.list[this.playIndex], true)
|
||||
this.setUrl(this.targetSong, true)
|
||||
this.status = this.statusText = this.$t('core.player.refresh_url')
|
||||
return
|
||||
}
|
||||
|
@ -407,7 +404,9 @@ export default {
|
|||
audio.currentTime = this.restorePlayTime
|
||||
this.restorePlayTime = 0
|
||||
}
|
||||
if (!this.targetSong.interval && this.listId != 'download') this.updateMusicInfo({ id: this.listId, index: this.playIndex, data: { interval: formatPlayTime2(this.maxPlayTime) } })
|
||||
if (!this.targetSong.interval && this.listId != 'download') {
|
||||
this.updateMusicInfo({ id: this.listId, index: this.playIndex, data: { interval: formatPlayTime2(this.maxPlayTime) }, musicInfo: this.targetSong })
|
||||
}
|
||||
})
|
||||
audio.addEventListener('loadstart', () => {
|
||||
console.log('loadstart')
|
||||
|
@ -470,10 +469,11 @@ export default {
|
|||
this.handleRegisterEvent('on')
|
||||
},
|
||||
async play() {
|
||||
console.log('play', this.playIndex)
|
||||
this.clearDelayNextTimeout()
|
||||
let targetSong = this.targetSong = this.list[this.playIndex]
|
||||
if (this.setting.player.togglePlayMethod == 'random') this.setPlayedList(targetSong)
|
||||
|
||||
const targetSong = this.targetSong
|
||||
|
||||
if (this.setting.player.togglePlayMethod == 'random') this.setPlayedList(this.playMusicInfo)
|
||||
this.retryNum = 0
|
||||
this.restorePlayTime = 0
|
||||
|
||||
|
@ -481,7 +481,7 @@ export default {
|
|||
const filePath = path.join(this.setting.download.savePath, targetSong.fileName)
|
||||
// console.log(filePath)
|
||||
if (!await checkPath(filePath) || !targetSong.isComplate || /\.ape$/.test(filePath)) {
|
||||
return this.list.length == 1 ? null : this.handleNext()
|
||||
return this.list.length == 1 ? null : this.playNext()
|
||||
}
|
||||
this.musicInfo.songmid = targetSong.musicInfo.songmid
|
||||
this.musicInfo.singer = targetSong.musicInfo.singer
|
||||
|
@ -492,7 +492,7 @@ export default {
|
|||
this.setImg(targetSong.musicInfo)
|
||||
this.setLrc(targetSong.musicInfo)
|
||||
} else {
|
||||
if (!this.assertApiSupport(targetSong.source)) return this.handleNext()
|
||||
if (!this.assertApiSupport(targetSong.source)) return this.playNext()
|
||||
this.musicInfo.songmid = targetSong.songmid
|
||||
this.musicInfo.singer = targetSong.singer
|
||||
this.musicInfo.name = targetSong.name
|
||||
|
@ -507,6 +507,15 @@ export default {
|
|||
name: this.musicInfo.name,
|
||||
album: this.musicInfo.album,
|
||||
})
|
||||
if (!this.playInfo.isTempPlay) {
|
||||
this.savePlayInfo({
|
||||
time: this.nowPlayTime,
|
||||
maxTime: this.maxPlayTime,
|
||||
listId: this.listId,
|
||||
list: this.listId == null ? this.list : null,
|
||||
index: this.playIndex,
|
||||
})
|
||||
}
|
||||
},
|
||||
clearDelayNextTimeout() {
|
||||
// console.log(this.delayNextTimeout)
|
||||
|
@ -519,120 +528,10 @@ export default {
|
|||
this.clearDelayNextTimeout()
|
||||
this.delayNextTimeout = setTimeout(() => {
|
||||
this.delayNextTimeout = null
|
||||
this.handleNext()
|
||||
this.playNext()
|
||||
}, 5000)
|
||||
},
|
||||
async filterList() {
|
||||
// if (this.list.listName === null) return
|
||||
let list
|
||||
let playedList = [...this.playedList]
|
||||
if (this.listId == 'download') {
|
||||
list = []
|
||||
for (const item of this.list) {
|
||||
const filePath = path.join(this.setting.download.savePath, item.fileName)
|
||||
if (!await checkPath(filePath) || !item.isComplate || /\.ape$/.test(filePath)) continue
|
||||
|
||||
let index = playedList.indexOf(item)
|
||||
if (index > -1) {
|
||||
playedList.splice(index, 1)
|
||||
continue
|
||||
}
|
||||
list.push(item)
|
||||
}
|
||||
} else {
|
||||
list = this.list.filter(s => {
|
||||
let index = playedList.indexOf(s)
|
||||
if (index > -1) {
|
||||
playedList.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
return this.assertApiSupport(s.source)
|
||||
})
|
||||
}
|
||||
if (!list.length && this.playedList.length) {
|
||||
this.clearPlayedList()
|
||||
return this.filterList()
|
||||
}
|
||||
return list
|
||||
},
|
||||
async handlePrev() {
|
||||
// console.log(playIndex)
|
||||
if (this.setting.player.togglePlayMethod == 'random' && this.playedList.length) {
|
||||
let index = this.playedList.indexOf(this.targetSong)
|
||||
index -= 1
|
||||
while (true) {
|
||||
if (index > -1) {
|
||||
let listIndex = this.list.indexOf(this.playedList[index])
|
||||
if (listIndex < 0) {
|
||||
this.removePlayedList(index)
|
||||
continue
|
||||
}
|
||||
this.setPlayIndex(listIndex)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
let list = await this.filterList()
|
||||
if (!list.length) return this.setPlayIndex(-1)
|
||||
let playIndex = list.indexOf(this.list[this.playIndex])
|
||||
let index
|
||||
switch (this.setting.player.togglePlayMethod) {
|
||||
case 'random':
|
||||
index = this.hanldeListRandom(list, playIndex)
|
||||
break
|
||||
case 'listLoop':
|
||||
case 'list':
|
||||
index = playIndex === 0 ? list.length - 1 : playIndex - 1
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
if (index < 0) return
|
||||
index = this.list.indexOf(list[index])
|
||||
this.setPlayIndex(index)
|
||||
},
|
||||
async handleNext() {
|
||||
// if (this.list.listName === null) return
|
||||
// eslint-disable-next-line no-debugger
|
||||
if (this.setting.player.togglePlayMethod == 'random' && this.playedList.length) {
|
||||
let index = this.playedList.indexOf(this.targetSong)
|
||||
index += 1
|
||||
while (true) {
|
||||
if (index < this.playedList.length) {
|
||||
let listIndex = this.list.indexOf(this.playedList[index])
|
||||
if (listIndex < 0) {
|
||||
this.removePlayedList(index)
|
||||
continue
|
||||
}
|
||||
this.setPlayIndex(listIndex)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
let list = await this.filterList()
|
||||
if (!list.length) return this.setPlayIndex(-1)
|
||||
let playIndex = list.indexOf(this.list[this.playIndex])
|
||||
// console.log(playIndex)
|
||||
let index
|
||||
switch (this.setting.player.togglePlayMethod) {
|
||||
case 'listLoop':
|
||||
index = playIndex === list.length - 1 ? 0 : playIndex + 1
|
||||
break
|
||||
case 'random':
|
||||
index = this.hanldeListRandom(list, playIndex)
|
||||
break
|
||||
case 'list':
|
||||
index = playIndex === list.length - 1 ? -1 : playIndex + 1
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
if (index < 0) return
|
||||
index = this.list.indexOf(list[index])
|
||||
this.setPlayIndex(index)
|
||||
},
|
||||
hanldeListRandom(list, index) {
|
||||
return getRandom(0, list.length)
|
||||
},
|
||||
|
@ -674,7 +573,7 @@ export default {
|
|||
togglePlay() {
|
||||
if (!audio.src) {
|
||||
if (this.restorePlayTime != null) {
|
||||
if (!this.assertApiSupport(this.targetSong.source)) return this.handleNext()
|
||||
if (!this.assertApiSupport(this.targetSong.source)) return this.playNext()
|
||||
this.setUrl(this.targetSong)
|
||||
}
|
||||
return
|
||||
|
@ -703,8 +602,9 @@ export default {
|
|||
this.musicInfo.url = targetSong.typeUrl[type]
|
||||
this.status = this.statusText = this.$t('core.player.geting_url')
|
||||
|
||||
return this.getUrl({ musicInfo: targetSong, originMusic, type, isRefresh }).then(() => {
|
||||
audio.src = this.musicInfo.url = targetSong.typeUrl[type]
|
||||
return this.getUrl({ musicInfo: targetSong, originMusic, type, isRefresh }).then(url => {
|
||||
if ((targetSong !== this.targetSong && originMusic !== this.targetSong) || this.isPlay) return
|
||||
audio.src = this.musicInfo.url = url
|
||||
}).catch(err => {
|
||||
// console.log('err', err.message)
|
||||
if (err.message == requestMsg.cancelRequest) return
|
||||
|
@ -714,13 +614,13 @@ export default {
|
|||
this.status = this.statusText = 'Try toggle source...'
|
||||
|
||||
return (originMusic.otherSource && originMusic.otherSource.length ? Promise.resolve(originMusic.otherSource) : musicSdk.findMusic(originMusic)).then(res => {
|
||||
this.updateMusicInfo({ id: this.listId, index: this.playIndex, data: { otherSource: res } })
|
||||
this.updateMusicInfo({ id: this.listId, index: this.playIndex, data: { otherSource: res }, musicInfo: originMusic })
|
||||
return res
|
||||
}).then(otherSource => {
|
||||
console.log('find otherSource', otherSource)
|
||||
if (otherSource.length) {
|
||||
for (const item of otherSource) {
|
||||
if (retryedSource.includes(item.source)) continue
|
||||
if (retryedSource.includes(item.source) || !this.assertApiSupport(item.source)) continue
|
||||
console.log('try toggle to: ', item.source, item.name, item.singer, item.interval)
|
||||
return this.setUrl(item, isRefresh, false, retryedSource, originMusic)
|
||||
}
|
||||
|
@ -825,13 +725,13 @@ export default {
|
|||
this.setProgressWidth()
|
||||
},
|
||||
handleToMusicLocation() {
|
||||
if (!this.listId || this.listId == 'download') return
|
||||
if (!this.listId || this.listId == '__temp__' || this.listId == 'download') return
|
||||
if (this.playIndex == -1) return
|
||||
this.$router.push({
|
||||
path: 'list',
|
||||
query: {
|
||||
id: this.listId,
|
||||
scrollIndex: this.playIndex,
|
||||
scrollIndex: this.playInfo.playIndex,
|
||||
},
|
||||
})
|
||||
},
|
||||
|
@ -846,7 +746,7 @@ export default {
|
|||
startLoadingTimeout() {
|
||||
// console.log('start load timeout')
|
||||
this.loadingTimeout = setTimeout(() => {
|
||||
this.handleNext()
|
||||
this.playNext()
|
||||
}, 20000)
|
||||
},
|
||||
clearLoadingTimeout() {
|
||||
|
@ -865,7 +765,7 @@ export default {
|
|||
if (skipTime > this.maxPlayTime) skipTime = (this.maxPlayTime - audio.currentTime) / 2
|
||||
if (skipTime - this.mediaBuffer.playTime < 1 || this.maxPlayTime - skipTime < 1) {
|
||||
this.mediaBuffer.playTime = 0
|
||||
this.handleNext()
|
||||
this.playNext()
|
||||
return
|
||||
}
|
||||
this.startBuffering()
|
||||
|
@ -925,13 +825,13 @@ export default {
|
|||
handlePlayDetailAction({ type, data }) {
|
||||
switch (type) {
|
||||
case 'prev':
|
||||
this.handlePrev()
|
||||
this.playPrev()
|
||||
break
|
||||
case 'togglePlay':
|
||||
this.togglePlay()
|
||||
break
|
||||
case 'next':
|
||||
this.handleNext()
|
||||
this.playNext()
|
||||
break
|
||||
case 'progress':
|
||||
this.setProgress(data)
|
||||
|
@ -972,6 +872,28 @@ export default {
|
|||
if (!this.musicInfo.songmid) return
|
||||
this.isShowAddMusicTo = true
|
||||
},
|
||||
handleRestorePlay(restorePlayInfo) {
|
||||
let musicInfo = this.list[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 = restorePlayInfo.time
|
||||
this.maxPlayTime = 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')
|
||||
})
|
||||
|
||||
if (this.setting.player.togglePlayMethod == 'random') this.setPlayedList(this.playMusicInfo)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -138,7 +138,7 @@ export default {
|
|||
// will-change: transform;
|
||||
li {
|
||||
cursor: pointer;
|
||||
min-width: 90px;
|
||||
min-width: 96px;
|
||||
line-height: 34px;
|
||||
// color: @color-btn;
|
||||
padding: 0 10px;
|
||||
|
|
|
@ -74,9 +74,9 @@ export default {
|
|||
'slideOutLeft',
|
||||
'slideOutRight',
|
||||
'slideOutUp',
|
||||
'hinge',
|
||||
// 'hinge',
|
||||
],
|
||||
inClass: 'animated flipInX',
|
||||
inClass: 'animated jackInTheBox',
|
||||
outClass: 'animated flipOutX',
|
||||
unwatchFn: null,
|
||||
}
|
||||
|
|
|
@ -114,6 +114,11 @@ export default {
|
|||
action: 'download',
|
||||
disabled: !this.listMenu.itemMenuControl.download,
|
||||
},
|
||||
{
|
||||
name: this.$t('material.song_list.list_play_later'),
|
||||
action: 'playLater',
|
||||
disabled: !this.listMenu.itemMenuControl.playLater,
|
||||
},
|
||||
{
|
||||
name: this.$t('material.song_list.list_search'),
|
||||
action: 'search',
|
||||
|
@ -173,6 +178,7 @@ export default {
|
|||
itemMenuControl: {
|
||||
play: true,
|
||||
addTo: true,
|
||||
playLater: true,
|
||||
download: true,
|
||||
search: true,
|
||||
sourceDetail: true,
|
||||
|
@ -335,6 +341,7 @@ export default {
|
|||
handleListItemRigthClick(event, index) {
|
||||
this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[this.list[index].source].getMusicDetailPageUrl
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.playLater =
|
||||
this.listMenu.itemMenuControl.download =
|
||||
this.assertApiSupport(this.list[index].source)
|
||||
let dom_selected = this.$refs.dom_tbody.querySelector('tr.selected')
|
||||
|
|
|
@ -3,17 +3,17 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
main(:class="$style.main" v-if="version.isDownloaded")
|
||||
h2 🚀程序更新🚀
|
||||
|
||||
div.scroll(:class="$style.info")
|
||||
div.scroll.select(:class="$style.info")
|
||||
div(:class="$style.current")
|
||||
h3 最新版本:{{version.newVersion.version}}
|
||||
h3 当前版本:{{version.version}}
|
||||
h3 版本变化:
|
||||
p(:class="$style.desc" v-html="version.newVersion.desc")
|
||||
pre(:class="$style.desc" v-text="version.newVersion.desc")
|
||||
div(:class="[$style.history, $style.desc]" v-if="history.length")
|
||||
h3 历史版本:
|
||||
div(:class="$style.item" v-for="ver in history")
|
||||
h4 v{{ver.version}}
|
||||
p(v-html="ver.desc")
|
||||
pre(v-text="ver.desc")
|
||||
div(:class="$style.footer")
|
||||
div(:class="$style.desc")
|
||||
p 新版本已下载完毕,
|
||||
|
@ -27,17 +27,17 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
main(:class="$style.main" v-else-if="version.isError && !version.isUnknow && version.newVersion.version != version.version")
|
||||
h2 ❌ 版本更新出错 ❌
|
||||
|
||||
div.scroll(:class="$style.info")
|
||||
div.scroll.select(:class="$style.info")
|
||||
div(:class="$style.current")
|
||||
h3 最新版本:{{version.newVersion.version}}
|
||||
h3 当前版本:{{version.version}}
|
||||
h3 版本变化:
|
||||
p(:class="$style.desc" v-html="version.newVersion.desc")
|
||||
pre(:class="$style.desc" v-text="version.newVersion.desc")
|
||||
div(:class="[$style.history, $style.desc]" v-if="history.length")
|
||||
h3 历史版本:
|
||||
div(:class="$style.item" v-for="ver in history")
|
||||
h4 v{{ver.version}}
|
||||
p(v-html="ver.desc")
|
||||
pre(v-text="ver.desc")
|
||||
|
||||
div(:class="$style.footer")
|
||||
div(:class="$style.desc")
|
||||
|
@ -58,7 +58,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
main(:class="$style.main" v-else-if="version.isDownloading && version.isTimeOut && !version.isUnknow")
|
||||
h2 ❗️ 新版本下载超时 ❗️
|
||||
div(:class="$style.desc")
|
||||
p 你当前所在网络访问GitHub较慢,导致新版本下载超时(已经下了半个钟了😳),建议手动更新版本!
|
||||
p 你当前所在网络访问GitHub较慢,导致新版本下载超时(已经下了半个钟了😳),你仍可选择继续等,但墙裂建议手动更新版本!
|
||||
p
|
||||
| 你可以去
|
||||
material-btn(min @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop/releases')" tips="点击打开") 软件发布页
|
||||
|
@ -75,7 +75,7 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
main(:class="$style.main" v-else-if="version.isUnknow")
|
||||
h2 ❓ 获取最新版本信息失败 ❓
|
||||
|
||||
div.scroll(:class="$style.info")
|
||||
div.scroll.select(:class="$style.info")
|
||||
div(:class="$style.current")
|
||||
h3 当前版本:{{version.version}}
|
||||
div(:class="$style.desc")
|
||||
|
@ -94,17 +94,17 @@ material-modal(:show="version.showModal" @close="handleClose" v-if="version.newV
|
|||
main(:class="$style.main" v-else)
|
||||
h2 🌟发现新版本🌟
|
||||
|
||||
div.scroll(:class="$style.info")
|
||||
div.scroll.select(:class="$style.info")
|
||||
div(:class="$style.current")
|
||||
h3 最新版本:{{version.newVersion.version}}
|
||||
h3 当前版本:{{version.version}}
|
||||
h3 版本变化:
|
||||
p(:class="$style.desc" v-html="version.newVersion.desc")
|
||||
pre(:class="$style.desc" v-text="version.newVersion.desc")
|
||||
div(:class="[$style.history, $style.desc]" v-if="history.length")
|
||||
h3 历史版本:
|
||||
div(:class="$style.item" v-for="ver in history")
|
||||
h4 v{{ver.version}}
|
||||
p(v-html="ver.desc")
|
||||
pre(v-text="ver.desc")
|
||||
|
||||
div(:class="$style.footer")
|
||||
div(:class="$style.desc")
|
||||
|
@ -146,7 +146,7 @@ export default {
|
|||
progress() {
|
||||
return this.version.downloadProgress
|
||||
? `${this.version.downloadProgress.percent.toFixed(2)}% - ${sizeFormate(this.version.downloadProgress.transferred)}/${sizeFormate(this.version.downloadProgress.total)} - ${sizeFormate(this.version.downloadProgress.bytesPerSecond)}/s`
|
||||
: '初始化中...'
|
||||
: '处理更新中...'
|
||||
},
|
||||
isIgnored() {
|
||||
return this.setting.ignoreVersion == this.version.newVersion.version
|
||||
|
@ -207,6 +207,11 @@ export default {
|
|||
font-size: 14px;
|
||||
line-height: 1.3;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
text-align: justify;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "Play",
|
||||
"list_play_later": "Play later",
|
||||
"list_add_to": "Add to ...",
|
||||
"list_download": "Download",
|
||||
"list_search": "Search",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"menu_play": "Play",
|
||||
"menu_play_later": "Play later",
|
||||
"menu_start": "Start task",
|
||||
"menu_pause": "Pause Task",
|
||||
"menu_file": "Locate File",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"lists_sync": "Sync",
|
||||
"lists_remove": "Remove",
|
||||
"list_play": "Play",
|
||||
"list_play_later": "Play later",
|
||||
"list_copy_name": "Copy name",
|
||||
"list_add_to": "Add to ...",
|
||||
"list_move_to": "Move to ...",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "Play",
|
||||
"list_play_later": "Play later",
|
||||
"list_add_to": "Add to ...",
|
||||
"list_download": "Download",
|
||||
"list_source_detail": "Song Page",
|
||||
|
@ -10,6 +11,7 @@
|
|||
"time": "Length",
|
||||
"lossless": "SQ",
|
||||
"high_quality": "HQ",
|
||||
"loding_list": "Loading...",
|
||||
"no_item": "Search what I want to 😉",
|
||||
"hot_search": "Top Searches",
|
||||
"history_search": "History Searches",
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
"basic": "General",
|
||||
"basic_theme": "Theme",
|
||||
"basic_show_animation": "Show switching animation",
|
||||
"basic_animation_title": "Animation effect of the pop-up layer",
|
||||
"basic_animation": "Random pop-up animation",
|
||||
"basic_source_title": "Choose a music source",
|
||||
"basic_source_test": "Test API (Available for most software features)",
|
||||
|
@ -21,8 +20,7 @@
|
|||
"basic_window_size_larger": "Larger",
|
||||
"basic_window_size_oversized": "Oversized",
|
||||
"basic_window_size_huge": "Huge",
|
||||
"basic_to_tray_title": "Minimize it to the system tray without closing the software when closing",
|
||||
"basic_to_tray": "Minimize to system tray when closing",
|
||||
"basic_to_tray": "Do not exit the software when closing the software and minimize it to the system tray",
|
||||
"basic_lang_title": "The language displayed in the software",
|
||||
"basic_lang": "Language",
|
||||
"basic_control_btn_position": "Control Button Position",
|
||||
|
@ -30,21 +28,13 @@
|
|||
"basic_control_btn_position_right": "Right",
|
||||
|
||||
"play": "Play",
|
||||
"play_toggle_title": "If none selected, it stopped when the music playing is done.",
|
||||
"play_toggle": "Playback mode",
|
||||
"play_toggle_list_loop": "Playlist repeat",
|
||||
"play_toggle_random": "Playlist shuffle",
|
||||
"play_toggle_list": "Play in order",
|
||||
"play_toggle_single_loop": "Single repeat",
|
||||
"play_save_play_time": "Remember playback progress",
|
||||
"play_lyric_transition": "Show lyrics translation",
|
||||
"play_quality_title": "The 320k quality is preferred for playing",
|
||||
"play_quality": "Prefer High Quality 320k",
|
||||
"play_task_bar_title": "Show playing progress on the taskbar",
|
||||
"play_task_bar": "Taskbar play progress bar",
|
||||
"play_quality": "Play 320K quality songs first (if supported)",
|
||||
"play_task_bar": "Show playing progress on the taskbar",
|
||||
"play_mediaDevice_title": "Select a media device for audio output",
|
||||
"play_mediaDevice": "Audio output",
|
||||
"play_mediaDevice_remove_stop_play": "Whether to pause playback when the audio output device is changed",
|
||||
"play_mediaDevice_remove_stop_play_title": "Whether to pause the song when the current sound output device is changed",
|
||||
"play_mediaDevice_remove_stop_play": "Pause the song when the current sound output device is changed",
|
||||
|
||||
"desktop_lyric": "Desktop Lyric Settings",
|
||||
"desktop_lyric_enable": "Display lyrics",
|
||||
|
@ -53,18 +43,13 @@
|
|||
"desktop_lyric_lock_screen": "It is not allowed to drag the lyrics window out of the main screen",
|
||||
|
||||
"search": "Search",
|
||||
"search_hot_title": "Select whether to show popular searches",
|
||||
"search_hot": "Top Searches",
|
||||
"search_history_title": "Select whether to show search history",
|
||||
"search_history": "Search history",
|
||||
"search_focus_search_box_title": "Whether the search box is automatically focused on startup",
|
||||
"search_focus_search_box": "Whether the search box is focused on startup",
|
||||
"search_focus_search_box": "Automatically focus the search box on startup",
|
||||
|
||||
"list": "List",
|
||||
"list_source_title": "Select whether to show music source",
|
||||
"list_source": "Select whether to show music source (for Your Library only)",
|
||||
"list_scroll_title": "Select whether to remember the playlist scrollbar position",
|
||||
"list_scroll": "Remember playlist scrolling position (for Your library only)",
|
||||
"list_source": "Show song source (only valid for my music category)",
|
||||
"list_scroll": "Remember the position of the scroll bar of the playlist (only valid for my music classification)",
|
||||
|
||||
"download": "Download",
|
||||
"download_enable": "Whether to enable download function",
|
||||
|
@ -150,7 +135,7 @@
|
|||
"update_latest": "The software is up-to-date, enjoy yourself!🥂",
|
||||
"update_open_version_modal_btn": "Open the update window🚀",
|
||||
"update_checking": "Checking for updates...",
|
||||
"update_init": "Initializing update...",
|
||||
"update_init": "Processing update...",
|
||||
|
||||
"about": "About lx-music-desktop",
|
||||
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
"tip_2": "If you encounter a link to a playlist that cannot be opened, welcome feedback",
|
||||
"tip_3": "Kugou source does not support opening with playlist ID, but supports Kugou code opening",
|
||||
"play_all": "Play",
|
||||
"play_later": "Play later",
|
||||
"add_all": "Collect"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍后播放",
|
||||
"list_add_to": "添加到...",
|
||||
"list_download": "下载",
|
||||
"list_source_detail": "歌曲详情页",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"menu_play": "播放",
|
||||
"menu_play_later": "稍后播放",
|
||||
"menu_start": "开始任务",
|
||||
"menu_pause": "暂停任务",
|
||||
"menu_file": "定位文件",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"lists_sync": "同步",
|
||||
"lists_remove": "删除",
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍后播放",
|
||||
"list_copy_name": "复制歌曲名",
|
||||
"list_source_detail": "歌曲详情页",
|
||||
"list_add_to": "添加到...",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍后播放",
|
||||
"list_add_to": "添加到...",
|
||||
"list_download": "下载",
|
||||
"list_source_detail": "歌曲详情页",
|
||||
|
@ -10,6 +11,7 @@
|
|||
"time": "时长",
|
||||
"lossless": "无损",
|
||||
"high_quality": "高品质",
|
||||
"loding_list": "加载中...",
|
||||
"no_item": "搜我所想~~😉",
|
||||
"hot_search": "热门搜索",
|
||||
"history_search": "历史搜索",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"basic": "基本设置",
|
||||
"basic_theme": "主题颜色",
|
||||
"basic_animation_title": "弹出层的动画效果",
|
||||
"basic_animation": "弹出层随机动画",
|
||||
"basic_show_animation": "显示切换动画",
|
||||
"basic_source_title": "选择音乐来源",
|
||||
|
@ -21,8 +20,7 @@
|
|||
"basic_window_size_larger": "较大",
|
||||
"basic_window_size_oversized": "超大",
|
||||
"basic_window_size_huge": "巨大",
|
||||
"basic_to_tray_title": "关闭时不退出软件将其最小化到系统托盘",
|
||||
"basic_to_tray": "关闭时最小化到系统托盘",
|
||||
"basic_to_tray": "关闭软件时不退出软件将其最小化到系统托盘",
|
||||
"basic_lang_title": "软件显示的语言",
|
||||
"basic_lang": "语言",
|
||||
"basic_control_btn_position": "控制按钮位置",
|
||||
|
@ -30,21 +28,13 @@
|
|||
"basic_control_btn_position_right": "右边",
|
||||
|
||||
"play": "播放设置",
|
||||
"play_toggle_title": "都不选时播放完当前歌曲就停止播放",
|
||||
"play_toggle": "歌曲切换方式",
|
||||
"play_toggle_list_loop": "列表循环",
|
||||
"play_toggle_random": "列表随机",
|
||||
"play_toggle_list": "顺序播放",
|
||||
"play_toggle_single_loop": "单曲循环",
|
||||
"play_save_play_time": "记住播放进度",
|
||||
"play_lyric_transition": "显示歌词翻译",
|
||||
"play_quality_title": "启用时将优先播放320K品质的歌曲",
|
||||
"play_quality": "优先播放高品质音乐",
|
||||
"play_task_bar_title": "在任务栏上显示当前歌曲播放进度",
|
||||
"play_task_bar": "任务栏播放进度条",
|
||||
"play_quality": "优先播放320K品质的歌曲(如果支持)",
|
||||
"play_task_bar": "在任务栏上显示当前歌曲播放进度",
|
||||
"play_mediaDevice_title": "选择声音输出的媒体设备",
|
||||
"play_mediaDevice": "音频输出",
|
||||
"play_mediaDevice_remove_stop_play": "音频输出设备被改变时是否暂停播放",
|
||||
"play_mediaDevice_remove_stop_play_title": "当前的声音输出设备被改变时是否暂停播放歌曲",
|
||||
"play_mediaDevice_remove_stop_play": "当前的声音输出设备被改变时暂停播放歌曲",
|
||||
|
||||
"desktop_lyric": "桌面歌词设置",
|
||||
"desktop_lyric_enable": "显示歌词",
|
||||
|
@ -53,18 +43,13 @@
|
|||
"desktop_lyric_lock_screen": "不允许歌词窗口拖出主屏幕之外",
|
||||
|
||||
"search": "搜索设置",
|
||||
"search_hot_title": "是否显示热门搜索",
|
||||
"search_hot": "热门搜索",
|
||||
"search_history_title": "是否显示历史搜索记录",
|
||||
"search_history": "搜索历史",
|
||||
"search_focus_search_box_title": "启动时是否自动聚焦搜索框",
|
||||
"search_focus_search_box": "启动时是否聚焦搜索框",
|
||||
"search_hot": "显示热门搜索",
|
||||
"search_history": "显示历史搜索记录",
|
||||
"search_focus_search_box": "启动时自动聚焦搜索框",
|
||||
|
||||
"list": "列表设置",
|
||||
"list_source_title": "是否显示歌曲源",
|
||||
"list_source": "是否显示歌曲源(仅对我的音乐分类有效)",
|
||||
"list_scroll_title": "是否记住播放列表滚动条位置",
|
||||
"list_scroll": "记住列表滚动位置(仅对我的音乐分类有效)",
|
||||
"list_source": "显示歌曲源(仅对我的音乐分类有效)",
|
||||
"list_scroll": "记住播放列表滚动条位置(仅对我的音乐分类有效)",
|
||||
|
||||
"download": "下载设置",
|
||||
"download_enable": "是否启用下载功能",
|
||||
|
@ -150,7 +135,7 @@
|
|||
"update_latest": "软件已是最新,尽情地体验吧~🥂",
|
||||
"update_open_version_modal_btn": "打开更新窗口 🚀",
|
||||
"update_checking": "检查更新中...",
|
||||
"update_init": "更新初始化中...",
|
||||
"update_init": "处理更新中...",
|
||||
|
||||
"about": "关于洛雪音乐",
|
||||
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
"tip_2": "若遇到无法打开的歌单链接,欢迎反馈",
|
||||
"tip_3": "酷狗源不支持用歌单ID打开,但支持酷狗码打开",
|
||||
"play_all": "播放",
|
||||
"play_later": "稍后播放",
|
||||
"add_all": "收藏"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍後播放",
|
||||
"list_add_to": "添加到...",
|
||||
"list_download": "下載",
|
||||
"list_search": "搜索",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"menu_play": "播放",
|
||||
"menu_play_later": "稍後播放",
|
||||
"menu_start": "開始任務",
|
||||
"menu_pause": "暫停任務",
|
||||
"menu_file": "定位文件",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"lists_sync": "同步",
|
||||
"lists_remove": "刪除",
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍後播放",
|
||||
"list_copy_name": "複製歌曲名",
|
||||
"list_add_to": "添加到...",
|
||||
"list_move_to": "移動到...",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"list_play": "播放",
|
||||
"list_play_later": "稍後播放",
|
||||
"list_add_to": "添加到...",
|
||||
"list_download": "下載",
|
||||
"list_source_detail": "歌曲詳情頁",
|
||||
|
@ -10,6 +11,7 @@
|
|||
"time": "時長",
|
||||
"lossless": "無損",
|
||||
"high_quality": "高品質",
|
||||
"loding_list": "加載中...",
|
||||
"no_item": "搜我所想~~😉",
|
||||
"hot_search": "熱門搜索",
|
||||
"history_search": "歷史搜索",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
{
|
||||
"basic": "基本設置",
|
||||
"basic_theme": "主題顏色",
|
||||
"basic_animation_title": "彈出層的動畫效果",
|
||||
"basic_animation": "彈出層隨機動畫",
|
||||
"basic_show_animation": "顯示切換動畫",
|
||||
"basic_source_title": "選擇音樂來源",
|
||||
|
@ -21,46 +20,37 @@
|
|||
"basic_window_size_larger": "較大",
|
||||
"basic_window_size_oversized": "超大",
|
||||
"basic_window_size_huge": "巨大",
|
||||
"basic_to_tray_title": "關閉時不退出軟件將其最小化到系統托盤",
|
||||
"basic_to_tray": "關閉時最小化到系統托盤",
|
||||
"basic_to_tray": "關閉軟件時不退出軟件將其最小化到系統托盤",
|
||||
"basic_lang_title": "軟件顯示的語言",
|
||||
"basic_lang": "語言",
|
||||
"basic_control_btn_position": "控制按鈕位置",
|
||||
"basic_control_btn_position_left": "左邊",
|
||||
"basic_control_btn_position_right": "右邊",
|
||||
|
||||
"play": "播放設置",
|
||||
"play_toggle_title": "都不選時播放完當前歌曲就停止播放",
|
||||
"play_toggle": "歌曲切換方式",
|
||||
"play_toggle_list_loop": "列表循環",
|
||||
"play_toggle_random": "列表隨機",
|
||||
"play_toggle_list": "順序播放",
|
||||
"play_toggle_single_loop": "單曲循環",
|
||||
"play_save_play_time": "記住播放進度",
|
||||
"play_lyric_transition": "顯示歌詞翻譯",
|
||||
"play_quality_title": "啟用時將優先播放320K品質的歌曲",
|
||||
"play_quality": "優先播放高品質音樂",
|
||||
"play_task_bar_title": "在任務欄上顯示當前歌曲播放進度",
|
||||
"play_task_bar": "任務欄播放進度條",
|
||||
"play_quality": "優先播放320K品質的歌曲(如果支持)",
|
||||
"play_task_bar": "在任務欄上顯示當前歌曲播放進度",
|
||||
"play_mediaDevice_title": "選擇聲音輸出的媒體設備",
|
||||
"play_mediaDevice": "音頻輸出",
|
||||
"play_mediaDevice_remove_stop_play": "音頻輸出設備被改變時是否暫停播放",
|
||||
"play_mediaDevice_remove_stop_play_title": "當前的聲音輸出設備被改變時是否暫停播放歌曲",
|
||||
"play_mediaDevice_remove_stop_play": "當前的聲音輸出設備被改變時暫停播放歌曲",
|
||||
|
||||
"desktop_lyric": "桌面歌詞設置",
|
||||
"desktop_lyric_enable": "顯示歌詞",
|
||||
"desktop_lyric_lock": "鎖定歌詞",
|
||||
"desktop_lyric_always_on_top": "使歌詞總是在其他窗口之上",
|
||||
"desktop_lyric_lock_screen": "不允許歌詞窗口拖出主屏幕之外",
|
||||
|
||||
"search": "搜索設置",
|
||||
"search_hot_title": "是否顯示熱門搜索",
|
||||
"search_hot": "熱門搜索",
|
||||
"search_history_title": "是否顯示歷史搜索記錄",
|
||||
"search_history": "搜索歷史",
|
||||
"search_focus_search_box_title": "啟動時是否自動聚焦搜索框",
|
||||
"search_focus_search_box": "啟動時是否聚焦搜索框",
|
||||
"search_hot": "顯示熱門搜索",
|
||||
"search_history": "顯示歷史搜索記錄",
|
||||
"search_focus_search_box": "啟動時自動聚焦搜索框",
|
||||
|
||||
"list": "列表設置",
|
||||
"list_source_title": "是否顯示歌曲源",
|
||||
"list_source": "是否顯示歌曲源(僅對我的音樂分類有效)",
|
||||
"list_scroll_title": "是否記住播放列表滾動條位置",
|
||||
"list_scroll": "記住列表滾動位置(僅對我的音樂分類有效)",
|
||||
"list_source": "顯示歌曲源(僅對我的音樂分類有效)",
|
||||
"list_scroll": "記住播放列表滾動條位置(僅對我的音樂分類有效)",
|
||||
|
||||
"download": "下載設置",
|
||||
"download_enable": "是否啟用下載功能",
|
||||
"download_path_title": "下載歌曲保存的路徑",
|
||||
|
@ -79,6 +69,7 @@
|
|||
"download_name2": "歌手 - 歌名",
|
||||
"download_name3": "歌名",
|
||||
"download_select_save_path": "選擇歌曲保存路徑",
|
||||
|
||||
"hot_key": "快捷鍵設置",
|
||||
"hot_key_local_title": "軟件內快捷鍵",
|
||||
"hot_key_global_title": "全局快捷鍵",
|
||||
|
@ -98,15 +89,18 @@
|
|||
"hot_key_desktop_lyric_toggle_visible": "開/關桌面歌詞",
|
||||
"hot_key_desktop_lyric_toggle_lock": "桌面歌詞鎖定切換",
|
||||
"hot_key_desktop_lyric_toggle_always_top": "桌面歌詞置頂切換",
|
||||
|
||||
"network": "網絡設置",
|
||||
"network_proxy_title": "HTTP代理設置(亂設置軟件將無法聯網)",
|
||||
"network_proxy_host": "主機",
|
||||
"network_proxy_port": "端口",
|
||||
"network_proxy_username": "用戶名",
|
||||
"network_proxy_password": "密碼",
|
||||
|
||||
"odc": "強迫症設置",
|
||||
"odc_clear_search_input": "離開搜索界面時清空搜索框",
|
||||
"odc_clear_search_list": "離開搜索界面時清空搜索列表",
|
||||
|
||||
"backup": "備份與恢復",
|
||||
"backup_part": "部分數據(列表數據包括試聽列表、收藏列表、用戶自定義列表,設置數據不包括快捷鍵設置)",
|
||||
"backup_part_import_list": "導入列表",
|
||||
|
@ -121,7 +115,8 @@
|
|||
"backup_part_import_setting_desc": "選擇配置文件",
|
||||
"backup_part_export_setting_desc": "選擇設置保存位置",
|
||||
"backup_part_import_list_desc": "選擇列表文件",
|
||||
"backup_part_export_list_desc": "選擇列表保存位置",
|
||||
"backup_part_export_list_desc": "選擇歌單保存位置",
|
||||
|
||||
"other": "其他",
|
||||
"other_tray_theme": "托盤圖標樣式",
|
||||
"other_tray_theme_native": "純色",
|
||||
|
@ -130,6 +125,7 @@
|
|||
"other_cache_label": "軟件已使用緩存大小:",
|
||||
"other_cache_label_title": "當前已用緩存",
|
||||
"other_cache_clear_btn": "清理緩存",
|
||||
|
||||
"update": "軟件更新",
|
||||
"update_latest_label": "最新版本:",
|
||||
"update_unknown": "未知",
|
||||
|
@ -139,8 +135,11 @@
|
|||
"update_latest": "軟件已是最新,盡情地體驗吧~🥂",
|
||||
"update_open_version_modal_btn": "打開更新窗口 🚀",
|
||||
"update_checking": "檢查更新中...",
|
||||
"update_init": "更新初始化中...",
|
||||
"update_init": "處理更新中...",
|
||||
|
||||
"about": "關於洛雪音樂",
|
||||
|
||||
|
||||
"is_enable": "是否啟用",
|
||||
"is_show": "是否顯示",
|
||||
"click_open": "點擊打開",
|
||||
|
|
|
@ -8,5 +8,6 @@
|
|||
"tip_2": "若遇到無法打開的歌單鏈接,歡迎反饋",
|
||||
"tip_3": "酷狗源不支持用歌單ID打開,但支持酷狗碼打開",
|
||||
"play_all": "播放",
|
||||
"play_later": "稍後播放",
|
||||
"add_all": "收藏"
|
||||
}
|
||||
|
|
|
@ -19,16 +19,31 @@ export default {
|
|||
},
|
||||
getVersionInfo2(state, retryNum = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpGet('https://cdn.stsky.cn/lx-music/desktop/version.json', {
|
||||
httpGet('https://gitee.com/lyswhut/lx-music-desktop-versions/raw/master/version.json', {
|
||||
timeout: 20000,
|
||||
}, (err, resp, body) => {
|
||||
if (!err && !body.version) err = new Error(JSON.stringify(body))
|
||||
if (err) {
|
||||
return ++retryNum > 3
|
||||
? reject(err)
|
||||
? this.dispatch('getVersionInfo3').then(resolve).catch(reject)
|
||||
: this.dispatch('getVersionInfo2', retryNum).then(resolve).catch(reject)
|
||||
}
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
},
|
||||
getVersionInfo3(state, retryNum = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
httpGet('https://cdn.stsky.cn/lx-music/desktop/version.json', {
|
||||
timeout: 20000,
|
||||
}, (err, resp, body) => {
|
||||
if (err) {
|
||||
return ++retryNum > 3
|
||||
? reject(err)
|
||||
: this.dispatch('getVersionInfo3', retryNum).then(resolve).catch(reject)
|
||||
}
|
||||
resolve(body)
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
|
|
|
@ -57,6 +57,20 @@ const mutations = {
|
|||
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 (userList != null) state.userList = userList
|
||||
if (window.localStorage.getItem('isResetOtherSource') != '1') {
|
||||
for (const item of defaultList.list) {
|
||||
if (item.otherSource) item.otherSource = null
|
||||
}
|
||||
for (const item of loveList.list) {
|
||||
if (item.otherSource) item.otherSource = null
|
||||
}
|
||||
for (const list of userList) {
|
||||
for (const item of list.list) {
|
||||
if (item.otherSource) item.otherSource = null
|
||||
}
|
||||
}
|
||||
window.localStorage.setItem('isResetOtherSource', '1')
|
||||
}
|
||||
allListInit(state.defaultList, state.loveList, state.userList)
|
||||
state.isInitedList = true
|
||||
},
|
||||
|
@ -142,9 +156,9 @@ const mutations = {
|
|||
if (!targetList) return
|
||||
targetList.list.splice(0, targetList.list.length)
|
||||
},
|
||||
updateMusicInfo(state, { id, index, data }) {
|
||||
updateMusicInfo(state, { id, index, data, musicInfo = {} }) {
|
||||
let targetList = allList[id]
|
||||
if (!targetList) return
|
||||
if (!targetList) return Object.assign(musicInfo, data)
|
||||
Object.assign(targetList.list[index], data)
|
||||
},
|
||||
createUserList(state, { name, id = `userlist_${Date.now()}`, list = [], source, sourceListId }) {
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import path from 'path'
|
||||
import music from '../../utils/music'
|
||||
import { getRandom, checkPath, assertApiSupport } from '../../utils'
|
||||
|
||||
// state
|
||||
const state = {
|
||||
|
@ -10,20 +12,101 @@ const state = {
|
|||
changePlay: false,
|
||||
isShowPlayerDetail: false,
|
||||
playedList: [],
|
||||
|
||||
playMusicInfo: null,
|
||||
tempPlayList: [],
|
||||
}
|
||||
|
||||
let urlRequest
|
||||
let picRequest
|
||||
let lrcRequest
|
||||
|
||||
const filterList = async({ playedList, listInfo, savePath, commit }) => {
|
||||
// if (this.list.listName === null) return
|
||||
let list
|
||||
let canPlayList = []
|
||||
const filteredPlayedList = playedList.filter(({ listId, isTempPlay }) => listInfo.id === listId && !isTempPlay).map(({ musicInfo }) => musicInfo)
|
||||
if (listInfo.id == 'download') {
|
||||
list = []
|
||||
for (const item of listInfo.list) {
|
||||
const filePath = path.join(savePath, item.fileName)
|
||||
if (!await checkPath(filePath) || !item.isComplate || /\.ape$/.test(filePath)) continue
|
||||
|
||||
canPlayList.push(item)
|
||||
|
||||
// 排除已播放音乐
|
||||
let index = filteredPlayedList.indexOf(item)
|
||||
if (index > -1) {
|
||||
filteredPlayedList.splice(index, 1)
|
||||
continue
|
||||
}
|
||||
list.push(item)
|
||||
}
|
||||
} else {
|
||||
list = listInfo.list.filter(s => {
|
||||
if (!assertApiSupport(s.source)) return false
|
||||
canPlayList.push(s)
|
||||
|
||||
let index = filteredPlayedList.indexOf(s)
|
||||
if (index > -1) {
|
||||
filteredPlayedList.splice(index, 1)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
if (!list.length && playedList.length) {
|
||||
commit('clearPlayedList')
|
||||
return canPlayList
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
list: state => state.listInfo.list,
|
||||
listId: state => state.listInfo.id,
|
||||
changePlay: satte => satte.changePlay,
|
||||
playIndex: state => state.playIndex,
|
||||
playInfo(state) {
|
||||
if (state.playMusicInfo == null) return { listId: null, playIndex: -1, playListId: null, listPlayIndex: -1, isPlayList: false, musicInfo: null }
|
||||
const playListId = state.listInfo.id
|
||||
let listId = state.playMusicInfo.listId
|
||||
const isTempPlay = !!state.playMusicInfo.isTempPlay
|
||||
const isPlayList = listId === playListId
|
||||
let playIndex = -1
|
||||
let listPlayIndex = state.playIndex
|
||||
|
||||
if (listId != '__temp__') {
|
||||
if (isPlayList) {
|
||||
playIndex = state.listInfo.list.indexOf(state.playMusicInfo.musicInfo)
|
||||
if (!isTempPlay) listPlayIndex = playIndex
|
||||
} else {
|
||||
let list = window.allList[listId]
|
||||
if (list) playIndex = list.list.indexOf(state.playMusicInfo.musicInfo)
|
||||
}
|
||||
}
|
||||
// console.log({
|
||||
// listId,
|
||||
// playIndex,
|
||||
// playListId,
|
||||
// listPlayIndex,
|
||||
// isPlayList,
|
||||
// isTempPlay,
|
||||
// musicInfo: state.playMusicInfo.musicInfo,
|
||||
// })
|
||||
return {
|
||||
listId,
|
||||
playIndex,
|
||||
playListId,
|
||||
listPlayIndex,
|
||||
isPlayList,
|
||||
isTempPlay,
|
||||
musicInfo: state.playMusicInfo.musicInfo,
|
||||
}
|
||||
},
|
||||
isShowPlayerDetail: state => state.isShowPlayerDetail,
|
||||
playMusicInfo: state => state.playMusicInfo,
|
||||
playedList: state => state.playedList,
|
||||
tempPlayList: state => state.tempPlayList,
|
||||
}
|
||||
|
||||
// actions
|
||||
|
@ -36,12 +119,13 @@ const actions = {
|
|||
// return Promise.reject(new Error('该歌曲没有可播放的音频'))
|
||||
}
|
||||
if (urlRequest && urlRequest.cancelHttp) urlRequest.cancelHttp()
|
||||
if (musicInfo.typeUrl[type] && !isRefresh) return Promise.resolve()
|
||||
if (musicInfo.typeUrl[type] && !isRefresh) return Promise.resolve(musicInfo.typeUrl[type])
|
||||
urlRequest = music[musicInfo.source].getMusicUrl(musicInfo, type)
|
||||
return urlRequest.promise.then(result => {
|
||||
if (originMusic) commit('setUrl', { musicInfo: originMusic, url: result.url, type })
|
||||
commit('setUrl', { musicInfo, url: result.url, type })
|
||||
return urlRequest.promise.then(({ url }) => {
|
||||
if (originMusic) commit('setUrl', { musicInfo: originMusic, url, type })
|
||||
commit('setUrl', { musicInfo, url, type })
|
||||
urlRequest = null
|
||||
return url
|
||||
}).catch(err => {
|
||||
urlRequest = null
|
||||
return Promise.reject(err)
|
||||
|
@ -78,6 +162,122 @@ const actions = {
|
|||
return Promise.reject(err)
|
||||
})
|
||||
},
|
||||
|
||||
async playPrev({ state, rootState, commit, getters }) {
|
||||
const currentListId = state.listInfo.id
|
||||
const currentList = state.listInfo.list
|
||||
if (state.playedList.length) {
|
||||
// 从已播放列表移除播放列表已删除的歌曲
|
||||
let index
|
||||
for (index = state.playedList.indexOf(state.playMusicInfo) - 1; index > -1; index--) {
|
||||
const playMusicInfo = state.playedList[index]
|
||||
if (playMusicInfo.listId == currentListId && !currentList.includes(playMusicInfo.musicInfo)) {
|
||||
commit('removePlayedList', index)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (index > -1) {
|
||||
commit('setPlayMusicInfo', state.playedList[index])
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let filteredList = await filterList({
|
||||
listInfo: state.listInfo,
|
||||
playedList: state.playedList,
|
||||
savePath: rootState.setting.download.savePath,
|
||||
commit,
|
||||
})
|
||||
if (!filteredList.length) return commit('setPlayMusicInfo', null)
|
||||
const playInfo = getters.playInfo
|
||||
let currentIndex = filteredList.indexOf(currentList[playInfo.listPlayIndex])
|
||||
if (currentIndex == -1) currentIndex = 0
|
||||
let nextIndex = currentIndex
|
||||
if (!playInfo.isTempPlay) {
|
||||
switch (rootState.setting.player.togglePlayMethod) {
|
||||
case 'random':
|
||||
nextIndex = getRandom(0, filteredList.length)
|
||||
break
|
||||
case 'listLoop':
|
||||
case 'list':
|
||||
nextIndex = currentIndex === 0 ? filteredList.length - 1 : currentIndex - 1
|
||||
break
|
||||
case 'singleLoop':
|
||||
break
|
||||
default:
|
||||
nextIndex = -1
|
||||
return
|
||||
}
|
||||
if (nextIndex < 0) return
|
||||
}
|
||||
|
||||
commit('setPlayMusicInfo', {
|
||||
musicInfo: filteredList[nextIndex],
|
||||
listId: currentListId,
|
||||
})
|
||||
},
|
||||
async playNext({ state, rootState, commit, getters }) {
|
||||
if (state.tempPlayList.length) {
|
||||
const playMusicInfo = state.tempPlayList[0]
|
||||
commit('removeTempPlayList', 0)
|
||||
commit('setPlayMusicInfo', playMusicInfo)
|
||||
return
|
||||
}
|
||||
const currentListId = state.listInfo.id
|
||||
const currentList = state.listInfo.list
|
||||
if (state.playedList.length) {
|
||||
// 从已播放列表移除播放列表已删除的歌曲
|
||||
let index
|
||||
for (index = state.playedList.indexOf(state.playMusicInfo) + 1; index < state.playedList.length; index++) {
|
||||
const playMusicInfo = state.playedList[index]
|
||||
if (playMusicInfo.listId == currentListId && !currentList.includes(playMusicInfo.musicInfo)) {
|
||||
commit('removePlayedList', index)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (index < state.playedList.length) {
|
||||
commit('setPlayMusicInfo', state.playedList[index])
|
||||
return
|
||||
}
|
||||
}
|
||||
let filteredList = await filterList({
|
||||
listInfo: state.listInfo,
|
||||
playedList: state.playedList,
|
||||
savePath: rootState.setting.download.savePath,
|
||||
commit,
|
||||
})
|
||||
|
||||
if (!filteredList.length) return commit('setPlayMusicInfo', null)
|
||||
const playInfo = getters.playInfo
|
||||
const currentIndex = filteredList.indexOf(currentList[playInfo.listPlayIndex])
|
||||
let nextIndex = currentIndex
|
||||
switch (rootState.setting.player.togglePlayMethod) {
|
||||
case 'listLoop':
|
||||
nextIndex = currentIndex === filteredList.length - 1 ? 0 : currentIndex + 1
|
||||
break
|
||||
case 'random':
|
||||
nextIndex = getRandom(0, filteredList.length)
|
||||
break
|
||||
case 'list':
|
||||
nextIndex = currentIndex === filteredList.length - 1 ? -1 : currentIndex + 1
|
||||
break
|
||||
case 'singleLoop':
|
||||
break
|
||||
default:
|
||||
nextIndex = -1
|
||||
return
|
||||
}
|
||||
if (nextIndex < 0) return
|
||||
|
||||
commit('setPlayMusicInfo', {
|
||||
musicInfo: filteredList[nextIndex],
|
||||
listId: currentListId,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,23 +294,28 @@ const mutations = {
|
|||
datas.musicInfo.tlrc = datas.tlyric
|
||||
},
|
||||
setList(state, { list, index }) {
|
||||
state.playMusicInfo = {
|
||||
musicInfo: list.list[index],
|
||||
listId: list.id,
|
||||
}
|
||||
state.listInfo = list
|
||||
state.playIndex = index
|
||||
state.changePlay = true
|
||||
// console.log(state.playMusicInfo)
|
||||
if (state.playedList.length) this.commit('player/clearPlayedList')
|
||||
if (state.tempPlayList.length) this.commit('player/clearTempPlayeList')
|
||||
},
|
||||
setPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
state.changePlay = true
|
||||
// console.log(state.changePlay)
|
||||
},
|
||||
fixPlayIndex(state, index) {
|
||||
state.playIndex = index
|
||||
setChangePlay(state) {
|
||||
state.changePlay = true
|
||||
},
|
||||
resetChangePlay(state) {
|
||||
state.changePlay = false
|
||||
},
|
||||
setPlayedList(state, item) {
|
||||
// console.log(item)
|
||||
if (state.playedList.includes(item)) return
|
||||
state.playedList.push(item)
|
||||
},
|
||||
|
@ -118,11 +323,35 @@ const mutations = {
|
|||
state.playedList.splice(index, 1)
|
||||
},
|
||||
clearPlayedList(state) {
|
||||
state.playedList = []
|
||||
state.playedList.splice(0, state.playedList.length)
|
||||
},
|
||||
visiblePlayerDetail(state, visible) {
|
||||
state.isShowPlayerDetail = visible
|
||||
},
|
||||
setTempPlayList(state, list) {
|
||||
state.tempPlayList.push(...list.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true })))
|
||||
if (!state.playMusicInfo) this.commit('player/playNext')
|
||||
},
|
||||
removeTempPlayList(state, index) {
|
||||
state.tempPlayList.splice(index, 1)
|
||||
},
|
||||
clearTempPlayeList(state) {
|
||||
state.tempPlayList.splice(0, state.tempPlayList.length)
|
||||
},
|
||||
|
||||
setPlayMusicInfo(state, playMusicInfo) {
|
||||
let playIndex = state.playIndex
|
||||
if (playMusicInfo == null) {
|
||||
playIndex = -1
|
||||
} else {
|
||||
let listId = playMusicInfo.listId
|
||||
if (listId != '__temp__' && listId === state.listInfo.id) playIndex = state.listInfo.list.indexOf(state.playMusicInfo.musicInfo)
|
||||
}
|
||||
|
||||
state.playMusicInfo = playMusicInfo
|
||||
state.playIndex = playIndex
|
||||
state.changePlay = true
|
||||
},
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -127,7 +127,7 @@ const actions = {
|
|||
}
|
||||
}))
|
||||
}
|
||||
Promise.all(task).then(results => commit('setLists', { results, page }))
|
||||
return Promise.all(task).then(results => commit('setLists', { results, page }))
|
||||
} else {
|
||||
return music[rootState.setting.search.searchSource].musicSearch.search(text, page, limit).catch(error => {
|
||||
console.log(error)
|
||||
|
|
|
@ -232,6 +232,7 @@ export const objectDeepMerge = (target, source, mergedObj) => {
|
|||
* @param {*} url
|
||||
*/
|
||||
export const openUrl = url => {
|
||||
if (!/^https?:\/\//.test(url)) return
|
||||
shell.openExternal(url)
|
||||
}
|
||||
|
||||
|
|
|
@ -59,25 +59,42 @@ export default {
|
|||
|
||||
async findMusic(musicInfo) {
|
||||
const tasks = []
|
||||
const sortSingle = singer => singer.includes('、') ? singer.split('、').sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0)).join('、') : singer
|
||||
const sortMusic = (arr, callback) => {
|
||||
const tempResult = []
|
||||
for (let i = arr.length - 1; i > -1; i--) {
|
||||
const item = arr[i]
|
||||
if (callback(item)) {
|
||||
delete item.sortedSinger
|
||||
tempResult.push(item)
|
||||
arr.splice(i, 1)
|
||||
}
|
||||
}
|
||||
tempResult.reverse()
|
||||
return tempResult
|
||||
}
|
||||
const trimStr = str => typeof str == 'string' ? str.trim() : str
|
||||
const sortedSinger = sortSingle(musicInfo.singer)
|
||||
const musicName = trimStr(musicInfo.name)
|
||||
for (const source of sources.sources) {
|
||||
if (!sources[source.id].musicSearch || source.id === musicInfo.source || source.id === 'xm') continue
|
||||
const sortedSinger = musicInfo.singer.includes('、') ? musicInfo.singer.split('、').sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0)).join('、') : null
|
||||
|
||||
tasks.push(sources[source.id].musicSearch.search(`${musicInfo.name} ${musicInfo.singer || ''}`.trim(), 1, { limit: 10 }).then(res => {
|
||||
tasks.push(sources[source.id].musicSearch.search(`${musicName} ${musicInfo.singer || ''}`.trim(), 1, { limit: 10 }).then(res => {
|
||||
for (const item of res.list) {
|
||||
item.sortedSinger = sortSingle(item.singer)
|
||||
item.name = trimStr(item.name)
|
||||
if (
|
||||
(
|
||||
item.singer === musicInfo.singer &&
|
||||
(item.name === musicInfo.name || item.interval === musicInfo.interval)
|
||||
item.sortedSinger === sortedSinger &&
|
||||
(item.name === musicName || item.interval === musicInfo.interval)
|
||||
) ||
|
||||
(
|
||||
item.interval === musicInfo.interval && item.name === musicInfo.name &&
|
||||
(item.singer.includes(musicInfo.singer) || musicInfo.singer.includes(item.singer))
|
||||
item.interval === musicInfo.interval && item.name === musicName &&
|
||||
(item.sortedSinger.includes(sortedSinger) || sortedSinger.includes(item.sortedSinger))
|
||||
) ||
|
||||
(
|
||||
sortedSinger &&
|
||||
item.singer.includes('、') &&
|
||||
item.singer.split('、').sort((a, b) => a.charCodeAt(0) - b.charCodeAt(0)).join('、') === sortedSinger
|
||||
item.name === musicName && item.albumName === musicInfo.albumName &&
|
||||
item.interval === musicInfo.interval
|
||||
)
|
||||
) {
|
||||
return item
|
||||
|
@ -89,35 +106,13 @@ export default {
|
|||
const result = (await Promise.all(tasks)).filter(s => s)
|
||||
const newResult = []
|
||||
if (result.length) {
|
||||
for (let i = result.length - 1; i > -1; i--) {
|
||||
const item = result[i]
|
||||
if (item.singer === musicInfo.singer && item.name === musicInfo.name && item.interval === musicInfo.interval) {
|
||||
newResult.push(item)
|
||||
result.splice(i, 1)
|
||||
}
|
||||
newResult.push(...sortMusic(result, item => item.sortedSinger === sortedSinger && item.name === musicName && item.interval === musicInfo.interval))
|
||||
newResult.push(...sortMusic(result, item => item.sortedSinger === sortedSinger && item.interval === musicInfo.interval))
|
||||
newResult.push(...sortMusic(result, item => item.name === musicName && item.sortedSinger === sortedSinger && item.albumName === musicInfo.albumName))
|
||||
newResult.push(...sortMusic(result, item => item.sortedSinger === sortedSinger && item.name === musicName))
|
||||
for (const item of result) {
|
||||
delete item.sortedSinger
|
||||
}
|
||||
for (let i = result.length - 1; i > -1; i--) {
|
||||
const item = result[i]
|
||||
if (item.singer === musicInfo.singer && item.interval === musicInfo.interval) {
|
||||
newResult.push(item)
|
||||
result.splice(i, 1)
|
||||
}
|
||||
}
|
||||
for (let i = result.length - 1; i > -1; i--) {
|
||||
const item = result[i]
|
||||
if (item.name === musicInfo.name && item.singer === musicInfo.singer && item.albumName === musicInfo.albumName) {
|
||||
newResult.push(item)
|
||||
result.splice(i, 1)
|
||||
}
|
||||
}
|
||||
for (let i = result.length - 1; i > -1; i--) {
|
||||
const item = result[i]
|
||||
if (item.singer === musicInfo.singer && item.name === musicInfo.name) {
|
||||
newResult.push(item)
|
||||
result.splice(i, 1)
|
||||
}
|
||||
}
|
||||
newResult.reverse()
|
||||
newResult.push(...result)
|
||||
}
|
||||
// console.log(newResult)
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
import { xmRequest } from './util'
|
||||
// import { xmRequest } from './util'
|
||||
|
||||
export default {
|
||||
_requestObj: null,
|
||||
async getList(retryNum = 0) {
|
||||
if (this._requestObj) this._requestObj.cancelHttp()
|
||||
if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
// if (this._requestObj) this._requestObj.cancelHttp()
|
||||
// if (retryNum > 2) return Promise.reject(new Error('try max num'))
|
||||
|
||||
const _requestObj = xmRequest('/api/search/getHotSearchWords')
|
||||
const { body, statusCode } = await _requestObj.promise
|
||||
// console.log(body)
|
||||
if (statusCode != 200 || body.code !== 'SUCCESS') return this.getList(++retryNum)
|
||||
// const _requestObj = xmRequest('/api/search/getHotSearchWords')
|
||||
// const { body, statusCode } = await _requestObj.promise
|
||||
// // console.log(body)
|
||||
// if (statusCode != 200 || body.code !== 'SUCCESS') return this.getList(++retryNum)
|
||||
// // console.log(body, statusCode)
|
||||
return { source: 'xm', list: this.filterList(body.result.data.hotWords) }
|
||||
// return { source: 'xm', list: this.filterList(body.result.data.hotWords) }
|
||||
return { source: 'xm', list: [] }
|
||||
},
|
||||
filterList(rawList) {
|
||||
return rawList.map(item => item.word)
|
||||
|
|
|
@ -96,7 +96,7 @@ export const xmRequest = (path, params = '') => {
|
|||
if (resp.body.code !== 'SUCCESS' && resp.body.rgv587_flag == 'sm') {
|
||||
window.globalObj.xm.isShowVerify = true
|
||||
return wait(300).then(() => {
|
||||
return rendererInvoke(NAMES.mainWindow.handle_xm_verify_open, 'https:' + resp.body.url).then(x5sec => {
|
||||
return rendererInvoke(NAMES.mainWindow.handle_xm_verify_open, /^https:/.test(resp.body.url) ? resp.body.url : 'https:' + resp.body.url).then(x5sec => {
|
||||
handleSaveToken({ cookies: { x5sec } })
|
||||
// console.log(x5sec)
|
||||
window.globalObj.xm.isShowVerify = false
|
||||
|
|
|
@ -45,7 +45,7 @@ export default {
|
|||
return {
|
||||
clickTime: window.performance.now(),
|
||||
clickIndex: -1,
|
||||
selectdData: [],
|
||||
selectedData: [],
|
||||
isShowDownloadMultiple: false,
|
||||
tabId: 'all',
|
||||
keyEvent: {
|
||||
|
@ -59,6 +59,7 @@ export default {
|
|||
play: true,
|
||||
start: true,
|
||||
pause: true,
|
||||
playLater: true,
|
||||
file: true,
|
||||
search: true,
|
||||
remove: true,
|
||||
|
@ -74,13 +75,13 @@ export default {
|
|||
computed: {
|
||||
...mapGetters(['setting']),
|
||||
...mapGetters('download', ['list', 'downloadStatus']),
|
||||
...mapGetters('player', ['listId', 'playIndex']),
|
||||
...mapGetters('player', ['playInfo']),
|
||||
isPlayList() {
|
||||
return this.listId == 'download'
|
||||
return this.playInfo.listId == 'download'
|
||||
},
|
||||
playListIndex() {
|
||||
if (this.listId != 'download' || !this.list.length) return
|
||||
let info = this.list[this.playIndex]
|
||||
if (this.playInfo.listId != 'download' || !this.list.length) return
|
||||
let info = this.list[this.playInfo.playIndex]
|
||||
if (!info) return -1
|
||||
let key = info.key
|
||||
return this.showList.findIndex(i => i.key == key)
|
||||
|
@ -140,6 +141,11 @@ export default {
|
|||
action: 'pause',
|
||||
hide: !this.listMenu.itemMenuControl.pause,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.download.menu_play_later'),
|
||||
action: 'playLater',
|
||||
hide: !this.listMenu.itemMenuControl.playLater,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.download.menu_file'),
|
||||
action: 'file',
|
||||
|
@ -229,7 +235,7 @@ export default {
|
|||
},
|
||||
handleSelectData(event, clickIndex) {
|
||||
if (this.keyEvent.isShiftDown) {
|
||||
if (this.selectdData.length) {
|
||||
if (this.selectedData.length) {
|
||||
let lastSelectIndex = this.lastSelectIndex
|
||||
this.removeAllSelect()
|
||||
if (lastSelectIndex != clickIndex) {
|
||||
|
@ -240,8 +246,8 @@ export default {
|
|||
clickIndex = temp
|
||||
isNeedReverse = true
|
||||
}
|
||||
this.selectdData = this.showList.slice(lastSelectIndex, clickIndex + 1)
|
||||
if (isNeedReverse) this.selectdData.reverse()
|
||||
this.selectedData = this.showList.slice(lastSelectIndex, clickIndex + 1)
|
||||
if (isNeedReverse) this.selectedData.reverse()
|
||||
let nodes = this.$refs.dom_tbody.childNodes
|
||||
do {
|
||||
nodes[lastSelectIndex].classList.add('active')
|
||||
|
@ -250,24 +256,24 @@ export default {
|
|||
}
|
||||
} else {
|
||||
event.currentTarget.classList.add('active')
|
||||
this.selectdData.push(this.showList[clickIndex])
|
||||
this.selectedData.push(this.showList[clickIndex])
|
||||
this.lastSelectIndex = clickIndex
|
||||
}
|
||||
} else if (this.keyEvent.isModDown) {
|
||||
this.lastSelectIndex = clickIndex
|
||||
let item = this.showList[clickIndex]
|
||||
let index = this.selectdData.indexOf(item)
|
||||
let index = this.selectedData.indexOf(item)
|
||||
if (index < 0) {
|
||||
this.selectdData.push(item)
|
||||
this.selectedData.push(item)
|
||||
event.currentTarget.classList.add('active')
|
||||
} else {
|
||||
this.selectdData.splice(index, 1)
|
||||
this.selectedData.splice(index, 1)
|
||||
event.currentTarget.classList.remove('active')
|
||||
}
|
||||
} else if (this.selectdData.length) this.removeAllSelect()
|
||||
} else if (this.selectedData.length) this.removeAllSelect()
|
||||
},
|
||||
removeAllSelect() {
|
||||
this.selectdData = []
|
||||
this.selectedData = []
|
||||
let dom_tbody = this.$refs.dom_tbody
|
||||
if (!dom_tbody) return
|
||||
let nodes = dom_tbody.querySelectorAll('.active')
|
||||
|
@ -306,6 +312,14 @@ export default {
|
|||
case 'remove':
|
||||
this.removeTask(item)
|
||||
break
|
||||
case 'playLater':
|
||||
if (this.selectedData.length) {
|
||||
this.setTempPlayList(this.selectedData.map(s => ({ listId: 'download', musicInfo: s })))
|
||||
this.removeAllSelect()
|
||||
} else {
|
||||
this.setTempPlayList([{ listId: 'download', musicInfo: item }])
|
||||
}
|
||||
break
|
||||
case 'file':
|
||||
this.handleOpenFolder(item.filePath)
|
||||
break
|
||||
|
@ -316,7 +330,7 @@ export default {
|
|||
},
|
||||
handleSelectAllData() {
|
||||
this.removeAllSelect()
|
||||
this.selectdData = [...this.showList]
|
||||
this.selectedData = [...this.showList]
|
||||
|
||||
let nodes = this.$refs.dom_tbody.childNodes
|
||||
for (const node of nodes) {
|
||||
|
@ -324,19 +338,19 @@ export default {
|
|||
}
|
||||
},
|
||||
// async handleFlowBtnClick(action) {
|
||||
// let selectdData = [...this.selectdData]
|
||||
// let selectedData = [...this.selectedData]
|
||||
// this.removeAllSelect()
|
||||
// await this.$nextTick()
|
||||
|
||||
// switch (action) {
|
||||
// case 'start':
|
||||
// this.startTasks(selectdData)
|
||||
// this.startTasks(selectedData)
|
||||
// break
|
||||
// case 'pause':
|
||||
// this.pauseTasks(selectdData)
|
||||
// this.pauseTasks(selectedData)
|
||||
// break
|
||||
// case 'remove':
|
||||
// this.removeTasks(selectdData)
|
||||
// this.removeTasks(selectedData)
|
||||
// break
|
||||
// }
|
||||
// },
|
||||
|
@ -353,7 +367,7 @@ export default {
|
|||
})
|
||||
},
|
||||
handleTabChange() {
|
||||
this.selectdData = []
|
||||
this.selectedData = []
|
||||
},
|
||||
handleListItemRigthClick(event, index) {
|
||||
this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[this.showList[index].musicInfo.source].getMusicDetailPageUrl
|
||||
|
@ -368,16 +382,19 @@ export default {
|
|||
let item = this.showList[index]
|
||||
if (item.isComplate) {
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.playLater =
|
||||
this.listMenu.itemMenuControl.file = true
|
||||
this.listMenu.itemMenuControl.start =
|
||||
this.listMenu.itemMenuControl.pause = false
|
||||
} else if (item.status === this.downloadStatus.ERROR || item.status === this.downloadStatus.PAUSE) {
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.pause =
|
||||
this.listMenu.itemMenuControl.file = false
|
||||
this.listMenu.itemMenuControl.start = true
|
||||
// } else if (item.status === this.downloadStatus.ERROR || item.status === this.downloadStatus.PAUSE) {
|
||||
// this.listMenu.itemMenuControl.play =
|
||||
// this.listMenu.itemMenuControl.playLater =
|
||||
// this.listMenu.itemMenuControl.pause =
|
||||
// this.listMenu.itemMenuControl.file = false
|
||||
// this.listMenu.itemMenuControl.start = true
|
||||
} else {
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.playLater =
|
||||
this.listMenu.itemMenuControl.start =
|
||||
this.listMenu.itemMenuControl.file = false
|
||||
this.listMenu.itemMenuControl.pause = true
|
||||
|
@ -407,10 +424,10 @@ export default {
|
|||
if (item) this.handlePlay(item)
|
||||
break
|
||||
case 'start':
|
||||
if (this.selectdData.length) {
|
||||
let selectdData = [...this.selectdData]
|
||||
if (this.selectedData.length) {
|
||||
let selectedData = [...this.selectedData]
|
||||
this.removeAllSelect()
|
||||
this.startTasks(selectdData)
|
||||
this.startTasks(selectedData)
|
||||
} else {
|
||||
item = this.showList[index]
|
||||
if (item) this.startTask(item)
|
||||
|
@ -420,10 +437,10 @@ export default {
|
|||
}
|
||||
break
|
||||
case 'pause':
|
||||
if (this.selectdData.length) {
|
||||
let selectdData = [...this.selectdData]
|
||||
if (this.selectedData.length) {
|
||||
let selectedData = [...this.selectedData]
|
||||
this.removeAllSelect()
|
||||
this.pauseTasks(selectdData)
|
||||
this.pauseTasks(selectedData)
|
||||
} else {
|
||||
item = this.showList[index]
|
||||
if (item) this.pauseTask(item)
|
||||
|
@ -443,10 +460,10 @@ export default {
|
|||
if (item) this.handleSearch(item.musicInfo)
|
||||
break
|
||||
case 'remove':
|
||||
if (this.selectdData.length) {
|
||||
let selectdData = [...this.selectdData]
|
||||
if (this.selectedData.length) {
|
||||
let selectedData = [...this.selectedData]
|
||||
this.removeAllSelect()
|
||||
this.removeTasks(selectdData)
|
||||
this.removeTasks(selectedData)
|
||||
} else {
|
||||
item = this.showList[index]
|
||||
if (item) this.removeTask(item)
|
||||
|
|
|
@ -77,7 +77,7 @@ export default {
|
|||
...mapActions('leaderboard', ['getBoardsList', 'getList']),
|
||||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('list', ['listAdd', 'listAddMultiple']),
|
||||
...mapMutations('player', ['setList']),
|
||||
...mapMutations('player', ['setList', 'setTempPlayList']),
|
||||
handleListBtnClick(info) {
|
||||
switch (info.action) {
|
||||
case 'download':
|
||||
|
@ -121,6 +121,14 @@ export default {
|
|||
}
|
||||
this.testPlay(info.index)
|
||||
break
|
||||
case 'playLater':
|
||||
if (this.selectedData.length) {
|
||||
this.setTempPlayList(this.selectedData.map(s => ({ listId: '__temp__', musicInfo: s })))
|
||||
this.resetSelect()
|
||||
} else {
|
||||
this.setTempPlayList([{ listId: '__temp__', musicInfo: this.list[info.index] }])
|
||||
}
|
||||
break
|
||||
case 'search':
|
||||
this.handleSearch(info.index)
|
||||
break
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
table
|
||||
tbody(@contextmenu.capture="handleContextMenu" ref="dom_tbody")
|
||||
tr(v-for='(item, index) in list' :key='item.songmid' :id="'mid_' + item.songmid" @contextmenu="handleListItemRigthClick($event, index)"
|
||||
@click="handleDoubleClick($event, index)" :class="[isPlayList && playIndex === index ? $style.active : '', assertApiSupport(item.source) ? null : $style.disabled]")
|
||||
@click="handleDoubleClick($event, index)" :class="[isPlayList && playInfo.playIndex === index ? $style.active : '', assertApiSupport(item.source) ? null : $style.disabled]")
|
||||
td.nobreak.center(style="width: 5%; padding-left: 3px; padding-right: 3px;" :class="$style.noSelect" @click.stop) {{index + 1}}
|
||||
td.break
|
||||
span.select {{item.name}}
|
||||
|
@ -122,6 +122,7 @@ export default {
|
|||
isShowItemMenu: false,
|
||||
itemMenuControl: {
|
||||
play: true,
|
||||
playLater: true,
|
||||
copyName: true,
|
||||
addTo: true,
|
||||
moveTo: true,
|
||||
|
@ -145,12 +146,12 @@ export default {
|
|||
computed: {
|
||||
...mapGetters(['userInfo', 'setting']),
|
||||
...mapGetters('list', ['isInitedList', 'defaultList', 'loveList', 'userList']),
|
||||
...mapGetters('player', {
|
||||
playerListId: 'listId',
|
||||
playIndex: 'playIndex',
|
||||
}),
|
||||
...mapGetters('player', ['playInfo']),
|
||||
playerListId() {
|
||||
return this.playInfo.listId
|
||||
},
|
||||
isPlayList() {
|
||||
return this.playerListId == this.listId
|
||||
return this.playInfo.listId == this.listId
|
||||
},
|
||||
list() {
|
||||
return this.listData.list
|
||||
|
@ -223,6 +224,11 @@ export default {
|
|||
action: 'download',
|
||||
disabled: !this.listMenu.itemMenuControl.download,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.list.list_play_later'),
|
||||
action: 'playLater',
|
||||
disabled: !this.listMenu.itemMenuControl.playLater,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.list.list_add_to'),
|
||||
action: 'addTo',
|
||||
|
@ -355,6 +361,7 @@ export default {
|
|||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('player', {
|
||||
setPlayList: 'setList',
|
||||
setTempPlayList: 'setTempPlayList',
|
||||
}),
|
||||
listenEvent() {
|
||||
window.eventHub.$on('key_shift_down', this.handle_key_shift_down)
|
||||
|
@ -726,6 +733,7 @@ export default {
|
|||
handleListItemRigthClick(event, index) {
|
||||
this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[this.list[index].source].getMusicDetailPageUrl
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.playLater =
|
||||
this.listMenu.itemMenuControl.download =
|
||||
this.assertApiSupport(this.list[index].source)
|
||||
let dom_selected = this.$refs.dom_tbody.querySelector('tr.selected')
|
||||
|
@ -789,6 +797,14 @@ export default {
|
|||
case 'play':
|
||||
this.testPlay(index)
|
||||
break
|
||||
case 'playLater':
|
||||
if (this.selectdListDetailData.length) {
|
||||
this.setTempPlayList(this.selectdListDetailData.map(s => ({ listId: this.listId, musicInfo: s })))
|
||||
this.removeAllSelectListDetail()
|
||||
} else {
|
||||
this.setTempPlayList([{ listId: this.listId, musicInfo: this.list[index] }])
|
||||
}
|
||||
break
|
||||
case 'copyName':
|
||||
minfo = this.list[index]
|
||||
clipboardWriteText(this.setting.download.fileName.replace('歌名', minfo.name).replace('歌手', minfo.singer))
|
||||
|
|
|
@ -3,60 +3,65 @@
|
|||
//- transition
|
||||
div(:class="$style.header")
|
||||
material-tab(:class="$style.tab" :list="sources" align="left" item-key="id" item-name="name" v-model="searchSourceId")
|
||||
div(v-if="listInfo.list.length" :class="$style.list")
|
||||
div(:class="$style.thead")
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th.nobreak.center(style="width: 5%;") #
|
||||
th.nobreak {{$t('view.search.name')}}
|
||||
th.nobreak(style="width: 22%;") {{$t('view.search.singer')}}
|
||||
th.nobreak(style="width: 22%;") {{$t('view.search.album')}}
|
||||
th.nobreak(style="width: 8%;") {{$t('view.search.time')}}
|
||||
th.nobreak(style="width: 13%;") {{$t('view.search.action')}}
|
||||
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
|
||||
table
|
||||
tbody(@contextmenu.capture="handleContextMenu" ref="dom_tbody")
|
||||
tr(v-for='(item, index) in listInfo.list' :key='item.songmid' @contextmenu="handleListItemRigthClick($event, index)" @click="handleDoubleClick($event, index)")
|
||||
td.nobreak.center(style="width: 5%; padding-left: 3px; padding-right: 3px;" :class="$style.noSelect" @click.stop) {{index + 1}}
|
||||
td.break
|
||||
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')}}
|
||||
span(:class="[$style.labelSource, $style.noSelect]" v-if="searchSourceId == 'all'") {{item.source}}
|
||||
td.break(style="width: 22%;")
|
||||
span.select {{item.singer}}
|
||||
td.break(style="width: 22%;")
|
||||
span.select {{item.albumName}}
|
||||
td(style="width: 8%;")
|
||||
span(:class="[$style.time, $style.noSelect]") {{item.interval || '--/--'}}
|
||||
td(style="width: 13%; padding-left: 0; padding-right: 0;")
|
||||
material-list-buttons(:index="index" :remove-btn="false" :class="$style.listBtn"
|
||||
:play-btn="assertApiSupport(item.source)"
|
||||
:download-btn="assertApiSupport(item.source)"
|
||||
@btn-click="handleListBtnClick")
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:max-page="listInfo.allPage" :limit="listInfo.limit" :page="page" @btn-click="handleTogglePage")
|
||||
div(v-else :class="$style.noitem")
|
||||
div.scroll(:class="$style.noitemListContainer" v-if="setting.search.isShowHotSearch || setting.search.isShowHistorySearch")
|
||||
dl(:class="[$style.noitemList, $style.noitemHotSearchList]" v-if="setting.search.isShowHotSearch")
|
||||
dt(:class="$style.noitemListTitle") {{$t('view.search.hot_search')}}
|
||||
dd(:class="$style.noitemListItem" @click="handleNoitemSearch(item)" v-for="item in hotSearchList") {{item}}
|
||||
dl(:class="$style.noitemList" v-if="setting.search.isShowHistorySearch && historyList.length")
|
||||
dt(:class="$style.noitemListTitle")
|
||||
span {{$t('view.search.history_search')}}
|
||||
span(:class="$style.historyClearBtn" @click="clearHistory" :tips="$t('view.search.history_clear')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-eraser')
|
||||
dd(:class="$style.noitemListItem" v-for="(item, index) in historyList" @contextmenu="removeHistory(index)" :key="index + item" @click="handleNoitemSearch(item)" :tips="$t('view.search.history_remove')") {{item}}
|
||||
div(v-else :class="$style.noitem_list")
|
||||
p {{$t('view.search.no_item')}}
|
||||
div(:class="$style.main")
|
||||
div(:class="$style.list" v-show="isLoading || listInfo.list.length")
|
||||
div(:class="$style.thead")
|
||||
table
|
||||
thead
|
||||
tr
|
||||
th.nobreak.center(style="width: 5%;") #
|
||||
th.nobreak {{$t('view.search.name')}}
|
||||
th.nobreak(style="width: 22%;") {{$t('view.search.singer')}}
|
||||
th.nobreak(style="width: 22%;") {{$t('view.search.album')}}
|
||||
th.nobreak(style="width: 8%;") {{$t('view.search.time')}}
|
||||
th.nobreak(style="width: 13%;") {{$t('view.search.action')}}
|
||||
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
|
||||
table
|
||||
tbody(@contextmenu.capture="handleContextMenu" ref="dom_tbody")
|
||||
tr(v-for='(item, index) in listInfo.list' :key='item.songmid' @contextmenu="handleListItemRigthClick($event, index)" @click="handleDoubleClick($event, index)")
|
||||
td.nobreak.center(style="width: 5%; padding-left: 3px; padding-right: 3px;" :class="$style.noSelect" @click.stop) {{index + 1}}
|
||||
td.break
|
||||
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')}}
|
||||
span(:class="[$style.labelSource, $style.noSelect]" v-if="searchSourceId == 'all'") {{item.source}}
|
||||
td.break(style="width: 22%;")
|
||||
span.select {{item.singer}}
|
||||
td.break(style="width: 22%;")
|
||||
span.select {{item.albumName}}
|
||||
td(style="width: 8%;")
|
||||
span(:class="[$style.time, $style.noSelect]") {{item.interval || '--/--'}}
|
||||
td(style="width: 13%; padding-left: 0; padding-right: 0;")
|
||||
material-list-buttons(:index="index" :remove-btn="false" :class="$style.listBtn"
|
||||
:play-btn="assertApiSupport(item.source)"
|
||||
:download-btn="assertApiSupport(item.source)"
|
||||
@btn-click="handleListBtnClick")
|
||||
div(:class="$style.pagination")
|
||||
material-pagination(:max-page="listInfo.allPage" :limit="listInfo.limit" :page="page" @btn-click="handleTogglePage")
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated fadeOut")
|
||||
div(v-show="isLoading" :class="$style.loading")
|
||||
p {{$t('view.search.loding_list')}}
|
||||
transition(enter-active-class="animated-fast fadeIn" leave-active-class="animated-fast fadeOut")
|
||||
div(v-show="!isLoading && !listInfo.list.length" :class="$style.noitem")
|
||||
div.scroll(:class="$style.noitemListContainer" v-if="setting.search.isShowHotSearch || setting.search.isShowHistorySearch")
|
||||
dl(:class="[$style.noitemList, $style.noitemHotSearchList]" v-if="setting.search.isShowHotSearch")
|
||||
dt(:class="$style.noitemListTitle") {{$t('view.search.hot_search')}}
|
||||
dd(:class="$style.noitemListItem" @click="handleNoitemSearch(item)" v-for="item in hotSearchList") {{item}}
|
||||
dl(:class="$style.noitemList" v-if="setting.search.isShowHistorySearch && historyList.length")
|
||||
dt(:class="$style.noitemListTitle")
|
||||
span {{$t('view.search.history_search')}}
|
||||
span(:class="$style.historyClearBtn" @click="clearHistory" :tips="$t('view.search.history_clear')")
|
||||
svg(version='1.1' xmlns='http://www.w3.org/2000/svg' xlink='http://www.w3.org/1999/xlink' height='100%' viewBox='0 0 512 512' space='preserve')
|
||||
use(xlink:href='#icon-eraser')
|
||||
dd(:class="$style.noitemListItem" v-for="(item, index) in historyList" @contextmenu="removeHistory(index)" :key="index + item" @click="handleNoitemSearch(item)" :tips="$t('view.search.history_remove')") {{item}}
|
||||
div(v-else :class="$style.noitem_list")
|
||||
p {{$t('view.search.no_item')}}
|
||||
material-menu(:menus="listItemMenu" :location="listMenu.menuLocation" item-name="name" :isShow="listMenu.isShowItemMenu" @menu-click="handleListItemMenuClick")
|
||||
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
|
||||
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectedData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
|
||||
//- material-flow-btn(:show="isShowEditBtn && (searchSourceId == 'all' || assertApiSupport(searchSourceId))" :remove-btn="false" @btn-click="handleFlowBtnClick")
|
||||
material-list-add-modal(:show="isShowListAdd" :musicInfo="musicInfo" @close="handleListAddModalClose")
|
||||
material-list-add-multiple-modal(:show="isShowListAddMultiple" :musicList="selectedData" @close="handleListAddMultipleModalClose")
|
||||
material-menu(:menus="listItemMenu" :location="listMenu.menuLocation" item-name="name" :isShow="listMenu.isShowItemMenu" @menu-click="handleListItemMenuClick")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -88,6 +93,7 @@ export default {
|
|||
isShowItemMenu: false,
|
||||
itemMenuControl: {
|
||||
play: true,
|
||||
playLater: true,
|
||||
addTo: true,
|
||||
download: true,
|
||||
sourceDetail: true,
|
||||
|
@ -97,6 +103,7 @@ export default {
|
|||
y: 0,
|
||||
},
|
||||
},
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
beforeRouteUpdate(to, from, next) {
|
||||
|
@ -148,6 +155,7 @@ export default {
|
|||
},
|
||||
searchSourceId(n) {
|
||||
if (n === this.setting.search.searchSource) return
|
||||
if (this.text !== '') this.isLoading = true
|
||||
this.$nextTick(() => {
|
||||
this.page = 1
|
||||
this.handleSearch(this.text, this.page)
|
||||
|
@ -174,6 +182,11 @@ export default {
|
|||
action: 'download',
|
||||
disabled: !this.listMenu.itemMenuControl.download,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.search.list_play_later'),
|
||||
action: 'playLater',
|
||||
disabled: !this.listMenu.itemMenuControl.playLater,
|
||||
},
|
||||
{
|
||||
name: this.$t('view.search.list_add_to'),
|
||||
action: 'addTo',
|
||||
|
@ -199,7 +212,7 @@ export default {
|
|||
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
|
||||
...mapMutations('search', ['clearList', 'setPage', 'removeHistory', 'clearHistory']),
|
||||
...mapMutations('list', ['listAdd', 'listAddMultiple']),
|
||||
...mapMutations('player', ['setList']),
|
||||
...mapMutations('player', ['setList', 'setTempPlayList']),
|
||||
...mapActions('hotSearch', {
|
||||
getHotSearch: 'getList',
|
||||
}),
|
||||
|
@ -238,12 +251,14 @@ export default {
|
|||
},
|
||||
handleSearch(text, page) {
|
||||
if (text === '') return this.clearList()
|
||||
|
||||
this.isLoading = true
|
||||
this.search({ text, page, limit: this.listInfo.limit }).then(data => {
|
||||
this.page = page
|
||||
this.$nextTick(() => {
|
||||
scrollTo(this.$refs.dom_scrollContent, 0)
|
||||
})
|
||||
}).finally(() => {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
handleDoubleClick(event, index) {
|
||||
|
@ -274,6 +289,14 @@ export default {
|
|||
case 'play':
|
||||
this.testPlay(info.index)
|
||||
break
|
||||
case 'playLater':
|
||||
if (this.selectedData.length) {
|
||||
this.setTempPlayList(this.selectedData.map(s => ({ listId: '__temp__', musicInfo: s })))
|
||||
this.resetSelect()
|
||||
} else {
|
||||
this.setTempPlayList([{ listId: '__temp__', musicInfo: this.list[info.index] }])
|
||||
}
|
||||
break
|
||||
case 'listAdd':
|
||||
this.musicInfo = this.listInfo.list[info.index]
|
||||
this.$nextTick(() => {
|
||||
|
@ -423,6 +446,7 @@ export default {
|
|||
handleListItemRigthClick(event, index) {
|
||||
this.listMenu.itemMenuControl.sourceDetail = !!musicSdk[this.listInfo.list[index].source].getMusicDetailPageUrl
|
||||
this.listMenu.itemMenuControl.play =
|
||||
this.listMenu.itemMenuControl.playLater =
|
||||
this.listMenu.itemMenuControl.download =
|
||||
this.assertApiSupport(this.listInfo.list[index].source)
|
||||
let dom_selected = this.$refs.dom_tbody.querySelector('tr.selected')
|
||||
|
@ -504,6 +528,12 @@ export default {
|
|||
.header {
|
||||
flex: none;
|
||||
}
|
||||
.main {
|
||||
flex: auto;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
}
|
||||
.list {
|
||||
// position: relative;
|
||||
height: 100%;
|
||||
|
@ -560,10 +590,30 @@ export default {
|
|||
// left: 50%;
|
||||
// transform: translateX(-50%);
|
||||
}
|
||||
.loading {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: @color-theme_2;
|
||||
|
||||
p {
|
||||
font-size: 24px;
|
||||
color: @color-theme_2-font-label;
|
||||
}
|
||||
}
|
||||
.noitem {
|
||||
flex: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
|
@ -635,6 +685,9 @@ each(@themes, {
|
|||
.labelSource {
|
||||
color: ~'@{color-@{value}-theme}';
|
||||
}
|
||||
.loading {
|
||||
background-color: ~'@{color-@{value}-theme_2}';
|
||||
}
|
||||
.noitem {
|
||||
p {
|
||||
color: ~'@{color-@{value}-theme_2-font-label}';
|
||||
|
|
|
@ -21,14 +21,13 @@ div.scroll(:class="$style.setting" ref="dom_setting")
|
|||
label {{$t('store.state.theme_' + theme.class)}}
|
||||
|
||||
dd
|
||||
h3#basic_show_animation {{$t('view.setting.basic_show_animation')}}
|
||||
div
|
||||
material-checkbox(id="setting_show_animate" v-model="current_setting.isShowAnimation" :label="$t('view.setting.is_show')")
|
||||
div(:class="[$style.gapTop, $style.top]")
|
||||
material-checkbox(id="setting_show_animate" v-model="current_setting.isShowAnimation" :label="$t('view.setting.basic_show_animation')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate" :label="$t('view.setting.basic_animation')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_to_tray" v-model="current_setting.tray.isShow" @change="handleTrayShowChange" :label="$t('view.setting.basic_to_tray')")
|
||||
|
||||
dd(:tips="$t('view.setting.basic_animation_title')")
|
||||
h3#basic_animation {{$t('view.setting.basic_animation')}}
|
||||
div
|
||||
material-checkbox(id="setting_animate" v-model="current_setting.randomAnimate" :label="$t('view.setting.is_enable')")
|
||||
|
||||
dd(:tips="$t('view.setting.basic_source_title')")
|
||||
h3#basic_source {{$t('view.setting.basic_source')}}
|
||||
|
@ -37,11 +36,6 @@ div.scroll(:class="$style.setting" ref="dom_setting")
|
|||
material-checkbox(:id="`setting_api_source_${item.id}`" name="setting_api_source" @change="handleAPISourceChange(item.id)"
|
||||
need v-model="current_setting.apiSource" :disabled="item.disabled" :value="item.id" :label="item.label")
|
||||
|
||||
dd(:tips="$t('view.setting.basic_to_tray_title')")
|
||||
h3#basic_to_tray {{$t('view.setting.basic_to_tray')}}
|
||||
div
|
||||
material-checkbox(id="setting_to_tray" v-model="current_setting.tray.isShow" @change="handleTrayShowChange" :label="$t('view.setting.is_enable')")
|
||||
|
||||
dd(:tips="$t('view.setting.basic_window_size_title')")
|
||||
h3#basic_window_size {{$t('view.setting.basic_window_size')}}
|
||||
div
|
||||
|
@ -68,27 +62,17 @@ div.scroll(:class="$style.setting" ref="dom_setting")
|
|||
name="setting_basic_control_btn_position" need v-model="current_setting.controlBtnPosition" :value="item.id" :label="item.name")
|
||||
|
||||
dt#play {{$t('view.setting.play')}}
|
||||
dd(:tips="$t('view.setting.play_toggle_title')")
|
||||
h3#play_toggle {{$t('view.setting.play_toggle')}}
|
||||
div
|
||||
material-checkbox(:id="`setting_player_togglePlay_${item.value}`" :class="$style.gapLeft" :value="item.value" :key="item.value"
|
||||
v-model="current_setting.player.togglePlayMethod" v-for="item in togglePlayMethods" :label="item.name")
|
||||
dd
|
||||
h3#play_lyric_transition {{$t('view.setting.play_lyric_transition')}}
|
||||
div
|
||||
material-checkbox(id="setting_player_lyric_transition" v-model="current_setting.player.isShowLyricTransition" :label="$t('view.setting.is_show')")
|
||||
dd(:tips="$t('view.setting.play_quality_title')")
|
||||
h3#play_quality {{$t('view.setting.play_quality')}}
|
||||
div
|
||||
material-checkbox(id="setting_player_highQuality" v-model="current_setting.player.highQuality" :label="$t('view.setting.is_enable')")
|
||||
dd(:tips="$t('view.setting.play_task_bar_title')")
|
||||
h3#play_task_bar {{$t('view.setting.play_task_bar')}}
|
||||
div
|
||||
material-checkbox(id="setting_player_showTaskProgess" v-model="current_setting.player.isShowTaskProgess" :label="$t('view.setting.is_enable')")
|
||||
dd(:tips="$t('view.setting.play_mediaDevice_remove_stop_play_title')")
|
||||
h3#play_mediaDevice_remove_stop_play {{$t('view.setting.play_mediaDevice_remove_stop_play')}}
|
||||
div
|
||||
material-checkbox(id="setting_player_isMediaDeviceRemovedStopPlay" v-model="current_setting.player.isMediaDeviceRemovedStopPlay" :label="$t('view.setting.is_enable')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_player_save_play_time" v-model="current_setting.player.isSavePlayTime" :label="$t('view.setting.play_save_play_time')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_player_lyric_transition" v-model="current_setting.player.isShowLyricTransition" :label="$t('view.setting.play_lyric_transition')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_player_highQuality" v-model="current_setting.player.highQuality" :label="$t('view.setting.play_quality')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_player_showTaskProgess" v-model="current_setting.player.isShowTaskProgess" :label="$t('view.setting.play_task_bar')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_player_isMediaDeviceRemovedStopPlay" v-model="current_setting.player.isMediaDeviceRemovedStopPlay" :label="$t('view.setting.play_mediaDevice_remove_stop_play')")
|
||||
dd(:tips="$t('view.setting.play_mediaDevice_title')")
|
||||
h3#play_mediaDevice {{$t('view.setting.play_mediaDevice')}}
|
||||
div
|
||||
|
@ -103,29 +87,22 @@ div.scroll(:class="$style.setting" ref="dom_setting")
|
|||
material-checkbox(id="setting_desktop_lyric_alwaysOnTop" v-model="current_setting.desktopLyric.isAlwaysOnTop" :label="$t('view.setting.desktop_lyric_always_on_top')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_desktop_lyric_lockScreen" v-model="current_setting.desktopLyric.isLockScreen" :label="$t('view.setting.desktop_lyric_lock_screen')")
|
||||
|
||||
dt#search {{$t('view.setting.search')}}
|
||||
dd(:tips="$t('view.setting.search_hot_title')")
|
||||
h3#search_hot {{$t('view.setting.search_hot')}}
|
||||
div
|
||||
material-checkbox(id="setting_search_showHot_enable" v-model="current_setting.search.isShowHotSearch" :label="$t('view.setting.is_show')")
|
||||
dd(:tips="$t('view.setting.search_history_title')")
|
||||
h3#search_history {{$t('view.setting.search_history')}}
|
||||
div
|
||||
material-checkbox(id="setting_search_showHistory_enable" v-model="current_setting.search.isShowHistorySearch" :label="$t('view.setting.is_show')")
|
||||
dd(:tips="$t('view.setting.search_focus_search_box_title')")
|
||||
h3#search_focus_search_box {{$t('view.setting.search_focus_search_box')}}
|
||||
div
|
||||
material-checkbox(id="setting_search_focusSearchBox_enable" v-model="current_setting.search.isFocusSearchBox" :label="$t('view.setting.is_enable')")
|
||||
dd
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_search_showHot_enable" v-model="current_setting.search.isShowHotSearch" :label="$t('view.setting.search_hot')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_search_showHistory_enable" v-model="current_setting.search.isShowHistorySearch" :label="$t('view.setting.search_history')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_search_focusSearchBox_enable" v-model="current_setting.search.isFocusSearchBox" :label="$t('view.setting.search_focus_search_box')")
|
||||
|
||||
dt#list {{$t('view.setting.list')}}
|
||||
dd(:tips="$t('view.setting.list_source_title')")
|
||||
h3#list_source {{$t('view.setting.list_source')}}
|
||||
div
|
||||
material-checkbox(id="setting_list_showSource_enable" v-model="current_setting.list.isShowSource" :label="$t('view.setting.is_show')")
|
||||
dd(:tips="$t('view.setting.list_scroll_title')")
|
||||
h3#list_scroll {{$t('view.setting.list_scroll')}}
|
||||
div
|
||||
material-checkbox(id="setting_list_scroll_enable" v-model="current_setting.list.isSaveScrollLocation" :label="$t('view.setting.is_enable')")
|
||||
dd
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_list_showSource_enable" v-model="current_setting.list.isShowSource" :label="$t('view.setting.list_source')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_list_scroll_enable" v-model="current_setting.list.isSaveScrollLocation" :label="$t('view.setting.list_scroll')")
|
||||
//- dd(:tips="播放列表是否显示专辑栏")
|
||||
h3 专辑栏
|
||||
div
|
||||
|
@ -195,13 +172,10 @@ div.scroll(:class="$style.setting" ref="dom_setting")
|
|||
material-input(:class="$style.gapLeft" v-model="current_setting.network.proxy.password" @change="handleProxyChange('password')" type="password" :placeholder="$t('view.setting.network_proxy_password')")
|
||||
dt#odc {{$t('view.setting.odc')}}
|
||||
dd
|
||||
h3#odc_clear_search_input {{$t('view.setting.odc_clear_search_input')}}
|
||||
div
|
||||
material-checkbox(id="setting_odc_isAutoClearSearchInput" v-model="current_setting.odc.isAutoClearSearchInput" :label="$t('view.setting.is_enable')")
|
||||
dd
|
||||
h3#odc_clear_search_list {{$t('view.setting.odc_clear_search_list')}}
|
||||
div
|
||||
material-checkbox(id="setting_odc_isAutoClearSearchList" v-model="current_setting.odc.isAutoClearSearchList" :label="$t('view.setting.is_enable')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_odc_isAutoClearSearchInput" v-model="current_setting.odc.isAutoClearSearchInput" :label="$t('view.setting.odc_clear_search_input')")
|
||||
div(:class="$style.gapTop")
|
||||
material-checkbox(id="setting_odc_isAutoClearSearchList" v-model="current_setting.odc.isAutoClearSearchList" :label="$t('view.setting.odc_clear_search_list')")
|
||||
dt#backup {{$t('view.setting.backup')}}
|
||||
dd
|
||||
h3#backup_part {{$t('view.setting.backup_part')}}
|
||||
|
@ -745,13 +719,18 @@ export default {
|
|||
}
|
||||
},
|
||||
exportPlayList(path) {
|
||||
const data = {
|
||||
const data = JSON.parse(JSON.stringify({
|
||||
type: 'playList',
|
||||
data: [
|
||||
this.defaultList,
|
||||
this.loveList,
|
||||
...this.userList,
|
||||
],
|
||||
}))
|
||||
for (const list of data.data) {
|
||||
for (const item of list.list) {
|
||||
if (item.otherSource) delete item.otherSource
|
||||
}
|
||||
}
|
||||
this.handleSaveFile(path, JSON.stringify(data))
|
||||
},
|
||||
|
@ -776,7 +755,7 @@ export default {
|
|||
}
|
||||
},
|
||||
async exportAllData(path) {
|
||||
let allData = {
|
||||
let allData = JSON.parse(JSON.stringify({
|
||||
type: 'allData',
|
||||
setting: Object.assign({ version: this.settingVersion }, this.setting),
|
||||
playList: [
|
||||
|
@ -784,6 +763,11 @@ export default {
|
|||
this.loveList,
|
||||
...this.userList,
|
||||
],
|
||||
}))
|
||||
for (const list of allData.playList) {
|
||||
for (const item of list.list) {
|
||||
if (item.otherSource) delete item.otherSource
|
||||
}
|
||||
}
|
||||
this.handleSaveFile(path, JSON.stringify(allData))
|
||||
},
|
||||
|
@ -1202,6 +1186,10 @@ export default {
|
|||
}
|
||||
}
|
||||
.gap-top {
|
||||
&.top {
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
+ .gap-top {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
|
|
@ -183,6 +183,7 @@ export default {
|
|||
...mapMutations('list', ['listAdd', 'listAddMultiple', 'createUserList']),
|
||||
...mapMutations('player', {
|
||||
setPlayList: 'setList',
|
||||
setTempPlayList: 'setTempPlayList',
|
||||
}),
|
||||
listenEvent() {
|
||||
window.eventHub.$on('key_backspace_down', this.handle_key_backspace_down)
|
||||
|
@ -243,6 +244,14 @@ export default {
|
|||
}
|
||||
this.testPlay(info.index)
|
||||
break
|
||||
case 'playLater':
|
||||
if (this.selectedData.length) {
|
||||
this.setTempPlayList(this.selectedData.map(s => ({ listId: '__temp__', musicInfo: s })))
|
||||
this.resetSelect()
|
||||
} else {
|
||||
this.setTempPlayList([{ listId: '__temp__', musicInfo: this.listDetail.list[info.index] }])
|
||||
}
|
||||
break
|
||||
case 'search':
|
||||
this.handleSearch(info.index)
|
||||
break
|
||||
|
|
Loading…
Reference in New Issue