@@ -32,22 +32,25 @@ enum InputMode {
3232 Select ,
3333 Popup ,
3434 PopupEdit ,
35+ SubscriptView ,
3536}
3637
3738/// App holds the state of the application
3839struct App {
3940 /// Current value of the input box
4041 input : String ,
41- v2ray_input : String ,
42+ settings_input : Vec < String > ,
4243 /// Current input mode
4344 input_mode : InputMode ,
4445 /// History of recorded messages
4546 messages : Vec < String > ,
4647 state : ListState ,
47- index : Option < usize > ,
48+ index_subscription : ListState ,
49+ index_settings : usize ,
4850 stateoflist : bool ,
4951 show_popup : bool ,
5052 informations : Vec < spider:: Information > ,
53+ subscription : Vec < String > ,
5154}
5255impl App {
5356 fn next ( & mut self ) {
@@ -62,7 +65,6 @@ impl App {
6265 None => 0 ,
6366 } ;
6467 self . state . select ( Some ( i) ) ;
65- self . index = Some ( i) ;
6668 }
6769
6870 fn previous ( & mut self ) {
@@ -77,25 +79,59 @@ impl App {
7779 None => 0 ,
7880 } ;
7981 self . state . select ( Some ( i) ) ;
80- self . index = Some ( i) ;
8182 }
8283
8384 fn unselect ( & mut self ) {
8485 self . state . select ( None ) ;
8586 }
87+ fn next_sub ( & mut self ) {
88+ let i = match self . index_subscription . selected ( ) {
89+ Some ( i) => {
90+ if i >= self . subscription . len ( ) - 1 {
91+ 0
92+ } else {
93+ i + 1
94+ }
95+ }
96+ None => 0 ,
97+ } ;
98+ self . index_subscription . select ( Some ( i) ) ;
99+ //self.index = Some(i);
100+ }
101+
102+ fn previous_sub ( & mut self ) {
103+ let i = match self . index_subscription . selected ( ) {
104+ Some ( i) => {
105+ if i == 0 {
106+ self . subscription . len ( ) - 1
107+ } else {
108+ i - 1
109+ }
110+ }
111+ None => 0 ,
112+ } ;
113+ self . index_subscription . select ( Some ( i) ) ;
114+ //self.index = Some(i);
115+ }
116+
117+ fn unselect_sub ( & mut self ) {
118+ self . index_subscription . select ( None ) ;
119+ }
86120}
87121impl Default for App {
88122 fn default ( ) -> App {
89123 App {
90124 input : String :: new ( ) ,
91- v2ray_input : String :: new ( ) ,
125+ settings_input : vec ! [ String :: new( ) , String :: new ( ) ] ,
92126 input_mode : InputMode :: Normal ,
93127 messages : Vec :: new ( ) ,
94128 state : ListState :: default ( ) ,
95- index : None ,
129+ index_subscription : ListState :: default ( ) ,
130+ index_settings : 0 ,
96131 stateoflist : false ,
97132 show_popup : false ,
98133 informations : Vec :: new ( ) ,
134+ subscription : Vec :: new ( ) ,
99135 }
100136 }
101137}
@@ -118,10 +154,9 @@ fn main() -> Result<(), Box<dyn Error>> {
118154 . collect ( ) ;
119155 app. stateoflist = true ;
120156 app. state . select ( Some ( 0 ) ) ;
121- app. index = Some ( 0 ) ;
122157 app. informations = informations;
123158 }
124- app. v2ray_input = utils:: start_v2core ( ) ;
159+ app. settings_input [ 0 ] = utils:: start_v2core ( ) ;
125160 let res = run_app ( & mut terminal, app) ;
126161
127162 // restore terminal
@@ -176,7 +211,6 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
176211 //app.messages = list[0].clone();
177212 app. stateoflist = true ;
178213 app. state . select ( Some ( 0 ) ) ;
179- app. index = Some ( 0 ) ;
180214 for alist in & list[ 0 ] {
181215 let information = spider:: Information :: new ( alist. to_string ( ) ) ;
182216 app. informations . push ( information. clone ( ) ) ;
@@ -221,7 +255,7 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
221255 app. input_mode = InputMode :: Normal ;
222256 }
223257 KeyCode :: F ( 5 ) => {
224- if let Some ( index) = app. index {
258+ if let Some ( index) = app. state . selected ( ) {
225259 let home = env:: var ( "HOME" ) . unwrap ( ) ;
226260 utils:: create_json_file (
227261 utils:: Save :: Running ,
@@ -232,7 +266,7 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
232266 |e| panic ! ( "failed to execute process: {}" , e) ,
233267 ) ;
234268 Command :: new ( "nohup" )
235- . arg ( app. v2ray_input . clone ( ) )
269+ . arg ( app. settings_input [ 0 ] . clone ( ) )
236270 . arg ( "-config" )
237271 . arg ( home. clone ( ) + "/.config/tv2ray/running.json" )
238272 . arg ( ">" )
@@ -257,14 +291,15 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
257291 KeyCode :: Char ( 'e' ) => {
258292 app. input_mode = InputMode :: PopupEdit ;
259293 }
294+
260295 KeyCode :: Char ( 's' ) => {
261296 if let Err ( err) = utils:: create_json_file (
262297 utils:: Save :: V2ray ,
263298 format ! (
264299 "{{
265300 \" v2core\" :\" {}\"
266301}}" ,
267- app. v2ray_input
302+ app. settings_input [ 0 ]
268303 ) ,
269304 ) {
270305 panic ! ( "{}" , err) ;
@@ -277,10 +312,45 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<(
277312 KeyCode :: Esc => app. input_mode = InputMode :: Popup ,
278313 // here todo
279314 KeyCode :: Char ( c) => {
280- app. v2ray_input . push ( c) ;
315+ app. settings_input [ app . index_settings ] . push ( c) ;
281316 }
282317 KeyCode :: Backspace => {
283- app. v2ray_input . pop ( ) ;
318+ app. settings_input [ app. index_settings ] . pop ( ) ;
319+ }
320+ KeyCode :: Down => {
321+ if app. index_settings == 0 {
322+ app. index_settings = 1 ;
323+ } else if !app. subscription . is_empty ( ) {
324+ app. input_mode = InputMode :: SubscriptView ;
325+ app. index_subscription . select ( Some ( 0 ) ) ;
326+ } else {
327+ app. index_settings = 0 ;
328+ }
329+ }
330+ KeyCode :: Up => {
331+ if app. index_settings == 1 {
332+ app. index_settings = 0 ;
333+ } else if !app. subscription . is_empty ( ) {
334+ app. input_mode = InputMode :: SubscriptView ;
335+ app. index_subscription . select ( Some ( 0 ) ) ;
336+ } else {
337+ app. index_settings = 1 ;
338+ }
339+ }
340+ KeyCode :: Enter => {
341+ app. subscription . push ( app. settings_input [ 1 ] . clone ( ) ) ;
342+ }
343+ _ => { }
344+ }
345+ }
346+ InputMode :: SubscriptView => {
347+ match key. code {
348+ KeyCode :: Up => app. previous_sub ( ) ,
349+ KeyCode :: Down => app. next_sub ( ) ,
350+ KeyCode :: Esc => {
351+ app. index_settings =0 ;
352+ app. unselect_sub ( ) ;
353+ app. input_mode = InputMode :: PopupEdit ;
284354 }
285355 _ => { }
286356 }
@@ -305,7 +375,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
305375 . split ( f. size ( ) ) ;
306376
307377 let ( msg, style) = match app. input_mode {
308- InputMode :: Normal | InputMode :: Popup | InputMode :: PopupEdit => (
378+ InputMode :: Normal | InputMode :: Popup | InputMode :: PopupEdit | InputMode :: SubscriptView => (
309379 vec ! [
310380 Span :: raw( "Press " ) ,
311381 Span :: styled( "q" , Style :: default ( ) . add_modifier( Modifier :: BOLD ) ) ,
@@ -388,7 +458,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
388458 // popup wiget
389459 f. render_stateful_widget ( messages, bottom_chunks[ 0 ] , & mut app. state ) ;
390460 //let block : Box<dyn Widget> = {
391- if let Some ( a) = app. index {
461+ if let Some ( a) = app. state . selected ( ) {
392462 let list = app. informations [ a] . information_to_list ( ) ;
393463 let messages: Vec < ListItem > = list
394464 . iter ( )
@@ -409,22 +479,9 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
409479
410480 if app. show_popup {
411481 //let block = Block::default().title("About port").borders(Borders::ALL);
412- let inputpop = Paragraph :: new ( app. v2ray_input . as_ref ( ) )
413- . style ( match app. input_mode {
414- InputMode :: PopupEdit => Style :: default ( ) . fg ( Color :: Yellow ) ,
415- _ => Style :: default ( ) ,
416- } )
417- . block ( Block :: default ( ) . borders ( Borders :: ALL ) . title ( "v2ray-core" ) ) ;
418- //f.render_widget(input, chunks[1]);
419- let area = centered_rect ( 60 , 20 , f. size ( ) ) ;
420- //let settings :Vec<Paragraph> = app
421- // .settings
422- // .iter()
423- // .map(|asetting| Paragraph::new(app.v2ray_input.as_ref())
424- // .style(Style::default())
425- // .block(Block::default().borders(Borders::ALL).title(asetting.clone())))
426482
427- // .collect();
483+ //f.render_widget(input, chunks[1]);
484+ let area = centered_rect ( 80 , 50 , f. size ( ) ) ;
428485
429486 let chunk = Layout :: default ( )
430487 . direction ( Direction :: Vertical )
@@ -433,6 +490,7 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
433490 [
434491 Constraint :: Length ( 1 ) ,
435492 Constraint :: Length ( 3 ) ,
493+ Constraint :: Length ( 3 ) ,
436494 Constraint :: Min ( 1 ) ,
437495 ]
438496 . as_ref ( ) ,
@@ -448,15 +506,46 @@ fn ui<B: Backend>(f: &mut Frame<B>, app: &mut App) {
448506 text. patch_style ( style) ;
449507 let title = Paragraph :: new ( text) ;
450508 f. render_widget ( title, chunk[ 0 ] ) ;
509+ let inputpop = Paragraph :: new ( app. settings_input [ 0 ] . as_ref ( ) )
510+ . style ( match ( & app. input_mode , app. index_settings ) {
511+ ( InputMode :: PopupEdit , 0 ) => Style :: default ( ) . fg ( Color :: Yellow ) ,
512+ ( _, _) => Style :: default ( ) ,
513+ } )
514+ . block ( Block :: default ( ) . borders ( Borders :: ALL ) . title ( "v2ray-core" ) ) ;
451515 f. render_widget ( inputpop, chunk[ 1 ] ) ;
452-
516+ let inputpop2 = Paragraph :: new ( app. settings_input [ 1 ] . as_ref ( ) )
517+ . style ( match ( & app. input_mode , app. index_settings ) {
518+ ( InputMode :: PopupEdit , 1 ) => Style :: default ( ) . fg ( Color :: Yellow ) ,
519+ ( _, _) => Style :: default ( ) ,
520+ } )
521+ . block ( Block :: default ( ) . borders ( Borders :: ALL ) . title ( "add domins" ) ) ;
522+ f. render_widget ( inputpop2, chunk[ 2 ] ) ;
523+ let subscription : Vec < ListItem > = app
524+ . subscription
525+ . iter ( )
526+ . enumerate ( )
527+ . map ( |( i, m) |{
528+ let content = vec ! [ Spans :: from( Span :: raw( format!( "{}:{}" , i, m) ) ) ] ;
529+ ListItem :: new ( content)
530+ } )
531+ . collect ( ) ;
532+ let subscription = List :: new ( subscription)
533+ . block ( Block :: default ( ) . borders ( Borders :: ALL ) . title ( "List" ) )
534+ . highlight_style (
535+ Style :: default ( )
536+ . bg ( Color :: LightBlue )
537+ . add_modifier ( Modifier :: BOLD ) ,
538+ )
539+ . highlight_symbol ( ">> " ) ;
540+ f. render_stateful_widget ( subscription, chunk[ 3 ] , & mut app. index_subscription ) ;
453541 if let InputMode :: PopupEdit = app. input_mode {
542+ let index = app. index_settings ;
454543 // Make the cursor visible and ask tui-rs to put it at the specified coordinates after rendering
455544 f. set_cursor (
456545 // Put cursor past the end of the input text
457- chunk[ 1 ] . x + app. v2ray_input . width ( ) as u16 + 1 ,
546+ chunk[ index + 2 ] . x + app. settings_input [ index ] . width ( ) as u16 + 1 ,
458547 // Move one line down, from the border to the input line
459- chunk[ 1 ] . y + 1 ,
548+ chunk[ index + 1 ] . y + 1 ,
460549 )
461550 //InputMode::Normal | InputMode::Select | InputMode::Popup =>
462551 // Hide the cursor. `Frame` does this by default, so we don't need to do anything here
0 commit comments