1
1
use indicatif:: { MultiProgress , ProgressBar , ProgressDrawTarget , ProgressStyle } ;
2
2
use std:: collections:: HashMap ;
3
+ use std:: time:: { Duration , Instant } ;
3
4
4
5
use crate :: dist:: Notification as In ;
5
6
use crate :: notifications:: Notification ;
@@ -14,7 +15,12 @@ pub(crate) struct DownloadTracker {
14
15
/// MultiProgress bar for the downloads.
15
16
multi_progress_bars : MultiProgress ,
16
17
/// 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 > ) > ,
18
24
}
19
25
20
26
impl DownloadTracker {
@@ -83,27 +89,39 @@ impl DownloadTracker {
83
89
) ;
84
90
pb. set_message ( component) ;
85
91
self . multi_progress_bars . add ( pb. clone ( ) ) ;
86
- self . file_progress_bars . insert ( url, pb ) ;
92
+ self . file_progress_bars . insert ( url, ( pb , None ) ) ;
87
93
}
88
94
89
95
/// Sets the length for a new ProgressBar and gives it a style.
90
96
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) {
92
98
pb. reset ( ) ;
93
99
pb. set_length ( content_len) ;
94
100
}
95
101
}
96
102
97
103
/// Notifies self that data of size `len` has been received.
98
104
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 ;
101
111
}
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
+ ) ;
102
120
}
103
121
104
122
/// Notifies self that the download has finished.
105
123
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 {
107
125
return ;
108
126
} ;
109
127
pb. set_style (
@@ -115,7 +133,7 @@ impl DownloadTracker {
115
133
116
134
/// Notifies self that the download has failed.
117
135
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 {
119
137
return ;
120
138
} ;
121
139
pb. set_style (
@@ -127,15 +145,10 @@ impl DownloadTracker {
127
145
128
146
/// Notifies self that the download is being retried.
129
147
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 {
131
149
return ;
132
150
} ;
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 ( ) ) ;
140
153
}
141
154
}
0 commit comments