@@ -4,15 +4,18 @@ use ratatui::{
44 prelude:: * ,
55 style:: { Style , Stylize } ,
66 text:: Line ,
7- widgets:: { Block , Borders , Paragraph , WidgetRef } ,
7+ widgets:: { Block , Borders , Paragraph , Widget , WidgetRef } ,
88} ;
9+ use std:: time:: { Duration , Instant } ;
910use tui_popup:: SizedWidgetRef ;
1011
1112#[ derive( Debug , Clone ) ]
1213pub struct LoadingWidget {
1314 message : String ,
1415 spinner_chars : Vec < char > ,
1516 current_frame : usize ,
17+ last_update : Instant ,
18+ frame_duration : Duration ,
1619}
1720
1821impl LoadingWidget {
@@ -21,15 +24,29 @@ impl LoadingWidget {
2124 message : message. to_string ( ) ,
2225 spinner_chars : vec ! [ '⠋' , '⠙' , '⠹' , '⠸' , '⠼' , '⠴' , '⠦' , '⠧' , '⠇' , '⠏' ] ,
2326 current_frame : 0 ,
27+ last_update : Instant :: now ( ) ,
28+ frame_duration : Duration :: from_millis ( 100 ) , // 10 FPS animation
2429 }
2530 }
2631
2732 pub fn next_frame ( & mut self ) {
2833 self . current_frame = ( self . current_frame + 1 ) % self . spinner_chars . len ( ) ;
34+ self . last_update = Instant :: now ( ) ;
35+ }
36+
37+ pub fn update_animation ( & mut self ) {
38+ let now = Instant :: now ( ) ;
39+ if now. duration_since ( self . last_update ) >= self . frame_duration {
40+ self . next_frame ( ) ;
41+ }
2942 }
3043
3144 fn get_spinner_char ( & self ) -> char {
32- self . spinner_chars [ self . current_frame ]
45+ // Calculate current frame based on elapsed time for automatic animation
46+ let elapsed = Instant :: now ( ) . duration_since ( self . last_update ) ;
47+ let additional_frames = ( elapsed. as_millis ( ) / self . frame_duration . as_millis ( ) ) as usize ;
48+ let current_frame = ( self . current_frame + additional_frames) % self . spinner_chars . len ( ) ;
49+ self . spinner_chars [ current_frame]
3350 }
3451}
3552
0 commit comments