feat(web): one track-list row shape, and drag reorder that snaps (M494, #5393)
release / govulncheck (push) Successful in 34s
release / web (push) Failing after 1m20s
release / go (push) Successful in 1m37s
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / integration (push) Canceled after 4m38s
release / android (push) Canceled after 4m39s
release / Build signed APK (releases and dev) (push) Canceled after 3m49s
release / govulncheck (push) Successful in 34s
release / web (push) Failing after 1m20s
release / go (push) Successful in 1m37s
release / Attach APK to the Release (tag releases only) (push) Canceled after 0s
release / Build + push container image (push) Canceled after 0s
release / Verify release artifacts (tag releases only) (push) Canceled after 0s
release / integration (push) Canceled after 4m38s
release / android (push) Canceled after 4m39s
release / Build signed APK (releases and dev) (push) Canceled after 3m49s
Every track list (album, Liked, Search, Search → Tracks, playlist, History) now draws its rows with TrackListRow inside a TrackList box, in place of four row components that had drifted apart: - TrackListRow owns the look: lead column, title over "artist · album", like, radio, add to queue, menu, duration, then a trailing slot. It also owns the stripe, hover, the now-playing band and the unavailable state. The stripe is dropped on now-playing and selected rows, where Tailwind would otherwise let `odd:` win. - TrackRow, PlaylistTrackRow and HistoryRow are wrappers that keep only their behaviour: track number and multi-select; grip, remove and dead-entry states; cover and timestamp. Playlist and History rows gain radio, add and the menu, so every list offers the same actions. - The radio control is Lucide's Radio icon, not the 📻 emoji. - Enter on a control inside a row now belongs to that control. The old TrackRow played the track when Enter was pressed on "add to queue". - TrackList has no fill, so the stripe shows on playlists too. Drag reorder (#5393): neodrag kept the drop offset, so after the list re-rendered the dragged row sat between two slots. reorderDrag, shared by the playlist and queue rows: - snaps the row to whole rows while dragging; - resets it to its slot on drop; - on playlists, gives the touch gesture to the grip only, so the list still scrolls by touch. The playlist page reorders optimistically and rolls back on error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import type { HistoryEvent } from '#lib/api/history.js';
|
||||
import { playQueue } from '#lib/player/store.svelte.js';
|
||||
import { coverUrl } from '#lib/media/covers.js';
|
||||
import TrackListRow from './TrackListRow.svelte';
|
||||
|
||||
let { event } = $props<{ event: HistoryEvent }>();
|
||||
|
||||
@@ -40,25 +41,26 @@
|
||||
const tooltip = $derived(new Date(event.played_at).toISOString());
|
||||
</script>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onclick={handleClick}
|
||||
aria-label={`Play ${event.track.title}`}
|
||||
class="flex w-full items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-surface-hover"
|
||||
<TrackListRow
|
||||
title={event.track.title}
|
||||
subtitle={`${event.track.artist_name} · ${event.track.album_title}`}
|
||||
durationSec={event.track.duration_sec}
|
||||
track={event.track}
|
||||
ariaLabel={`Play ${event.track.title}`}
|
||||
onActivate={handleClick}
|
||||
>
|
||||
<img
|
||||
src={coverUrl(event.track.album_id)}
|
||||
alt=""
|
||||
class="h-11 w-11 shrink-0 rounded object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate text-sm font-medium text-text-primary">{event.track.title}</div>
|
||||
<div class="truncate text-xs text-text-secondary">
|
||||
{event.track.artist_name} · {event.track.album_title}
|
||||
</div>
|
||||
</div>
|
||||
<span title={tooltip} class="shrink-0 text-xs text-text-secondary">
|
||||
{timestamp}
|
||||
</span>
|
||||
</button>
|
||||
{#snippet lead()}
|
||||
<img
|
||||
src={coverUrl(event.track.album_id)}
|
||||
alt=""
|
||||
class="h-8 w-8 rounded object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
{/snippet}
|
||||
|
||||
{#snippet trailing()}
|
||||
<span title={tooltip} class="w-16 shrink-0 text-right text-xs text-text-secondary">
|
||||
{timestamp}
|
||||
</span>
|
||||
{/snippet}
|
||||
</TrackListRow>
|
||||
|
||||
Reference in New Issue
Block a user