Merge library components and styles work

This commit is contained in:
2026-09-25 01:24:00 +02:00
38 changed files with 1053 additions and 697 deletions
+7 -1
View File
@@ -27,6 +27,12 @@
let scroller = $state<HTMLElement>();
const transitionKey = $derived(
page.url.pathname === '/library' || page.url.pathname.startsWith('/library/')
? '/library'
: page.url.pathname
);
trackNavigation();
restoreScroll(() => scroller);
@@ -81,7 +87,7 @@
<MobileHeader user={data.user} accountUrl={data.accountUrl} />
<TopBar user={data.user} accountUrl={data.accountUrl} />
<main class="flex-1">
{#key page.url.pathname}
{#key transitionKey}
<div class="animate-fade">{@render children()}</div>
{/key}
</main>
@@ -47,5 +47,7 @@
<Page>
<PageHeader title="Gestionar música" description={current.description} />
<Tabs label="Secciones de la biblioteca" {tabs} />
{@render children()}
{#key page.url.pathname}
<div class="animate-fade">{@render children()}</div>
{/key}
</Page>
@@ -1,14 +1,16 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/state';
import LibraryAlbumEditor from '$lib/components/music/library/LibraryAlbumEditor.svelte';
let { data, form } = $props();
</script>
<div class="mt-4">
<div class="animate-enter mt-4">
{#key data.album.id}
<LibraryAlbumEditor
album={data.album}
artist={page.data.user?.name ?? ''}
tracks={data.tracks.items}
memberIds={data.memberIds}
formMessage={form?.message}
@@ -1,5 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/state';
import LibraryAlbumEditor from '$lib/components/music/library/LibraryAlbumEditor.svelte';
let { data, form } = $props();
@@ -9,9 +10,10 @@
});
</script>
<div class="mt-4">
<div class="animate-enter mt-4">
<LibraryAlbumEditor
album={null}
artist={page.data.user?.name ?? ''}
tracks={data.tracks.items}
memberIds={[]}
formMessage={form?.action === 'saveAlbum' ? form.message : undefined}
@@ -14,10 +14,9 @@
import Checkbox from '$lib/components/ui/primitives/Checkbox.svelte';
import Button from '$lib/components/ui/primitives/Button.svelte';
import ExplicitBadge from '$lib/components/ui/media/ExplicitBadge.svelte';
import Chip from '$lib/components/ui/primitives/Chip.svelte';
import { LIMITS } from '$lib/validation';
import { formatSize } from '$lib/utils/format';
import { genreOptions } from '$lib/data/genres';
import GenrePicker from '$lib/components/music/GenrePicker.svelte';
type Status = 'idle' | 'uploading' | 'done' | 'error';
type StepState = 'idle' | 'active' | 'done';
@@ -44,15 +43,6 @@
{ key: 'done', label: 'Listo', hint: 'Se procesa y aparece en tu biblioteca.' }
];
const options = $derived(genreOptions(data.genres));
const blocked = $derived(
new Set(
options
.filter((option) => tags.includes(option.genre))
.flatMap((option) => option.incompatibleWith)
)
);
const busy = $derived(status === 'uploading');
const canPublish = $derived(
@@ -91,10 +81,6 @@
pickAudio(file);
}
function toggleTag(tag: string) {
tags = tags.includes(tag) ? tags.filter((current) => current !== tag) : [...tags, tag];
}
function reset() {
title = '';
audioName = '';
@@ -258,28 +244,12 @@
{/snippet}
</Field>
<Field label="Géneros">
<div class="mb-2 flex flex-wrap gap-2">
{#each options as option (option.genre)}
<Chip
selected={tags.includes(option.genre)}
disabled={blocked.has(option.genre)}
onclick={() => toggleTag(option.genre)}
>
{option.label}
</Chip>
{/each}
</div>
{#each tags as tag (tag)}
<input type="hidden" name="tags" value={tag} />
{/each}
{#snippet hint()}
<p>
Elige al menos uno. Algunos géneros no se pueden combinar, como Metal con Ambient.
</p>
<span class="shrink-0 tabular-nums">{tags.length} elegidos</span>
{/snippet}
</Field>
<GenrePicker
genres={data.genres}
bind:selected={tags}
name="tags"
help="Elige al menos uno. Algunos géneros no se pueden combinar, como Metal con Ambient."
/>
<Checkbox bind:checked={isExplicit} name="isExplicit">
<span class="inline-flex items-center gap-2">
+3
View File
@@ -28,6 +28,7 @@
--color-on-art-2: var(--mf-on-art-2);
--color-danger: oklch(63.7% 0.15 25.331);
--color-danger-fg: var(--mf-danger-fg);
--color-danger-tint: color-mix(in srgb, var(--color-danger) 15%, transparent);
--color-btn: var(--mf-btn-bg);
--color-btn-hover: var(--mf-btn-bg-hover);
--color-cta-strong-hover: var(--mf-cta-strong-hover);
@@ -60,6 +61,8 @@
--spacing-icon-2xl: 1.75rem;
--spacing-icon-3xl: 2.5rem;
--spacing-section: 2.875rem;
--spacing-dropzone: 16rem;
--spacing-cover-fill: 11rem;
--container-prose-sm: 26rem;
--container-hero: 34rem;