feat(playlists): single playlist view

This commit is contained in:
2024-12-02 23:20:27 +01:00
parent 19f8fde191
commit b5ace5ac28
16 changed files with 372 additions and 44 deletions

View File

@@ -1,14 +1,17 @@
<script lang="ts">
import type { Track } from '$lib/proto/library';
import dayjs from 'dayjs';
import { Button } from '$lib/components/ui/button';
import Trash2 from 'virtual:icons/lucide/trash-2';
import { enhance } from '$app/forms';
import Play from 'virtual:icons/lucide/play';
import type { SubmitFunction } from '../../../routes/playlists/[id]/$types';
import { getCoverUrl } from '$lib/covers';
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;
@@ -24,36 +27,6 @@
const library = getLibraryState();
const player = getPlayerState();
let coverImages = $derived.by(() => {
if (tracks.length === 0) {
return [];
}
if (tracks.length >= 4) {
return tracks.slice(0, 4).map((t) => getCoverUrl(t.hash));
}
if (tracks.length === 1) {
return [getCoverUrl(tracks[0].hash)];
}
if (tracks.length === 2) {
const x = getCoverUrl(tracks[0].hash);
const y = getCoverUrl(tracks[1].hash);
return [x, y, y, x];
}
let _covers: string[] = [];
let i = 0;
while (_covers.length < 4) {
_covers.push(getCoverUrl(tracks[i].hash));
i = (i + 1) % tracks.length;
}
return _covers;
});
const playPlaylist: SubmitFunction = async () => {
return async ({ update, result }) => {
await update({
@@ -84,20 +57,21 @@
};
</script>
<div class="overflow-hidden rounded-md border">
<div class="relative grid" class:grid-cols-2={coverImages.length > 1}>
{#each coverImages as cover}
<img class="aspect-square" src={cover} alt="" />
{:else}
<div class="w-full aspect-square animate-pulse bg-secondary"></div>
{/each}
</div>
<!-- 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(totalDuration, 'milliseconds').format('mm:ss')}
{dayjs.duration(totalDuration, 'milliseconds').format('mm:ss')}
</p>
<p class="text-xs text-muted-foreground">
{tracks.length} track{tracks.length !== 1 ? 's' : ''}