From 88df19480816fbd51eb61df9e65a7af87763ae1d Mon Sep 17 00:00:00 2001 From: Frank Stellmacher <171614930+Psychotoxical@users.noreply.github.com> Date: Thu, 4 Jun 2026 02:28:13 +0200 Subject: [PATCH] fix(tracks): RC3 layout regressions + multi-artist links (#976) * fix(tracks): RC3 layout regressions + multi-artist links - Restore vertical rhythm on the Tracks hub: the header/hero/rails/browse sections sat two wrapper divs below .tracks-page so its flex gap never reached them and they collapsed together. New .tracks-hub-stack re-applies the gap, fixing the tagline-touching-hero and Random-Pick-overlapping-hero spacing (the rail's nav buttons no longer ride into the box above). - Stop the sticky browse-table header going transparent on hover: its base background became opaque but the :hover rule still forced transparent, so rows bled through. Header now keeps its card background on hover. - Widen the Duration column (56px -> 72px; 56 -> 64 on mobile) so the "DURATION" header no longer clips/overruns. - Split multi-artist tracks into individually clickable artist links in both the "Track of the moment" hero and the browse list rows (OpenSubsonic artists[] with single-artist fallback), matching the album tracklist. * docs(changelog): Tracks RC3 spacing, Duration, header hover, multi-artist (#976) --- CHANGELOG.md | 9 +++++++ src/components/SongRow.tsx | 25 +++++++++++++------ src/components/tracks/TracksPageChrome.tsx | 23 +++++++++++++---- src/pages/SearchBrowsePage.tsx | 2 +- src/styles/tracks/_intro.css | 10 ++++++++ src/styles/tracks/responsive.css | 4 +-- ...racks-hub-searchresults-advancedsearch.css | 9 ++++--- src/styles/tracks/virtual-song-list.css | 1 - 8 files changed, 64 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f479cf2..f417bcad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -855,6 +855,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Hiding **Mainstage** from the sidebar no longer leaves the app opening on a blank page โ it now starts on the first visible library entry instead. * When every Mainstage section is turned off, the page shows a short message with a shortcut into **Settings โ Personalisation** rather than appearing empty. +### Tracks โ spacing, Duration column, header hover, multi-artist links + +**By [@Psychotoxical](https://github.com/Psychotoxical), reported by zunoz on Discord, PR [#976](https://github.com/Psychotoxical/psysonic/pull/976)** + +* The Tracks hub sections (tagline, **Track of the moment**, **Random Pick** rail, **Browse all tracks**) no longer bunch together โ even vertical spacing is restored, so the rail's navigation buttons stop riding up into the card above. +* The **Browse all tracks** table no longer clips the **Duration** column header. +* The track-list column header keeps its background on hover instead of turning transparent and letting rows show through. +* **Track of the moment** and the browse rows split multi-artist tracks into individually clickable artist links, matching the album track list. + ## [1.46.0] - 2026-05-18 > **๐ Special thanks to [@zz5zz](https://github.com/zz5zz)** for his tireless quirk-spotting and bug reports on the [Psysonic Discord](https://discord.gg/AMnDRErm4u) โ several of the polish fixes in this release landed directly off the back of his messages. diff --git a/src/components/SongRow.tsx b/src/components/SongRow.tsx index 311306c9..3876edbb 100644 --- a/src/components/SongRow.tsx +++ b/src/components/SongRow.tsx @@ -39,6 +39,13 @@ function SongRow({ song, showBpm }: Props) { enqueue([songToTrack(song)]); }; + // Split multi-artist tracks into individually clickable links (OpenSubsonic + // `artists[]`), falling back to the single flat artist when absent โ mirrors + // the album tracklist so a "A ยท B" credit isn't one link to a single artist. + const artistRefs = song.artists && song.artists.length > 0 + ? song.artists + : [{ id: song.artistId, name: song.artist }]; + const bpmTooltip = song.localBpmSource === 'analysis' ? t('search.bpmSourceAnalysis') @@ -93,13 +100,17 @@ function SongRow({ song, showBpm }: Props) {
- hero.artistId && navigateToArtist(hero.artistId)}
- >{hero.artist}
+ {heroArtistRefs.map((a, i) => (
+