1pub mod app;
14pub mod keyboard_help;
15pub mod openapi;
16pub mod openapi_sync;
17pub mod path_picker;
18pub mod screens;
19pub mod text_search;
20pub mod utils;
21
22use anyhow::Result;
23use std::time::Duration;
24
25use crate::client::RommClient;
26use crate::config::{openapi_cache_path, should_check_updates, Config};
27
28use self::app::App;
29use self::openapi_sync::sync_openapi_registry;
30use self::screens::connected_splash::StartupSplash;
31use self::screens::setup_wizard::SetupWizard;
32
33fn install_panic_hook() {
34 let original_hook = std::panic::take_hook();
35 std::panic::set_hook(Box::new(move |panic| {
36 let _ = crossterm::terminal::disable_raw_mode();
37 let _ = crossterm::execute!(
38 std::io::stdout(),
39 crossterm::terminal::LeaveAlternateScreen,
40 crossterm::event::DisableMouseCapture
41 );
42 original_hook(panic);
43 }));
44}
45
46fn startup_splash_for(
47 from_setup_wizard: bool,
48 config: &Config,
49 server_version: &Option<String>,
50) -> Option<StartupSplash> {
51 if from_setup_wizard {
52 return Some(StartupSplash::new(
53 config.base_url.clone(),
54 server_version.clone(),
55 ));
56 }
57 if server_version.is_some() {
58 return Some(StartupSplash::new(
59 config.base_url.clone(),
60 server_version.clone(),
61 ));
62 }
63 None
64}
65
66async fn run_started(client: RommClient, config: Config, from_setup_wizard: bool) -> Result<()> {
67 install_panic_hook();
68 let cache_path = openapi_cache_path()?;
69 let (registry, server_version) = sync_openapi_registry(&client, &cache_path).await?;
70 let startup_update = if should_check_updates() {
71 match tokio::time::timeout(Duration::from_secs(2), crate::update::check_for_update()).await
72 {
73 Ok(Ok(status)) if status.should_update => Some(status),
74 _ => None,
75 }
76 } else {
77 None
78 };
79
80 let splash = startup_splash_for(from_setup_wizard, &config, &server_version);
81 let mut app = App::new(
82 client,
83 config,
84 registry,
85 server_version,
86 splash,
87 startup_update,
88 );
89 app.run().await
90}
91
92pub async fn run(client: RommClient, config: Config) -> Result<()> {
94 run_started(client, config, false).await
95}
96
97pub async fn run_interactive(verbose: bool) -> Result<()> {
99 let (from_wizard, config) = match crate::config::load_config() {
100 Ok(c) => (false, c),
101 Err(_) => (true, SetupWizard::new().run(verbose).await?),
102 };
103 let client = RommClient::new(&config, verbose)?;
104 run_started(client, config, from_wizard).await
105}