11use indicatif:: { MultiProgress , ProgressBar , ProgressDrawTarget , ProgressStyle } ;
22use std:: collections:: HashMap ;
3+ use std:: time:: { Duration , Instant } ;
34
45use crate :: dist:: Notification as In ;
56use crate :: notifications:: Notification ;
@@ -14,7 +15,12 @@ pub(crate) struct DownloadTracker {
1415 /// MultiProgress bar for the downloads.
1516 multi_progress_bars : MultiProgress ,
1617 /// Mapping of URLs being downloaded to their corresponding progress bars.
17- file_progress_bars : HashMap < String , ProgressBar > ,
18+ /// The `Option<Instant>` represents the instant where the download is being retried,
19+ /// allowing us delay the reappearance of the progress bar so that the user can see
20+ /// the message "retrying download" for at least a second.
21+ /// Without it, the progress bar would reappear immediately, not allowing the user to
22+ /// correctly see the message, before the progress bar starts again.
23+ file_progress_bars : HashMap < String , ( ProgressBar , Option < Instant > ) > ,
1824}
1925
2026impl DownloadTracker {
@@ -83,27 +89,39 @@ impl DownloadTracker {
8389 ) ;
8490 pb. set_message ( component) ;
8591 self . multi_progress_bars . add ( pb. clone ( ) ) ;
86- self . file_progress_bars . insert ( url, pb ) ;
92+ self . file_progress_bars . insert ( url, ( pb , None ) ) ;
8793 }
8894
8995 /// Sets the length for a new ProgressBar and gives it a style.
9096 pub ( crate ) fn content_length_received ( & mut self , content_len : u64 , url : & str ) {
91- if let Some ( pb ) = self . file_progress_bars . get ( url) {
97+ if let Some ( ( pb , _ ) ) = self . file_progress_bars . get ( url) {
9298 pb. reset ( ) ;
9399 pb. set_length ( content_len) ;
94100 }
95101 }
96102
97103 /// Notifies self that data of size `len` has been received.
98104 pub ( crate ) fn data_received ( & mut self , len : usize , url : & str ) {
99- if let Some ( pb) = self . file_progress_bars . get ( url) {
100- pb. inc ( len as u64 ) ;
105+ let Some ( ( pb, retry_time) ) = self . file_progress_bars . get_mut ( url) else {
106+ return ;
107+ } ;
108+ pb. inc ( len as u64 ) ;
109+ if !retry_time. is_some_and ( |instant| instant. elapsed ( ) > Duration :: from_secs ( 1 ) ) {
110+ return ;
101111 }
112+ * retry_time = None ;
113+ pb. set_style (
114+ ProgressStyle :: with_template (
115+ "{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
116+ )
117+ . unwrap ( )
118+ . progress_chars ( "## " ) ,
119+ ) ;
102120 }
103121
104122 /// Notifies self that the download has finished.
105123 pub ( crate ) fn download_finished ( & mut self , url : & str ) {
106- let Some ( pb ) = self . file_progress_bars . get ( url) else {
124+ let Some ( ( pb , _ ) ) = self . file_progress_bars . get ( url) else {
107125 return ;
108126 } ;
109127 pb. set_style (
@@ -115,7 +133,7 @@ impl DownloadTracker {
115133
116134 /// Notifies self that the download has failed.
117135 pub ( crate ) fn download_failed ( & mut self , url : & str ) {
118- let Some ( pb ) = self . file_progress_bars . get ( url) else {
136+ let Some ( ( pb , _ ) ) = self . file_progress_bars . get ( url) else {
119137 return ;
120138 } ;
121139 pb. set_style (
@@ -127,15 +145,10 @@ impl DownloadTracker {
127145
128146 /// Notifies self that the download is being retried.
129147 pub ( crate ) fn retrying_download ( & mut self , url : & str ) {
130- let Some ( pb ) = self . file_progress_bars . get ( url) else {
148+ let Some ( ( pb , retry_time ) ) = self . file_progress_bars . get_mut ( url) else {
131149 return ;
132150 } ;
133- pb. set_style (
134- ProgressStyle :: with_template (
135- "{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
136- )
137- . unwrap ( )
138- . progress_chars ( "## " ) ,
139- ) ;
151+ * retry_time = Some ( Instant :: now ( ) ) ;
152+ pb. set_style ( ProgressStyle :: with_template ( "{msg:>12.bold} retrying download" ) . unwrap ( ) ) ;
140153 }
141154}
0 commit comments