QiuLiang-99 2025-07-19 14:40:00 +08:00 committed by GitHub
commit 7a1fd82ddd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 409 additions and 128 deletions

View File

@ -3,7 +3,10 @@
<layout-aside id="left" /> <layout-aside id="left" />
<div id="right"> <div id="right">
<layout-toolbar id="toolbar" /> <layout-toolbar id="toolbar" />
<layout-view id="view" /> <div class="middle">
<layout-view id="view" />
<layout-play-list-window v-if="isShowPlaylist" id="playlist" @close="closePlaylist" />
</div>
<layout-play-bar id="player" /> <layout-play-bar id="player" />
</div> </div>
<layout-icons /> <layout-icons />
@ -18,45 +21,32 @@
<script setup> <script setup>
import { onMounted } from '@common/utils/vueTools' import { onMounted } from '@common/utils/vueTools'
// import BubbleCursor from '@common/utils/effects/cursor-effects/bubbleCursor'
// import '@common/utils/effects/snow.min'
import useApp from '@renderer/core/useApp' import useApp from '@renderer/core/useApp'
import { isShowPlaylist } from '@renderer/store/player/state'
import { setShowPlaylist } from '@renderer/store/player/action'
const closePlaylist = () => {
setShowPlaylist(false)
}
useApp() useApp()
onMounted(() => { onMounted(() => {
document.getElementById('root').style.display = 'block' document.getElementById('root').style.display = 'block'
// const styles = getComputedStyle(document.documentElement)
// window.lxData.bubbleCursor = new BubbleCursor({
// fillStyle: styles.getPropertyValue('--color-primary-alpha-900'),
// strokeStyle: styles.getPropertyValue('--color-primary-alpha-700'),
// })
}) })
// onBeforeUnmount(() => {
// window.lxData.bubbleCursor?.destroy()
// })
</script> </script>
<style lang="less"> <style lang="less">
@import './assets/styles/index.less'; @import './assets/styles/index.less';
@import './assets/styles/layout.less'; @import './assets/styles/layout.less';
html {
height: 100vh;
}
html, body { html, body {
// overflow: hidden; height: 100%;
box-sizing: border-box; box-sizing: border-box;
user-select: none;
} }
body {
user-select: none;
height: 100%;
}
#root { #root {
height: 100%; height: 100%;
position: relative; position: relative;
@ -69,58 +59,6 @@ body {
box-sizing: border-box; box-sizing: border-box;
} }
.disableAnimation * {
transition: none !important;
animation: none !important;
}
.transparent {
background: transparent;
padding: @shadow-app;
// #waiting-mask {
// border-radius: @radius-border;
// left: @shadow-app;
// right: @shadow-app;
// top: @shadow-app;
// bottom: @shadow-app;
// }
#body {
border-radius: @radius-border;
}
#root {
box-shadow: 0 0 @shadow-app rgba(0, 0, 0, 0.5);
border-radius: @radius-border;
}
// #container {
// border-radius: @radius-border;
// background-color: transparent;
// }
}
.disableTransparent {
background-color: var(--color-content-background);
#body {
border: 1Px solid var(--color-primary-light-500);
}
#right {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
// #view { // 5px
// margin-right: 5Px;
// }
}
.fullscreen {
background-color: var(--color-content-background);
#right {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
#container { #container {
position: relative; position: relative;
display: flex; display: flex;
@ -132,17 +70,21 @@ body {
flex: none; flex: none;
width: @width-app-left; width: @width-app-left;
} }
#right { #right {
flex: auto; flex: auto;
display: flex; display: flex;
flex-flow: column nowrap; flex-direction: column;
transition: background-color @transition-normal;
background-color: var(--color-main-background); background-color: var(--color-main-background);
border-top-left-radius: @radius-border; border-top-left-radius: @radius-border;
border-bottom-left-radius: @radius-border; border-bottom-left-radius: @radius-border;
overflow: hidden; }
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.1);
.middle {
flex: auto;
display: flex;
position: relative;
min-height: 0;
} }
#toolbar, #player { #toolbar, #player {
flex: none; flex: none;
@ -157,12 +99,15 @@ body {
.view-container { .view-container {
transition: opacity @transition-normal; transition: opacity @transition-normal;
} }
#root.show-modal > .view-container { #playlist {
opacity: .9; position: absolute;
} top: 0;
#view.show-modal > .view-container { right: 0;
opacity: .2; width: 320px;
height: 100%;
z-index: 1000;
background-color: #fff;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
} }
</style> </style>

View File

@ -0,0 +1,25 @@
<template>
<button class="playlist-button" @click="togglePlaylist">
🎵 播放列表
</button>
</template>
<script setup>
import { isShowPlaylist } from '@renderer/store/player/state'
import { setShowPlaylist } from '@renderer/store/player/action'
const togglePlaylist = () => {
setShowPlaylist(!isShowPlaylist.value)
}
</script>
<style scoped>
.playlist-button {
padding: 10px 20px;
background-color: #4caf50;
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
}
.playlist-button:hover {
background-color: #45a049;
}
</style>

View File

@ -43,7 +43,7 @@
</button> </button>
<template #content> <template #content>
<div :class="$style.setting"> <div :class="$style.setting">
<button :class="$style.btn" :aria-label="$t('player__play_toggle_mode_list_loop')" @click="toggleMode('listLoop')"> <button :class="$style.btn" :aria-label="$t('player__play_toggle_mode_list_loop')" @click="toggleMode('listLoop')"><!-- //todo -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 24 24" space="preserve"> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" height="100%" viewBox="0 0 24 24" space="preserve">
<use xlink:href="#icon-list-loop" /> <use xlink:href="#icon-list-loop" />
</svg> </svg>

View File

@ -17,6 +17,7 @@
<common-volume-btn /> <common-volume-btn />
<common-toggle-play-mode-btn /> <common-toggle-play-mode-btn />
<common-list-add-modal v-model:show="isShowAddMusicTo" :music-info="playMusicInfo.musicInfo" /> <common-list-add-modal v-model:show="isShowAddMusicTo" :music-info="playMusicInfo.musicInfo" />
<common-play-list-button />
</div> </div>
</template> </template>

View File

@ -0,0 +1,187 @@
<template>
<div class="playlist-window">
<button class="close-button" @click="emitClose"></button>
<h2 class="title">播放列表</h2>
<div class="song-list">
<div
v-for="(song, index) in songs"
:key="index"
class="song-item"
:class="[
{ active: currentPlayIndexValue === index },
{ selected: selectedIndex === index || rightClickSelectedIndex === index }
]"
@click="handleListItemClick(index)"
@contextmenu.prevent="handleListItemRightClick(index, $event)"
>
<div class="song-index">{{ index + 1 }}</div>
<div class="song-info">
<div class="song-title">{{ song.title }}</div>
<div class="song-meta">{{ song.artist }} · {{ song.album }}</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, toRef } from 'vue'
import { tempPlayList, currentPlaybackOrder, currentPlayIndex } from '@renderer/store/player/state'
// 便使 .value
const currentPlayIndexValue = toRef(currentPlayIndex, 'value')
const emit = defineEmits(['close'])
// ref reactive
const playlist = ref(tempPlayList)
//
const songs = computed(() => {
const showlist = []
for (const idx of currentPlaybackOrder.value) {
const info = playlist.value[idx]
if (info?.musicInfo) {
showlist.push({
title: info.musicInfo.name,
artist: info.musicInfo.singer,
album: info.musicInfo.meta.albumName,
})
}
}
return showlist
})
//
const selectedIndex = ref(null)
const rightClickSelectedIndex = ref(null)
//
function handleListItemClick(index) {
selectedIndex.value = index
// currentPlayIndex
currentPlayIndex.value = index
}
//
function handleListItemRightClick(index, event) {
rightClickSelectedIndex.value = index
// event.clientX/Y
}
//
function emitClose() {
emit('close')
}
</script>
<style scoped>
.playlist-window {
background-color: #222;
color: white;
padding: 20px;
border-radius: 10px;
width: 320px;
max-height: 80%;
overflow-y: auto;
display: flex;
flex-direction: column;
}
/* 关闭按钮 */
.close-button {
position: absolute;
top: 10px;
right: 10px;
background: transparent;
color: white;
border: none;
font-size: 18px;
cursor: pointer;
}
/* 标题 */
.title {
margin-bottom: 15px;
font-size: 18px;
font-weight: bold;
text-align: center;
color: white;
}
/* 歌曲列表容器 */
.song-list {
display: flex;
flex-direction: column;
}
/* 交替背景:奇数白色,偶数浅灰 */
.song-item:nth-child(2n-1) {
background-color: #ffffff;
}
.song-item:nth-child(2n) {
background-color: #f5f5f5; /* 很浅的灰 */
}
/* 通用样式 */
.song-item {
display: flex;
align-items: center;
padding: 10px;
border-radius: 6px;
transition: background-color 0.2s;
cursor: pointer;
color: black; /* 字体统一黑色 */
}
/* hover 状态稍微加深一下 */
.song-item:hover {
background-color: #eaeaea!important;
}
/* 当前播放项高亮(深灰) */
.active {
background-color: #EBEBEB ;
color: black ;
}
/* 选中(左键或右键)状态,更深的灰 */
.selected {
background-color: #ebebeb ;
color: black !important;
}
/* 序号 */
.song-index {
width: 24px;
text-align: right;
margin-right: 10px;
color: #666666;
font-size: 14px;
flex-shrink: 0;
}
/* 歌曲信息 */
.song-info {
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 标题 */
.song-title {
font-size: 16px;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: black;
}
/* 元信息(歌手 · 专辑) */
.song-meta {
font-size: 12px;
color: #444444;
margin-top: 2px;
}
</style>

View File

@ -17,7 +17,7 @@ export default ({ selectedList, props, removeAllSelect, emit }: {
}) => { }) => {
let clickTime = 0 let clickTime = 0
let clickIndex = -1 let clickIndex = -1
// todo 待接管
const handlePlayMusic = async(index: number, single: boolean) => { const handlePlayMusic = async(index: number, single: boolean) => {
let targetSong = props.list[index] let targetSong = props.list[index]
const defaultListMusics = await getListMusics(defaultList.id) const defaultListMusics = await getListMusics(defaultList.id)

View File

@ -1,5 +1,5 @@
import { isEmpty, setPause, setPlay, setResource, setStop } from '@renderer/plugins/player' 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 { import {
getList, getList,
clearPlayedList, clearPlayedList,
@ -148,6 +148,7 @@ export const setMusicUrl = (musicInfo: LX.Music.MusicInfo | LX.Download.ListItem
// 恢复上次播放的状态 // 恢复上次播放的状态
const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => { const handleRestorePlay = async(restorePlayInfo: LX.Player.SavedPlayInfo) => {
// todo 恢复软件关闭时tempplaylist的状态
const musicInfo = playMusicInfo.musicInfo const musicInfo = playMusicInfo.musicInfo
if (!musicInfo) return if (!musicInfo) return
@ -243,7 +244,7 @@ export const playListById = (listId: string, id: string) => {
// pause() // pause()
const musicInfo = getList(listId).find(m => m.id == id) const musicInfo = getList(listId).find(m => m.id == id)
if (!musicInfo) return if (!musicInfo) return
setPlayMusicInfo(listId, musicInfo) setPlayMusicInfo(listId, musicInfo)//todo 设置播放音乐
if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList() if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList()
clearTempPlayeList() clearTempPlayeList()
handlePlay() handlePlay()
@ -258,7 +259,7 @@ export const playList = (listId: string, index: number) => {
const prevListId = playInfo.playerListId const prevListId = playInfo.playerListId
setPlayListId(listId) setPlayListId(listId)
// pause() // pause()
setPlayMusicInfo(listId, getList(listId)[index]) setPlayMusicInfo(listId, getList(listId)[index])//todo 设置播放音乐
if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList() if (appSetting['player.isAutoCleanPlayedList'] || prevListId != listId) clearPlayedList()
clearTempPlayeList() clearTempPlayeList()
handlePlay() handlePlay()
@ -339,7 +340,7 @@ export const getNextPlayMusicInfo = async(): Promise<LX.Player.PlayMusicInfo | n
nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1
break break
case 'random': case 'random':
nextIndex = getRandom(0, filteredList.length) nextIndex = getRandom(0, filteredList.length)//todo
break break
case 'list': case 'list':
nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1
@ -364,9 +365,9 @@ export const getNextPlayMusicInfo = async(): Promise<LX.Player.PlayMusicInfo | n
return nextPlayMusicInfo return nextPlayMusicInfo
} }
const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => { export const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => {
// pause() // pause()
setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay) setPlayMusicInfo(playMusicInfo.listId, playMusicInfo.musicInfo, playMusicInfo.isTempPlay)//todo 设置播放音乐
handlePlay() handlePlay()
} }
/** /**
@ -376,14 +377,41 @@ const handlePlayNext = (playMusicInfo: LX.Player.PlayMusicInfo) => {
*/ */
export const playNext = async(isAutoToggle = false): Promise<void> => { export const playNext = async(isAutoToggle = false): Promise<void> => {
console.log('skip next', isAutoToggle) 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) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲 if (tempPlayList.length) { // 如果稍后播放列表存在歌曲则直接播放改列表的歌曲
const playMusicInfo = tempPlayList[0] const playMusicInfo = tempPlayList[currentPlaybackOrder.value[currentPlayIndex.value]]
removeTempPlayList(0) // removeTempPlayList(0)
handlePlayNext(playMusicInfo) handlePlayNext(playMusicInfo)
console.log('play temp list') console.log('play temp list')
return return
} }
////////////预计此处往下的代码失去作用(被接管)/////////////
if (playMusicInfo.musicInfo == null) { if (playMusicInfo.musicInfo == null) {
handleToggleStop() handleToggleStop()
console.log('musicInfo empty') console.log('musicInfo empty')
@ -447,32 +475,32 @@ export const playNext = async(isAutoToggle = false): Promise<void> => {
if (playerIndex == -1 && filteredList.length) playerIndex = 0 if (playerIndex == -1 && filteredList.length) playerIndex = 0
let nextIndex = playerIndex let nextIndex = playerIndex
let togglePlayMethod = appSetting['player.togglePlayMethod'] // let togglePlayMethod = appSetting['player.togglePlayMethod']
if (!isAutoToggle) { // if (!isAutoToggle) {
switch (togglePlayMethod) { // switch (togglePlayMethod) {
case 'list': // case 'list':
case 'singleLoop': // case 'singleLoop':
case 'none': // case 'none':
togglePlayMethod = 'listLoop' // togglePlayMethod = 'listLoop'
} // }
} // }
switch (togglePlayMethod) { // switch (togglePlayMethod) {
case 'listLoop': // case 'listLoop':
nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1 // nextIndex = playerIndex === filteredList.length - 1 ? 0 : playerIndex + 1
break // break
case 'random': // case 'random':
nextIndex = getRandom(0, filteredList.length) // nextIndex = getRandom(0, filteredList.length)
break // break
case 'list': // case 'list':
nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1 // nextIndex = playerIndex === filteredList.length - 1 ? -1 : playerIndex + 1
break // break
case 'singleLoop': // case 'singleLoop':
break // break
default: // default:
nextIndex = -1 // nextIndex = -1
console.log('stop toggle play', togglePlayMethod, isAutoToggle) // console.log('stop toggle play', togglePlayMethod, isAutoToggle)
return // return
} // }
if (nextIndex < 0) { if (nextIndex < 0) {
console.log('next index empty') console.log('next index empty')
return return
@ -489,6 +517,42 @@ export const playNext = async(isAutoToggle = false): Promise<void> => {
* *
*/ */
export const playPrev = async(isAutoToggle = false): Promise<void> => { export const playPrev = async(isAutoToggle = false): Promise<void> => {
// 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) { if (playMusicInfo.musicInfo == null) {
handleToggleStop() handleToggleStop()
return return

View File

@ -12,6 +12,7 @@ import {
playMusicInfo, playMusicInfo,
playedList, playedList,
tempPlayList, tempPlayList,
isShowPlaylist,
} from './state' } from './state'
import { getListMusicsFromCache } from '@renderer/store/list/action' import { getListMusicsFromCache } from '@renderer/store/list/action'
import { downloadList } from '@renderer/store/download/state' import { downloadList } from '@renderer/store/download/state'
@ -61,6 +62,10 @@ export const setShowPlayerDetail = (val: boolean) => {
isShowPlayerDetail.value = val isShowPlayerDetail.value = val
} }
export const setShowPlaylist = (val: boolean) => {
isShowPlaylist.value = val
}
export const setShowPlayComment = (val: boolean) => { export const setShowPlayComment = (val: boolean) => {
isShowPlayComment.value = val isShowPlayComment.value = val
} }
@ -223,8 +228,10 @@ export const clearPlayedList = () => {
/** /**
* *
* @param list * @param list
*/ *///todo
export const addTempPlayList = (list: LX.Player.TempPlayListItem[]) => { export const addTempPlayList = (list: LX.Player.TempPlayListItem[]) => {
// todo 添加到下一首播放而不是到最后一首
// todo 重复歌曲不添加
const topList: Array<Omit<LX.Player.TempPlayListItem, 'top'>> = [] const topList: Array<Omit<LX.Player.TempPlayListItem, 'top'>> = []
const bottomList = list.filter(({ isTop, ...musicInfo }) => { const bottomList = list.filter(({ isTop, ...musicInfo }) => {
if (isTop) { 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 (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 (bottomList.length) arrPush(tempPlayList, bottomList.map(({ musicInfo, listId }) => ({ musicInfo, listId, isTempPlay: true })))
if (!playMusicInfo.musicInfo) void playNext() // if (!playMusicInfo.musicInfo) void playNext()
// 造成了奇怪的bug
} }
/** /**
* *

View File

@ -36,6 +36,8 @@ export const statusText = ref('')
export const isShowPlayerDetail = ref(false) export const isShowPlayerDetail = ref(false)
export const isShowPlaylist = ref(false)
export const isShowPlayComment = ref(false) export const isShowPlayComment = ref(false)
export const isShowLrcSelectContent = ref(false) export const isShowLrcSelectContent = ref(false)
@ -69,5 +71,9 @@ export const playedList = window.lxData.playedList = shallowReactive<LX.Player.P
export const tempPlayList = shallowReactive<LX.Player.PlayMusicInfo[]>([]) export const tempPlayList = shallowReactive<LX.Player.PlayMusicInfo[]>([])
export const currentPlayIndex = ref<number>(0)
export const currentPlaybackOrder = ref<number[]>([])
window.lxData.playInfo = playInfo window.lxData.playInfo = playInfo
window.lxData.playMusicInfo = playMusicInfo window.lxData.playMusicInfo = playMusicInfo

View File

@ -3,6 +3,7 @@ import {
computed, computed,
} from '@common/utils/vueTools' } from '@common/utils/vueTools'
import { useI18n } from '@renderer/plugins/i18n' import { useI18n } from '@renderer/plugins/i18n'
import { tempPlayList, currentPlayIndex, currentPlaybackOrder } from '@renderer/store/player/state'
// const playNextModes = [ // const playNextModes = [
// 'listLoop', // 'listLoop',
@ -28,6 +29,21 @@ export default () => {
if (mode == appSetting['player.togglePlayMethod']) return if (mode == appSetting['player.togglePlayMethod']) return
// let index = playNextModes.indexOf(appSetting['player.togglePlayMethod']) // let index = playNextModes.indexOf(appSetting['player.togglePlayMethod'])
// if (++index >= playNextModes.length) index = 0 // 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) setTogglePlayMode(mode)
} }

View File

@ -4,6 +4,7 @@ import { LIST_IDS } from '@common/constants'
export default ({ selectedList, list, listAll, removeAllSelect }) => { export default ({ selectedList, list, listAll, removeAllSelect }) => {
const handlePlayMusic = (index) => { const handlePlayMusic = (index) => {
// todo 待接管
playList(LIST_IDS.DOWNLOAD, listAll.value.indexOf(list.value[index])) playList(LIST_IDS.DOWNLOAD, listAll.value.indexOf(list.value[index]))
} }

View File

@ -1,15 +1,43 @@
import { addTempPlayList } from '@renderer/store/player/action' import { addTempPlayList, clearTempPlayeList, getList } from '@renderer/store/player/action'
import { playList } from '@renderer/core/player' 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 }) => { export default ({ props, selectedList, list, removeAllSelect }) => {
let clickTime = 0 let clickTime = 0
let clickIndex = -1 let clickIndex = -1
const handlePlayMusic = (index) => { 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) => { const handlePlayMusicLater = (index, single) => {
// todo 修改播放歌曲逻辑
if (selectedList.value.length && !single) { if (selectedList.value.length && !single) {
addTempPlayList(selectedList.value.map(s => ({ listId: props.listId, musicInfo: s }))) addTempPlayList(selectedList.value.map(s => ({ listId: props.listId, musicInfo: s })))
removeAllSelect() removeAllSelect()