diff --git a/src/renderer/App.vue b/src/renderer/App.vue index c9151f4c..e51cc388 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -3,7 +3,10 @@ @@ -18,45 +21,32 @@ - - diff --git a/src/renderer/components/common/PlayListButton.vue b/src/renderer/components/common/PlayListButton.vue new file mode 100644 index 00000000..8e5e47e8 --- /dev/null +++ b/src/renderer/components/common/PlayListButton.vue @@ -0,0 +1,25 @@ + + + diff --git a/src/renderer/components/common/TogglePlayModeBtn.vue b/src/renderer/components/common/TogglePlayModeBtn.vue index ab5f2e50..d4570756 100644 --- a/src/renderer/components/common/TogglePlayModeBtn.vue +++ b/src/renderer/components/common/TogglePlayModeBtn.vue @@ -43,7 +43,7 @@ diff --git a/src/renderer/components/layout/PlayListWindow/index.vue b/src/renderer/components/layout/PlayListWindow/index.vue new file mode 100644 index 00000000..29b0e7ed --- /dev/null +++ b/src/renderer/components/layout/PlayListWindow/index.vue @@ -0,0 +1,187 @@ + + + + + diff --git a/src/renderer/components/material/OnlineList/usePlay.ts b/src/renderer/components/material/OnlineList/usePlay.ts index a7f59417..263d9eda 100644 --- a/src/renderer/components/material/OnlineList/usePlay.ts +++ b/src/renderer/components/material/OnlineList/usePlay.ts @@ -17,7 +17,7 @@ export default ({ selectedList, props, removeAllSelect, emit }: { }) => { let clickTime = 0 let clickIndex = -1 - + // todo 待接管 const handlePlayMusic = async(index: number, single: boolean) => { let targetSong = props.list[index] const defaultListMusics = await getListMusics(defaultList.id) diff --git a/src/renderer/core/player/action.ts b/src/renderer/core/player/action.ts index 88995d0a..8e6f9527 100644 --- a/src/renderer/core/player/action.ts +++ b/src/renderer/core/player/action.ts @@ -1,5 +1,5 @@ import { isEmpty, setPause, setPlay, setResource, setStop } from '@renderer/plugins/player' -import { isPlay, playedList, playInfo, playMusicInfo, tempPlayList, musicInfo as _musicInfo } from '@renderer/store/player/state' +import { isPlay, playedList, playInfo, playMusicInfo, tempPlayList, musicInfo as _musicInfo, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state' import { getList, clearPlayedList, @@ -148,6 +148,7 @@ export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem // 恢复上次播放的状态 const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => { + // todo 恢复软件关闭时tempplaylist的状态 const musicInfo = playMusicInfo.musicInfo if (!musicInfo) return @@ -243,7 +244,7 @@ export const playListById = (listId: string, id: string) => { // pause() const musicInfo = getList(listId).find(m => m.id == id) if (!musicInfo) return - setPlayMusicInfo(listId, musicInfo) + setPlayMusicInfo(listId, musicInfo)//todo 设置播放音乐 if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList() clearTempPlayeList() handlePlay() @@ -258,7 +259,7 @@ export const playList = (listId: string, index: number) => { const prevListId = playInfo.playerListId setPlayListId(listId) // pause() - setPlayMusicInfo(listId, getList(listId)[index]) + setPlayMusicInfo(listId, getList(listId)[index])//todo 设置播放音乐 if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList() clearTempPlayeList() handlePlay() @@ -339,7 +340,7 @@ export const getNextPlayMusicInfo = async(): Promise { +export const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => { // pause() - setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) + setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay)//todo 设置播放音乐 handlePlay() } /** @@ -376,14 +377,41 @@ const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => { */ export const playNext = async(isAutoToggle = false): Promise => { console.log('skip next', isAutoToggle) + let togglePlayMethod = appSetting['player.togglePlayMethod'] + if (!isAutoToggle) { + switch (togglePlayMethod) { + case 'list': + case 'singleLoop': + case 'none': + togglePlayMethod = 'listLoop' + } + } + switch (togglePlayMethod) { + case 'listLoop': + currentPlayIndex.value++ + // bug 实际上不是列表循环... + break + case 'random': + currentPlayIndex.value++ + break + case 'list': + currentPlayIndex.value++ + break + case 'singleLoop': + break + default: + currentPlayIndex.value = -1 + console.log('stop toggle play', togglePlayMethod, isAutoToggle) + return + } if (tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 - const playMusicInfo = tempPlayList[0] - removeTempPlayList(0) + const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]] + // removeTempPlayList(0) handlePlayNext(playMusicInfo) console.log('play temp list') return } - + ////////////预计此处往下的代码失去作用(被接管)///////////// if (playMusicInfo.musicInfo == null) { handleToggleStop() console.log('musicInfo empty') @@ -447,32 +475,32 @@ export const playNext = async(isAutoToggle = false): Promise => { if (playerIndex == -1 && filteredList.length) playerIndex = 0 let nextIndex = playerIndex - let togglePlayMethod = appSetting['player.togglePlayMethod'] - if (!isAutoToggle) { - switch (togglePlayMethod) { - case 'list': - case 'singleLoop': - case 'none': - togglePlayMethod = 'listLoop' - } - } - switch (togglePlayMethod) { - case 'listLoop': - nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 - break - case 'random': - nextIndex = getRandom(0, filteredList.length) - break - case 'list': - nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 - break - case 'singleLoop': - break - default: - nextIndex = -1 - console.log('stop toggle play', togglePlayMethod, isAutoToggle) - return - } + // let togglePlayMethod = appSetting['player.togglePlayMethod'] + // if (!isAutoToggle) { + // switch (togglePlayMethod) { + // case 'list': + // case 'singleLoop': + // case 'none': + // togglePlayMethod = 'listLoop' + // } + // } + // switch (togglePlayMethod) { + // case 'listLoop': + // nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 + // break + // case 'random': + // nextIndex = getRandom(0, filteredList.length) + // break + // case 'list': + // nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 + // break + // case 'singleLoop': + // break + // default: + // nextIndex = -1 + // console.log('stop toggle play', togglePlayMethod, isAutoToggle) + // return + // } if (nextIndex < 0) { console.log('next index empty') return @@ -489,6 +517,42 @@ export const playNext = async(isAutoToggle = false): Promise => { * 上一曲 */ export const playPrev = async(isAutoToggle = false): Promise => { + // todo 重复代码块,可以提取 + let togglePlayMethod = appSetting['player.togglePlayMethod'] + if (!isAutoToggle) { + switch (togglePlayMethod) { + case 'list': + case 'singleLoop': + case 'none': + togglePlayMethod = 'listLoop' + } + } + switch (togglePlayMethod) { + case 'listLoop': + currentPlayIndex.value-- + // bug 实际上不是列表循环... + break + case 'random': + currentPlayIndex.value-- + break + case 'list': + currentPlayIndex.value-- + break + case 'singleLoop': + break + default: + currentPlayIndex.value = -1 + console.log('stop toggle play', togglePlayMethod, isAutoToggle) + return + } + if (currentPlayIndex.value > 0) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 + const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]] + // removeTempPlayList(0) + handlePlayNext(playMusicInfo) + console.log('play temp list') + return + } + ////////////预计此处往下的代码失去作用(被接管)///////////// if (playMusicInfo.musicInfo == null) { handleToggleStop() return diff --git a/src/renderer/store/player/action.ts b/src/renderer/store/player/action.ts index 87977fc1..79db7e9d 100644 --- a/src/renderer/store/player/action.ts +++ b/src/renderer/store/player/action.ts @@ -12,6 +12,7 @@ import { playMusicInfo, playedList, tempPlayList, + isShowPlaylist, } from './state' import { getListMusicsFromCache } from '@renderer/store/list/action' import { downloadList } from '@renderer/store/download/state' @@ -61,6 +62,10 @@ export const setShowPlayerDetail = (val: boolean) => { isShowPlayerDetail.value = val } +export const setShowPlaylist = (val: boolean) => { + isShowPlaylist.value = val +} + export const setShowPlayComment = (val: boolean) => { isShowPlayComment.value = val } @@ -223,8 +228,10 @@ export const clearPlayedList = () => { /** * 添加歌曲到稍后播放列表 * @param list 歌曲列表 - */ + *///todo export const addTempPlayList = (list: LX.Player.TempPlayListItem[]) => { + // todo 添加到下一首播放而不是到最后一首 + // todo 重复歌曲不添加 const topList: Array> = [] const bottomList = list.filter(({ isTop, ...musicInfo }) => { if (isTop) { @@ -236,7 +243,8 @@ export const addTempPlayList = (list: LX.Player.TempPlayListItem[]) => { if (topList.length) arrUnshift(tempPlayList, topList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) if (bottomList.length) arrPush(tempPlayList, bottomList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true }))) - if (!playMusicInfo.musicInfo) void playNext() + // if (!playMusicInfo.musicInfo) void playNext() + // 造成了奇怪的bug } /** * 从稍后播放列表移除歌曲 diff --git a/src/renderer/store/player/state.ts b/src/renderer/store/player/state.ts index 48aea238..88acdb89 100644 --- a/src/renderer/store/player/state.ts +++ b/src/renderer/store/player/state.ts @@ -36,6 +36,8 @@ export const statusText = ref('') export const isShowPlayerDetail = ref(false) +export const isShowPlaylist = ref(false) + export const isShowPlayComment = ref(false) export const isShowLrcSelectContent = ref(false) @@ -69,5 +71,9 @@ export const playedList = window.lxData.playedList = shallowReactive([]) +export const currentPlayIndex = ref(0) + +export const currentPlaybackOrder = ref([]) + window.lxData.playInfo = playInfo window.lxData.playMusicInfo = playMusicInfo diff --git a/src/renderer/utils/compositions/useNextTogglePlay.ts b/src/renderer/utils/compositions/useNextTogglePlay.ts index 37047eae..72d44f6f 100644 --- a/src/renderer/utils/compositions/useNextTogglePlay.ts +++ b/src/renderer/utils/compositions/useNextTogglePlay.ts @@ -3,6 +3,7 @@ import { computed, } from '@common/utils/vueTools' import { useI18n } from '@renderer/plugins/i18n' +import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state' // const playNextModes = [ // 'listLoop', @@ -28,6 +29,21 @@ export default () => { if (mode == appSetting['player.togglePlayMethod']) return // let index = playNextModes.indexOf(appSetting['player.togglePlayMethod']) // if (++index >= playNextModes.length) index = 0 + const N = tempPlayList.length + const prevPlayIndex = currentPlaybackOrder.value[currentPlayIndex.value] + if (mode === 'random') { + currentPlayIndex.value = 0 + const allIndexes = Array.from({ length: N }, (_, i) => i).filter(i => i !== prevPlayIndex) + for (let i = allIndexes.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[allIndexes[i], allIndexes[j]] = [allIndexes[j], allIndexes[i]] + } + currentPlaybackOrder.value = [prevPlayIndex, ...allIndexes] + } else { + currentPlaybackOrder.value = Array.from({ length: N }, (_, i) => i) + currentPlayIndex.value = prevPlayIndex + } + // todo 因为只有此函数会修改播放类别,所以直接在这里应用修改效果 setTogglePlayMode(mode) } diff --git a/src/renderer/views/Download/usePlay.js b/src/renderer/views/Download/usePlay.js index dd7da417..f038c5e3 100644 --- a/src/renderer/views/Download/usePlay.js +++ b/src/renderer/views/Download/usePlay.js @@ -4,6 +4,7 @@ import { LIST_IDS } from '@common/constants' export default ({ selectedList, list, listAll, removeAllSelect }) => { const handlePlayMusic = (index) => { + // todo 待接管 playList(LIST_IDS.DOWNLOAD, listAll.value.indexOf(list.value[index])) } diff --git a/src/renderer/views/List/MusicList/usePlay.js b/src/renderer/views/List/MusicList/usePlay.js index a2340004..fa3e300f 100644 --- a/src/renderer/views/List/MusicList/usePlay.js +++ b/src/renderer/views/List/MusicList/usePlay.js @@ -1,15 +1,43 @@ -import { addTempPlayList } from '@renderer/store/player/action' -import { playList } from '@renderer/core/player' +import { addTempPlayList, clearTempPlayeList, getList } from '@renderer/store/player/action' +import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state' +import { handlePlayNext } from '@renderer/core/player' +import { appSetting } from '@renderer/store/setting' +// import { arrShuffle } from '@common/utils/common' +// setup 函数或组件初始化中 + export default ({ props, selectedList, list, removeAllSelect }) => { let clickTime = 0 let clickIndex = -1 const handlePlayMusic = (index) => { - playList(props.listId, index) + currentPlayIndex.value = 0 + if (tempPlayList.length > 0) { // 双击操作会切换到当前歌单 + clearTempPlayeList() + } + const currentchooselist = getList(props.listId) + for (let music of currentchooselist) { + addTempPlayList([{ listId: props.listId, musicInfo: music }]) + } + // todo 重复代码块,可提取 + const N = tempPlayList.length + if (appSetting['player.togglePlayMethod'] === 'random') { + const allIndexes = Array.from({ length: N }, (_, i) => i).filter(i => i !== index) + for (let i = allIndexes.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)) + ;[allIndexes[i], allIndexes[j]] = [allIndexes[j], allIndexes[i]] + } + currentPlaybackOrder.value = [index, ...allIndexes] + } else { + currentPlaybackOrder.value = Array.from({ length: N }, (_, i) => i) + currentPlayIndex.value = index + } + const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]] + handlePlayNext(playMusicInfo) } const handlePlayMusicLater = (index, single) => { + // todo 修改播放歌曲逻辑 if (selectedList.value.length && !single) { addTempPlayList(selectedList.value.map(s => ({ listId: props.listId, musicInfo: s }))) removeAllSelect()