web-player: P7 — filas (ListRow, MediaIdentity, EqBars)
Crea MediaIdentity.svelte (renombra y generaliza TrackTitleCell, puramente presentacional: arte + título + subtítulo, sin manejo de click) y ListRow.svelte encima (href|onclick, active, size xs/sm/lg, variant row|card, leading/trailing/overlay). Usa MediaIdentity también en player/TrackInfo... (pendiente: TrackInfo se deja para P12, que ya tiene tarea explícita de tocar ese archivo). Migra a ListRow: SearchResultRow (Explorar, 4 grupos — se borra el componente), Inicio (Continuar escuchando, Populares, spotlight, Tus playlists), Queue (A continuación), Sidebar (playlists). Las 6 tablas de pista (AlbumTrackTable, PlaylistTrackTable, library, liked, mixes, LibraryPicker) migran a MediaIdentity con su propio use:pressable local, ya que TrackList (P8) todavía no existe. EqBars gana prop `overlay` (fondo scrim/45, color on-art) que sustituye a NowPlaying.svelte (borrado). Corrige de paso 6 llamadas a plural() que P5 había dejado sin migrar (liked, library, mixes, playlists, PlaylistHeader, Inicio). Deltas documentados en el registro del plan: fila activa de Sidebar ahora usa el tinte de acento (antes gris neutro); tarjeta "Tus playlists" de Inicio pierde la línea de autor redundante y su radio pasa a rounded-art; filas de Queue pierden el opacity-80 del arte. Verificado con npm run check/build; sin QA visual autenticada (Docker no disponible en esta sesión). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
import MediaIdentity from './MediaIdentity.svelte';
|
||||
import { pressable } from '$lib/actions/pressable';
|
||||
|
||||
interface Props {
|
||||
href?: string;
|
||||
onclick?: () => void;
|
||||
oncontextmenu?: (event: MouseEvent) => void;
|
||||
active?: boolean;
|
||||
size?: 'xs' | 'sm' | 'lg';
|
||||
variant?: 'row' | 'card';
|
||||
title: string;
|
||||
subtitle?: string | null;
|
||||
subtitleHref?: string | number | null;
|
||||
explicit?: boolean;
|
||||
trackId?: string | number;
|
||||
trackIds?: (string | number)[];
|
||||
coverSrc?: string | null;
|
||||
art?: Snippet;
|
||||
overlay?: Snippet;
|
||||
leading?: Snippet;
|
||||
trailing?: Snippet;
|
||||
class?: string;
|
||||
style?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
href,
|
||||
onclick,
|
||||
oncontextmenu,
|
||||
active = false,
|
||||
size = 'sm',
|
||||
variant = 'row',
|
||||
title,
|
||||
subtitle,
|
||||
subtitleHref,
|
||||
explicit = false,
|
||||
trackId,
|
||||
trackIds,
|
||||
coverSrc,
|
||||
art,
|
||||
overlay,
|
||||
leading,
|
||||
trailing,
|
||||
class: klass = '',
|
||||
style
|
||||
}: Props = $props();
|
||||
|
||||
const classes = $derived(
|
||||
`flex items-center gap-3 text-left transition-colors ${
|
||||
variant === 'card' ? 'rounded-art p-2.25 pr-3.5' : 'rounded-control p-2'
|
||||
} ${active ? 'bg-accent-tint' : 'hover:bg-hover'} ${klass}`
|
||||
);
|
||||
</script>
|
||||
|
||||
{#snippet content()}
|
||||
{@render leading?.()}
|
||||
<MediaIdentity
|
||||
{title}
|
||||
artist={subtitle}
|
||||
ownerUserId={subtitleHref}
|
||||
{trackId}
|
||||
{trackIds}
|
||||
{coverSrc}
|
||||
{size}
|
||||
{explicit}
|
||||
{active}
|
||||
{art}
|
||||
{overlay}
|
||||
/>
|
||||
{@render trailing?.()}
|
||||
{/snippet}
|
||||
|
||||
{#if href}
|
||||
<a {href} {oncontextmenu} class={classes} {style}>
|
||||
{@render content()}
|
||||
</a>
|
||||
{:else}
|
||||
<div
|
||||
role="button"
|
||||
tabindex="0"
|
||||
use:pressable={onclick ?? (() => {})}
|
||||
{oncontextmenu}
|
||||
class={classes}
|
||||
{style}
|
||||
>
|
||||
{@render content()}
|
||||
</div>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user