fix(home): render all 13 configurator sections; own recent-albums history

Two Home bugs, one dropped port. #566: four configurator sections
(favoriteAlbums 'Library Albums', qobuzMixes, releaseWatch, topArtists)
were offered and persisted but had no HomeView render arm and no data
in load_home — enabling them produced an invisible row. All four were
genuine Tauri-Home features (DiscoveryView.svelte arms :632/:653/:660/
:666, loaded unconditionally), so this is the full port, not a trim:
own HomeState fields (separate lifecycle from ForYouState), shared
foryou fetch pipelines (favorite_album_cards / fetch_release_watch /
top_artist_cards extracted pub(crate), For You behavior untouched),
Home-scoped artwork targets, and HomeView arms mirroring ForYouView.
load_home joins the three fetches concurrently with the index — zero
added latency. A HOME_RENDERABLE guard next to descriptors_for is now
the single source of truth: an enabled id without a render arm can
never emit an invisible descriptor again.

#567: 'Recently Played Albums' starved because albums derived from the
24-track history (long albums collapse to ~4 distinct). recently.rs
now keeps a separate album history (dedupe by id at record time, own
24 cap) with additive migration from the legacy bare-array format;
tracks keep their cap; load()/load_albums() signatures unchanged.

Zero new msgids (all three titles reuse For You's). qbz-app tests
10/10; slintcheck green.

cc
This commit is contained in:
vicrodh committed 2026-07-08 11:46:57 -06:00
1 parent 99a2079df1
commit 338d20df9b
8 files changed
+384 -70

No files matched your search

+57
View File
@@ -11,6 +11,8 @@ import { Typography } from "../foundation/typography.slint";
import { HomeState, HomeActions, DiscoverState, DiscoverActions, GenreFilterState, GenreFilterActions, NavState, ContentView, ShellState, SettingsState } from "../state.slint";
import { Carousel } from "Carousel.slint";
import { SlimCarousel } from "SlimCarousel.slint";
import { ArtistCarousel } from "ArtistCarousel.slint";
import { QobuzMixesRow } from "QobuzMixesRow.slint";
import { PlaylistCarousel } from "PlaylistCarousel.slint";
import { PlaylistTagFilter } from "PlaylistTagFilter.slint";
import { HomeSkeleton } from "HomeSkeleton.slint";
@@ -421,6 +423,61 @@ export component HomeView inherits Rectangle {
root.album-clicked(id);
}
}
// Library Albums (#566) — the user's favorite albums,
// mirroring the For You favoriteAlbums carousel. Data +
// localized title are pushed by Rust into
// HomeState.favorite-albums; self-hides while empty
// (no placeholder, 1:1 with the For You arm).
if desc.id == "favoriteAlbums"
&& HomeState.favorite-albums.albums.length > 0: Carousel {
section: HomeState.favorite-albums;
album-clicked(id) => {
root.album-clicked(id);
}
media-action(kind, id, action) => {
root.media-action(kind, id, action);
}
}
// Qobuz Mixes (#566) — static navigation tiles, ALWAYS
// rendered when enabled (no data gate; 1:1 with the For
// You arm and Tauri Home).
if desc.id == "qobuzMixes": QobuzMixesRow {
open-mix(which) => {
root.media-action("mix", which, "open");
}
}
// Release Watch (#566) — album carousel, mirroring the
// For You releaseWatch arm; data + localized title pushed
// by Rust into HomeState.release-watch. Self-hides while
// empty.
if desc.id == "releaseWatch"
&& HomeState.release-watch.albums.length > 0: Carousel {
section: HomeState.release-watch;
album-clicked(id) => {
root.album-clicked(id);
}
media-action(kind, id, action) => {
root.media-action(kind, id, action);
}
}
// Your Top Artists (#566) — artist carousel, mirroring
// the For You topArtists arm (title @tr'd here, like For
// You's). Self-hides while empty.
if desc.id == "topArtists"
&& HomeState.top-artists.length > 0: ArtistCarousel {
title: @tr("Your Top Artists");
artists: HomeState.top-artists;
artist-clicked(id) => {
root.open-artist(id);
}
media-action(kind, id, action) => {
root.media-action(kind, id, action);
}
}
}
// For You renders its own ordered, heterogeneous