diff --git a/src/renderer/components/material/SongList.vue b/src/renderer/components/material/SongList.vue
index de87a1ac..c9681c40 100644
--- a/src/renderer/components/material/SongList.vue
+++ b/src/renderer/components/material/SongList.vue
@@ -18,7 +18,7 @@ div(:class="$style.songList")
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")
+ material-checkbox(:id="index.toString()" v-model="selectdList" @change="handleChangeSelect" :value="item")
td.break(style="width: 25%;")
| {{item.name}}
span.badge.badge-info(v-if="item._types['320k']") 高品质
@@ -34,7 +34,7 @@ div(:class="$style.songList")
div(:class="$style.pagination")
material-pagination(:count="total" :limit="limit" :page="page" @btn-click="handleTogglePage")
div(v-else :class="$style.noitem")
- p(v-html="noitem")
+ p(v-html="noItem")
material-flow-btn(:show="isShowEditBtn && (source == 'kw' || !isAPITemp)" :remove-btn="false" @btn-click="handleFlowBtnClick")
@@ -73,9 +73,9 @@ export default {
source: {
type: String,
},
- noitem: {
+ noItem: {
type: String,
- default: '搜我所想~~😉',
+ default: '列表加载中...',
},
},
computed: {
@@ -95,7 +95,19 @@ export default {
this.isSelectAll = false
this.isShowEditBtn = false
}
- this.$emit('input', [...n])
+ },
+ selectdData(n) {
+ const len = n.length
+ if (len) {
+ this.isSelectAll = true
+ this.isIndeterminate = len !== this.list.length
+ this.isShowEditBtn = true
+ this.selectdList = [...n]
+ } else {
+ this.isSelectAll = false
+ this.isShowEditBtn = false
+ this.resetSelect()
+ }
},
list(n) {
this.resetSelect()
@@ -145,6 +157,9 @@ export default {
emitEvent(action, data) {
this.$emit('action', { action, data })
},
+ handleChangeSelect() {
+ this.$emit('input', [...this.selectdList])
+ },
},
}
diff --git a/src/renderer/components/material/TagList.vue b/src/renderer/components/material/TagList.vue
new file mode 100644
index 00000000..20020ac0
--- /dev/null
+++ b/src/renderer/components/material/TagList.vue
@@ -0,0 +1,194 @@
+
+ div(:class="$style.tagList")
+ div(:class="$style.label" ref="dom_btn" @click="handleShow") {{value.name}}
+ div.scroll(:class="$style.list" @click.stop ref="dom_list" :style="listStyle")
+ div(:class="$style.tag" @click="handleClick(null)") 全部
+ dl(:class="$style.type" v-for="type in list")
+ dt(:class="$style.type") {{type.name}}
+ dd(:class="$style.tag" v-for="tag in type.list" @click="handleClick(tag)") {{tag.name}}
+
+
+
+
+
+
diff --git a/src/renderer/store/modules/songList.js b/src/renderer/store/modules/songList.js
index 5a30fe14..961f344d 100644
--- a/src/renderer/store/modules/songList.js
+++ b/src/renderer/store/modules/songList.js
@@ -25,12 +25,19 @@ const state = {
limit: 30,
key: null,
},
+ isVisibleListDetail: false,
}
+sources.forEach(source => {
+ state.tags[source.id] = null
+})
+
+
// getters
const getters = {
sourceInfo: () => ({ sources, sortList }),
tags: state => state.tags,
+ isVisibleListDetail: state => state.isVisibleListDetail,
listData(state) {
return state.list
},
@@ -47,17 +54,19 @@ const actions = {
},
getList({ state, rootState, commit }, page) {
let source = rootState.setting.songList.source
- let tabId = rootState.setting.songList.tagId
+ let tabId = rootState.setting.songList.tagInfo.id
let sortId = rootState.setting.songList.sortId
+ console.log(sortId)
let key = `${source}${sortId}${tabId}${page}`
if (state.list.list.length && state.list.key == key) return true
- return music[source].songList.getList(sortId, tabId, page).then(result => commit('setList', { result, key }))
+ return music[source].songList.getList(sortId, tabId, page).then(result => commit('setList', { result, key, page }))
},
getListDetail({ state, rootState, commit }, { id, page }) {
let source = rootState.setting.songList.source
- let key = `${source}${id}${page}}`
+ 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 }))
+ console.log(id, page)
+ return music[source].songList.getListDetail(id, page).then(result => commit('setListDetail', { result, key, page }))
},
}
@@ -66,20 +75,23 @@ const mutations = {
setTags(state, { tags, source }) {
state.tags[source] = tags
},
- setList(state, { result, key }) {
+ setList(state, { result, key, page }) {
state.list.list = result.list
state.list.total = result.total
state.list.limit = result.limit
- state.list.page = result.page
+ state.list.page = page
state.list.key = key
},
- setListDetail(state, { result, key }) {
+ setListDetail(state, { result, key, page }) {
state.listDetail.list = result.list
state.listDetail.total = result.total
state.listDetail.limit = result.limit
- state.listDetail.page = result.page
+ state.listDetail.page = page
state.listDetail.key = key
},
+ setVisibleListDetail(state, bool) {
+ state.isVisibleListDetail = bool
+ },
}
export default {
diff --git a/src/renderer/store/mutations.js b/src/renderer/store/mutations.js
index 5988335c..c11d257d 100644
--- a/src/renderer/store/mutations.js
+++ b/src/renderer/store/mutations.js
@@ -12,8 +12,8 @@ export default {
if (tabId != null) state.setting.leaderboard.tabId = tabId
if (source != null) state.setting.leaderboard.source = source
},
- setSongList(state, { sortId, tagId, source }) {
- if (tagId != null) state.setting.songList.tagId = tagId
+ setSongList(state, { sortId, tagInfo, source }) {
+ if (tagInfo != null) state.setting.songList.tagInfo = tagInfo
if (sortId != null) state.setting.songList.sortId = sortId
if (source != null) state.setting.songList.source = source
},
diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js
index 47bf0dfa..4e9a8127 100644
--- a/src/renderer/utils/index.js
+++ b/src/renderer/utils/index.js
@@ -186,7 +186,10 @@ export const updateSetting = setting => {
songList: {
source: 'kw',
sortId: 'hot',
- tagId: null,
+ tagInfo: {
+ name: '全部',
+ id: null,
+ },
},
themeId: 0,
sourceId: 'kw',
diff --git a/src/renderer/utils/music/bd/songList.js b/src/renderer/utils/music/bd/songList.js
index 54344f94..95da24ca 100644
--- a/src/renderer/utils/music/bd/songList.js
+++ b/src/renderer/utils/music/bd/songList.js
@@ -127,7 +127,7 @@ export default {
},
filterTagInfo(rawList) {
return rawList.map(type => ({
- type: type.first,
+ name: type.first,
list: type.second.map(item => ({
parent_id: type.first,
parent_name: type.first,
diff --git a/src/renderer/utils/music/kg/leaderboard.js b/src/renderer/utils/music/kg/leaderboard.js
index 826e783d..b1abf396 100644
--- a/src/renderer/utils/music/kg/leaderboard.js
+++ b/src/renderer/utils/music/kg/leaderboard.js
@@ -5,7 +5,7 @@ export default {
list: [
{
id: 'kgtop500',
- name: 'TOP500',
+ name: '酷狗TOP500',
bangid: '8888',
},
{
@@ -45,7 +45,7 @@ export default {
},
{
id: 'kgdyrgb',
- name: '电音热歌榜',
+ name: '电音榜',
bangid: '33160',
},
{
diff --git a/src/renderer/utils/music/kg/songList.js b/src/renderer/utils/music/kg/songList.js
index 283768f6..e16de429 100644
--- a/src/renderer/utils/music/kg/songList.js
+++ b/src/renderer/utils/music/kg/songList.js
@@ -41,8 +41,9 @@ export default {
? `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_smarty=1&cdn=cdn&t=5&c=${tagId}`
: `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_smarty=1&`
},
- getSongListUrl(sortId, tagId = '', page) {
- return `http://www2.kugou.kugou.com/yueku/v9/special/index/getData/getData.html&cdn=cdn&t=${sortId}&c=${tagId}?is_ajax=1&p=${page}`
+ getSongListUrl(sortId, tagId, page) {
+ if (tagId == null) tagId = ''
+ return `http://www2.kugou.kugou.com/yueku/v9/special/getSpecial?is_ajax=1&cdn=cdn&t=${sortId}&c=${tagId}&p=${page}`
},
getSongListDetailUrl(id) {
return `http://www2.kugou.kugou.com/yueku/v9/special/single/${id}-5-9999.html`
@@ -71,10 +72,10 @@ export default {
},
filterTagInfo(rawData) {
const result = []
- for (const type of Object.keys(rawData)) {
+ for (const name of Object.keys(rawData)) {
result.push({
- type,
- list: rawData[type].data.map(tag => ({
+ name,
+ list: rawData[name].data.map(tag => ({
parent_id: tag.parent_id,
parent_name: tag.pname,
id: tag.id,
@@ -196,7 +197,7 @@ export default {
interval: formatPlayTime(item.duration / 1000),
img: null,
lrc: null,
- hash: item.HASH,
+ hash: item.hash,
types,
_types,
typeUrl: {},
@@ -232,7 +233,6 @@ export default {
)
if (!tagId) tasks.push(this.getSongListRecommend()) // 如果是所有类别,则顺便获取推荐列表
return Promise.all(tasks).then(([list, info, recommendList]) => {
- console.log(recommendList)
if (recommendList) list.unshift(...recommendList)
return {
list,
diff --git a/src/renderer/utils/music/kw/songList.js b/src/renderer/utils/music/kw/songList.js
index 0f2908c4..4d40f800 100644
--- a/src/renderer/utils/music/kw/songList.js
+++ b/src/renderer/utils/music/kw/songList.js
@@ -58,7 +58,7 @@ export default {
},
filterTagInfo(rawList) {
return rawList.map(type => ({
- type: type.name,
+ name: type.name,
list: type.data.map(item => ({
parent_id: type.id,
parent_name: type.name,
@@ -115,7 +115,7 @@ export default {
return this._requestObj_listDetail.promise.then(({ body }) => {
if (body.result !== 'ok') return this.getListDetail(id, page)
return {
- list: this.filterListDetail(body.data.musiclist),
+ list: this.filterListDetail(body.musiclist),
page,
limit: body.rn,
total: body.total,
diff --git a/src/renderer/views/Leaderboard.vue b/src/renderer/views/Leaderboard.vue
index a26a9d94..3789a9e2 100644
--- a/src/renderer/views/Leaderboard.vue
+++ b/src/renderer/views/Leaderboard.vue
@@ -1,9 +1,9 @@
div(:class="$style.leaderboard")
div(:class="$style.header")
- material-tab(:class="$style.tab" :list="types" item-key="id" item-name="name" v-model="tabId")
+ material-tab(:class="$style.tab" :list="types" align="left" 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")
- material-song-list(v-model="selectdData" noItem="列表加载中..." @action="handleSongListAction" :source="source" :page="page" :limit="info.limit" :total="info.total" :list="list")
+ 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")
@@ -81,6 +81,7 @@ export default {
if (index == null) {
targetSong = this.selectdData[0]
this.defaultListAddMultiple(this.selectdData)
+ this.resetSelect()
} else {
targetSong = this.list[index]
this.defaultListAdd(targetSong)
@@ -122,6 +123,7 @@ export default {
}
this.createDownloadMultiple({ list: [...this.selectdData], type })
this.isShowDownloadMultiple = false
+ this.resetSelect()
},
handleFlowBtnClick(action) {
switch (action) {
@@ -133,6 +135,7 @@ export default {
break
case 'add':
this.defaultListAddMultiple(this.selectdData)
+ this.resetSelect()
break
}
},
@@ -150,6 +153,9 @@ export default {
return this.handleSearch(data)
}
},
+ resetSelect() {
+ this.selectdData = []
+ },
},
}
diff --git a/src/renderer/views/SongList.vue b/src/renderer/views/SongList.vue
index 8784175f..9001b77b 100644
--- a/src/renderer/views/SongList.vue
+++ b/src/renderer/views/SongList.vue
@@ -1,8 +1,22 @@
div(:class="$style.leaderboard")
div(:class="$style.header")
+ material-tag-list(:class="$style.tagList" :list="tagList" v-model="tagInfo")
material-tab(:class="$style.tab" :list="sorts" 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.container")
+ div(:class="$style.materialSongList" v-show="isVisibleListDetail")
+ material-song-list(v-model="selectdData" @action="handleSongListAction" :source="source" :page="listDetail.page" :limit="listDetail.limit" :total="listDetail.total" :list="listDetail.list")
+ div.scroll(:class="$style.content" ref="dom_scrollContent" v-show="!isVisibleListDetail")
+ ul
+ li(:class="$style.item" v-for="(item, index) in listData.list" @click="handleItemClick(index)")
+ div(:class="$style.left")
+ img(:src="item.img")
+ div(:class="$style.right" :src="item.img")
+ h4(:title="item.name") {{item.name}}
+ p(:title="item.desc") {{item.desc}}
+ div(:class="$style.pagination")
+ material-pagination(:count="listData.total" :limit="listData.limit" :page="listData.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")
@@ -15,11 +29,12 @@ export default {
name: 'SongList',
data() {
return {
- tagId: null,
+ tagInfo: {
+ name: '全部',
+ id: null,
+ },
sortId: undefined,
source: null,
- listPage: 1,
- songListPage: 1,
isShowDownload: false,
musicInfo: null,
selectdData: [],
@@ -29,7 +44,7 @@ export default {
},
computed: {
...mapGetters(['setting']),
- ...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'listDetail']),
+ ...mapGetters('songList', ['sourceInfo', 'tags', 'listData', 'isVisibleListDetail', 'listDetail']),
...mapGetters('list', ['defaultList']),
sorts() {
return this.source ? this.sourceInfo.sortList[this.source] : []
@@ -37,24 +52,31 @@ export default {
isAPITemp() {
return this.setting.apiSource == 'temp'
},
+ tagList() {
+ return this.tags[this.source] ? this.tags[this.source].tags : []
+ },
},
watch: {
sortId(n, o) {
this.setSongList({ sortId: n })
- if (o === undefined && this.listPage !== 1) return
+ if (o === undefined && this.listData.page !== 1) return
this.getList(1).then(() => {
- this.listPage = this.listData.listPage
+ this.$nextTick(() => {
+ scrollTo(this.$refs.dom_scrollContent, 0)
+ })
})
},
- tagId(n, o) {
- this.setSongList({ tagId: n })
- if (!o && this.listPage !== 1) return
+ tagInfo(n, o) {
+ this.setSongList({ tagInfo: n })
+ if (!o && this.listData.page !== 1) return
if (this.isToggleSource) {
this.isToggleSource = false
return
}
this.getList(1).then(() => {
- this.listPage = this.listData.listPage
+ this.$nextTick(() => {
+ scrollTo(this.$refs.dom_scrollContent, 0)
+ })
})
},
source(n, o) {
@@ -62,41 +84,31 @@ export default {
if (!this.tags[n]) this.getTags()
if (o) {
this.isToggleSource = true
- this.tagId = null
+ this.tagInfo = {
+ name: '全部',
+ id: null,
+ }
this.sortId = this.sorts[0] && this.sorts[0].id
}
},
},
mounted() {
this.source = this.setting.songList.source
- this.tagId = this.setting.songList.tagId
- this.listPage = this.listData.page
- this.songListPage = this.listDetail.page
+ this.isToggleSource = true
+ this.tagInfo = this.setting.songList.tagInfo
this.sortId = this.setting.songList.sortId
},
methods: {
...mapMutations(['setSongList']),
...mapActions('songList', ['getTags', 'getList', 'getListDetail']),
+ ...mapMutations('songList', ['setVisibleListDetail']),
...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.musicInfo = this.listDetail.list[info.index]
this.$nextTick(() => {
this.isShowDownload = true
})
@@ -116,8 +128,9 @@ export default {
if (index == null) {
targetSong = this.selectdData[0]
this.defaultListAddMultiple(this.selectdData)
+ this.resetSelect()
} else {
- targetSong = this.list[index]
+ targetSong = this.listDetail.list[index]
this.defaultListAdd(targetSong)
}
let targetIndex = this.defaultList.list.findIndex(
@@ -132,7 +145,7 @@ export default {
}
},
handleSearch(index) {
- const info = this.list[index]
+ const info = this.listDetail.list[index]
this.$router.push({
path: 'search',
query: {
@@ -142,19 +155,11 @@ export default {
},
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
@@ -169,6 +174,10 @@ export default {
this.resetSelect()
this.isShowDownloadMultiple = false
},
+ handleItemClick(index) {
+ this.setVisibleListDetail(true)
+ this.getListDetail({ id: this.listData.list[index].id, page: 1 })
+ },
handleFlowBtnClick(action) {
switch (action) {
case 'download':
@@ -176,7 +185,6 @@ export default {
break
case 'play':
this.testPlay()
- this.resetSelect()
break
case 'add':
this.defaultListAddMultiple(this.selectdData)
@@ -184,6 +192,23 @@ export default {
break
}
},
+ handleSongListAction({ action, data }) {
+ switch (action) {
+ case 'listBtnClick':
+ return this.handleListBtnClick(data)
+ case 'togglePage':
+ return this.handleTogglePage(data)
+ case 'flowBtnClick':
+ return this.handleFlowBtnClick(data)
+ case 'testPlay':
+ return this.testPlay(data)
+ case 'search':
+ return this.handleSearch(data)
+ }
+ },
+ resetSelect() {
+ this.selectdData = []
+ },
},
}
@@ -211,46 +236,62 @@ export default {
flex: none;
width: 80px;
}
-.content {
+
+.container {
flex: auto;
- display: flex;
overflow: hidden;
- flex-flow: column nowrap;
}
-.list {
- position: relative;
+
+.materialSongList {
+ position: absolute;
+ width: 100%;
height: 100%;
- font-size: 14px;
- display: flex;
- flex-flow: column nowrap;
- // table {
- // position: relative;
- // thead {
- // position: fixed;
- // width: 100%;
- // th {
- // width: 100%;
- // }
- // }
- // }
+ top: 0;
+ left: 0;
}
-.thead {
- flex: none;
-}
-.tbody {
- flex: auto;
+
+.content {
+ height: 100%;
overflow-y: auto;
- td {
+ padding: 0 15px;
+ ul {
+ display: flex;
+ flex-flow: row wrap;
+ }
+}
+.item {
+ width: 100% / 3;
+ box-sizing: border-box;
+ display: flex;
+ padding-top: 15px;
+}
+.left {
+ flex: none;
+ width: 30%;
+ display: flex;
+ img {
+ max-width: 100%;
+ }
+}
+.right {
+ flex: auto;
+ padding: 5px 15px 5px 7px;
+ overflow: hidden;
+ h4 {
+ font-size: 14px;
+ text-align: justify;
+ line-height: 1.2;
+ .mixin-ellipsis-1;
+ }
+ p {
+ margin-top: 12px;
font-size: 12px;
- :global(.badge) {
- margin-right: 3px;
- &:first-child {
- margin-left: 3px;
- }
- &:last-child {
- margin-right: 0;
- }
- }
+ .mixin-ellipsis-2;
+ text-align: justify;
+ line-height: 1.2;
+ // text-indent: 24px;
+
+ color: #888;
}
}
.pagination {