From 46e824468a077f3c35f267e70a04d412cce4a29f Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Sat, 23 Dec 2023 14:16:22 +0000 Subject: [PATCH] Set up ratatui and demonstrate event handling. I've had to put the event-reading in another thread, because I couldn't see any way to tie extra fds into ratatui's poll loop. So instead I'm going to have to make subthreads communicate to the main loop via an interthread channel. --- Cargo.toml | 1 + src/main.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 5f6a2c0..164d99f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" chrono = { version = "0.4.31", features = ["serde"] } crossterm = "0.27.0" html2text = "0.9.0" +ratatui = "0.25.0" reqwest = { version = "0.11.23", features = ["blocking"] } serde = { version = "1.0.193", features = ["derive"] } serde_json = "1.0.108" diff --git a/src/main.rs b/src/main.rs index 9ea485a..22fc65c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,22 @@ use mastodonochrome::OurError; use mastodonochrome::auth::AuthConfig; use std::io::Read; -fn main() -> Result<(), mastodonochrome::OurError> { +use crossterm::{ + event::{self, Event, KeyCode, KeyEventKind}, + terminal::{ + disable_raw_mode, enable_raw_mode, EnterAlternateScreen, + LeaveAlternateScreen, + }, + ExecutableCommand, +}; +use ratatui::{ + prelude::{CrosstermBackend, Stylize, Terminal}, + widgets::{Paragraph, Wrap}, +}; +use std::io::stdout; + +#[allow(unused)] +fn streaming(auth: &AuthConfig) -> Result<(), mastodonochrome::OurError> { let auth = AuthConfig::load()?; let client = reqwest::blocking::Client::new(); @@ -44,3 +59,54 @@ fn main() -> Result<(), mastodonochrome::OurError> { Ok(()) } + +fn main() -> std::io::Result<()> { + stdout().execute(EnterAlternateScreen)?; + enable_raw_mode()?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + terminal.clear()?; + + let (sender, receiver) = std::sync::mpsc::sync_channel(1); + + let _term_input_thread = std::thread::spawn(move || { + while let Ok(ev) = event::read() { + if let Err(_) = sender.send(ev) { + break; + } + } + }); + + loop { + terminal.draw(|frame| { + let area = frame.size(); + dbg!("sqook!", std::time::SystemTime::now()); + frame.render_widget( + Paragraph::new("Hello Ratatui! (press 'q' to quit)") + .white() + .on_blue() + .wrap(Wrap { trim: true }), + area, + ); + })?; + + match receiver.recv() { + Err(_) => break, + Ok(ev) => { + dbg!(&ev); + match ev { + Event::Key(key) => { + if key.kind == KeyEventKind::Press + && key.code == KeyCode::Char('q') + { + break; + } + }, + _ => (), + } + }, + } + } + stdout().execute(LeaveAlternateScreen)?; + disable_raw_mode()?; + Ok(()) +} -- 2.30.2