chiark / gitweb /
Set up ratatui and demonstrate event handling.
authorSimon Tatham <anakin@pobox.com>
Sat, 23 Dec 2023 14:16:22 +0000 (14:16 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 23 Dec 2023 14:16:22 +0000 (14:16 +0000)
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
src/main.rs

index 5f6a2c0585f5c7232c67675b3e29d15caff582a9..164d99fbea6b4016c9a37be2c24cfebfcf42fac5 100644 (file)
@@ -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"
index 9ea485a74bb42c3ca006e373e0bacc4c321d7339..22fc65c6926e7d14d1d2d12911cd993b6ba17241 100644 (file)
@@ -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(())
+}