Skip to main content

romm_cli/tui/screens/setup_wizard/
run.rs

1//! Standalone first-run setup event loop.
2
3use anyhow::{anyhow, Result};
4use crossterm::event::{self, DisableMouseCapture, EnableMouseCapture, Event};
5use crossterm::execute;
6use crossterm::terminal::{
7    disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
8};
9use ratatui::backend::CrosstermBackend;
10use ratatui::Terminal;
11use std::io::stdout;
12
13use crate::config::{default_theme_id, Config};
14use crate::tui::theme::{resolve_theme_or_default, RommStyles};
15
16use super::types::SetupWizard;
17
18impl SetupWizard {
19    pub async fn run(mut self, verbose: bool) -> Result<Config> {
20        enable_raw_mode()?;
21        let mut stdout = stdout();
22        execute!(
23            stdout,
24            EnterAlternateScreen,
25            EnableMouseCapture,
26            crossterm::event::EnableBracketedPaste
27        )?;
28        let backend = CrosstermBackend::new(stdout);
29        let mut terminal = Terminal::new(backend)?;
30        let theme = resolve_theme_or_default(&default_theme_id());
31
32        loop {
33            let styles = RommStyles::new(theme.as_ref());
34            terminal.draw(|f| {
35                let area = f.area();
36                self.render(f, area, &styles);
37                if let Some((x, y)) = self.cursor_pos(area) {
38                    f.set_cursor_position((x, y));
39                }
40            })?;
41
42            if event::poll(std::time::Duration::from_millis(100))? {
43                let ev = event::read()?;
44                let mut should_exit = false;
45
46                match ev {
47                    Event::Key(key) if self.handle_key(&key)? => {
48                        should_exit = true;
49                    }
50                    Event::Paste(text) => {
51                        self.handle_paste(&text);
52                    }
53                    _ => {}
54                }
55
56                if should_exit {
57                    disable_raw_mode()?;
58                    execute!(
59                        terminal.backend_mut(),
60                        crossterm::event::DisableBracketedPaste,
61                        LeaveAlternateScreen,
62                        DisableMouseCapture
63                    )?;
64                    terminal.show_cursor()?;
65                    return Err(anyhow!("setup cancelled"));
66                }
67
68                if self.testing {
69                    let styles = RommStyles::new(theme.as_ref());
70                    terminal.draw(|f| {
71                        let area = f.area();
72                        self.render(f, area, &styles);
73                    })?;
74                    let result = self.try_connect_and_persist(verbose).await;
75                    self.testing = false;
76                    match result {
77                        Ok(cfg) => {
78                            disable_raw_mode()?;
79                            execute!(
80                                terminal.backend_mut(),
81                                crossterm::event::DisableBracketedPaste,
82                                LeaveAlternateScreen,
83                                DisableMouseCapture
84                            )?;
85                            terminal.show_cursor()?;
86                            return Ok(cfg);
87                        }
88                        Err(e) => {
89                            self.error = Some(format!("{e:#}"));
90                        }
91                    }
92                }
93            }
94        }
95    }
96}