77 lines
1.9 KiB
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>
|