diff --git a/publish/changeLog.md b/publish/changeLog.md index 02ef5fef..c61118c6 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -4,6 +4,7 @@ - 新增设置-播放详情页设置-延迟歌词滚动设置(#1985) - 新增鼠标在音量按钮使用滚轮时可以调整音量大小的功能(#2000) - 新增设置-下载设置-同时下载任务数设置(#1498) +- 新增 我的列表-换源播放 功能,换源后下次再播放该列表的该歌曲时将优先尝试播放所选源的歌曲,该功能允许你手动指定来源以解决自动换源失败或者换源不准确的问题 ### 优化 diff --git a/src/common/types/music.d.ts b/src/common/types/music.d.ts index 12be91bf..c09aad6d 100644 --- a/src/common/types/music.d.ts +++ b/src/common/types/music.d.ts @@ -22,6 +22,7 @@ declare namespace LX { songId: string | number // 歌曲ID,mg源为copyrightId,local为文件路径 albumName: string // 歌曲专辑名称 picUrl?: string | null // 歌曲图片链接 + toggleMusicInfo?: MusicInfoOnline | null } interface MusicInfoMeta_online extends MusicInfoMetaBase { diff --git a/src/lang/en-us.json b/src/lang/en-us.json index dd02def8..81606d46 100644 --- a/src/lang/en-us.json +++ b/src/lang/en-us.json @@ -113,6 +113,7 @@ "list__source_detail": "Song Page", "list__start": "Start Task", "list__sync": "Update", + "list__toggle_source": "Change source", "list_add__btn_title": "Add the song(s) to {name}", "list_add__multiple_btn_title": "Add these song(s) to {name}", "list_add__multiple_title_add": "Add the selected {num} song(s) to ...", @@ -193,6 +194,7 @@ "music_sort__title": "Adjust the position of {name} to: ", "music_sort__title_multiple": "Adjust the position of the selected {num} songs to: ", "music_time": "Length", + "music_toggle_clean": "Cancel source change", "my_list": "Your Library", "no_item": "Nothing's here...", "not_agree": "Not accept", diff --git a/src/lang/zh-cn.json b/src/lang/zh-cn.json index 2f0cc8e3..89de19c2 100644 --- a/src/lang/zh-cn.json +++ b/src/lang/zh-cn.json @@ -113,6 +113,7 @@ "list__source_detail": "歌曲详情页", "list__start": "开始任务", "list__sync": "更新", + "list__toggle_source": "手动换源", "list_add__btn_title": "把该歌曲添加到 {name}", "list_add__multiple_btn_title": "把这些歌曲添加到 {name}", "list_add__multiple_title_add": "添加已选的 {num} 首歌曲到...", @@ -193,6 +194,7 @@ "music_sort__title": "将 {name} 的位置调整到:", "music_sort__title_multiple": "将已选的 {num} 首歌曲的位置调整到:", "music_time": "时长", + "music_toggle_clean": "取消换源", "my_list": "我的列表", "no_item": "列表竟然是空的...", "not_agree": "不接受", diff --git a/src/lang/zh-tw.json b/src/lang/zh-tw.json index 91ff22e8..4ccfda3b 100644 --- a/src/lang/zh-tw.json +++ b/src/lang/zh-tw.json @@ -113,6 +113,7 @@ "list__source_detail": "歌曲詳情頁", "list__start": "開始任務", "list__sync": "更新", + "list__toggle_source": "手動換源", "list_add__btn_title": "把該歌曲加到 {name}", "list_add__multiple_btn_title": "把這些歌曲加到 {name}", "list_add__multiple_title_add": "新增已選取的 {num} 首歌曲到...", @@ -193,6 +194,7 @@ "music_sort__title": "將 {name} 的位置調整到:", "music_sort__title_multiple": "將已選取的 {num} 首歌曲的位置調整至:", "music_time": "時長", + "music_toggle_clean": "取消換源", "my_list": "我的列表", "no_item": "列表竟然是空的...", "not_agree": "不接受", diff --git a/src/renderer/assets/svgs/angle-right-solid.svg b/src/renderer/assets/svgs/angle-right-solid.svg index aa6e5ae1..470821a7 100644 --- a/src/renderer/assets/svgs/angle-right-solid.svg +++ b/src/renderer/assets/svgs/angle-right-solid.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/checkbox-blank.svg b/src/renderer/assets/svgs/checkbox-blank.svg index 2de7c43c..7d4be815 100644 --- a/src/renderer/assets/svgs/checkbox-blank.svg +++ b/src/renderer/assets/svgs/checkbox-blank.svg @@ -1,5 +1 @@ - - - + diff --git a/src/renderer/assets/svgs/fullscreen-exit.svg b/src/renderer/assets/svgs/fullscreen-exit.svg index 1f443d9b..347d636d 100644 --- a/src/renderer/assets/svgs/fullscreen-exit.svg +++ b/src/renderer/assets/svgs/fullscreen-exit.svg @@ -1,3 +1 @@ - - - + diff --git a/src/renderer/assets/svgs/headphones.svg b/src/renderer/assets/svgs/headphones.svg index 49d9ff50..a4fe31ea 100644 --- a/src/renderer/assets/svgs/headphones.svg +++ b/src/renderer/assets/svgs/headphones.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/help-circle-outline.svg b/src/renderer/assets/svgs/help-circle-outline.svg index 14e83c0b..ff236f9a 100644 --- a/src/renderer/assets/svgs/help-circle-outline.svg +++ b/src/renderer/assets/svgs/help-circle-outline.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/information-slab-circle-outline.svg b/src/renderer/assets/svgs/information-slab-circle-outline.svg index b3ddf086..2a15ec1b 100644 --- a/src/renderer/assets/svgs/information-slab-circle-outline.svg +++ b/src/renderer/assets/svgs/information-slab-circle-outline.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/music.svg b/src/renderer/assets/svgs/music.svg index 36d700fa..63f53bcf 100644 --- a/src/renderer/assets/svgs/music.svg +++ b/src/renderer/assets/svgs/music.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/phone.svg b/src/renderer/assets/svgs/phone.svg index ffdf58d8..9614c335 100644 --- a/src/renderer/assets/svgs/phone.svg +++ b/src/renderer/assets/svgs/phone.svg @@ -1,4 +1 @@ - - - - \ No newline at end of file + diff --git a/src/renderer/assets/svgs/play-outline.svg b/src/renderer/assets/svgs/play-outline.svg index ec5afe93..1be9a940 100644 --- a/src/renderer/assets/svgs/play-outline.svg +++ b/src/renderer/assets/svgs/play-outline.svg @@ -1 +1 @@ -Play \ No newline at end of file + diff --git a/src/renderer/assets/svgs/plex.svg b/src/renderer/assets/svgs/plex.svg index 97ed81a6..8cfe565d 100644 --- a/src/renderer/assets/svgs/plex.svg +++ b/src/renderer/assets/svgs/plex.svg @@ -1,4 +1 @@ - - - - + diff --git a/src/renderer/assets/svgs/share.svg b/src/renderer/assets/svgs/share.svg new file mode 100644 index 00000000..c4f4b440 --- /dev/null +++ b/src/renderer/assets/svgs/share.svg @@ -0,0 +1 @@ + diff --git a/src/renderer/assets/svgs/tune-variant.svg b/src/renderer/assets/svgs/tune-variant.svg index 02314ad1..948d9191 100644 --- a/src/renderer/assets/svgs/tune-variant.svg +++ b/src/renderer/assets/svgs/tune-variant.svg @@ -1,5 +1 @@ - - - + diff --git a/src/renderer/assets/svgs/volume-high-outline.svg b/src/renderer/assets/svgs/volume-high-outline.svg index c2f840e7..0c3a8369 100644 --- a/src/renderer/assets/svgs/volume-high-outline.svg +++ b/src/renderer/assets/svgs/volume-high-outline.svg @@ -1 +1 @@ -Volume High \ No newline at end of file + diff --git a/src/renderer/assets/svgs/volume-low-outline.svg b/src/renderer/assets/svgs/volume-low-outline.svg index db7124e5..52fa8a6b 100644 --- a/src/renderer/assets/svgs/volume-low-outline.svg +++ b/src/renderer/assets/svgs/volume-low-outline.svg @@ -1 +1 @@ -Volume Low \ No newline at end of file + diff --git a/src/renderer/assets/svgs/volume-medium-outline.svg b/src/renderer/assets/svgs/volume-medium-outline.svg index 3a8866c8..1610c1b0 100644 --- a/src/renderer/assets/svgs/volume-medium-outline.svg +++ b/src/renderer/assets/svgs/volume-medium-outline.svg @@ -1 +1 @@ -Volume Medium \ No newline at end of file + diff --git a/src/renderer/assets/svgs/volume-mute-outline.svg b/src/renderer/assets/svgs/volume-mute-outline.svg index 06fc2cc9..ef3a87ec 100644 --- a/src/renderer/assets/svgs/volume-mute-outline.svg +++ b/src/renderer/assets/svgs/volume-mute-outline.svg @@ -1,9 +1 @@ - - Volume Mute - - - - + diff --git a/src/renderer/assets/svgs/volume-off-outline.svg b/src/renderer/assets/svgs/volume-off-outline.svg index 50047d5b..2ddc5b6d 100644 --- a/src/renderer/assets/svgs/volume-off-outline.svg +++ b/src/renderer/assets/svgs/volume-off-outline.svg @@ -1 +1 @@ -Volume Off \ No newline at end of file + diff --git a/src/renderer/components/base/Selection.vue b/src/renderer/components/base/Selection.vue index ac32b265..e874456e 100644 --- a/src/renderer/components/base/Selection.vue +++ b/src/renderer/components/base/Selection.vue @@ -198,7 +198,7 @@ export default { // color: var(--color-button-font); outline: none; transition: background-color @transition-normal; - background-color: var(--color-button-font)-background; + background-color: transparent; box-sizing: border-box; .mixin-ellipsis-1; diff --git a/src/renderer/core/music/download.ts b/src/renderer/core/music/download.ts index 9c183a2a..a6404871 100644 --- a/src/renderer/core/music/download.ts +++ b/src/renderer/core/music/download.ts @@ -8,17 +8,18 @@ import { } from './online' import { buildLyricInfo, getCachedLyricInfo } from './utils' -export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () => {} }: { +export const getMusicUrl = async({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: { musicInfo: LX.Download.ListItem isRefresh: boolean onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void + allowToggleSource?: boolean }): Promise => { if (!isRefresh) { const path = await getDownloadFilePath(musicInfo, appSetting['download.savePath']) if (path) return path } - return getOnlineMusicUrl({ musicInfo: musicInfo.metadata.musicInfo, isRefresh, onToggleSource }) + return getOnlineMusicUrl({ musicInfo: musicInfo.metadata.musicInfo, isRefresh, onToggleSource, allowToggleSource }) } export const getPicUrl = async({ musicInfo, isRefresh, listId, onToggleSource = () => {} }: { diff --git a/src/renderer/core/music/index.ts b/src/renderer/core/music/index.ts index a103a12b..5826b34b 100644 --- a/src/renderer/core/music/index.ts +++ b/src/renderer/core/music/index.ts @@ -24,18 +24,20 @@ export const getMusicUrl = async({ quality, isRefresh = false, onToggleSource, + allowToggleSource, }: { musicInfo: LX.Music.MusicInfo | LX.Download.ListItem isRefresh?: boolean quality?: LX.Quality onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void + allowToggleSource?: boolean }): Promise => { if ('progress' in musicInfo) { - return getDownloadMusicUrl({ musicInfo, isRefresh, onToggleSource }) + return getDownloadMusicUrl({ musicInfo, isRefresh, onToggleSource, allowToggleSource }) } else if (musicInfo.source == 'local') { - return getLocalMusicUrl({ musicInfo, isRefresh, onToggleSource }) + return getLocalMusicUrl({ musicInfo, isRefresh, onToggleSource, allowToggleSource }) } else { - return getOnlineMusicUrl({ musicInfo, isRefresh, quality, onToggleSource }) + return getOnlineMusicUrl({ musicInfo, isRefresh, quality, onToggleSource, allowToggleSource }) } } diff --git a/src/renderer/core/music/local.ts b/src/renderer/core/music/local.ts index a8f21a91..4f38f1b2 100644 --- a/src/renderer/core/music/local.ts +++ b/src/renderer/core/music/local.ts @@ -66,9 +66,10 @@ const getOtherSourceByLocal = async(musicInfo: LX.Music.MusicInfoLocal, handl throw new Error('source not found') } -export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () => {} }: { +export const getMusicUrl = async({ musicInfo, isRefresh, allowToggleSource = true, onToggleSource = () => {} }: { musicInfo: LX.Music.MusicInfoLocal isRefresh: boolean + allowToggleSource?: boolean onToggleSource?: (musicInfo?: LX.Music.MusicInfoOnline) => void }): Promise => { if (!isRefresh) { @@ -83,6 +84,8 @@ export const getMusicUrl = async({ musicInfo, isRefresh, onToggleSource = () => }) } catch {} + if (!allowToggleSource) throw new Error('failed') + onToggleSource() return getOtherSourceByLocal(musicInfo, async(otherSource) => { return getOnlineOtherSourceMusicUrl({ musicInfos: [...otherSource], onToggleSource, isRefresh }).then(({ url, quality: targetQuality, musicInfo: targetMusicInfo, isFromCache }) => { diff --git a/src/renderer/core/player/action.ts b/src/renderer/core/player/action.ts index a83e6154..f212107f 100644 --- a/src/renderer/core/player/action.ts +++ b/src/renderer/core/player/action.ts @@ -23,6 +23,10 @@ import { addDislikeInfo } from '@renderer/core/dislikeList' // import { checkMusicFileAvailable } from '@renderer/utils/music' let gettingUrlId = '' +const createGettingUrlId = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem) => { + const tInfo = 'progress' in musicInfo ? musicInfo.metadata.musicInfo.meta.toggleMusicInfo : musicInfo.meta.toggleMusicInfo + return `${musicInfo.id}_${tInfo?.id ?? ''}` +} const createDelayNextTimeout = (delay: number) => { let timeout: NodeJS.Timeout | null const clearDelayNextTimeout = () => { @@ -56,7 +60,7 @@ const { addDelayNextTimeout: addLoadTimeout, clearDelayNextTimeout: clearLoadTim */ const diffCurrentMusicInfo = (curMusicInfo: LX.Music.MusicInfo | LX.Download.ListItem): boolean => { // return curMusicInfo !== playMusicInfo.musicInfo || isPlay.value - return gettingUrlId != curMusicInfo.id || curMusicInfo.id != playMusicInfo.musicInfo?.id || isPlay.value + return gettingUrlId != createGettingUrlId(curMusicInfo) || curMusicInfo.id != playMusicInfo.musicInfo?.id || isPlay.value } let cancelDelayRetry: (() => void) | null = null @@ -87,14 +91,21 @@ const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListIt if (appSetting['player.autoSkipOnError']) addLoadTimeout() // const type = getPlayType(appSetting['player.highQuality'], musicInfo) + let toggleMusicInfo = ('progress' in musicInfo ? musicInfo.metadata.musicInfo : musicInfo).meta.toggleMusicInfo - return getMusicUrl({ - musicInfo, + return (toggleMusicInfo ? getMusicUrl({ + musicInfo: toggleMusicInfo, isRefresh, - onToggleSource(mInfo) { - if (diffCurrentMusicInfo(musicInfo)) return - setAllStatus(window.i18n.t('toggle_source_try')) - }, + allowToggleSource: false, + }) : Promise.reject(new Error('not found'))).catch(async() => { + return getMusicUrl({ + musicInfo, + isRefresh, + onToggleSource(mInfo) { + if (diffCurrentMusicInfo(musicInfo)) return + setAllStatus(window.i18n.t('toggle_source_try')) + }, + }) }).then(url => { if (window.lx.isPlayedStop || diffCurrentMusicInfo(musicInfo)) return null @@ -118,7 +129,7 @@ export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem // if (appSetting['player.autoSkipOnError']) addLoadTimeout() if (!diffCurrentMusicInfo(musicInfo)) return if (cancelDelayRetry) cancelDelayRetry() - gettingUrlId = musicInfo.id + gettingUrlId = createGettingUrlId(musicInfo) void getMusicPlayUrl(musicInfo, isRefresh).then((url) => { if (!url) return setResource(url) @@ -458,7 +469,7 @@ export const playPrev = async(isAutoToggle = false): Promise => { export const play = () => { if (playMusicInfo.musicInfo == null) return if (isEmpty()) { - if (playMusicInfo.musicInfo.id != gettingUrlId) setMusicUrl(playMusicInfo.musicInfo) + if (createGettingUrlId(playMusicInfo.musicInfo) != gettingUrlId) setMusicUrl(playMusicInfo.musicInfo) return } setPlay() diff --git a/src/renderer/store/download/action.ts b/src/renderer/store/download/action.ts index b50ca295..132043e8 100644 --- a/src/renderer/store/download/action.ts +++ b/src/renderer/store/download/action.ts @@ -210,23 +210,40 @@ const downloadLyric = (downloadInfo: LX.Download.ListItem) => { } const getUrl = async(downloadInfo: LX.Download.ListItem, isRefresh: boolean = false) => { - return getMusicUrl({ - musicInfo: downloadInfo.metadata.musicInfo, - isRefresh: false, + let toggleMusicInfo = downloadInfo.metadata.musicInfo.meta.toggleMusicInfo + return (toggleMusicInfo ? getMusicUrl({ + musicInfo: toggleMusicInfo, + isRefresh, quality: downloadInfo.metadata.quality, - allowToggleSource: appSetting['download.isUseOtherSource'], + allowToggleSource: false, + }) : Promise.reject(new Error('not found'))).catch(() => { + return getMusicUrl({ + musicInfo: downloadInfo.metadata.musicInfo, + isRefresh: false, + quality: downloadInfo.metadata.quality, + allowToggleSource: appSetting['download.isUseOtherSource'], + }) }).catch(() => '') } const handleRefreshUrl = (downloadInfo: LX.Download.ListItem) => { setStatusText(downloadInfo, window.i18n.t('download_status_error_refresh_url')) - getMusicUrl({ - musicInfo: downloadInfo.metadata.musicInfo, + let toggleMusicInfo = downloadInfo.metadata.musicInfo.meta.toggleMusicInfo + ;(toggleMusicInfo ? getMusicUrl({ + musicInfo: toggleMusicInfo, isRefresh: true, quality: downloadInfo.metadata.quality, - allowToggleSource: appSetting['download.isUseOtherSource'], + allowToggleSource: false, + }) : Promise.reject(new Error('not found'))).catch(() => { + return getMusicUrl({ + musicInfo: downloadInfo.metadata.musicInfo, + isRefresh: true, + quality: downloadInfo.metadata.quality, + allowToggleSource: appSetting['download.isUseOtherSource'], + }) }) + .catch(() => '') .then(url => { - // commit('setStatusText', { downloadInfo, text: '链接刷新成功' }) + // commit('setStatusText', { downloadInfo, text: '链接刷新成功' }) setUrl(downloadInfo, url) void window.lx.worker.download.updateUrl(downloadInfo.id, url) }) diff --git a/src/renderer/store/index.ts b/src/renderer/store/index.ts index 18d86098..585c8345 100644 --- a/src/renderer/store/index.ts +++ b/src/renderer/store/index.ts @@ -83,8 +83,12 @@ export const windowSizeActive = computed(() => { return windowSizeList.find(i => i.id === appSetting['common.windowSizeId']) ?? windowSizeList[0] }) +export const getSourceI18nPrefix = () => { + return appSetting['common.sourceNameType'] == 'real' ? 'source_' : 'source_alias_' +} + export const sourceNames = computed(() => { - const prefix = appSetting['common.sourceNameType'] == 'real' ? 'source_' : 'source_alias_' + const prefix = getSourceI18nPrefix() const sourceNames: Record = { kw: 'kw', tx: 'tx', diff --git a/src/renderer/utils/music.ts b/src/renderer/utils/music.ts index 1a4f4234..6d021358 100644 --- a/src/renderer/utils/music.ts +++ b/src/renderer/utils/music.ts @@ -1,5 +1,6 @@ import { checkPath, joinPath, extname, basename, readFile, getFileStats } from '@common/utils/nodejs' import { formatPlayTime } from '@common/utils/common' +import type { IComment } from 'music-metadata/lib/type' export const checkDownloadFileAvailable = async(musicInfo: LX.Download.ListItem, savePath: string): Promise => { return musicInfo.isComplate && !/\.ape$/.test(musicInfo.metadata.fileName) && @@ -188,7 +189,10 @@ export const getLocalMusicFileLyric = async(path: string): Promise i.id == 'USLT') - if (ust && ust.value.text.length > 10) return ust.value.text + if (ust) { + const value = ust.value as IComment + if (value.text && value.text.length > 10) return value.text + } } return null } diff --git a/src/renderer/utils/musicSdk/index.js b/src/renderer/utils/musicSdk/index.js index ae841c02..82aa336b 100644 --- a/src/renderer/utils/musicSdk/index.js +++ b/src/renderer/utils/musicSdk/index.js @@ -59,8 +59,21 @@ export default { }, supportQuality, - async findMusic({ name, singer, albumName, interval, source: s }) { + async searchMusic({ name, singer, source: s, limit = 10 }) { + const trimStr = str => typeof str == 'string' ? str.trim() : str + const musicName = trimStr(name) const tasks = [] + const excludeSource = ['xm'] + for (const source of sources.sources) { + if (!sources[source.id].musicSearch || source.id == s || excludeSource.includes(source.id)) continue + tasks.push(sources[source.id].musicSearch.search(`${musicName} ${singer || ''}`.trim(), 1, limit).catch(_ => null)) + } + return (await Promise.all(tasks)).filter(s => s) + }, + + async findMusic({ name, singer, albumName, interval, source: s }) { + const lists = await this.searchMusic({ name, singer, source: s, limit: 25 }) + const singersRxp = /、|&|;|;|\/|,|,|\|/ const sortSingle = singer => singersRxp.test(singer) ? singer.split(singersRxp).sort((a, b) => a.localeCompare(b)).join('、') @@ -86,21 +99,18 @@ export default { const sortedSinger = filterStr(String(sortSingle(singer)).toLowerCase()) const lowerCaseName = filterStr(String(musicName).toLowerCase()) const lowerCaseAlbumName = filterStr(String(albumName).toLowerCase()) - const excludeSource = ['xm'] - for (const source of sources.sources) { - if (!sources[source.id].musicSearch || source.id == s || excludeSource.includes(source.id)) continue - tasks.push(sources[source.id].musicSearch.search(`${musicName} ${singer || ''}`.trim(), 1, 25).then(res => { - for (const item of res.list) { - item.name = trimStr(item.name) - item.sortedSinger = filterStr(String(sortSingle(item.singer)).toLowerCase()) - item.lowerCaseName = filterStr(String(item.name ?? '').toLowerCase()) - item.lowerCaseAlbumName = filterStr(String(item.albumName ?? '').toLowerCase()) - // console.log(lowerCaseName, item.lowerCaseName, item.source) - if ( - ( - item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName - ) || + const result = lists.map(source => { + for (const item of source.list) { + item.name = trimStr(item.name) + item.sortedSinger = filterStr(String(sortSingle(item.singer)).toLowerCase()) + item.lowerCaseName = filterStr(String(item.name ?? '').toLowerCase()) + item.lowerCaseAlbumName = filterStr(String(item.albumName ?? '').toLowerCase()) + // console.log(lowerCaseName, item.lowerCaseName, item.source) + if ( + ( + item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName + ) || ( (interval ? item.interval == interval : true) && item.lowerCaseName == lowerCaseName && (item.sortedSinger.includes(sortedSinger) || sortedSinger.includes(item.sortedSinger)) @@ -113,17 +123,15 @@ export default { item.lowerCaseName == lowerCaseName && (lowerCaseAlbumName ? item.lowerCaseAlbumName == lowerCaseAlbumName : true) && (item.sortedSinger.includes(sortedSinger) || sortedSinger.includes(item.sortedSinger)) ) - ) { - return item - } - if (!singer) { - if (item.lowerCaseName == lowerCaseName && (interval ? item.interval == interval : true)) return item - } + ) { + return item } - return null - }).catch(_ => null)) - } - const result = (await Promise.all(tasks)).filter(s => s) + if (!singer) { + if (item.lowerCaseName == lowerCaseName && (interval ? item.interval == interval : true)) return item + } + } + return null + }).filter(s => s) const newResult = [] if (result.length) { newResult.push(...sortMusic(result, item => item.sortedSinger == sortedSinger && item.lowerCaseName == lowerCaseName && item.interval == interval)) diff --git a/src/renderer/views/List/MusicList/components/MusicToggleModal.vue b/src/renderer/views/List/MusicList/components/MusicToggleModal.vue new file mode 100644 index 00000000..39b9a8ee --- /dev/null +++ b/src/renderer/views/List/MusicList/components/MusicToggleModal.vue @@ -0,0 +1,356 @@ + + + + + + diff --git a/src/renderer/views/List/MusicList/index.vue b/src/renderer/views/List/MusicList/index.vue index a8154571..bfd229f0 100644 --- a/src/renderer/views/List/MusicList/index.vue +++ b/src/renderer/views/List/MusicList/index.vue @@ -98,6 +98,7 @@ + @@ -107,6 +108,7 @@ import { clipboardWriteText } from '@common/utils/electron' import { assertApiSupport } from '@renderer/store/utils' import SearchList from './components/SearchList.vue' import MusicSortModal from './components/MusicSortModal.vue' +import MusicToggleModal from './components/MusicToggleModal.vue' import useListInfo from './useListInfo' import useList from './useList' import useMenu from './useMenu' @@ -117,12 +119,14 @@ import useSort from './useSort' import useMusicActions from './useMusicActions' import useSearch from './useSearch' import useListScroll from './useListScroll' +import useMusicToggle from './useMusicToggle' import { appSetting } from '@renderer/store/setting' export default { name: 'MusicList', components: { SearchList, MusicSortModal, + MusicToggleModal, }, props: { listId: { @@ -197,6 +201,13 @@ export default { sortMusic, } = useSort({ props, list, selectedList, removeAllSelect }) + const { + handleShowMusicToggleModal, + isShowMusicToggleModal, + selectedToggleMusicInfo, + toggleSource, + } = useMusicToggle(props, list) + const { handleSearch, handleOpenMusicDetail, @@ -218,6 +229,7 @@ export default { handleShowDownloadModal, handlePlayMusic, handlePlayMusicLater, + handleShowMusicToggleModal, handleSearch, handleShowMusicAddModal, handleShowMusicMoveModal, @@ -338,6 +350,10 @@ export default { handleRestoreScroll, actionButtonsVisible, + + isShowMusicToggleModal, + selectedToggleMusicInfo, + toggleSource, } }, } diff --git a/src/renderer/views/List/MusicList/useMenu.js b/src/renderer/views/List/MusicList/useMenu.js index 88995cfb..e625cdf7 100644 --- a/src/renderer/views/List/MusicList/useMenu.js +++ b/src/renderer/views/List/MusicList/useMenu.js @@ -11,6 +11,7 @@ export default ({ handlePlayMusic, handlePlayMusicLater, handleSearch, + handleShowMusicToggleModal, handleShowMusicAddModal, handleShowMusicMoveModal, handleShowSortModal, @@ -26,6 +27,7 @@ export default ({ addTo: true, moveTo: true, sort: true, + toggleSource: true, download: true, search: true, dislike: true, @@ -68,6 +70,11 @@ export default ({ action: 'sort', disabled: !itemMenuControl.sort, }, + { + name: t('list__toggle_source'), + action: 'toggleSource', + disabled: !itemMenuControl.toggleSource, + }, { name: t('list__copy_name'), action: 'copyName', @@ -142,6 +149,9 @@ export default ({ case 'sort': handleShowSortModal(index) break + case 'toggleSource': + handleShowMusicToggleModal(index) + break case 'download': handleShowDownloadModal(index) break diff --git a/src/renderer/views/List/MusicList/useMusicToggle.js b/src/renderer/views/List/MusicList/useMusicToggle.js new file mode 100644 index 00000000..a8990b31 --- /dev/null +++ b/src/renderer/views/List/MusicList/useMusicToggle.js @@ -0,0 +1,49 @@ +// import { updateListMusicsPosition } from '@renderer/store/list/action' +import { ref, nextTick } from '@common/utils/vueTools' +import { updateListMusics } from '@renderer/store/list/listManage' +import { playList } from '@renderer/core/player' +import { getListMusicsFromCache } from '@renderer/store/list/action' + +export default (props, list) => { + const isShowMusicToggleModal = ref(false) + const musicInfo = ref(null) + + const handleShowMusicToggleModal = (index) => { + musicInfo.value = list.value[index] + nextTick(() => { + isShowMusicToggleModal.value = true + }) + } + + const toggleSource = (toggleMusicInfo) => { + const id = musicInfo.value.id + const index = list.value.findIndex(m => m.id == id) + if (index < 0) { + isShowMusicToggleModal.value = false + return + } + musicInfo.value.meta.toggleMusicInfo = toggleMusicInfo + updateListMusics([ + { + id: props.listId, + musicInfo: { + ...musicInfo.value, + meta: { + ...musicInfo.value.meta, + toggleMusicInfo, + }, + }, + }, + ]) + const rawInfo = getListMusicsFromCache(props.listId)[index] + rawInfo.meta.toggleMusicInfo = toggleMusicInfo + playList(props.listId, index) + } + + return { + isShowMusicToggleModal, + selectedToggleMusicInfo: musicInfo, + handleShowMusicToggleModal, + toggleSource, + } +} diff --git a/src/renderer/views/Search/index.vue b/src/renderer/views/Search/index.vue index 957358cd..17483846 100644 --- a/src/renderer/views/Search/index.vue +++ b/src/renderer/views/Search/index.vue @@ -1,8 +1,8 @@