sidebar and artist pipeline: one list in the rail, recents anchored to ids, and popular takes its own lane

This commit is contained in:
KeelrLeek committed 2026-07-31 18:21:04 -05:00
1 parent 606250c361
commit eba29824c9
12 files changed
+1595 -281

No files matched your search

+63 -1
View File
@@ -2520,6 +2520,19 @@ pub async fn catalog_artist_overview(
.ok_or_else(|| "artist overview lookup failed".to_string())
}
#[tauri::command]
pub async fn catalog_artist_popular(
state: State<'_, LibraryState>,
artist_id: u64,
) -> Result<Vec<metadata::CatalogTrack>, String> {
state.touch_catalog_activity();
state
.metadata
.catalog_artist_popular(artist_id)
.await
.ok_or_else(|| "artist popular lookup failed".to_string())
}
#[tauri::command]
pub async fn catalog_related(
state: State<'_, LibraryState>,
@@ -3957,20 +3970,69 @@ pub async fn open_external(url: String) -> Result<(), String> {
// ---- play history ----
#[tauri::command]
#[allow(clippy::too_many_arguments)]
pub async fn record_play(
lib: State<'_, LibraryState>,
artist: String,
title: String,
path: Option<String>,
catalog_album_id: Option<String>,
album_title: Option<String>,
album_artist: Option<String>,
cover_url: Option<String>,
) -> Result<i64, String> {
let l = lib.library.clone();
tauri::async_runtime::spawn_blocking(move || {
l.record_play(&artist, &title, now_secs())
let cat = library::CatalogPlay {
album_id: catalog_album_id.as_deref(),
title: album_title.as_deref(),
artist: album_artist.as_deref(),
cover: cover_url.as_deref(),
};
l.record_play(&artist, &title, path.as_deref(), cat, now_secs())
.map_err(|e| e.to_string())
})
.await
.map_err(|e| e.to_string())?
}
/// Wipe listening history. Destructive and not undoable — `plays` only;
/// albums, tracks and playlists are untouched. Returns rows removed.
#[tauri::command]
pub async fn clear_play_history(lib: State<'_, LibraryState>) -> Result<usize, String> {
let l = lib.library.clone();
tauri::async_runtime::spawn_blocking(move || {
l.clear_play_history().map_err(|e| e.to_string())
})
.await
.map_err(|e| e.to_string())?
}
#[tauri::command]
pub async fn play_row_count(lib: State<'_, LibraryState>) -> Result<i64, String> {
let l = lib.library.clone();
tauri::async_runtime::spawn_blocking(move || l.play_row_count().map_err(|e| e.to_string()))
.await
.map_err(|e| e.to_string())?
}
/// The sidebar's recently-played list. `min_secs` keeps skips out of it.
#[tauri::command]
pub async fn recent_albums(
lib: State<'_, LibraryState>,
limit: Option<u32>,
min_secs: Option<u32>,
) -> Result<Vec<library::RecentAlbum>, String> {
let l = lib.library.clone();
let limit = limit.unwrap_or(20);
let min_secs = min_secs.unwrap_or(45);
tauri::async_runtime::spawn_blocking(move || {
l.recent_albums(limit, min_secs).map_err(|e| e.to_string())
})
.await
.map_err(|e| e.to_string())?
}
#[tauri::command]
pub async fn add_play_seconds(
lib: State<'_, LibraryState>,
+4
View File
@@ -73,6 +73,9 @@ pub fn run() {
commands::record_play,
commands::add_play_seconds,
commands::artist_play_stats,
commands::recent_albums,
commands::clear_play_history,
commands::play_row_count,
commands::list_playlists,
commands::create_playlist,
commands::delete_playlist,
@@ -93,6 +96,7 @@ pub fn run() {
commands::catalog_ocr_experiment,
commands::catalog_artist_hero_seed,
commands::catalog_artist_overview,
commands::catalog_artist_popular,
commands::pick_artist_hero,
commands::clear_artist_hero,
commands::catalog_related,