feat(home): auto-refresh recently-played rails + a row refresh button

Home's recently-played albums/tracks only populated on a full home load, so
tracks played mid-session never appeared until restart. Re-read the LOCAL
store into the rails when a track is recorded while Home is visible, and on
Home re-mount if it went dirty — event-driven, no polling, cheap (small JSON
read + cached artwork). Also add a manual refresh button in each recently-
played row header next to the page chevrons (moved off the top toolbar, where
it crowded the discovery tab bar).

cc
This commit is contained in:
vicrodh committed 2026-07-13 13:11:43 -06:00
1 parent 8df8c18ab0
commit a174e06119
7 files changed
+232 -27

No files matched your search

+23 -1
View File
@@ -8,7 +8,7 @@
import { Theme } from "../foundation/semantic-colors.slint";
import { Typography } from "../foundation/typography.slint";
import { HomeState, HomeActions, DiscoverState, DiscoverActions, GenreFilterState, GenreFilterActions, NavState, ContentView, ShellState, SettingsState } from "../state.slint";
import { HomeState, HomeActions, DiscoverState, DiscoverActions, GenreFilterState, GenreFilterActions, NavState, ContentView, ShellState, SettingsState, TooltipState } from "../state.slint";
import { Carousel } from "Carousel.slint";
import { SlimCarousel } from "SlimCarousel.slint";
import { ArtistCarousel } from "ArtistCarousel.slint";
@@ -121,6 +121,9 @@ component GenreButton inherits Rectangle {
}
}
// Manual refresh for the recently-played rails — sits in the toolbar next
// to the nav cluster. Same 32px icon-button form as GearButton, plus the
// global hover tooltip (TooltipState — the TransportControls pattern).
component GearButton inherits Rectangle {
callback clicked();
@@ -157,6 +160,14 @@ export component HomeView inherits Rectangle {
background: Theme.surface-main;
// The view remounts on every navigation to Home (AppShell's `if` mount),
// so this is the "Home regained focus" hook: Rust re-reads the LOCAL
// recently-played rails only when a play was recorded while Home was
// off-screen (dirty-flag gated — otherwise a no-op).
init => {
HomeActions.home-mounted();
}
VerticalLayout {
spacing: 0px;
@@ -390,6 +401,13 @@ export component HomeView inherits Rectangle {
// play-history, not a /discover endpoint — so it goes
// through its own action, not discover-view-all).
show-view-all: true;
// Manual refresh, in the row header next to the page
// chevrons (the recently-played rows are the only ones
// that go stale between full home loads).
show-refresh: true;
refresh-clicked => {
HomeActions.refresh-recent();
}
album-clicked(id) => {
root.album-clicked(id);
}
@@ -410,6 +428,10 @@ export component HomeView inherits Rectangle {
if desc.id == "continueListening" && HomeState.recent.length > 0: SlimCarousel {
title: @tr("Recently Played Tracks");
items: HomeState.recent;
show-refresh: true;
refresh-clicked => {
HomeActions.refresh-recent();
}
item-clicked(id) => {
root.media-action("track", id, "play");
}