1pub mod app;
2pub mod image;
3pub mod inputs;
4pub mod io;
5pub mod utils;
6
7use crate::{
8 app::{ui, App, AppReturn},
9 io::IoEvent,
10};
11use crossterm::{
12 event::{DisableMouseCapture, EnableMouseCapture},
13 execute,
14 terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
15};
16use eyre::Result;
17use inputs::{events::Events, InputEvent};
18use std::{io::stdout, sync::Arc, time::Duration};
19use tui::{backend::CrosstermBackend, Terminal};
20
21pub async fn start_ui<'a>(app: &Arc<tokio::sync::Mutex<App<'a>>>, path: String) -> Result<()> {
22 let mut stdout = stdout();
23 enable_raw_mode()?;
24 execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
25 let backend = CrosstermBackend::new(stdout);
26 let mut terminal = Terminal::new(backend)?;
27 terminal.clear()?;
28 terminal.hide_cursor()?;
29
30 let tick_rate = Duration::from_millis(100);
31 let mut events = Events::new(tick_rate);
32
33 {
34 let mut app = app.lock().await;
35 app.dispatch(IoEvent::Initialize(path)).await;
36 }
37
38 loop {
39 let mut app = app.lock().await;
40
41 terminal.draw(|rect| ui::draw(rect, &mut app))?;
42
43 let result = match events.next().await {
44 InputEvent::Input(key) => app.do_action(key).await,
45 InputEvent::Tick => app.update_on_tick().await,
46 };
47
48 if result == AppReturn::Exit {
49 events.close();
50 break;
51 }
52 }
53
54 disable_raw_mode()?;
55 execute!(
56 terminal.backend_mut(),
57 LeaveAlternateScreen,
58 DisableMouseCapture
59 )?;
60 terminal.show_cursor()?;
61
62 Ok(())
63}