feat(PlayListItem, Library): add PlayListItem component and integrate into Library page

This commit is contained in:
Astrian Zheng 2025-05-28 10:45:16 +10:00
parent 0cfd82d34a
commit ab67e07384
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
3 changed files with 68 additions and 13 deletions

View File

@ -0,0 +1,13 @@
<script setup lang="ts">
defineProps<{
size: number
}>()
</script>
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" :class="`w-${size} h-${size}`">
<path
d="M23.4132 8.7918L18.0211 13.7783L16.6058 12.363L18.8719 10.2674L14.039 9.69434L12.0006 5.27502L11.2169 6.97405L9.70961 5.46678L12.0006 0.5L15.3862 7.84006L23.4132 8.7918ZM8.45885 9.87258L5.12921 10.2674L8.70231 13.5717L7.75383 18.3451L12.0006 15.968L16.2473 18.3451L16.0777 17.4914L8.45885 9.87258ZM18.6224 20.0361L19.054 22.2082L12.0006 18.26L4.94715 22.2082L6.52248 14.2799L0.587891 8.7918L6.65832 8.07205L1.39397 2.80769L2.80818 1.39348L22.6072 21.1925L21.193 22.6067L18.6224 20.0361Z">
</path>
</svg>
</template>

View File

@ -0,0 +1,44 @@
<script lang="ts" setup>
import { artistsOrganize } from '../utils'
import { ref } from 'vue'
import { useFavourites } from '../stores/useFavourites'
import StarSlashIcon from '../assets/icons/starslash.vue'
const favourites = useFavourites()
const hover = ref(false)
defineProps<{
item: QueueItem
index: number
}>()
const emit = defineEmits<{
(e: 'play', index: number): void
}>()
</script>
<template>
<button class="text-left flex p-2 hover:bg-neutral-400/10 odd:bg-neutral-400/5 rounded-md transition-all"
@mouseenter="hover = true" @mouseleave="hover = false">
<div class="items-center flex flex-auto w-0" @click="emit('play', index)">
<img :src="item.album?.coverUrl" class="w-12 h-12 rounded-md object-cover inline-block mr-2" />
<div>
<div class="text-white text-base font-medium">{{ item.song.name }}</div>
<div class="text-white/50 text-sm">{{ item.album?.name }} - {{ artistsOrganize(item.song.artists ?? []) }}
</div>
</div>
</div>
<div class="flex" v-if="hover">
<button @click.stop="() => {
favourites.toggleFavourite(item)
}">
<StarSlashIcon
class="text-white/80 hover:text-white active:text-white/75 hover:scale-110 active:scale-95 transition-all"
:size="4" />
</button>
</div>
</button>
</template>

View File

@ -5,7 +5,7 @@ import ShuffleIcon from '../assets/icons/shuffle.vue'
import { useFavourites } from '../stores/useFavourites'
import { ref } from 'vue'
import { artistsOrganize } from '../utils'
import PlayListItem from '../components/PlayListItem.vue'
import { usePlayQueueStore } from '../stores/usePlayQueueStore'
const favourites = useFavourites()
@ -13,7 +13,9 @@ const playQueueStore = usePlayQueueStore()
const currentList = ref<'favourites' | number>('favourites')
function playTheList(list: 'favourites' | number) {
function playTheList(list: 'favourites' | number, playFrom: number = 0) {
if (playFrom < 0 || playFrom >= favourites.favouritesCount) { playFrom = 0 }
if (usePlayQueueStore().queueReplaceLock) {
if (!confirm("当前操作会将你的播放队列清空、放入这张歌单所有曲目,并从头播放。继续吗?")) { return }
usePlayQueueStore().queueReplaceLock = false
@ -28,7 +30,7 @@ function playTheList(list: 'favourites' | number) {
album: item.album
}))
playQueueStore.list = newPlayQueue.slice().reverse()
playQueueStore.currentIndex = 0
playQueueStore.currentIndex = playFrom
playQueueStore.isPlaying = true
playQueueStore.isBuffering = true
} else {
@ -118,16 +120,12 @@ function shuffle(list: 'favourites' | number) {
</div>
<div class="flex flex-col gap-2 mt-4 mr-8">
<button v-for="item in favourites.favourites.slice().reverse()" :key="item.song.cid"
class="text-left flex items-center p-2 hover:bg-neutral-400/10 odd:bg-neutral-400/5 rounded-md transition-all">
<img :src="item.album?.coverUrl" class="w-12 h-12 rounded-md object-cover inline-block mr-2" />
<div>
<div class="text-white text-base font-medium">{{ item.song.name }}</div>
<div class="text-white/50 text-sm">{{ item.album?.name }} - {{ artistsOrganize(item.song.artists ?? []) }}
</div>
</div>
</button>
<div class="flex flex-col gap-2 mt-4 mr-8 pb-8">
<PlayListItem v-for="(item, index) in favourites.favourites.slice().reverse()" :key="item.song.cid" :item="item"
:index="index" @play="(playFrom) => {
console.log('play from', playFrom)
playTheList('favourites', playFrom)
}" />
</div>
</div>
</div>