fix(slint): favorites covers stayed grey under sort/group

The artwork pipeline wrote a decoded cover into the SOURCE model
(FavoritesState.albums / .tracks) by index, but the views render the
derived albums-visible / albums-grouped / tracks-visible models, which
are independent clones whenever a sort/group/search is active. So a
late-arriving cover never reached the rendered card (grey until a
re-derive). Add favorites::set_album_artwork / set_track_artwork to also
propagate the cover by id into the rendered model(s); apply_artwork calls
them for FavoriteAlbum / FavoriteTrack. The disk cache was already in use;
this was purely the render target.

cc
This commit is contained in:
vicrodh committed 2026-05-27 11:45:43 -06:00
1 parent 159310bbf0
commit 39c8e86d7b
2 files changed
+56 -2

No files matched your search

+9 -2
View File
@@ -502,15 +502,22 @@ fn apply_artwork(
ArtworkTarget::FavoriteTrack { index } => {
let model = window.global::<crate::FavoritesState>().get_tracks();
if let Some(mut item) = model.row_data(index) {
item.artwork = image;
item.artwork = image.clone();
let id = item.id.to_string();
model.set_row_data(index, item);
// Also reach the rendered (possibly sorted/grouped) model.
crate::favorites::set_track_artwork(window, &id, image);
}
}
ArtworkTarget::FavoriteAlbum { index } => {
let model = window.global::<crate::FavoritesState>().get_albums();
if let Some(mut item) = model.row_data(index) {
item.artwork = image;
item.artwork = image.clone();
let id = item.id.to_string();
model.set_row_data(index, item);
// Also reach the rendered visible/grouped model (clones when
// a sort/group is active — they don't share `albums`).
crate::favorites::set_album_artwork(window, &id, image);
}
}
ArtworkTarget::DiscoverBrowseAlbum { index } => {
+47
View File
@@ -791,6 +791,53 @@ pub fn remove_album_row(window: &AppWindow, id: &str) {
}
}
// ---- Artwork propagation -----------------------------------------------
// The artwork pipeline writes a decoded cover into the SOURCE model
// (`albums` / `tracks`) by index, but the views render the derived
// `albums-visible` / `albums-grouped` / `tracks-visible` models, which are
// independent clones whenever a sort / group / search is active. So a
// late-arriving cover never reached the rendered card (it stayed grey
// until a re-derive). Propagate it into the rendered model(s) by id too.
fn set_artwork_in_albums(model: &ModelRc<AlbumCardItem>, id: &str, image: &slint::Image) {
for i in 0..model.row_count() {
if let Some(mut item) = model.row_data(i) {
if item.id.as_str() == id {
item.artwork = image.clone();
model.set_row_data(i, item);
break;
}
}
}
}
/// Set a freshly-decoded album cover (by id) on the rendered favorites
/// album models (flat `albums-visible` + every `albums-grouped` section).
pub fn set_album_artwork(window: &AppWindow, id: &str, image: slint::Image) {
let st = window.global::<FavoritesState>();
set_artwork_in_albums(&st.get_albums_visible(), id, &image);
let grouped = st.get_albums_grouped();
for s in 0..grouped.row_count() {
if let Some(section) = grouped.row_data(s) {
set_artwork_in_albums(&section.albums, id, &image);
}
}
}
/// Same for the rendered favorites tracks model (`tracks-visible`).
pub fn set_track_artwork(window: &AppWindow, id: &str, image: slint::Image) {
let model = window.global::<FavoritesState>().get_tracks_visible();
for i in 0..model.row_count() {
if let Some(mut item) = model.row_data(i) {
if item.id.as_str() == id {
item.artwork = image.clone();
model.set_row_data(i, item);
break;
}
}
}
}
// ---- Tracks multi-select (mirrors playlist.rs) -------------------------
// Selection lives on TrackItem.selected in the rendered `tracks-visible`
// model (which shares `tracks` when no search filter is active).