Files
groove-web/src/lib/components/groove/PlaylistListing.svelte

77 lines
1.9 KiB
Svelte

<script lang="ts">
import type { Track } from '$lib/proto/library';
import { Button } from '$lib/components/ui/button';
import Trash2 from 'virtual:icons/lucide/trash-2';
import Play from 'virtual:icons/lucide/play';
import { getLibraryState } from '$lib/library.svelte';
import { getPlayerState } from '$lib/player.svelte';
import PlaylistCover from './PlaylistCover.svelte';
import { goto } from '$app/navigation';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);
interface Props {
id: number;
name: string;
tracks: Track[];
}
let { id, name, tracks }: Props = $props();
let totalDuration = $derived<number>(
tracks.reduce((acc, track) => acc + Number(track.duration), 0)
);
const library = getLibraryState();
const player = getPlayerState();
</script>
<!-- svelte-ignore a11y_interactive_supports_focus -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
role="button"
class="overflow-hidden rounded-md border"
onclick={() => goto(`/playlists/${id}`)}
>
<PlaylistCover {tracks} />
<div class="space-y-2 p-4">
<div class="relative space-y-2">
<h3 class="font-medium leading-none">{name}</h3>
<div>
<p class="text-xs text-muted-foreground">
{dayjs.duration(totalDuration, 'milliseconds').format('mm:ss')}
</p>
<p class="text-xs text-muted-foreground">
{tracks.length} track{tracks.length !== 1 ? 's' : ''}
</p>
</div>
</div>
<div class="flex w-full justify-between gap-1">
<Button
type="submit"
variant="outline"
size="icon"
onclick={(e) => {
e.stopPropagation();
player.playPlaylist(id, fetch);
}}
>
<Play />
</Button>
<Button
type="submit"
variant="outline"
size="icon"
onclick={(e) => {
e.stopPropagation();
library.deletePlaylist(id, fetch);
}}
>
<Trash2 />
</Button>
</div>
</div>
</div>