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:
7 files changed
+232
-27
No files matched your search
@@ -69,9 +69,12 @@ component ViewAllLink inherits Rectangle {
|
||||
export component Carousel inherits VerticalLayout {
|
||||
in property <DiscoverSection> section;
|
||||
in property <bool> show-view-all: false;
|
||||
// Optional refresh affordance in the row header (recently-played rows).
|
||||
in property <bool> show-refresh: false;
|
||||
callback album-clicked(string);
|
||||
callback media-action(string, string, string);
|
||||
callback view-all-clicked();
|
||||
callback refresh-clicked();
|
||||
|
||||
property <length> card-width: 200px;
|
||||
// Overridable so a host view (Discover Recommendations) can give the row a
|
||||
@@ -189,6 +192,15 @@ export component Carousel inherits VerticalLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
if root.show-refresh: VerticalLayout {
|
||||
alignment: center;
|
||||
NavButton {
|
||||
icon: @image-url("../assets/icons/refresh-cw.svg");
|
||||
clicked => {
|
||||
root.refresh-clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
VerticalLayout {
|
||||
alignment: center;
|
||||
NavButton {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ export component SlimCarousel inherits VerticalLayout {
|
||||
// (recent, popular) are unchanged; only the Weekly rows opt in.
|
||||
in property <bool> show-list-actions: false;
|
||||
callback list-action(string);
|
||||
// Optional refresh affordance in the row header (recently-played rows).
|
||||
// Shown regardless of page count, unlike the chevrons.
|
||||
in property <bool> show-refresh: false;
|
||||
callback refresh-clicked();
|
||||
|
||||
property <int> columns: 4;
|
||||
property <int> rows: 3;
|
||||
@@ -99,6 +103,18 @@ export component SlimCarousel inherits VerticalLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
if root.show-refresh: HorizontalLayout {
|
||||
spacing: 4px;
|
||||
VerticalLayout {
|
||||
alignment: center;
|
||||
NavButton {
|
||||
icon: @image-url("../assets/icons/refresh-cw.svg");
|
||||
clicked => {
|
||||
root.refresh-clicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only when there is a second page.
|
||||
if root.total > root.per-page: HorizontalLayout {
|
||||
spacing: 4px;
|
||||
|
||||
@@ -204,6 +204,14 @@ export global HomeActions {
|
||||
// "View all" on the Recently Played Albums rail -> the full-page listing
|
||||
// (RecentAlbumsView), fed from the local play-history store.
|
||||
callback open-recent-albums();
|
||||
// Fired by HomeView's init on every (re)mount. Rust re-reads the LOCAL
|
||||
// recently-played store into the two rails IF a play was recorded while
|
||||
// Home was off-screen (dirty-flag gated in Rust — a no-op otherwise, so
|
||||
// mounting Home stays free).
|
||||
callback home-mounted();
|
||||
// Manual refresh (the toolbar button next to the nav cluster):
|
||||
// unconditionally re-read the local recently-played rails.
|
||||
callback refresh-recent();
|
||||
}
|
||||
|
||||
// RecentAlbumsView — the full "Recently Played Albums" page opened from the
|
||||
|
||||
Reference in new issue
Block a user