forked from Keelrleek/SoulStream
discography: the whole catalogue on a page of its own
"Show all" beside the artist page's Discography head opens every release as a stack of album-page heroes with their tracklists — the shapes Kyle picked off the mock: the search page's top-result card as a compact header, the album hero at --cover-scale 0.45 per record, a per-record accent sampled from its own cover, the year rail and the tab summary. The tab row does not stick and there is no Playing badge. Records the artist page has not fetched are shown rather than hidden, and the entrance is the W1 stagger — 300ms in, 55ms per row, 28px of lift, eight rows. It does not re-file the releases. catalog.discoTabs is the artist page's OWN computed tab list, published as it derives it and republished as the evidence improves. It has to work this way: the filing depends on the background description harvest that runs while you look at the artist page and on the MusicBrainz type hints from the deferred identity pass, neither of which is derivable from the payload — so a second classifier would read neither and would quietly file some releases differently from the page that linked to it. One list, computed once, handed over. If the tabs in hand belong to somebody else, opening a discography lands on the artist page instead, which republishes them and puts "Show all" one click away; an empty discography would be a lie about the catalogue. The page's CSS was extracted from src/ rather than retyped — CatalogAlbum's record section, CatalogSearch's header card and PlayerBar's menu, pulled through the same rule-matcher the mockup generator uses — so it inherits the app's measurements instead of approximating them. Verified against the running app: artwork 108px, record hero 114.3, header 147.5, header top 78, bar offset 0, ambience banner 0, rail centring error 0 and 12.8px of clearance at every scroll depth and pane width. Pond files 12+16+2+2 = 32 families on both pages. It is the one page exempt from BAR_VIEWS' padding-top rule, deliberately: its blurred ambience layer has to begin at the very top of the pane, and a padding there would start it halfway through the glass bar. It takes the inset on its header's margin instead, which lands in the same place.
This commit is contained in:
1 parent
819a2757bc
commit
34313e6035
5 files changed
+1709
-3
No files matched your search
@@ -35,6 +35,8 @@ function entryKey(e) {
|
||||
switch (e.view) {
|
||||
case "catalogArtist":
|
||||
return `artist:${e.artistId}`;
|
||||
case "catalogDiscography":
|
||||
return `disco:${e.artistId}`;
|
||||
case "catalogAlbum":
|
||||
return `album:${e.albumId}`;
|
||||
case "catalog":
|
||||
@@ -227,7 +229,11 @@ export function trail() {
|
||||
// artist crumb is taken from history when it is there, so it carries the
|
||||
// portrait and id already resolved, and is synthesised from the record's
|
||||
// own artist name when the album was reached directly.
|
||||
if (here.view === "catalogAlbum" && here.artist) {
|
||||
// A discography sits under its artist too, so both branches want the same
|
||||
// crumb — found in history when it is there (it carries the portrait and id
|
||||
// already resolved) and synthesised from the record's own artist name when
|
||||
// the album was reached directly.
|
||||
if ((here.view === "catalogAlbum" || here.view === "catalogDiscography") && here.artist) {
|
||||
const known = [...nav.stack]
|
||||
.reverse()
|
||||
.find((e) => e.view === "catalogArtist" && e.label === here.artist);
|
||||
|
||||
Reference in new issue
Block a user