initiation librodrome
This commit is contained in:
52
app/components/player/PlayerPlaylist.vue
Normal file
52
app/components/player/PlayerPlaylist.vue
Normal file
@@ -0,0 +1,52 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user