watchparty/client/src/views/home/Home.css
Nicolas 5a1bc8d932
All checks were successful
Publier l'image Docker / test (push) Successful in 19s
Publier l'image Docker / publish (push) Successful in 12s
Fix the listen-party queue's layout and its missing album art
Reported directly: the music bar's queue popup looked broken, and the
listen-party card on the home page never showed an image. Put together a
mockup first (this app's own theme tokens, not a generic one) to confirm
the redesign direction before touching any code, since the queue side
was a real UI rework, not a one-line fix.

The layout bug: MusicBar.ts's queue rows were reusing views/album's
shared .trackRow (styles/trackList.css) - a CSS grid with 4 fixed
columns sized for THAT page's own row shape (track number, name,
duration, a button). The queue never had a track number, and rendered
completely different content in that same slot, so the track's own name
- the first child - landed in the 28px column meant for a one-or-two-
digit index, crushed to its first couple of characters, while the
artist/album text filled the wide column meant for the name instead.
Fixed with a dedicated .queueRow (flex, not grid): album art, a
truncating name+artist/album/added-by info column, duration on the
right.

The missing images: confirmed directly against the real Emby server
(three sampled tracks, Fields=AlbumId,ImageTags) that an individual
Audio item essentially never carries its own Primary image - every one
tested answered 500, not even a clean 404 - while the same tracks'
parent albums mostly did. Every place that built an image URL from a
raw EmbyItem was independently reconstructing /api/catalog/image/{id}
by hand (CatalogService.toItemDto, and three separate spots in
index.ts's party-creation routes bypassing toItemDto entirely) - all
now funnel through one new CatalogService.imageUrlFor(item), which
points a track at its AlbumId instead of its own id when one's known.
EmbyItem gained AlbumId; every Fields param listing Audio items now
requests it.

While fixing the now-working image, the home page's party card turned
out to be the wrong shape for music too: a fixed 48x72 portrait box,
correct for a movie/show poster, forcing a hard crop on an album's
square cover. Video parties are untouched; a music party's card now
gets a 56x56 square box instead, toggled from LobbyPartyDto.mediaType.

Tests: imageUrlFor (movie/episode unaffected, a track with an AlbumId
falls back to it, a track with neither still falls back to its own id
rather than a broken URL). Full typecheck/test/build clean on both
projects (118/118 server tests). Verified visually against the actual
compiled app.css (not just the mockup) - injected real markup using the
new classes into a running instance and confirmed the queue rows and
both card shapes render as designed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-15 10:34:39 +02:00

62 lines
1.4 KiB
CSS

.section { margin-bottom: 32px; }
/* ---- Horizontal carousels ---- */
.carousel {
display: flex;
gap: 16px;
overflow-x: auto;
padding-bottom: 10px;
}
.carousel .tile { flex: 0 0 160px; }
.carousel .partyCard { flex: 0 0 280px; }
.partyCard {
display: flex;
align-items: center;
gap: 12px;
background: var(--bg-header);
border-radius: 10px;
padding: 10px;
}
.partyCard img {
width: 48px;
height: 72px;
object-fit: cover;
border-radius: 6px;
background: var(--panel);
flex-shrink: 0;
}
/* A music party's own cover art is square (an album's, not a movie/show
poster) - the portrait 48x72 box above was forcing a hard crop on it.
Video parties keep the portrait box unchanged. */
.partyCard img.partyCardArt--square {
width: 56px;
height: 56px;
}
.partyCard img.noImage { visibility: hidden; }
.partyCardInfo {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.partyCardInfo strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.partyCard button { flex-shrink: 0; padding: 8px 14px; font-size: 13px; }
/* Stands in for "Rejoindre" on the one card that's this browser tab's own
active listen party - see renderParties in Home.ts. Same footprint as
the button it replaces, so the row doesn't visibly reflow. */
.partyCardMine {
flex-shrink: 0;
padding: 8px 14px;
color: var(--accent-bright);
font-weight: 600;
}