diff --git a/publish/changeLog.md b/publish/changeLog.md index 21bb85bb..74eccad3 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -1,12 +1,10 @@ ### 新增 -- 新增**测试接口**,该接口同样速度较慢,但软件的大部分功能可用,**请自行切换到该接口**,找接口辛苦,且用且珍惜! +- 在设置界面-关于洛雪音乐说明部分新增**最新版网盘下载地址**与**打赏地址** +- 新增酷我、酷狗、百度源**歌单** ### 优化 -- 取消需要刷新URL时windows任务栏进度显示错误状态(现显示为暂停状态) - -### 修复 - -- 修复使用临时接口时在试听列表双击灰色歌曲仍然会进行播放的Bug -- 修复歌词加载Bug +- 目前使用的测试接口与临时接口已趋于稳定 +- 测试接口支持**酷我、酷狗、百度、网易云**源直接播放与下载 +- 临时接口仅支持**酷我**源直接播放与下载 diff --git a/src/renderer/components/core/Aside.vue b/src/renderer/components/core/Aside.vue index 9d4e8c3b..b07cbe27 100644 --- a/src/renderer/components/core/Aside.vue +++ b/src/renderer/components/core/Aside.vue @@ -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") 排行榜 diff --git a/src/renderer/components/material/SongList.vue b/src/renderer/components/material/SongList.vue new file mode 100644 index 00000000..1f3da395 --- /dev/null +++ b/src/renderer/components/material/SongList.vue @@ -0,0 +1,201 @@ + + + + + + diff --git a/src/renderer/store/modules/songList.js b/src/renderer/store/modules/songList.js new file mode 100644 index 00000000..f9f66c34 --- /dev/null +++ b/src/renderer/store/modules/songList.js @@ -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, +} diff --git a/src/renderer/store/mutations.js b/src/renderer/store/mutations.js index 89fdcebc..2b46854b 100644 --- a/src/renderer/store/mutations.js +++ b/src/renderer/store/mutations.js @@ -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, '
') diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js index d91e2d83..cbd60f5a 100644 --- a/src/renderer/utils/index.js +++ b/src/renderer/utils/index.js @@ -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) diff --git a/src/renderer/utils/music/bd/index.js b/src/renderer/utils/music/bd/index.js index 97bae063..b3be4315 100644 --- a/src/renderer/utils/music/bd/index.js +++ b/src/renderer/utils/music/bd/index.js @@ -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) }, diff --git a/src/renderer/utils/music/bd/songList.js b/src/renderer/utils/music/bd/songList.js index ff5593cd..8d718320 100644 --- a/src/renderer/utils/music/bd/songList.js +++ b/src/renderer/utils/music/bd/songList.js @@ -13,10 +13,12 @@ export default { sortList: [ { name: '最热', + tabId: 'bdhot', id: '最热', }, { name: '最新', + tabId: 'bdnew', id: '最新', }, ], diff --git a/src/renderer/utils/music/kg/index.js b/src/renderer/utils/music/kg/index.js index 4e83935a..c18d1db9 100644 --- a/src/renderer/utils/music/kg/index.js +++ b/src/renderer/utils/music/kg/index.js @@ -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) }, diff --git a/src/renderer/utils/music/kg/songList.js b/src/renderer/utils/music/kg/songList.js index 82b23606..89dc0675 100644 --- a/src/renderer/utils/music/kg/songList.js +++ b/src/renderer/utils/music/kg/songList.js @@ -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', }, ], diff --git a/src/renderer/utils/music/kw/index.js b/src/renderer/utils/music/kw/index.js index 81989495..3f5b91b9 100644 --- a/src/renderer/utils/music/kw/index.js +++ b/src/renderer/utils/music/kw/index.js @@ -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) diff --git a/src/renderer/utils/music/kw/songList.js b/src/renderer/utils/music/kw/songList.js index 2a0ea23a..0b43de52 100644 --- a/src/renderer/utils/music/kw/songList.js +++ b/src/renderer/utils/music/kw/songList.js @@ -13,10 +13,12 @@ export default { sortList: [ { name: '最热', + tabId: 'kwhot', id: 'hot', }, { name: '最新', + tabId: 'kwnew', id: 'new', }, ], diff --git a/src/renderer/views/Leaderboard.vue b/src/renderer/views/Leaderboard.vue index 52bce7cb..e75e0bf7 100644 --- a/src/renderer/views/Leaderboard.vue +++ b/src/renderer/views/Leaderboard.vue @@ -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 @@ @@ -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%); -} + diff --git a/src/renderer/views/Setting.vue b/src/renderer/views/Setting.vue index 1af3dc93..05207d6b 100644 --- a/src/renderer/views/Setting.vue +++ b/src/renderer/views/Setting.vue @@ -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 + | 最新版网盘下载地址(网盘内有MAC、windows版): + span.hover(title="点击打开" @click="handleOpenUrl('https://www.lanzous.com/b906260/')") https://www.lanzous.com/b906260/ + |   密码: + 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") diff --git a/src/renderer/views/SongList.vue b/src/renderer/views/SongList.vue index 6c2e9d97..d28904e2 100644 --- a/src/renderer/views/SongList.vue +++ b/src/renderer/views/SongList.vue @@ -1,20 +1,310 @@ + + +