11use indicatif:: { MultiProgress , ProgressBar , ProgressDrawTarget , ProgressStyle } ;
2- use std:: time :: Duration ;
2+ use std:: collections :: HashMap ;
33
44use crate :: dist:: Notification as In ;
55use crate :: notifications:: Notification ;
@@ -13,8 +13,8 @@ use crate::utils::Notification as Un;
1313pub ( crate ) struct DownloadTracker {
1414 /// MultiProgress bar for the downloads.
1515 multi_progress_bars : MultiProgress ,
16- /// ProgressBar for the current download .
17- progress_bar : ProgressBar ,
16+ /// Mapping of URLs being downloaded to their corresponding progress bars .
17+ file_progress_bars : HashMap < String , ProgressBar > ,
1818}
1919
2020impl DownloadTracker {
@@ -28,22 +28,35 @@ impl DownloadTracker {
2828
2929 Self {
3030 multi_progress_bars,
31- progress_bar : ProgressBar :: hidden ( ) ,
31+ file_progress_bars : HashMap :: new ( ) ,
3232 }
3333 }
3434
3535 pub ( crate ) fn handle_notification ( & mut self , n : & Notification < ' _ > ) -> bool {
3636 match * n {
37- Notification :: Install ( In :: Utils ( Un :: DownloadContentLengthReceived ( content_len) ) ) => {
38- self . content_length_received ( content_len) ;
37+ Notification :: Install ( In :: Utils ( Un :: DownloadContentLengthReceived (
38+ content_len,
39+ url,
40+ ) ) ) => {
41+ if let Some ( url) = url {
42+ self . content_length_received ( content_len, url) ;
43+ }
3944 true
4045 }
41- Notification :: Install ( In :: Utils ( Un :: DownloadDataReceived ( data) ) ) => {
42- self . data_received ( data. len ( ) ) ;
46+ Notification :: Install ( In :: Utils ( Un :: DownloadDataReceived ( data, url) ) ) => {
47+ if let Some ( url) = url {
48+ self . data_received ( data. len ( ) , url) ;
49+ }
4350 true
4451 }
45- Notification :: Install ( In :: Utils ( Un :: DownloadFinished ) ) => {
46- self . download_finished ( ) ;
52+ Notification :: Install ( In :: Utils ( Un :: DownloadFinished ( url) ) ) => {
53+ if let Some ( url) = url {
54+ self . download_finished ( url) ;
55+ }
56+ true
57+ }
58+ Notification :: Install ( In :: DownloadingComponent ( component, _, _, url) ) => {
59+ self . create_progress_bar ( component. to_owned ( ) , url. to_owned ( ) ) ;
4760 true
4861 }
4962 Notification :: Install ( In :: Utils ( Un :: DownloadPushUnit ( _) ) ) => true ,
@@ -53,30 +66,44 @@ impl DownloadTracker {
5366 }
5467 }
5568
56- /// Sets the length for a new ProgressBar and gives it a style .
57- pub ( crate ) fn content_length_received ( & mut self , content_len : u64 ) {
58- self . progress_bar . set_length ( content_len ) ;
59- self . progress_bar . set_style (
69+ /// Creates a new ProgressBar for the given component .
70+ pub ( crate ) fn create_progress_bar ( & mut self , component : String , url : String ) {
71+ let pb = ProgressBar :: hidden ( ) ;
72+ pb . set_style (
6073 ProgressStyle :: with_template (
61- "[{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
74+ "{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
6275 )
6376 . unwrap ( )
6477 . progress_chars ( "## " ) ,
6578 ) ;
79+ pb. set_message ( component) ;
80+ self . multi_progress_bars . add ( pb. clone ( ) ) ;
81+ self . file_progress_bars . insert ( url, pb) ;
82+ }
83+
84+ /// Sets the length for a new ProgressBar and gives it a style.
85+ pub ( crate ) fn content_length_received ( & mut self , content_len : u64 , url : & str ) {
86+ if let Some ( pb) = self . file_progress_bars . get ( url) {
87+ pb. set_length ( content_len) ;
88+ }
6689 }
6790
6891 /// Notifies self that data of size `len` has been received.
69- pub ( crate ) fn data_received ( & mut self , len : usize ) {
70- if self . progress_bar . is_hidden ( ) && self . progress_bar . elapsed ( ) >= Duration :: from_secs ( 1 ) {
71- self . multi_progress_bars . add ( self . progress_bar . clone ( ) ) ;
92+ pub ( crate ) fn data_received ( & mut self , len : usize , url : & str ) {
93+ if let Some ( pb ) = self . file_progress_bars . get ( url ) {
94+ pb . inc ( len as u64 ) ;
7295 }
73- self . progress_bar . inc ( len as u64 ) ;
7496 }
7597
7698 /// Notifies self that the download has finished.
77- pub ( crate ) fn download_finished ( & mut self ) {
78- self . progress_bar . finish_and_clear ( ) ;
79- self . multi_progress_bars . remove ( & self . progress_bar ) ;
80- self . progress_bar = ProgressBar :: hidden ( ) ;
99+ pub ( crate ) fn download_finished ( & mut self , url : & str ) {
100+ let Some ( pb) = self . file_progress_bars . get ( url) else {
101+ return ;
102+ } ;
103+ pb. set_style (
104+ ProgressStyle :: with_template ( "{msg:>12.bold} downloaded {total_bytes} in {elapsed}" )
105+ . unwrap ( ) ,
106+ ) ;
107+ pb. finish ( ) ;
81108 }
82109}
0 commit comments