feat(AlbumDetail, Player, Library): enhance playback functionality and improve user prompts

This commit is contained in:
Astrian Zheng 2025-05-28 10:18:05 +10:00
parent 65e3520ecf
commit 0cfd82d34a
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
4 changed files with 73 additions and 26 deletions

View File

@ -114,7 +114,7 @@ const playQueue = usePlayQueueStore()
function playTheAlbum(from: number = 0) { function playTheAlbum(from: number = 0) {
if (playQueue.queueReplaceLock) { if (playQueue.queueReplaceLock) {
if (!confirm("当前操作会将你的播列清空、放入这张专辑所有曲目,并从新待播清单的开头播放。继续吗?")) { return } if (!confirm("当前操作会将你的放队列清空、放入这张专辑所有曲目,并从头播放。继续吗?")) { return }
playQueue.queueReplaceLock = false playQueue.queueReplaceLock = false
} }
@ -132,6 +132,17 @@ function playTheAlbum(from: number = 0) {
playQueue.isBuffering = true playQueue.isBuffering = true
} }
function shuffle() {
playTheAlbum()
playQueue.shuffleCurrent = true
playQueue.playMode.shuffle = false
setTimeout(() => {
playQueue.playMode.shuffle = true
playQueue.isPlaying = true
playQueue.isBuffering = true
}, 100)
}
</script> </script>
<template> <template>
@ -180,11 +191,7 @@ function playTheAlbum(from: number = 0) {
<button <button
class="text-white w-10 h-10 bg-neutral-800/80 border border-[#ffffff39] backdrop-blur-3xl rounded-full flex justify-center items-center hover:bg-neutral-700/80 transition-all" class="text-white w-10 h-10 bg-neutral-800/80 border border-[#ffffff39] backdrop-blur-3xl rounded-full flex justify-center items-center hover:bg-neutral-700/80 transition-all"
@click="() => { @click="shuffle">
playTheAlbum()
playQueue.shuffleCurrent = true
playQueue.playMode.shuffle = true
}">
<ShuffleIcon :size="4" /> <ShuffleIcon :size="4" />
</button> </button>

View File

@ -260,33 +260,35 @@ watch(() => error.value, (newError) => {
// //
watch(() => playQueueStore.playMode.shuffle, (isShuffle) => { watch(() => playQueueStore.playMode.shuffle, (isShuffle) => {
if (isShuffle) { if (isShuffle) {
//
const currentIndex = playQueueStore.currentIndex const currentIndex = playQueueStore.currentIndex
const trackCount = playQueueStore.list.length const trackCount = playQueueStore.list.length
// 便
// // 1.
let shuffledList = [...Array(currentIndex).keys()] let shuffledList = [...Array(currentIndex).keys()]
// shuffleCurrent false undefined
// 2.
let shuffleSpace = [...Array(trackCount).keys()].filter(index =>
playQueueStore.shuffleCurrent ? index >= currentIndex : index > currentIndex
)
// 3.
shuffleSpace.sort(() => Math.random() - 0.5)
// 4. currentIndex
if (!playQueueStore.shuffleCurrent) { if (!playQueueStore.shuffleCurrent) {
shuffledList.push(currentIndex) shuffledList.push(currentIndex)
} }
// shuffleCurrent
playQueueStore.shuffleCurrent = undefined
// // 5. + +
let shuffleSpace = [...Array(trackCount).keys()]
shuffleSpace = shuffleSpace.filter((item) => item > currentIndex)
console.log(shuffleSpace)
//
shuffleSpace.sort(() => Math.random() - 0.5)
//
shuffledList = shuffledList.concat(shuffleSpace) shuffledList = shuffledList.concat(shuffleSpace)
// // 6. shuffleList
playQueueStore.shuffleList = shuffledList playQueueStore.shuffleList = shuffledList
// shuffleCurrent
playQueueStore.shuffleCurrent = undefined
} else { } else {
// currentIndex // 退
playQueueStore.currentIndex = playQueueStore.shuffleList[playQueueStore.currentIndex] playQueueStore.currentIndex = playQueueStore.shuffleList[playQueueStore.currentIndex]
} }

View File

@ -32,7 +32,7 @@ onMounted(async () => {
function playTheAlbum(from: number = 0) { function playTheAlbum(from: number = 0) {
if (playQueue.queueReplaceLock) { if (playQueue.queueReplaceLock) {
if (!confirm("当前操作会将你的播列清空、放入这张专辑所有曲目,并从新待播清单的开头播放。继续吗?")) { return } if (!confirm("当前操作会将你的放队列清空、放入这张专辑所有曲目,并从头播放。继续吗?")) { return }
playQueue.queueReplaceLock = false playQueue.queueReplaceLock = false
} }
@ -98,7 +98,8 @@ function playTheAlbum(from: number = 0) {
</div> </div>
</div> </div>
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<TrackItem v-for="(track, index) in album?.songs" :key="track.cid" :album="album" :track="track" :index="index" :playfrom="playTheAlbum" /> <TrackItem v-for="(track, index) in album?.songs" :key="track.cid" :album="album" :track="track" :index="index"
:playfrom="playTheAlbum" />
</div> </div>
</div> </div>
</div> </div>

View File

@ -6,10 +6,47 @@ import ShuffleIcon from '../assets/icons/shuffle.vue'
import { useFavourites } from '../stores/useFavourites' import { useFavourites } from '../stores/useFavourites'
import { ref } from 'vue' import { ref } from 'vue'
import { artistsOrganize } from '../utils' import { artistsOrganize } from '../utils'
import { usePlayQueueStore } from '../stores/usePlayQueueStore'
const favourites = useFavourites() const favourites = useFavourites()
const playQueueStore = usePlayQueueStore()
const currentList = ref<'favourites' | number>('favourites') const currentList = ref<'favourites' | number>('favourites')
function playTheList(list: 'favourites' | number) {
if (usePlayQueueStore().queueReplaceLock) {
if (!confirm("当前操作会将你的播放队列清空、放入这张歌单所有曲目,并从头播放。继续吗?")) { return }
usePlayQueueStore().queueReplaceLock = false
}
playQueueStore.list = []
if (list === 'favourites') {
if (favourites.favouritesCount === 0) return
let newPlayQueue = favourites.favourites.map(item => ({
song: item.song,
album: item.album
}))
playQueueStore.list = newPlayQueue.slice().reverse()
playQueueStore.currentIndex = 0
playQueueStore.isPlaying = true
playQueueStore.isBuffering = true
} else {
// Handle other lists if needed
}
}
function shuffle(list: 'favourites' | number) {
playTheList(list)
playQueueStore.shuffleCurrent = true
playQueueStore.playMode.shuffle = false
setTimeout(() => {
playQueueStore.playMode.shuffle = true
playQueueStore.isPlaying = true
playQueueStore.isBuffering = true
}, 100)
}
</script> </script>
<template> <template>
@ -66,14 +103,14 @@ const currentList = ref<'favourites' | number>('favourites')
<div class="flex gap-2"> <div class="flex gap-2">
<button <button
class="bg-sky-500/20 hover:bg-sky-500/30 active:bg-sky-600/30 active:shadow-inner backdrop-blur-3xl border border-[#ffffff39] rounded-full w-56 h-10 text-base text-white flex justify-center items-center gap-2 transition-all" class="bg-sky-500/20 hover:bg-sky-500/30 active:bg-sky-600/30 active:shadow-inner backdrop-blur-3xl border border-[#ffffff39] rounded-full w-56 h-10 text-base text-white flex justify-center items-center gap-2 transition-all"
@click=""> @click="playTheList('favourites')">
<PlayIcon :size="4" /> <PlayIcon :size="4" />
<div>播放歌单</div> <div>播放歌单</div>
</button> </button>
<button <button
class="text-white w-10 h-10 bg-neutral-800/80 border border-[#ffffff39] backdrop-blur-3xl rounded-full flex justify-center items-center hover:bg-neutral-700/80 transition-all" class="text-white w-10 h-10 bg-neutral-800/80 border border-[#ffffff39] backdrop-blur-3xl rounded-full flex justify-center items-center hover:bg-neutral-700/80 transition-all"
@click=""> @click="shuffle('favourites')">
<ShuffleIcon :size="4" /> <ShuffleIcon :size="4" />
</button> </button>
</div> </div>