feat(slint): offline button on every Qobuz track row + cache-whole-playlist
- TrackRow show-download now defaults to true: every Qobuz track row (album,
artist, label, playlist, mix, search, favorites) carries the offline
cloud/check button. Non-Qobuz surfaces (future Local Library / Plex) opt out
by setting it false.
- Playlist header gains a "make offline" CircleAction -> ("playlist","cache")
-> offline_cache::cache_playlist (get_playlist -> batch its tracks), mirroring
the album-header action.
qbz-slint compiles clean.
cc
This commit is contained in:
4 files changed
+52
-1
No files matched your search
@@ -2551,6 +2551,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
playback::play_tracks(runtime, weak, handle, tracks, idx);
|
||||
});
|
||||
}
|
||||
("playlist", "cache") => {
|
||||
if let Ok(pid) = id.parse::<u64>() {
|
||||
offline_cache::cache_playlist(
|
||||
runtime.clone(),
|
||||
weak.clone(),
|
||||
handle.clone(),
|
||||
pid,
|
||||
);
|
||||
}
|
||||
}
|
||||
("playlist", "play-all") => {
|
||||
let runtime = runtime.clone();
|
||||
let weak = weak.clone();
|
||||
|
||||
@@ -310,6 +310,32 @@ pub fn cache_album(
|
||||
});
|
||||
}
|
||||
|
||||
/// Cache a whole playlist for offline playback: fetch its tracks, then batch.
|
||||
pub fn cache_playlist(
|
||||
runtime: Runtime,
|
||||
weak: slint::Weak<AppWindow>,
|
||||
handle: tokio::runtime::Handle,
|
||||
playlist_id: u64,
|
||||
) {
|
||||
let inner = handle.clone();
|
||||
handle.spawn(async move {
|
||||
let pl = match runtime.core().get_playlist(playlist_id).await {
|
||||
Ok(p) => p,
|
||||
Err(e) => {
|
||||
log::error!("[qbz-slint] cache playlist {playlist_id} failed: {e}");
|
||||
crate::toast::error_weak(&weak, "Couldn't load that playlist");
|
||||
return;
|
||||
}
|
||||
};
|
||||
let tracks: Vec<qbz_models::Track> = pl.tracks.map(|c| c.items).unwrap_or_default();
|
||||
if tracks.is_empty() {
|
||||
crate::toast::error_weak(&weak, "This playlist has no playable tracks");
|
||||
return;
|
||||
}
|
||||
cache_tracks(runtime, weak, inner, tracks);
|
||||
});
|
||||
}
|
||||
|
||||
/// Remove a track's offline copy (DB row + on-disk bundle/file + library row).
|
||||
pub fn remove_cached(
|
||||
_runtime: Runtime,
|
||||
|
||||
@@ -375,6 +375,18 @@ export component PlaylistView inherits Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make the whole playlist available offline.
|
||||
VerticalLayout {
|
||||
horizontal-stretch: 0;
|
||||
alignment: center;
|
||||
CircleAction {
|
||||
icon: @image-url("../assets/icons/cloud-download.svg");
|
||||
enabled: PlaylistState.tracks.length > 0;
|
||||
clicked => {
|
||||
root.media-action("playlist", PlaylistState.id, "cache");
|
||||
}
|
||||
}
|
||||
}
|
||||
// Edit (rename / delete) — only the user's own.
|
||||
if PlaylistState.is-owner: VerticalLayout {
|
||||
horizontal-stretch: 0;
|
||||
|
||||
@@ -32,7 +32,10 @@ export component TrackRow inherits Rectangle {
|
||||
in property <bool> show-artwork: true;
|
||||
in property <bool> show-album: false;
|
||||
in property <bool> show-favorite: false;
|
||||
in property <bool> show-download: false;
|
||||
// On by default: every Qobuz track row carries the offline cloud/check
|
||||
// button. A non-Qobuz surface (future Local Library / Plex rows, which are
|
||||
// already local) should set this false.
|
||||
in property <bool> show-download: true;
|
||||
in property <bool> multi-select-mode: false;
|
||||
// Custom-order reorder controls (up/down chevrons) at the leading
|
||||
// edge — used by the playlist custom sort.
|
||||
|
||||
Reference in new issue
Block a user