Skip to content

Commit d5086d3

Browse files
author
cht
committed
添加弹出窗口的功能
1 parent 973ba89 commit d5086d3

1 file changed

Lines changed: 123 additions & 34 deletions

File tree

src/main.rs

Lines changed: 123 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,25 @@ enum InputMode {
3232
Select,
3333
Popup,
3434
PopupEdit,
35+
SubscriptView,
3536
}
3637

3738
/// App holds the state of the application
3839
struct 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
}
5255
impl 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
}
87121
impl 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

Comments
 (0)