@@ -15,10 +15,18 @@ use tui_input::backend::crossterm::EventHandler as _;
1515
1616use crate :: ui:: { KeyboardHandler , ModalResult , UiModal , input_value_and_pos, is_portrait} ;
1717
18+ #[ derive( PartialEq ) ]
19+ enum Overwrite {
20+ Reset ,
21+ Prompted ,
22+ Confirmed ,
23+ }
24+
1825pub ( crate ) struct SaveAsFileModal {
1926 filename : Input ,
2027 folder : Box < str > ,
2128 ext : Box < str > ,
29+ overwrite : Overwrite ,
2230}
2331
2432impl UiModal for SaveAsFileModal {
@@ -47,7 +55,7 @@ impl UiModal for SaveAsFileModal {
4755 . style ( Color :: White )
4856 . block ( Block :: bordered ( ) . light_blue ( ) )
4957 . render ( input_area, frame. buffer_mut ( ) ) ;
50- Self :: render_input_hints ( hints_area, frame) ;
58+ self . render_input_hints ( hints_area, frame) ;
5159
5260 frame. set_cursor_position ( Position {
5361 x : input_area. x + x,
@@ -61,14 +69,19 @@ impl KeyboardHandler for SaveAsFileModal {
6169 if key. code == KeyCode :: Esc {
6270 ModalResult :: Close
6371 } else if key. code == KeyCode :: Enter {
72+ if self . overwrite == Overwrite :: Prompted {
73+ self . overwrite = Overwrite :: Confirmed ;
74+ }
6475 let filename = self . filename . value ( ) . trim ( ) ;
6576 let valid = !filename. is_empty ( ) && !self . is_file_exists ( filename) ;
66- if valid {
77+ if valid || self . overwrite == Overwrite :: Confirmed {
6778 ModalResult :: Filename ( filename. to_owned ( ) )
6879 } else {
80+ self . overwrite = Overwrite :: Prompted ;
6981 ModalResult :: None
7082 }
7183 } else {
84+ self . overwrite = Overwrite :: Reset ;
7285 self . filename . handle_event ( & Event :: Key ( key) ) ;
7386 ModalResult :: None
7487 }
@@ -81,18 +94,29 @@ impl SaveAsFileModal {
8194 filename : Input :: new ( filename. to_owned ( ) ) ,
8295 folder : folder. into ( ) ,
8396 ext : ext. into ( ) ,
97+ overwrite : Overwrite :: Reset ,
8498 }
8599 }
86100
87- fn render_input_hints ( area : Rect , frame : & mut Frame ) {
88- let keystyle = Style :: default ( ) . green ( ) ;
89- let parts = Line :: from ( vec ! [
90- Span :: styled( "Enter" , keystyle) ,
91- Span :: raw( ": confirm " ) ,
92- Span :: styled( "Esc" , keystyle) ,
93- Span :: raw( ": close" ) ,
94- ] ) ;
95- Paragraph :: new ( parts) . render ( area, frame. buffer_mut ( ) ) ;
101+ fn render_input_hints ( & self , area : Rect , frame : & mut Frame ) {
102+ let line = if self . overwrite == Overwrite :: Prompted {
103+ let error = Style :: default ( ) . red ( ) . bold ( ) ;
104+ Line :: from ( vec ! [
105+ Span :: styled( "File already exists. Press " , error) ,
106+ Span :: styled( "Enter" , error. not_bold( ) ) ,
107+ Span :: styled( " again to overwrite" , error) ,
108+ ] )
109+ . centered ( )
110+ } else {
111+ let keystyle = Style :: default ( ) . green ( ) ;
112+ Line :: from ( vec ! [
113+ Span :: styled( "Enter" , keystyle) ,
114+ Span :: raw( ": confirm " ) ,
115+ Span :: styled( "Esc" , keystyle) ,
116+ Span :: raw( ": close" ) ,
117+ ] )
118+ } ;
119+ Paragraph :: new ( line) . render ( area, frame. buffer_mut ( ) ) ;
96120 }
97121
98122 fn is_file_exists ( & self , filename : & str ) -> bool {
0 commit comments