/** The banner on its own (`catalog_artist_hero_seed`), ahead of the page. * Three sources in the Rust, cheapest first: the hero Kyle picked on this * phone (a file, no network at all), the art manifest, then the provider. * The full page still owns the final artwork — this only paints first. */ export function loadHeroSeed(id) { if (id == null || catalog.heroSeeds[id]) return; catalog.heroSeeds[id] = { status: "loading", banner: null, custom: false }; api.catalogArtistHeroSeed(id).then( (s) => { catalog.heroSeeds[id] = s?.banner ? { status: "ready", banner: s.banner, custom: !!s.banner_custom } : { status: "none", banner: null, custom: false }; }, () => { catalog.heroSeeds[id] = { status: "error", banner: null, custom: false }; }, ); } /** The artist and the first page of releases in one round * (`catalog_artist_overview`) — the desktop's fast content stage, for the * desktop's own reason: the identity chain inside the full page rides * MusicBrainz's gate and is measured there at several seconds. Its * `popular_tracks` are deliberately dropped: Popular has a ranked lane of * its own already, and the overview's list is budgeted and unranked. */ export function loadOverview(id) { if (id == null || catalog.overviews[id]) return; catalog.overviews[id] = { status: "loading", artist: null, albums: [] }; api.catalogArtistOverview(id).then( (o) => { catalog.overviews[id] = { status: "ready", artist: o?.artist ?? null, albums: o?.albums ?? [] }; }, () => { catalog.overviews[id] = { status: "error", artist: null, albums: [] }; }, ); }