[findings] findings from multi-progress
Closed this issue ยท 20 comments
Here's a few gotchas I've run into so far -- will keep updating this issue as I run into things ;) I'm happy to tackle some of them as time allows, but we can start with talking about them :)
-
The progress/download bars work just fine without having called
start()
- they will just be defaultindicatif
styling (ugly). Could be easy for a user to miss and not understand why the styling isn't working. -
Some weird UI behavior that I haven't figured out yet (the only "Bitcoin Core" is the title of the
multi_progress
:
This is a simple multi-progress withdownload
+spinner
+spinner
being added sequentially, withstart
andstop
being called on them before creating the next bar.
EDIT: This seems to have something to do with the stop()
method on either the progressbar or multibar -- you can see in the image in pt. 5 that when I don't call stop()
on the multi_progress
that this duplicate doesn't happen.
-
Would be better if
with_
methods returned&mut Self
, otherwise there'smove
issues in closures. -
There should be a
get_theme()
method to return the current theme. I'm trying to "swap" the template of a progress bar from a spinner ("Preparing to download...") to a download bar ("Downloading...") and it's proving very difficult. "Preparing to download" is retrieving headers and getting the total size, and "Downloading" is when the size is known and the progress bar can start.
What I'd like to ideally have is a spinner while preparing, and switch to download once I know the size.
Here's a little example from the "download" step in the image from pt. 2:
let multi = cliclack::multi_progress("Bitcoin Core");
let dl = multi.add(progress_bar(100).with_spinner_template());
dl.bar().set_message("Download starting...");
let mut total_size = 0;
let mut progress = 0;
let bitcoin_core_archive = download_file(
&bitcoin_url,
&ctx.tmp_dir,
|size| {
total_size = size.clone();
// `dl` MOVED HERE
let dl = dl.with_download_template();
dl.bar().set_message("Downloading Bitcoin Core...");
dl.bar().set_length(total_size);
},
|chunk, _| {
// `dl` has been moved...
dl.bar().inc(chunk);
progress += chunk;
},
)
.await?;
dl.stop(format!(
" {} {}",
style("โ").green(),
"Download Bitcoin Core"
));
-
If one forgets to call
stop()
on themulti_progress
then the grouping fails:
Note that untilmulti.stop()
is called, this formatting is applied (i.e. it's very obvious during longer steps like downloading). -
I seem to be getting extra padding before the
outro()
? I didn't see this in your screenshot ๐ค
@cylewitruk Progress bars is a rabbit hole.
Alright,
pt.2: It's fixable, I can fix it.
pt.5: cliclack
is literally a printer, if you forget to notify that the multi-bar is stopped, it doesn't become stopped. As an option, I have to implement a mediator pattern where the progress bars hold the reference to the multi-bar and they notify they're finished.
pt.6: the padding is noticeable if the multi-progress block is at the end of the list before the outro
. There is always a gap to keep spacing before the next element.
@cylewitruk Progress bars is a rabbit hole.
Haha ๐ฐ It's a little fun, admit it ๐ They look pretty cool, anyway :)
pt.2: It's fixable, I can fix it.
Ok!
pt.5:
cliclack
is literally a printer, if you forget to notify that the multi-bar is stopped, it doesn't become stopped. As an option, I have to implement a mediator pattern where the progress bars hold the reference to the multi-bar and they notify they're finished.
I had this working in my PR branch, guessing I did something similar. Afk right now but iirc I had logic to print the left bar based on the bar's position in the multibar, so only the last one ever printed with the S_BAR_END
which removed the flickering. Let me know if you want me to come with a suggestion-PR?
pt.6: the padding is noticeable if the multi-progress block is at the end of the list before the
outro
. There is always a gap to keep spacing before the next element.
Aha, okay -- in this particular case it feels a little weird visually to me - what do you think?
My feeling is that it feels that it makes the "finish" more connected to the following element than the current.
Realized that an outro
shouldn't be used here in the middle of the interaction :)
I had logic to print the left bar based on the bar's position in the multibar
I have the same logic.
What I'd like to ideally have is a spinner while preparing, and switch to download once I know the size.
Keep it simple: run the spinner, wait, show awaiting is done, and at the next step show a progress bar.
There should be a get_theme() method to return the current theme.
When you implement your theme it inherits ALL the methods of the default theme, you can retrieve any string from those methods.
For now, use 0.2.1
with fixes.
@cylewitruk and I still find it super buggy... More fixes to come
@cylewitruk and I still find it super buggy... More fixes to come
Yeah there's still some issues, but not all that bad imo -- stuff I'm putting in this ticket are just findings/thoughts, nothing that is a blocker so far, so no stress (well, pt. 2 is a bit annoying ๐ ) :) Feel free to tack-on things you find here as well so the info is consolidated -- I figure we can create issues from things here that should be changed/fixed instead of issue-spamming.
I have the same logic.
Hmm, weird...
When you implement your theme it inherits ALL the methods of the default theme, you can retrieve any string from those methods.
Sure, that'll work. My thought here is simply to avoid making users create a theme just for the sake of getting access to defaults.
The multiprogress
module is private, so the MultiProgress
(not re-exported) can't be passed around (nice to be able to do when isolating different steps to smaller methods).
What I'd like to ideally have is a spinner while preparing, and switch to download once I know the size.
@cylewitruk Check the version 0.2.2
, I added a clear()
method, so you can now add the spinner, clear it, and continue with a progress bar!
Warning: I also had to stop exposing indicatif via the bar()
method but it made rendering easier to implement.
P.S.: MultiProgress is public: https://docs.rs/cliclack/latest/cliclack/struct.MultiProgress.html
What I'd like to ideally have is a spinner while preparing, and switch to download once I know the size.
@cylewitruk Check the version
0.2.2
, I added aclear()
method, so you can now add the spinner, clear it, and continue with a progress bar!
Great! Thanks :)
Warning: I also had to stop exposing indicatif via the
bar()
method but it made rendering easier to implement.
Hm, how do I set_message()
, set_length()
and inc()
now?
P.S.: MultiProgress is public: docs.rs/cliclack/latest/cliclack/struct.MultiProgress.html
It worked now after a cargo update
๐ (I'm using github directly atm, so no need to publish to crates.io yet if it's troublesome)
Hm, how do I set_message(), set_length() and inc() now?
I have to add it to API :) Honestly, indicatif's finish_and_clear
and other similar methods are out of control, corner cases only.
I have to add it to API :)
Hehe okay, wasn't sure if I was missing something ๐
Honestly, indicatif's
finish_and_clear
and other similar methods are out of control, corner cases only.
A lot of the stuff in indicatif
is slightly questionable imo ๐คฃ That's where cliclack
has a real strength in abstracting away a lot of the complexity and giving reasonable defaults :)
But two frameworks fighting for the terminal doesn't make things easier when it comes to implementing this stuff ๐
@cylewitruk Check the main
branch
@cylewitruk Check the
main
branch
@fadeevab theere we go, it builds again! ๐ฏ ๐พ thanks :)
@fadeevab aaahhh, now we're looking pretty nice :)
@cylewitruk Woow, noooice :)
@cylewitruk To be sure I understand: do you mean an empty line under the cyan end bar?
@cylewitruk To be sure I understand: do you mean an empty line under the cyan end bar?
No, alignment of "preparing" vs. "Clean"
@cylewitruk I can suggest redefining the theme: format_progress_start
, it sets the 2 spaces.
@cylewitruk FYI, the patch is simple, however, 2 spaces look good as well. PR #34
@cylewitruk Let's close this issue, everything seems fixed now. Let's start a new discussion if it's indeed necessary.