@@ -28,6 +28,7 @@ struct UiState {
2828 paused : bool ,
2929 phase : Phase ,
3030 info : String ,
31+ comments : Option < String > ,
3132
3233 dl_series : Vec < u64 > ,
3334 ul_series : Vec < u64 > ,
@@ -92,6 +93,7 @@ impl Default for UiState {
9293 paused : false ,
9394 phase : Phase :: IdleLatency ,
9495 info : String :: new ( ) ,
96+ comments : None ,
9597 dl_series : Vec :: new ( ) ,
9698 ul_series : Vec :: new ( ) ,
9799 idle_lat_series : Vec :: new ( ) ,
@@ -143,6 +145,52 @@ impl Default for UiState {
143145 }
144146}
145147
148+ fn push_wrapped_status_kv (
149+ out : & mut Vec < Line < ' static > > ,
150+ label : & str ,
151+ value : & str ,
152+ status_area_width : u16 ,
153+ ) {
154+ let value = value. trim ( ) ;
155+ if value. is_empty ( ) {
156+ return ;
157+ }
158+
159+ // Account for borders (2 chars on each side)
160+ let usable_width = status_area_width. saturating_sub ( 4 ) . max ( 1 ) ;
161+ let label_text = format ! ( "{label}:" ) ;
162+ let label_width = label_text. chars ( ) . count ( ) as u16 ;
163+
164+ let value_chars: Vec < char > = value. chars ( ) . collect ( ) ;
165+ let mut remaining = value_chars. as_slice ( ) ;
166+ let mut first = true ;
167+
168+ while !remaining. is_empty ( ) {
169+ let line_width = if first {
170+ usable_width. saturating_sub ( label_width + 1 ) . max ( 1 )
171+ } else {
172+ usable_width. saturating_sub ( 2 ) . max ( 1 )
173+ } ;
174+
175+ let chars_to_take = ( remaining. len ( ) as u16 ) . min ( line_width) as usize ;
176+ let ( line_chars, rest) = remaining. split_at ( chars_to_take) ;
177+ let line_text: String = line_chars. iter ( ) . collect ( ) ;
178+
179+ if first {
180+ out. push ( Line :: from ( vec ! [
181+ Span :: styled( label_text. clone( ) , Style :: default ( ) . fg( Color :: Gray ) ) ,
182+ Span :: raw( " " ) ,
183+ Span :: raw( line_text) ,
184+ ] ) ) ;
185+ first = false ;
186+ } else {
187+ out. push ( Line :: from ( vec ! [ Span :: raw( " " ) , Span :: raw( line_text) ] ) ) ;
188+ }
189+
190+ remaining = rest;
191+ }
192+ }
193+
146194impl UiState {
147195 fn push_series ( series : & mut Vec < u64 > , v : u64 ) {
148196 const MAX : usize = 120 ;
@@ -250,6 +298,7 @@ pub async fn run(args: Cli) -> Result<()> {
250298 let mut state = UiState {
251299 phase : Phase :: IdleLatency ,
252300 auto_save : args. auto_save ,
301+ comments : args. comments . clone ( ) ,
253302 ..Default :: default ( )
254303 } ;
255304 state. initial_history_load_size = initial_load;
@@ -1280,12 +1329,17 @@ fn draw_dashboard(area: Rect, f: &mut ratatui::Frame, state: &UiState) {
12801329 ) ,
12811330 ] ) ] ;
12821331
1332+ // Custom comments (wrapping to fit status area)
1333+ if let Some ( comments) = state. comments . as_deref ( ) {
1334+ push_wrapped_status_kv ( & mut status_lines, "Comments" , comments, main[ 3 ] . width ) ;
1335+ }
1336+
12831337 // Info line - split into two lines if it contains a saved path, with wrapping
12841338 if state. info . starts_with ( "Saved:" ) || state. info . starts_with ( "Saved (verifying):" ) {
12851339 // Split into label and path
12861340 if let Some ( colon_pos) = state. info . find ( ':' ) {
12871341 let ( label, path) = state. info . split_at ( colon_pos + 1 ) ;
1288- let label_text = label. trim ( ) ;
1342+ let label_text = label. trim ( ) . to_string ( ) ;
12891343 let path_str = path. trim ( ) ;
12901344
12911345 // Wrap the path to fit within available width
@@ -1313,7 +1367,7 @@ fn draw_dashboard(area: Rect, f: &mut ratatui::Frame, state: &UiState) {
13131367 if is_first_path_line {
13141368 // First line - include label and first part of path
13151369 status_lines. push ( Line :: from ( vec ! [
1316- Span :: styled( label_text, Style :: default ( ) . fg( Color :: Gray ) ) ,
1370+ Span :: styled( label_text. clone ( ) , Style :: default ( ) . fg( Color :: Gray ) ) ,
13171371 Span :: raw( " " ) ,
13181372 Span :: raw( line_text) ,
13191373 ] ) ) ;
@@ -1328,13 +1382,13 @@ fn draw_dashboard(area: Rect, f: &mut ratatui::Frame, state: &UiState) {
13281382 } else {
13291383 status_lines. push ( Line :: from ( vec ! [
13301384 Span :: styled( "Info: " , Style :: default ( ) . fg( Color :: Gray ) ) ,
1331- Span :: raw( & state. info) ,
1385+ Span :: raw( state. info. clone ( ) ) ,
13321386 ] ) ) ;
13331387 }
13341388 } else {
13351389 status_lines. push ( Line :: from ( vec ! [
13361390 Span :: styled( "Info: " , Style :: default ( ) . fg( Color :: Gray ) ) ,
1337- Span :: raw( & state. info) ,
1391+ Span :: raw( state. info. clone ( ) ) ,
13381392 ] ) ) ;
13391393 }
13401394
0 commit comments