ssh_utils_lib/widgets/
popup_input_box.rs

1use crossterm::event::{self, Event, KeyCode, KeyEventKind};
2use ratatui::backend::Backend;
3use ratatui::style::Style;
4use ratatui::text::Line;
5use ratatui::widgets::{Block, Borders, Paragraph};
6use ratatui::Terminal;
7use anyhow::Result;
8
9use crate::helper;
10
11pub struct PopupInputBox {
12    title: String,
13    input: String,
14}
15
16impl PopupInputBox {
17    pub fn new(title: String) -> Self {
18        Self {
19            title,
20            input: String::new(),
21        }
22    }
23
24    fn render(&self) -> Paragraph {
25        let mask_text = "*".repeat(self.input.len());
26        let input_text = format!("{}", mask_text);
27        let content = vec![Line::from(input_text)];
28
29        Paragraph::new(content)
30            .block(
31                Block::default()
32                    .title(self.title.clone())
33                    .borders(Borders::ALL),
34            )
35            .style(Style::default())
36    }
37
38    fn input(&mut self, c: char) {
39        self.input.push(c);
40    }
41
42    fn backspace(&mut self) {
43        self.input.pop();
44    }
45
46    fn draw(&self, terminal: &mut Terminal<impl Backend>) -> Result<()> {
47        terminal.draw(|f| {
48            let area = helper::centered_rect(50, 60, f.area());
49            f.render_widget(self.render(), area)
50        })?;
51        Ok(())
52    }
53
54    pub fn run(&mut self, mut terminal: &mut Terminal<impl Backend>) -> Result<Option<String>> {
55        loop {
56            self.draw(&mut terminal)?;
57            if let Event::Key(key) = event::read()? {
58                if key.kind == KeyEventKind::Press {
59                    match key.code {
60                        KeyCode::Char(to_insert) => {
61                            self.input(to_insert);
62                        }
63                        KeyCode::Backspace => {
64                            self.backspace();
65                        }
66                        KeyCode::Enter => {
67                            return Ok(Some(self.input.clone()));
68                        }
69                        KeyCode::Esc => {
70                            return Ok(None);
71                        }
72                        _ => {}
73                    }
74                }
75            }
76        }
77    }
78}