feat: Add progress bar when syncing albums

Signed-off-by: SindreKjelsrud <sindre@kjelsrud.dev>
This commit is contained in:
SindreKjelsrud 2026-01-13 22:02:06 +01:00
parent f946dbb9ce
commit 49c4a79845
Signed by: sidski
GPG key ID: D2BBDF3EDE6BA9A6
3 changed files with 106 additions and 1 deletions

61
Cargo.lock generated
View file

@ -284,6 +284,19 @@ dependencies = [
"yaml-rust2",
]
[[package]]
name = "console"
version = "0.15.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8"
dependencies = [
"encode_unicode",
"libc",
"once_cell",
"unicode-width",
"windows-sys 0.59.0",
]
[[package]]
name = "const-random"
version = "0.1.18"
@ -414,6 +427,12 @@ dependencies = [
"const-random",
]
[[package]]
name = "encode_unicode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
[[package]]
name = "encoding_rs"
version = "0.8.35"
@ -902,6 +921,19 @@ dependencies = [
"hashbrown 0.16.1",
]
[[package]]
name = "indicatif"
version = "0.17.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235"
dependencies = [
"console",
"number_prefix",
"portable-atomic",
"unicode-width",
"web-time",
]
[[package]]
name = "ipnet"
version = "2.11.0"
@ -1100,6 +1132,7 @@ dependencies = [
"dirs",
"fs_extra",
"id3",
"indicatif",
"mockito",
"pathdiff",
"reqwest",
@ -1133,6 +1166,12 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "number_prefix"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "once_cell"
version = "1.21.3"
@ -1301,6 +1340,12 @@ version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
[[package]]
name = "portable-atomic"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
[[package]]
name = "potential_utf"
version = "0.1.4"
@ -2049,6 +2094,12 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
[[package]]
name = "unicode-width"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
[[package]]
name = "url"
version = "2.5.7"
@ -2204,6 +2255,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.11"

View file

@ -40,6 +40,9 @@ pathdiff = "0.2"
# CLI
clap = { version = "4.0", features = ["derive"] }
# TUI Progress bars
indicatif = "0.17"
# ID3 tag parsing
id3 = "1.13"

View file

@ -8,6 +8,8 @@ pub mod sync;
pub use config::Config;
use clap::{Parser, Subcommand};
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use std::sync::Arc;
#[derive(Parser)]
#[command(name = "navipod")]
@ -39,7 +41,46 @@ pub async fn run(config: Config) -> anyhow::Result<()> {
match cli.command {
Commands::Sync { album, artist } => {
sync::sync_content(config, album, artist).await?;
// Create multi-progress for TUI
let multi = MultiProgress::new();
// Main progress bar for overall sync
let pb = multi.add(ProgressBar::new(100));
pb.set_style(
ProgressStyle::default_bar()
.template("{msg}\n{spinner:.green} [{bar:40.cyan/blue}] {pos}/{len} albums ({percent}%)")
.unwrap()
.progress_chars("█▓▒░ "),
);
pb.set_message("Syncing albums...");
// Status line for current activity
let status_pb = multi.add(ProgressBar::new_spinner());
status_pb.set_style(
ProgressStyle::default_spinner()
.template("{spinner:.green} {msg}")
.unwrap(),
);
// Create progress callback
let pb_clone = pb.clone();
let status_clone = status_pb.clone();
let progress_callback = Arc::new(move |album: String, song: String, done: usize, total: usize| {
if total > 0 {
pb_clone.set_length(total as u64);
pb_clone.set_position(done as u64);
}
status_clone.set_message(format!("Album: {} | {}", album, song));
});
// Run sync with progress
let result = sync::sync_content_with_progress(config, album, artist, Some(progress_callback)).await;
// Finish progress bars
pb.finish_with_message("Sync complete!");
status_pb.finish_and_clear();
result?;
}
Commands::ListAlbums => {
let mut navidrome = navidrome::NavidromeClient::new(&config.navidrome)?;