Split the library page into song, album and upload routes with linked tabs

This commit is contained in:
2026-09-25 01:11:01 +02:00
parent 9928840577
commit 797bed8e7d
20 changed files with 351 additions and 279 deletions
@@ -1,55 +0,0 @@
<script lang="ts">
import type { Album, LibraryTrack } from '$lib/types';
import { albumCover } from '$lib/utils/hrefs';
import { albumMeta } from '$lib/utils/format';
import MediaCard from '$lib/components/ui/media/MediaCard.svelte';
import MediaCreateCard from '$lib/components/ui/media/MediaCreateCard.svelte';
import LibraryAlbumEditor from './LibraryAlbumEditor.svelte';
interface Props {
albums: Album[];
tracks: LibraryTrack[];
albumTrackIds: Record<string, string[]>;
formMessage?: string;
}
let { albums, tracks, albumTrackIds, formMessage }: Props = $props();
let editing = $state<{ album: Album | null } | null>(null);
</script>
{#if editing}
<div class="mt-4">
{#key editing.album?.id}
<LibraryAlbumEditor
album={editing.album}
{tracks}
memberIds={editing.album ? (albumTrackIds[editing.album.id] ?? []) : []}
{formMessage}
onClose={() => (editing = null)}
/>
{/key}
</div>
{:else}
<div class="mt-4 grid-cards-lg">
<MediaCreateCard
title="Nuevo álbum"
subtitle="Álbum, EP o Single"
onclick={() => (editing = { album: null })}
/>
{#each albums as album, i (album.id)}
<MediaCard
href="/albums/{album.id}"
title={album.title}
subtitle={albumMeta(album.releaseYear, album.trackCount)}
trackIds={album.coverTrackIds}
src={albumCover(album.id, 'large')}
index={i + 1}
onclick={(event) => {
event.preventDefault();
editing = { album };
}}
/>
{/each}
</div>
{/if}
@@ -105,7 +105,7 @@
description="Sube la primera y aparecerá aquí lista para reproducir."
>
{#snippet actions()}
<Button href="/upload">
<Button href="/library/uploads">
<Upload class="size-icon-sm" />
Sube la primera
</Button>
@@ -73,7 +73,7 @@
<aside class="flex flex-col gap-6 {klass}">
<p class="text-xs font-medium tracking-eyebrow text-fg-2 uppercase">Aplicar a esta subida</p>
<div class="grid gap-8 sm:grid-cols-[11rem_minmax(0,1fr)]">
<div class="grid gap-8 sm:grid-cols-[auto_1fr]">
<Field label="Portada">
<div class="w-full max-w-44">
<ImageDropzone