mx-bookmarks

A small bookmarks tui based on the matrix protocol and MSC2771
git clone git://archive.git.mtrnord.blog/MTRNord/mx-bookmarks.git
Log | Files | Refs | LICENSE

main.rs (2475B)


      1 use crate::app::{ui, App};
      2 use crossterm::{
      3     event::{self, DisableMouseCapture, EnableMouseCapture, Event as CEvent, KeyCode},
      4     execute,
      5     terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
      6 };
      7 use std::{
      8     io::{stdout, Write},
      9     sync::mpsc,
     10     thread,
     11     time::{Duration, Instant},
     12 };
     13 use tui::{backend::CrosstermBackend, Terminal};
     14 mod app;
     15 mod tui_utils;
     16 mod extra_ruma;
     17 
     18 enum Event<I> {
     19     Input(I),
     20     Tick,
     21 }
     22 
     23 #[tokio::main]
     24 pub async fn main() -> anyhow::Result<()>{
     25     enable_raw_mode()?;
     26 
     27     let mut stdout = stdout();
     28     execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
     29     let backend = CrosstermBackend::new(stdout);
     30 
     31     let mut terminal = Terminal::new(backend)?;
     32 
     33     // Setup input handling
     34     let (tx, rx) = mpsc::channel();
     35     let tick_rate = Duration::from_millis(250);
     36 
     37     thread::spawn(move || {
     38         let mut last_tick = Instant::now();
     39         loop {
     40             // poll for tick rate duration, if no events, sent tick event.
     41             let timeout = tick_rate
     42                 .checked_sub(last_tick.elapsed())
     43                 .unwrap_or_else(|| Duration::from_secs(0));
     44             if event::poll(timeout).unwrap() {
     45                 if let CEvent::Key(key) = event::read().unwrap() {
     46                     tx.send(Event::Input(key)).unwrap();
     47                 }
     48             }
     49             if last_tick.elapsed() >= tick_rate {
     50                 tx.send(Event::Tick).unwrap();
     51                 last_tick = Instant::now();
     52             }
     53         }
     54     });
     55 
     56     let mut app = App::new("Bookmarks", true);
     57 
     58     terminal.clear()?;
     59 
     60     loop {
     61         terminal.draw(|f| ui::draw(f, &mut app))?;
     62         match rx.recv()? {
     63             Event::Input(event) => match event.code {
     64                 KeyCode::Char('q') => {
     65                     disable_raw_mode()?;
     66                     execute!(
     67                         terminal.backend_mut(),
     68                         LeaveAlternateScreen,
     69                         DisableMouseCapture
     70                     )?;
     71                     terminal.show_cursor()?;
     72                     break;
     73                 }
     74                 KeyCode::Char(c) => app.on_key(c),
     75                 KeyCode::Left => app.on_left(),
     76                 KeyCode::Right => app.on_right(),
     77                 _ => {}
     78             },
     79             Event::Tick => {
     80                 app.on_tick();
     81             }
     82         }
     83         if app.should_quit {
     84             break;
     85         }
     86     }
     87 
     88     Ok(())
     89 }