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 files to their corresponding progress bars .
17+ file_progress_bars : HashMap < String , ProgressBar > ,
1818}
1919
2020impl DownloadTracker {
@@ -28,22 +28,29 @@ 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+ file,
40+ ) ) ) => {
41+ self . content_length_received ( content_len, file) ;
3942 true
4043 }
41- Notification :: Install ( In :: Utils ( Un :: DownloadDataReceived ( data) ) ) => {
42- self . data_received ( data. len ( ) ) ;
44+ Notification :: Install ( In :: Utils ( Un :: DownloadDataReceived ( data, file ) ) ) => {
45+ self . data_received ( data. len ( ) , file ) ;
4346 true
4447 }
45- Notification :: Install ( In :: Utils ( Un :: DownloadFinished ) ) => {
46- self . download_finished ( ) ;
48+ Notification :: Install ( In :: Utils ( Un :: DownloadFinished ( file) ) ) => {
49+ self . download_finished ( file) ;
50+ true
51+ }
52+ Notification :: Install ( In :: DownloadingComponent ( component, _, _) ) => {
53+ self . create_progress_bar ( component) ;
4754 true
4855 }
4956 Notification :: Install ( In :: Utils ( Un :: DownloadPushUnit ( _) ) ) => true ,
@@ -53,30 +60,61 @@ impl DownloadTracker {
5360 }
5461 }
5562
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 (
63+ /// Helper function to find the progress bar for a given file.
64+ fn find_progress_bar ( & mut self , file : & str ) -> Option < & mut ProgressBar > {
65+ // During the installation this function can be called with an empty file/URL.
66+ if file. is_empty ( ) {
67+ return None ;
68+ }
69+ let component = self
70+ . file_progress_bars
71+ . keys ( )
72+ . find ( |comp| file. contains ( * comp) )
73+ . cloned ( ) ?;
74+
75+ self . file_progress_bars . get_mut ( & component)
76+ }
77+
78+ /// Creates a new ProgressBar for the given component.
79+ pub ( crate ) fn create_progress_bar ( & mut self , component : & str ) {
80+ let pb = ProgressBar :: hidden ( ) ;
81+ pb. set_style (
6082 ProgressStyle :: with_template (
61- "[{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
83+ "{msg:>12.bold} [{bar:40}] {bytes}/{total_bytes} ({bytes_per_sec}, ETA: {eta})" ,
6284 )
6385 . unwrap ( )
6486 . progress_chars ( "## " ) ,
6587 ) ;
88+ pb. set_message ( component. to_string ( ) ) ;
89+ self . multi_progress_bars . add ( pb. clone ( ) ) ;
90+ self . file_progress_bars . insert ( component. to_string ( ) , pb) ;
91+ }
92+
93+ /// Sets the length for a new ProgressBar and gives it a style.
94+ pub ( crate ) fn content_length_received ( & mut self , content_len : u64 , file : & str ) {
95+ if let Some ( pb) = self . find_progress_bar ( file) {
96+ pb. set_length ( content_len) ;
97+ }
6698 }
6799
68100 /// 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 ( ) ) ;
101+ pub ( crate ) fn data_received ( & mut self , len : usize , file : & str ) {
102+ if let Some ( pb ) = self . find_progress_bar ( file ) {
103+ pb . inc ( len as u64 ) ;
72104 }
73- self . progress_bar . inc ( len as u64 ) ;
74105 }
75106
76107 /// 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 ( ) ;
108+ pub ( crate ) fn download_finished ( & mut self , file : & str ) {
109+ if let Some ( pb) = self . find_progress_bar ( file) {
110+ pb. set_style (
111+ ProgressStyle :: with_template (
112+ "{msg:>12.bold} downloaded {total_bytes} in {elapsed}." ,
113+ )
114+ . unwrap ( ) ,
115+ ) ;
116+ let msg = pb. message ( ) ;
117+ pb. finish_with_message ( msg) ;
118+ }
81119 }
82120}
0 commit comments