新增列表多选操作功能

This commit is contained in:
lyswhut
2019-08-19 18:19:39 +08:00
parent 8817318a53
commit 601e1a67a1
26 changed files with 750 additions and 192 deletions
+96 -18
View File
@@ -6,8 +6,11 @@ div(:class="$style.download")
table
thead
tr
th.nobreak(style="width: 30%;") 歌曲名
th.nobreak(style="width: 25%;") 进度
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: 28%;") 歌曲名
th.nobreak(style="width: 22%;") 进度
th.nobreak(style="width: 15%;") 状态
th.nobreak(style="width: 10%;") 品质
th.nobreak(style="width: 20%;") 操作
@@ -15,12 +18,17 @@ div(:class="$style.download")
table
tbody
tr(v-for='(item, index) in list' :key='item.key' @click="handleDoubleClick(index)" :class="isPlayList && playIndex === index ? $style.active : ''")
td.break(style="width: 30%;") {{item.musicInfo.name}} - {{item.musicInfo.singer}}
td.break(style="width: 25%;") {{item.progress.progress}}%
td.nobreak.center(style="width: 37px;" @click.stop)
material-checkbox(:id="index.toString()" v-model="selectdData" :value="item")
td.break(style="width: 28%;") {{item.musicInfo.name}} - {{item.musicInfo.singer}}
td.break(style="width: 22%;") {{item.progress.progress}}%
td.break(style="width: 15%;") {{item.statusText}}
td.break(style="width: 10%;") {{item.type.toUpperCase()}}
td(style="width: 20%; padding-left: 0; padding-right: 0;")
material-list-buttons(:index="index" :downloadBtn="false" @btn-click="handleBtnClick")
material-list-buttons(:index="index" :download-btn="false" :start-btn="!item.isComplate && item.status != downloadStatus.WAITING && (item.status != downloadStatus.RUN)"
:pause-btn="!item.isComplate && (item.status == downloadStatus.RUN || item.status == downloadStatus.WAITING)"
:play-btn="item.status == downloadStatus.COMPLETED" @btn-click="handleListBtnClick")
material-flow-btn(:show="isShowEditBtn" :play-btn="false" :download-btn="false" :add-btn="false" :start-btn="true" :pause-btn="true" @btn-click="handleFlowBtnClick")
div(:class="$style.noItem" v-else)
</template>
@@ -34,26 +42,51 @@ export default {
return {
clickTime: window.performance.now(),
clickIndex: -1,
selectdData: [],
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
isShowDownloadMultiple: false,
}
},
computed: {
...mapGetters('download', ['list', 'dls']),
...mapGetters('download', ['list', 'dls', 'downloadStatus']),
...mapGetters('player', ['listId', 'playIndex']),
isPlayList() {
return this.listId == 'download'
},
},
methods: {
...mapActions('download', ['removeTask', 'resumeTask']),
...mapMutations('player', ['setList']),
pauseTask(index) {
let info = this.list[index]
this.dls[info.key].pause()
watch: {
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
}
},
startTask(index) {
list() {
this.resetSelect()
},
},
methods: {
...mapActions('download', ['removeTask', 'removeTaskMultiple', 'startTask']),
...mapMutations('player', ['setList']),
...mapMutations('download', ['pauseTask']),
handlePauseTask(index) {
let info = this.list[index]
let dl = this.dls[info.key]
dl ? dl.resume() : this.resumeTask(info)
dl ? dl.pause() : this.pauseTask(info)
console.log('pause')
},
handleStartTask(index) {
console.log('start')
let info = this.list[index]
let dl = this.dls[info.key]
dl ? dl.resume() : this.startTask(info)
},
handleDoubleClick(index) {
if (
@@ -72,26 +105,71 @@ export default {
let info = this.list[index]
if (info.isComplate) {
this.handlePlay(index)
} else if (info.isDownloading) {
this.pauseTask(index)
} else if (info.status === this.downloadStatus.RUN) {
this.handlePauseTask(index)
} else {
this.startTask(index)
this.handleStartTask(index)
}
},
handlePlay(index) {
if (!checkPath(this.list[index].filePath)) return
this.setList({ list: this.list, listId: 'download', index })
},
handleBtnClick(info) {
handleListBtnClick(info) {
switch (info.action) {
case 'play':
this.handlePlay(info.index)
break
case 'start':
this.handleStartTask(info.index)
break
case 'pause':
this.handlePauseTask(info.index)
break
case 'remove':
this.removeTask(info.index)
break
}
},
handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : []
},
resetSelect() {
this.isSelectAll = false
this.selectdData = []
},
handleFlowBtnClick(action) {
switch (action) {
case 'start':
this.selectdData.forEach(item => {
if (item.isComplate || item.status == this.downloadStatus.RUN) return
let index = this.list.indexOf(item)
if (index < 0) return
this.handleStartTask(index)
})
break
case 'pause':
let runs = []
this.selectdData.forEach(item => {
if (item.isComplate || item.status == this.downloadStatus.PAUSE) return
if (item.status == this.downloadStatus.RUN) return runs.push(item)
let index = this.list.indexOf(item)
if (index < 0) return
this.handlePauseTask(index)
})
runs.forEach(item => {
if (item.isComplate || item.status == this.downloadStatus.PAUSE) return
let index = this.list.indexOf(item)
if (index < 0) return
this.handlePauseTask(index)
})
break
case 'remove':
this.removeTaskMultiple(this.selectdData)
break
}
this.resetSelect()
},
},
}
</script>
+73 -14
View File
@@ -9,30 +9,37 @@
table
thead
tr
th.nobreak(style="width: 27%;") 歌曲名
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: 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.break(style="width: 27%;")
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: 25%;") {{item.albumName}}
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="handleBtnClick")
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="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
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" :remove-btn="false" @btn-click="handleFlowBtnClick")
</template>
<script>
@@ -48,8 +55,13 @@ export default {
page: 1,
clickTime: 0,
clickIndex: -1,
showDownload: false,
isShowDownload: false,
musicInfo: null,
selectdData: [],
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
isShowDownloadMultiple: false,
}
},
computed: {
@@ -76,6 +88,20 @@ export default {
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
}
},
list() {
this.resetSelect()
},
},
mounted() {
this.source = this.setting.leaderboard.source
@@ -85,8 +111,8 @@ export default {
methods: {
...mapMutations(['setLeaderboard']),
...mapActions('leaderboard', ['getList']),
...mapActions('download', ['createDownload']),
...mapMutations('list', ['defaultListAdd']),
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
...mapMutations('list', ['defaultListAdd', 'defaultListAddMultiple']),
...mapMutations('player', ['setList']),
handleDoubleClick(index) {
if (
@@ -101,12 +127,12 @@ export default {
this.clickTime = 0
this.clickIndex = -1
},
handleBtnClick(info) {
handleListBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
this.isShowDownload = true
})
break
case 'play':
@@ -120,8 +146,14 @@ export default {
}
},
testPlay(index) {
let targetSong = this.list[index]
this.defaultListAdd(targetSong)
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
)
@@ -150,9 +182,36 @@ export default {
})
})
},
handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : []
},
resetSelect() {
this.isSelectAll = false
this.selectdData = []
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
this.isShowDownload = false
},
handleAddDownloadMultiple(type) {
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
}
},
},
}
+61 -10
View File
@@ -6,9 +6,12 @@
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%;" v-if="setting.list.isShowAlbumName") 专辑
th.nobreak(style="width: 20%;" v-if="setting.list.isShowAlbumName") 专辑
th.nobreak(style="width: 20%;") 操作
th.nobreak(style="width: 10%;") 时长
div.scroll(:class="$style.tbody")
@@ -16,6 +19,8 @@
tbody
tr(v-for='(item, index) in list' :key='item.songmid'
@click="handleDoubleClick(index)" :class="[isPlayList && playIndex === index ? $style.active : '', isAPITemp && item.source != 'kw' ? $style.disabled : '']")
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-light(v-if="item._types['128k']") 128K
//- span.badge.badge-light(v-if="item._types['192k']") 192K
@@ -23,16 +28,18 @@
//- span.badge.badge-info(v-if="item._types.ape") APE
//- span.badge.badge-success(v-if="item._types.flac") FLAC
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;" v-if="setting.list.isShowAlbumName") {{item.albumName}}
td.break(style="width: 20%;" v-if="setting.list.isShowAlbumName") {{item.albumName}}
td(style="width: 20%; padding-left: 0; padding-right: 0;")
material-list-buttons(:index="index" @btn-click="handleBtnClick")
material-list-buttons(:index="index" @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-secondary(type='button' @click.stop='handleRemove(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.noItem" v-else)
material-download-modal(:show="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
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" :add-btn="false" :play-btn="false" @btn-click="handleFlowBtnClick")
</template>
<script>
@@ -43,8 +50,13 @@ export default {
return {
clickTime: window.performance.now(),
clickIndex: -1,
showDownload: false,
isShowDownload: false,
musicInfo: null,
selectdData: [],
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
isShowDownloadMultiple: false,
}
},
computed: {
@@ -66,6 +78,22 @@ export default {
return this.setting.apiSource == 'temp'
},
},
watch: {
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()
},
},
// beforeRouteUpdate(to, from, next) {
// // if (to.query.id === undefined) return
// // if (to.query.text === '') {
@@ -92,9 +120,9 @@ export default {
// }
// },
methods: {
...mapMutations('list', ['defaultListRemove']),
...mapMutations('list', ['defaultListRemove', 'defaultListRemoveMultiple']),
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
...mapMutations('player', ['setList']),
...mapActions('download', ['createDownload']),
handleDoubleClick(index) {
if (
window.performance.now() - this.clickTime > 400 ||
@@ -115,12 +143,12 @@ export default {
handleRemove(index) {
this.defaultListRemove(index)
},
handleBtnClick(info) {
handleListBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
this.isShowDownload = true
})
break
case 'play':
@@ -135,7 +163,30 @@ export default {
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
this.isShowDownload = false
},
handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : []
},
resetSelect() {
this.isSelectAll = false
this.selectdData = []
},
handleAddDownloadMultiple(type) {
this.createDownloadMultiple({ list: [...this.selectdData], type })
this.resetSelect()
this.isShowDownloadMultiple = false
},
handleFlowBtnClick(action) {
switch (action) {
case 'download':
this.isShowDownloadMultiple = true
break
case 'remove':
this.defaultListRemoveMultiple(this.selectdData)
this.resetSelect()
break
}
},
},
}
+39 -10
View File
@@ -27,13 +27,15 @@
td.break(style="width: 20%;") {{item.singer}}
td.break(style="width: 25%;") {{item.albumName}}
td(style="width: 15%;")
material-list-buttons(:index="index" :remove-btn="false" @btn-click="handleBtnClick")
material-list-buttons(:index="index" :remove-btn="false" @btn-click="handleListBtnClick")
td(style="width: 10%;") {{item.interval}}
div(:class="$style.pagination")
material-pagination(:count="listInfo.total" :limit="limit" :page="page" @btn-click="handleTogglePage")
div(v-else :class="$style.noitem")
p 搜我所想~~😉
material-download-modal(:show="showDownload" :musicInfo="musicInfo" @select="handleAddDownload" @close="showDownload = false")
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" :remove-btn="false" @btn-click="handleFlowBtnClick")
</template>
<script>
@@ -48,12 +50,13 @@ export default {
text: '',
clickTime: 0,
clickIndex: -1,
showDownload: false,
isShowDownload: false,
musicInfo: null,
selectdData: [],
isSelectAll: false,
isIndeterminate: false,
isShowEditBtn: false,
isShowDownloadMultiple: false,
}
},
beforeRouteUpdate(to, from, next) {
@@ -104,9 +107,9 @@ export default {
},
methods: {
...mapActions('search', ['search']),
...mapActions('download', ['createDownload']),
...mapActions('download', ['createDownload', 'createDownloadMultiple']),
...mapMutations('search', ['clearList', 'setPage']),
...mapMutations('list', ['defaultListAdd']),
...mapMutations('list', ['defaultListAdd', 'defaultListAddMultiple']),
...mapMutations('player', ['setList']),
handleSearch(text, page) {
this.search({ text, page, limit: this.limit }).then(data => {
@@ -129,12 +132,12 @@ export default {
this.clickTime = 0
this.clickIndex = -1
},
handleBtnClick(info) {
handleListBtnClick(info) {
switch (info.action) {
case 'download':
this.musicInfo = this.list[info.index]
this.$nextTick(() => {
this.showDownload = true
this.isShowDownload = true
})
break
case 'play':
@@ -145,8 +148,14 @@ export default {
}
},
testPlay(index) {
let targetSong = this.list[index]
this.defaultListAdd(targetSong)
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
)
@@ -163,7 +172,12 @@ export default {
},
handleAddDownload(type) {
this.createDownload({ musicInfo: this.musicInfo, type })
this.showDownload = false
this.isShowDownload = false
},
handleAddDownloadMultiple(type) {
this.createDownloadMultiple({ list: [...this.selectdData], type })
this.resetSelect()
this.isShowDownloadMultiple = false
},
handleSelectAllData(isSelect) {
this.selectdData = isSelect ? [...this.list] : []
@@ -172,6 +186,21 @@ export default {
this.isSelectAll = false
this.selectdData = []
},
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>
+1 -1
View File
@@ -142,7 +142,7 @@ export default {
apiSources: [
{
id: 'messoer',
label: '由 messoer 提供的接口(推荐,软件的所有功能都可用)',
label: '由 messoer 提供的接口(推荐,软件的所有功能都可用)<br><span style="line-height: 1.5;"><strong>注意:</strong>本接口10秒内请求数超过100次会封10小时的IP</span>',
},
{
id: 'temp',