53 lines
1.6 KiB
Vue
53 lines
1.6 KiB
Vue
<template>
|
|
<div class="max-h-80 overflow-y-auto p-4">
|
|
<h3 class="mb-3 font-display text-sm font-semibold uppercase tracking-wider text-white/50">
|
|
Playlist
|
|
</h3>
|
|
<ul class="flex flex-col gap-1">
|
|
<li
|
|
v-for="song in store.playlist"
|
|
:key="song.id"
|
|
class="flex cursor-pointer items-center gap-3 rounded-lg p-2 transition-colors hover:bg-white/5"
|
|
:class="{ 'bg-primary/10 text-primary': song.id === store.currentSong?.id }"
|
|
@click="playSong(song)"
|
|
>
|
|
<span class="font-mono text-xs text-white/30 w-6 text-right">
|
|
{{ store.playlist.indexOf(song) + 1 }}
|
|
</span>
|
|
<div
|
|
v-if="song.id === store.currentSong?.id && store.isPlaying"
|
|
class="i-lucide-volume-2 h-4 w-4 flex-shrink-0 text-primary"
|
|
/>
|
|
<div
|
|
v-else
|
|
class="i-lucide-music h-4 w-4 flex-shrink-0 text-white/30"
|
|
/>
|
|
<div class="min-w-0 flex-1">
|
|
<p class="truncate text-sm">{{ song.title }}</p>
|
|
<p class="truncate text-xs text-white/40">{{ song.artist }}</p>
|
|
</div>
|
|
<span class="font-mono text-xs text-white/30">
|
|
{{ formatDuration(song.duration) }}
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { Song } from '~/types/song'
|
|
|
|
const store = usePlayerStore()
|
|
const { playSongFromPlaylist } = usePlaylist()
|
|
|
|
function playSong(song: Song) {
|
|
playSongFromPlaylist(song)
|
|
}
|
|
|
|
function formatDuration(seconds: number): string {
|
|
const mins = Math.floor(seconds / 60)
|
|
const secs = Math.floor(seconds % 60)
|
|
return `${mins}:${secs.toString().padStart(2, '0')}`
|
|
}
|
|
</script>
|