android: the catalog's numbers — Popular's own lane, a count per row, the artist's photo

Popular is asked on its own as well as with the page, so the section can
paint before the full page is built and an artist whose page came back
with none still gets one. A catalog record's rows that the album's own
artist anchor found no count for — a feature's guest, a compilation's
stranger — get the deferred Last.fm pass by their own artist id. The
artist page's ⋯ is its own sheet now: choose a hero photo from this phone,
or put the catalog's own back; set_artist_hero is pick_artist_hero's
install step split out and shared, so the desktop's dialog keeps its door.
You gains the desktop's Refresh artist portraits, and a data: URL is the
image itself in the art gate — a chosen hero comes back from Rust as one,
and the thumbnail fetch used to throw it away.
This commit is contained in:
KeelrLeek committed 2026-09-13 23:46:07 -05:00
1 parent c737809325
commit 1737c5e1b6
12 files changed
+232 -13

No files matched your search

+26 -3
View File
@@ -2017,10 +2017,21 @@ pub async fn pick_artist_hero(
let Some(source) = rx.await.unwrap_or(None) else {
return Ok(None);
};
install_artist_hero(&app, artist_id, source).map(Some)
}
/// A picked image — the desktop's dialog, or a photo the phone's storage
/// plugin already copied into the app's cache — validated and written as
/// this artist's chosen hero.
fn install_artist_hero(
app: &tauri::AppHandle,
artist_id: u64,
source: String,
) -> Result<ArtistHeroOverride, String> {
let source = std::path::PathBuf::from(source);
let (width, height) = validate_artist_hero(&source)?;
let (ext, _) = artist_image_format(&source)?;
let dir = artist_hero_dir(&app)?;
let dir = artist_hero_dir(app)?;
let temporary = dir.join(format!("{artist_id}.importing"));
std::fs::copy(&source, &temporary).map_err(|e| e.to_string())?;
for old_ext in ["jpg", "png", "webp"] {
@@ -2031,11 +2042,23 @@ pub async fn pick_artist_hero(
let _ = std::fs::remove_file(&temporary);
return Err(error.to_string());
}
let mut hero = load_artist_hero_override(&app, artist_id)?
let mut hero = load_artist_hero_override(app, artist_id)?
.ok_or_else(|| "The imported hero could not be reopened".to_string())?;
hero.width = width;
hero.height = height;
Ok(Some(hero))
Ok(hero)
}
/// The phone's door onto the same import: a photo already on disk (the
/// storage plugin's picker copied it into the app's cache) becomes this
/// artist's chosen hero. The dialog above stays the desktop's.
#[tauri::command]
pub async fn set_artist_hero(
app: tauri::AppHandle,
artist_id: u64,
path: String,
) -> Result<ArtistHeroOverride, String> {
install_artist_hero(&app, artist_id, path)
}
#[tauri::command]
+1
View File
@@ -325,6 +325,7 @@ pub fn run() {
commands::catalog_artist_overview,
commands::catalog_artist_popular,
commands::pick_artist_hero,
commands::set_artist_hero,
commands::clear_artist_hero,
commands::catalog_related,
commands::catalog_track_listeners,