11use std:: error;
22
33use tui:: backend:: Backend ;
4- use tui:: layout:: { Constraint , Direction , Layout } ;
4+ use tui:: layout:: { Alignment , Constraint , Direction , Layout } ;
55use tui:: style:: { Color , Modifier , Style } ;
66use tui:: terminal:: Frame ;
7- use tui:: widgets:: { Block , Borders , Cell , Gauge , Row , Table } ;
7+ use tui:: widgets:: { Block , Borders , Cell , Gauge , Paragraph , Row , Table , Wrap } ;
8+ use crate :: interface:: page:: Page ;
9+ use crate :: interface:: page:: Page :: { MainPage , QrcodePage , InfoPage } ;
810
911use crate :: otp:: otp_element:: OTPElement ;
1012use crate :: interface:: table:: { fill_table, StatefulTable } ;
@@ -21,8 +23,10 @@ pub struct App {
2123 pub ( crate ) table : StatefulTable ,
2224 pub ( crate ) elements : Vec < OTPElement > ,
2325 progress : u16 ,
26+ /// Text to print replacing the percentage
2427 pub ( crate ) label_text : String ,
2528 pub ( crate ) print_percentage : bool ,
29+ pub ( crate ) current_page : Page ,
2630}
2731
2832impl App {
@@ -31,7 +35,7 @@ impl App {
3135 let mut title = String :: from ( env ! ( "CARGO_PKG_NAME" ) ) ;
3236 title. push_str ( " v" ) ;
3337 title. push_str ( env ! ( "CARGO_PKG_VERSION" ) ) ;
34- Self { running : true , title, table : StatefulTable :: new ( & elements) , elements, progress : percentage ( ) , label_text : String :: from ( "" ) , print_percentage : true , }
38+ Self { running : true , title, table : StatefulTable :: new ( & elements) , elements, progress : percentage ( ) , label_text : String :: from ( "" ) , print_percentage : true , current_page : MainPage , }
3539 }
3640
3741 /// Handles the tick event of the terminal.
@@ -49,6 +53,63 @@ impl App {
4953
5054 /// Renders the user interface widgets.
5155 pub fn render < B : Backend > ( & mut self , frame : & mut Frame < ' _ , B > ) {
56+ match & self . current_page {
57+ MainPage => self . render_table ( frame) ,
58+ QrcodePage => self . render_qrcode_page ( frame) ,
59+ InfoPage => self . render_info_page ( frame) ,
60+ }
61+ }
62+
63+ fn render_info_page < B : Backend > ( & self , frame : & mut Frame < ' _ , B > ) {
64+ let text = "Press:\n + -> Increment the HOTP counter\n - -> Decrement the HOTP counter\n
65+ k -> Show QRCode of the selected element\n Enter -> Copy the OTP Code to the clipboard\n q, CTRL-D, Esc -> Exit the application" ;
66+ let paragraph = Paragraph :: new ( text)
67+ . block ( Block :: default ( ) . title ( self . title . as_str ( ) ) . borders ( Borders :: ALL ) )
68+ . style ( Style :: default ( ) . fg ( Color :: White ) . bg ( Color :: Black ) )
69+ . alignment ( Alignment :: Center )
70+ . wrap ( Wrap { trim : true } ) ;
71+ self . render_paragraph ( frame, paragraph) ;
72+ }
73+
74+ fn render_qrcode_page < B : Backend > ( & self , frame : & mut Frame < ' _ , B > ) {
75+ let paragraph = if let Some ( i) = self . table . state . selected ( ) {
76+ if let Some ( element) = self . elements . get ( i) {
77+ let title = format ! ( "{} - {}" , element. issuer( ) , element. label( ) ) ;
78+ Paragraph :: new ( element. get_qrcode ( ) )
79+ . block ( Block :: default ( ) . title ( title) . borders ( Borders :: ALL ) )
80+ . style ( Style :: default ( ) . fg ( Color :: White ) . bg ( Color :: Black ) )
81+ . alignment ( Alignment :: Center )
82+ . wrap ( Wrap { trim : true } )
83+ }
84+ else {
85+ Paragraph :: new ( "No element is selected" )
86+ . block ( Block :: default ( ) . title ( "Nope" ) . borders ( Borders :: ALL ) )
87+ . style ( Style :: default ( ) . fg ( Color :: White ) . bg ( Color :: Black ) )
88+ . alignment ( Alignment :: Center )
89+ . wrap ( Wrap { trim : true } )
90+ }
91+
92+ }
93+ else {
94+ Paragraph :: new ( "No element is selected" )
95+ . block ( Block :: default ( ) . title ( "Nope" ) . borders ( Borders :: ALL ) )
96+ . style ( Style :: default ( ) . fg ( Color :: White ) . bg ( Color :: Black ) )
97+ . alignment ( Alignment :: Center )
98+ . wrap ( Wrap { trim : true } )
99+ } ;
100+ self . render_paragraph ( frame, paragraph) ;
101+ }
102+
103+ fn render_paragraph < B : Backend > ( & self , frame : & mut Frame < ' _ , B > , paragraph : Paragraph ) {
104+ let rects = Layout :: default ( )
105+ . direction ( Direction :: Vertical )
106+ . constraints ( [ Constraint :: Percentage ( 100 ) ] . as_ref ( ) )
107+ . split ( frame. size ( ) ) ;
108+
109+ frame. render_widget ( paragraph, rects[ 0 ] ) ;
110+ }
111+
112+ fn render_table < B : Backend > ( & mut self , frame : & mut Frame < ' _ , B > ) {
52113 let rects = Layout :: default ( )
53114 . direction ( Direction :: Vertical )
54115 . constraints ( [ Constraint :: Percentage ( 95 ) , Constraint :: Percentage ( 5 ) ] . as_ref ( ) )
@@ -107,4 +168,5 @@ impl App {
107168 frame. render_stateful_widget ( t, rects[ 0 ] , & mut self . table . state ) ;
108169 frame. render_widget ( progress_bar, rects[ 1 ] ) ;
109170 }
171+
110172}
0 commit comments