重构歌曲列表

pull/96/head
lyswhut 2019-09-01 18:09:54 +08:00
parent c81c33a430
commit 78c0badd95
15 changed files with 662 additions and 115 deletions

View File

@ -1,12 +1,10 @@
### 新增
- 新增**测试接口**,该接口同样速度较慢,但软件的大部分功能可用,**请自行切换到该接口**,找接口辛苦,且用且珍惜!
- 在设置界面-关于洛雪音乐说明部分新增**最新版网盘下载地址**与**打赏地址**
- 新增酷我、酷狗、百度源**歌单**
### 优化
- 取消需要刷新URL时windows任务栏进度显示错误状态现显示为暂停状态
### 修复
- 修复使用临时接口时在试听列表双击灰色歌曲仍然会进行播放的Bug
- 修复歌词加载Bug
- 目前使用的测试接口与临时接口已趋于稳定
- 测试接口支持**酷我、酷狗、百度、网易云**源直接播放与下载
- 临时接口仅支持**酷我**源直接播放与下载

View File

@ -9,7 +9,7 @@ div(:class="$style.aside")
dt 在线音乐
dd
router-link(:active-class="$style.active" to="search") 搜索
//- dd
dd
router-link(:active-class="$style.active" to="songList") 歌单
dd
router-link(:active-class="$style.active" to="leaderboard") 排行榜

View File

@ -0,0 +1,201 @@
<template lang="pug">
div(:class="$style.songList")
div(v-if="list.length" :class="$style.list")
div(:class="$style.thead")
table
thead
tr
th.nobreak.center(style="width: 37px;")
material-checkbox(id="search_select_all" v-model="isSelectAll" @change="handleSelectAllData"
:indeterminate="isIndeterminate" :title="isSelectAll && !isIndeterminate ? '全不选' : '全选'")
th.nobreak(style="width: 25%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 25%;") 专辑
th.nobreak(style="width: 15%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)")
td.nobreak.center(style="width: 37px;" @click.stop)
material-checkbox(:id="index.toString()" v-model="selectdList" :value="item")
td.break(style="width: 25%;")
| {{item.name}}
span.badge.badge-info(v-if="item._types['320k']") 高品质
span.badge.badge-success(v-if="item._types.ape || item._types.flac") 无损
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;") {{item.albumName}}
td(style="width: 15%;")
material-list-buttons(:index="index" :search-btn="true" :remove-btn="false" @btn-click="handleListBtnClick"
:play-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')" :download-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')")
td(style="width: 10%;") {{item.interval}}
div(:class="$style.pagination")
material-pagination(:count="total" :limit="limit" :page="page" @btn-click="handleTogglePage")
div(v-else :class="$style.noitem")
p 搜我所想~~😉
material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")
</template>
<script>
import { mapGetters } from 'vuex'
import { scrollTo } from '../../utils'
export default {
model: {
prop: 'selectdData',
event: 'input',
},
props: {
list: {
type: Array,
default() {
return []
},
},
page: {
type: Number,
required: true,
},
limit: {
type: Number,
required: true,
},
total: {
type: Number,
required: true,
},
selectdData: {
type: Array,
required: true,
},
source: {
type: String,
},
},
computed: {
...mapGetters(['setting']),
isAPITemp() {
return this.setting.apiSource == 'temp'
},
},
watch: {
selectdList(n) {
const len = n.length
if (len) {
this.isSelectAll = true
this.isIndeterminate = len !== this.list.length
this.isShowEditBtn = true
} else {
this.isSelectAll = false
this.isShowEditBtn = false
}
this.$emit('input', [...n])
},
list(n) {
this.resetSelect()
this.$nextTick(() => scrollTo(this.$refs.dom_scrollContent, 0))
},
},
data() {
return {
clickTime: 0,
clickIndex: -1,
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
selectdList: [],
}
},
methods: {
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
this.emitEvent((this.source == 'kw' || (!this.isAPITemp && this.list[index].source != 'tx')) ? 'testPlay' : 'search', index)
this.clickTime = 0
this.clickIndex = -1
},
handleListBtnClick(info) {
this.emitEvent('listBtnClick', info)
},
handleSelectAllData(isSelect) {
this.selectdList = isSelect ? [...this.list] : []
},
resetSelect() {
this.selectdList = false
this.selectdList = []
},
handleTogglePage(page) {
this.emitEvent('togglePage', page)
},
handleFlowBtnClick(action) {
this.emitEvent('flowBtnClick', action)
},
emitEvent(action, data) {
this.$emit('action', { action, data })
},
},
}
</script>
<style lang="less" module>
@import '../../assets/styles/layout.less';
.song-list {
overflow: hidden;
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.list {
position: relative;
font-size: 14px;
overflow: hidden;
display: flex;
flex-flow: column nowrap;
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
:global(.badge) {
margin-right: 3px;
&:first-child {
margin-left: 3px;
}
&:last-child {
margin-right: 0;
}
}
}
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
.noitem {
position: relative;
height: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
p {
font-size: 24px;
color: #ccc;
}
}
</style>

View File

@ -0,0 +1,91 @@
import music from '../../utils/music'
const sortList = {}
const sources = []
for (const source of music.sources) {
const songList = music[source.id].songList
if (!songList) continue
sortList[source.id] = songList.sortList
sources.push(source)
}
// state
const state = {
tags: {},
list: {
list: [],
total: 0,
page: 1,
limit: 30,
key: null,
},
listDetail: {
list: [],
total: 0,
page: 1,
limit: 30,
key: null,
},
}
// getters
const getters = {
sourceInfo: () => ({ sources, sortList }),
tags: state => state.tags,
listData(state) {
return state.list
},
listDetail(state) {
return state.listDetail
},
}
// actions
const actions = {
getTags({ state, rootState, commit }) {
let source = rootState.setting.songList.source
return music[source].songList.getTags().then(result => commit('setTags', { result, source }))
},
getList({ state, rootState, commit }, page) {
let source = rootState.setting.songList.source
let tabId = rootState.setting.songList.sortId
let sortType = rootState.setting.songList.sortType
let key = `${source}${sortType}${tabId}${page}}`
if (state.list.list.length && state.list.key == key) return true
return music[source].songList.getList(sortType, tabId, page).then(result => commit('setList', { result, key }))
},
getListDetail({ state, rootState, commit }, { id, page }) {
let source = rootState.setting.songList.source
let key = `${source}${id}${page}}`
if (state.listDetail.list.length && state.listDetail.key == key) return true
return music[source].songList.getListDetail(id, page).then(result => commit('setListDetail', { result, key }))
},
}
// mitations
const mutations = {
setTags(state, { tags, source }) {
state.tags[source] = tags
},
setList(state, { result, key }) {
state.list.list = result.list
state.list.total = result.total
state.list.limit = result.limit
state.list.page = result.page
state.list.key = key
},
setListDetail(state, { result, key }) {
state.listDetail.list = result.list
state.listDetail.total = result.total
state.listDetail.limit = result.limit
state.listDetail.page = result.page
state.listDetail.key = key
},
}
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}

View File

@ -12,6 +12,10 @@ export default {
if (tabId != null) state.setting.leaderboard.tabId = tabId
if (source != null) state.setting.leaderboard.source = source
},
setSongList(state, { sortId, source }) {
if (sortId != null) state.setting.leaderboard.sortId = sortId
if (source != null) state.setting.leaderboard.source = source
},
setNewVersion(state, val) {
// val.history.forEach(ver => {
// ver.desc = ver.desc.replace(/\n/g, '<br>')

View File

@ -1,5 +1,5 @@
import fs from 'fs'
import { shell, remote } from 'electron'
import { shell, remote, clipboard } from 'electron'
import path from 'path'
import os from 'os'
import crypto from 'crypto'
@ -162,7 +162,7 @@ export const isChildren = (parent, children) => {
* @param {*} setting
*/
export const updateSetting = setting => {
const defaultVersion = '1.0.4'
const defaultVersion = '1.0.5'
const defaultSetting = {
version: defaultVersion,
player: {
@ -183,6 +183,11 @@ export const updateSetting = setting => {
source: 'kw',
tabId: 'kwbiaosb',
},
songList: {
source: 'kw',
sortId: 'kwhot',
tagId: '',
},
themeId: 0,
sourceId: 'kw',
apiSource: 'test',
@ -202,7 +207,7 @@ export const updateSetting = setting => {
objectDeepMerge(defaultSetting, overwriteSetting)
setting = defaultSetting
}
if (setting.apiSource != 'test') setting.apiSource = 'test' // 强制设置回 test 接口源
if (setting.apiSource != 'temp') setting.apiSource = 'test' // 强制设置回 test 接口源
return setting
}
@ -228,3 +233,9 @@ export const setTitle = title => {
* @param {*} str
*/
export const toMD5 = str => crypto.createHash('md5').update(str).digest('hex')
/**
* 复制文本到剪贴板
* @param {*} str
*/
export const clipboardWriteText = str => clipboard.writeText(str)

View File

@ -1,9 +1,11 @@
import leaderboard from './leaderboard'
import api_source from '../api-source'
import musicInfo from './musicInfo'
import songList from './songList'
const bd = {
leaderboard,
songList,
getMusicUrl(songInfo, type) {
return api_source('bd').getMusicUrl(songInfo, type)
},

View File

@ -13,10 +13,12 @@ export default {
sortList: [
{
name: '最热',
tabId: 'bdhot',
id: '最热',
},
{
name: '最新',
tabId: 'bdnew',
id: '最新',
},
],

View File

@ -1,9 +1,10 @@
import leaderboard from './leaderboard'
import api_source from '../api-source'
import songList from './songList'
const kg = {
leaderboard,
songList,
getMusicUrl(songInfo, type) {
return api_source('kg').getMusicUrl(songInfo, type)
},

View File

@ -12,22 +12,27 @@ export default {
sortList: [
{
name: '推荐',
tabId: 'kgrecommend',
id: '5',
},
{
name: '最热',
tabId: 'kghot',
id: '6',
},
{
name: '最新',
tabId: 'kgnew',
id: '7',
},
{
name: '热藏',
tabId: 'kghotcollect',
id: '3',
},
{
name: '飙升',
tabId: 'kgup',
id: '8',
},
],

View File

@ -6,6 +6,7 @@ import leaderboard from './leaderboard'
import lyric from './lyric'
import pic from './pic'
import api_source from '../api-source'
import songList from './songList'
const kw = {
_musicInfoRequestObj: null,
@ -32,6 +33,7 @@ const kw = {
tempSearch,
musicSearch,
leaderboard,
songList,
getLyric(songInfo) {
// let singer = songInfo.singer.indexOf('、') > -1 ? songInfo.singer.split('、')[0] : songInfo.singer
return lyric.getLyric(songInfo.songmid)

View File

@ -13,10 +13,12 @@ export default {
sortList: [
{
name: '最热',
tabId: 'kwhot',
id: 'hot',
},
{
name: '最新',
tabId: 'kwnew',
id: 'new',
},
],

View File

@ -3,40 +3,7 @@
div(:class="$style.header")
material-tab(:class="$style.tab" :list="types" item-key="id" item-name="name" v-model="tabId")
material-select(:class="$style.select" :list="sourceInfo.sources" item-key="id" item-name="name" v-model="source")
div(:class="$style.content")
div(v-if="list.length" :class="$style.list")
div(:class="$style.thead")
table
thead
tr
th.nobreak.center(style="width: 37px;")
material-checkbox(id="search_select_all" v-model="isSelectAll" @change="handleSelectAllData"
:indeterminate="isIndeterminate" :title="isSelectAll && !isIndeterminate ? '全不选' : '全选'")
th.nobreak(style="width: 25%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 22%;") 专辑
th.nobreak(style="width: 18%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)")
td.nobreak.center(style="width: 37px;" @click.stop)
material-checkbox(:id="index.toString()" v-model="selectdData" :value="item")
td.break(style="width: 25%;")
| {{item.name}}
//- span.badge.badge-info(v-if="item._types['320k']")
//- span.badge.badge-success(v-if="item._types.ape || item._types.flac")
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 22%;") {{item.albumName}}
td(style="width: 18%;")
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')" :download-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')" :remove-btn="false" @btn-click="handleListBtnClick")
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)')
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)')
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)')
td(style="width: 10%;") {{item.interval || '--/--'}}
div(:class="$style.pagination")
material-pagination(:count="info.total" :limit="info.limit" :page="info.page" @btn-click="handleTogglePage")
material-song-list(v-model="selectdData" @action="handleSongListAction" :source="source" :page="page" :limit="info.limit" :total="info.total" :list="list")
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectdData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")
@ -44,8 +11,6 @@
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
import { scrollTo } from '../utils'
// import music from '../utils/music'
export default {
name: 'Leaderboard',
data() {
@ -81,24 +46,23 @@ export default {
if (!o && this.page !== 1) return
this.getList(1).then(() => {
this.page = this.info.page
scrollTo(this.$refs.dom_scrollContent, 0)
})
},
source(n, o) {
this.setLeaderboard({ source: n })
if (o) this.tabId = this.types[0] && this.types[0].id
},
selectdData(n) {
const len = n.length
if (len) {
this.isSelectAll = true
this.isIndeterminate = len !== this.list.length
this.isShowEditBtn = true
} else {
this.isSelectAll = false
this.isShowEditBtn = false
}
},
// selectdData(n) {
// const len = n.length
// if (len) {
// this.isSelectAll = true
// this.isIndeterminate = len !== this.list.length
// this.isShowEditBtn = true
// } else {
// this.isSelectAll = false
// this.isShowEditBtn = false
// }
// },
list() {
this.resetSelect()
},
@ -177,9 +141,6 @@ export default {
handleTogglePage(page) {
this.getList(page).then(() => {
this.page = this.info.page
this.$nextTick(() => {
scrollTo(this.$refs.dom_scrollContent, 0)
})
})
},
handleSelectAllData(isSelect) {
@ -218,6 +179,9 @@ export default {
break
}
},
handleSongListAction({ action, data }) {
console.log(action, data)
},
},
}
</script>
@ -250,46 +214,5 @@ export default {
overflow: hidden;
flex-flow: column nowrap;
}
.list {
position: relative;
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
// table {
// position: relative;
// thead {
// position: fixed;
// width: 100%;
// th {
// width: 100%;
// }
// }
// }
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
:global(.badge) {
margin-right: 3px;
&:first-child {
margin-left: 3px;
}
&:last-child {
margin-right: 0;
}
}
}
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
</style>

View File

@ -81,7 +81,12 @@ div.scroll(:class="$style.setting")
dd
p.small
| 本软件完全免费代码已开源开源地址
span.hover(@click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop')") https://github.com/lyswhut/lx-music-desktop
span.hover(title="点击打开" @click="handleOpenUrl('https://github.com/lyswhut/lx-music-desktop#readme')") https://github.com/lyswhut/lx-music-desktop
p.small
| 最新版网盘下载地址网盘内有MACwindows版
span.hover(title="点击打开" @click="handleOpenUrl('https://www.lanzous.com/b906260/')") https://www.lanzous.com/b906260/
| &nbsp;&nbsp;密码
span.hover(title="点击复制" @click="clipboardWriteText('glqw')") glqw
p.small
| 本软件仅用于学习交流使用禁止将本软件用于
strong 非法用途
@ -101,6 +106,10 @@ div.scroll(:class="$style.setting")
| 若觉得好用的话可以去 GitHub 点个
strong star
| 支持作者哦~~🍻
p
span 如果你资金充裕还可以
material-btn(@click="handleOpenUrl('https://cdn.stsky.cn/qrc.png')" min title="土豪,你好 🙂") 打赏下作者
span 以帮我分担点服务器费用~
p
small By
| 落雪无痕
@ -108,7 +117,7 @@ div.scroll(:class="$style.setting")
<script>
import { mapGetters, mapMutations } from 'vuex'
import { openDirInExplorer, openSelectDir, openSaveDir, updateSetting, openUrl } from '../utils'
import { openDirInExplorer, openSelectDir, openSaveDir, updateSetting, openUrl, clipboardWriteText } from '../utils'
import { rendererSend } from '../../common/icp'
import fs from 'fs'
@ -175,12 +184,12 @@ export default {
// },
{
id: 'test',
label: '测试接口(软件的大部分功能可用,该接口访问速度较慢,请耐心等待',
label: '测试接口(软件的大部分功能可用,该接口访问速度较慢',
disabled: false,
},
{
id: 'temp',
label: '临时接口(软件的某些功能不可用,该接口访问速度较慢,请耐心等待',
label: '临时接口(软件的某些功能不可用,该接口比测试接口快一些,建议测试接口不可用再使用本接口',
disabled: false,
},
],
@ -379,6 +388,12 @@ export default {
showUpdateModal() {
this.setVersionModalVisible({ isShow: true })
},
clipboardWriteText(text) {
clipboardWriteText(text)
},
openRewardModal() {
},
},
}
</script>

View File

@ -1,20 +1,310 @@
<template lang="pug">
div
h2 推荐
div(:class="$style.leaderboard")
div(:class="$style.header")
//- material-tab(:class="$style.tab" :list="types" item-key="id" item-name="name" v-model="sortId")
//- material-select(:class="$style.select" :list="sourceInfo.sources" item-key="id" item-name="name" v-model="source")
//- div(:class="$style.content")
div(v-if="list.length" :class="$style.list")
div(:class="$style.thead")
table
thead
tr
th.nobreak.center(style="width: 37px;")
material-checkbox(id="search_select_all" v-model="isSelectAll" @change="handleSelectAllData"
:indeterminate="isIndeterminate" :title="isSelectAll && !isIndeterminate ? '全不选' : '全选'")
th.nobreak(style="width: 25%;") 歌曲名
th.nobreak(style="width: 20%;") 歌手
th.nobreak(style="width: 22%;") 专辑
th.nobreak(style="width: 18%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody" ref="dom_scrollContent")
table
tbody
tr(v-for='(item, index) in list' :key='item.songmid' @click="handleDoubleClick(index)")
td.nobreak.center(style="width: 37px;" @click.stop)
material-checkbox(:id="index.toString()" v-model="selectdData" :value="item")
td.break(style="width: 25%;")
| {{item.name}}
//- span.badge.badge-info(v-if="item._types['320k']")
//- span.badge.badge-success(v-if="item._types.ape || item._types.flac")
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 22%;") {{item.albumName}}
td(style="width: 18%;")
material-list-buttons(:index="index" :search-btn="true" :play-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')" :download-btn="item.source == 'kw' || (!isAPITemp && item.source != 'tx')" :remove-btn="false" @btn-click="handleListBtnClick")
//- button.btn-info(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k'] || item._types.flac" @click.stop='openDownloadModal(index)')
//- button.btn-secondary(type='button' v-if="item._types['128k'] || item._types['192k'] || item._types['320k']" @click.stop='testPlay(index)')
//- button.btn-success(type='button' v-if="(item._types['128k'] || item._types['192k'] || item._types['320k']) && userInfo" @click.stop='showListModal(index)')
td(style="width: 10%;") {{item.interval || '--/--'}}
div(:class="$style.pagination")
material-pagination(:count="info.total" :limit="info.limit" :page="info.page" @btn-click="handleTogglePage")
material-download-modal(:show="isShowDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="isShowDownload = false")
material-download-multiple-modal(:show="isShowDownloadMultiple" :list="selectdData" @select="handleAddDownloadMultiple" @close="isShowDownloadMultiple = false")
material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")
</template>
<script>
import { mapGetters, mapMutations, mapActions } from 'vuex'
import { scrollTo } from '../utils'
// import music from '../utils/music'
export default {
name: 'SongList',
name: 'Leaderboard',
data() {
return {
count: 0,
tagId: null,
sortId: null,
source: null,
listPage: 1,
songListPage: 1,
clickTime: 0,
clickIndex: -1,
isShowDownload: false,
musicInfo: null,
selectdData: [],
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
isShowDownloadMultiple: false,
}
},
computed: {
...mapGetters(['setting']),
...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'listDetail']),
...mapGetters('list', ['defaultList']),
types() {
return this.source ? this.sourceInfo.sources[this.source] : []
},
isAPITemp() {
return this.setting.apiSource == 'temp'
},
},
watch: {
sortId(n, o) {
this.setSongList({ sortId: n })
if (!o && this.listPage !== 1) return
this.getList(1).then(() => {
this.listPage = this.info.listPage
scrollTo(this.$refs.dom_scrollContent, 0)
})
},
tagId(n, o) {
this.setSongList({ sortId: n })
if (!o && this.songListPage !== 1) return
this.getList(1).then(() => {
this.songListPage = this.info.songListPage
scrollTo(this.$refs.dom_scrollContent, 0)
})
},
source(n, o) {
this.setSongList({ source: n })
if (o) {
this.tagId = this.tags[0] && this.tags[0].id
this.sortType = this.sortList[0] && this.sortList[0].id
}
},
selectdData(n) {
const len = n.length
if (len) {
this.isSelectAll = true
this.isIndeterminate = len !== this.list.length
this.isShowEditBtn = true
} else {
this.isSelectAll = false
this.isShowEditBtn = false
}
},
list() {
this.resetSelect()
},
},
mounted() {
this.source = this.setting.songList.source
// this.sortId = this.setting.songList.sortId
this.listPage = this.listData.page
this.songListPage = this.listDetail.page
},
methods: {
add() {
this.count++
...mapMutations(['setSongList']),
...mapActions('songList', ['getTags', 'getList', 'getListDetail']),
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
...mapMutations('list', ['defaultListAdd', 'defaultListAddMultiple']),
...mapMutations('player', ['setList']),
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
this.clickIndex !== index
) {
this.clickTime = window.performance.now()
this.clickIndex = index
return
}
(this.source == 'kw' || (!this.isAPITemp && this.list[index].source != 'tx')) ? this.testPlay(index) : this.handleSearch(index)
this.clickTime = 0
this.clickIndex = -1
},
handleListBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.isShowDownload = true
})
break
case 'play':
this.testPlay(info.index)
break
case 'search':
this.handleSearch(info.index)
break
// case 'add':
// break
}
},
testPlay(index) {
let targetSong
if (index == null) {
targetSong = this.selectdData[0]
this.defaultListAddMultiple(this.selectdData)
} else {
targetSong = this.list[index]
this.defaultListAdd(targetSong)
}
let targetIndex = this.defaultList.list.findIndex(
s => s.songmid === targetSong.songmid
)
if (targetIndex > -1) {
this.setList({
list: this.defaultList.list,
listId: 'test',
index: targetIndex,
})
}
},
handleSearch(index) {
const info = this.list[index]
this.$router.push({
path: 'search',
query: {
text: `${info.name} ${info.singer}`,
},
})
},
handleTogglePage(page) {
this.getList(page).then(() => {
this.page = this.info.page
this.$nextTick(() => {
scrollTo(this.$refs.dom_scrollContent, 0)
})
})
},
handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : []
},
resetSelect() {
this.isSelectAll = false
this.selectdData = []
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.isShowDownload = false
},
handleAddDownloadMultiple(type) {
switch (this.source) {
// case 'kg':
case 'wy':
type = '128k'
}
this.createDownloadMultiple({ list: [...this.selectdData], type })
this.resetSelect()
this.isShowDownloadMultiple = false
},
handleFlowBtnClick(action) {
switch (action) {
case 'download':
this.isShowDownloadMultiple = true
break
case 'play':
this.testPlay()
this.resetSelect()
break
case 'add':
this.defaultListAddMultiple(this.selectdData)
this.resetSelect()
break
}
},
},
}
</script>
<style lang="less" module>
@import '../assets/styles/layout.less';
.leaderboard {
height: 100%;
display: flex;
flex-flow: column nowrap;
}
.header {
flex: none;
width: 100%;
display: flex;
flex-flow: row nowrap;
}
.tab {
flex: auto;
}
.select {
flex: none;
width: 80px;
}
.content {
flex: auto;
display: flex;
overflow: hidden;
flex-flow: column nowrap;
}
.list {
position: relative;
height: 100%;
font-size: 14px;
display: flex;
flex-flow: column nowrap;
// table {
// position: relative;
// thead {
// position: fixed;
// width: 100%;
// th {
// width: 100%;
// }
// }
// }
}
.thead {
flex: none;
}
.tbody {
flex: auto;
overflow-y: auto;
td {
font-size: 12px;
:global(.badge) {
margin-right: 3px;
&:first-child {
margin-left: 3px;
}
&:last-child {
margin-right: 0;
}
}
}
}
.pagination {
text-align: center;
padding: 15px 0;
// left: 50%;
// transform: translateX(-50%);
}
</style>