aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.rs80
-rw-r--r--src/event.rs37
-rw-r--r--src/main.rs7
3 files changed, 88 insertions, 36 deletions
diff --git a/src/app.rs b/src/app.rs
index f0ffff0..7ba3da8 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,21 +1,26 @@
use std::{
error::Error,
io::{stdout, Stdout},
- time::Duration,
};
-use crossterm::event::{poll, read, KeyCode, KeyModifiers};
+use crossterm::{
+ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
+ ExecutableCommand,
+};
use rand::Rng;
-use tokio::sync::mpsc::{channel, Receiver, Sender};
+use tokio::{
+ spawn,
+ sync::mpsc::{channel, Receiver, Sender},
+};
-use crate::event::Event;
+use crate::event::{handle_input, Event};
-const TICK_RATE: u64 = 1000 / 20;
+pub const TICK_RATE: u64 = 1000 / 20;
pub struct App {
stdout: Stdout,
quote: Vec<String>,
- event_tx: Sender<Event>,
+ pub event_tx: Sender<Event>,
event_rx: Receiver<Event>,
running: bool,
}
@@ -34,39 +39,44 @@ impl App {
}
}
- pub async fn run(&mut self) {
- todo!()
- }
+ pub async fn run(&mut self) -> Result<(), Box<dyn Error>> {
+ self.stdout.execute(EnterAlternateScreen)?;
+ enable_raw_mode()?;
+
+ let (ks_tx, ks_rx): (Sender<()>, Receiver<()>) = channel(1);
+ let ev = self.event_tx.clone();
+ spawn(async {
+ start_input_handler(ev, ks_rx).await;
+ });
- // TODO
- // - [ ] Pause on focus lost
- // - [ ] Invalidate on paste
- async fn handle_input(&mut self) -> Result<(), Box<dyn Error>> {
+ self.running = true;
while self.running {
- if poll(Duration::from_millis(TICK_RATE))? {
- match read()? {
- //crossterm::event::Event::FocusGained => todo!(),
- //crossterm::event::Event::FocusLost => todo!(),
- //crossterm::event::Event::Paste(_) => todo!(),
- crossterm::event::Event::Key(key_event) => {
- if key_event.code == KeyCode::Char('c')
- && key_event.modifiers == KeyModifiers::CONTROL
- {
- self.event_tx.send(Event::Terminate).await?;
- continue;
- }
- if key_event.code == KeyCode::Backspace {
- self.event_tx.send(Event::Backspace).await?;
- continue;
- }
- if let KeyCode::Char(c) = key_event.code {
- self.event_tx.send(Event::KeyPress(c)).await?;
- }
- }
- _ => (),
- }
+ self.process().await?;
+ }
+ let _ = ks_tx.send(());
+
+ disable_raw_mode()?;
+ self.stdout.execute(LeaveAlternateScreen)?;
+ return Ok(());
+ }
+
+ async fn process(&mut self) -> Result<(), Box<dyn Error>> {
+ match self.event_rx.recv().await.unwrap() {
+ Event::Terminate => {
+ self.running = false;
}
+ Event::KeyPress(_) => todo!(),
+ Event::Backspace => todo!(),
}
return Ok(());
}
}
+
+async fn start_input_handler(ev: Sender<Event>, mut kill_switch: Receiver<()>) {
+ loop {
+ tokio::select! {
+ _ = handle_input(&ev) => (),
+ _ = kill_switch.recv() => return,
+ }
+ }
+}
diff --git a/src/event.rs b/src/event.rs
index 1320c68..d5cdabe 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -1,5 +1,42 @@
+use std::{error::Error, time::Duration};
+
+use crossterm::event::{poll, read, KeyCode, KeyModifiers};
+use tokio::sync::mpsc::Sender;
+
+use crate::app::TICK_RATE;
+
pub enum Event {
Terminate,
KeyPress(char),
Backspace,
}
+
+// TODO
+// - [ ] Pause on focus lost
+// - [ ] Invalidate on paste
+pub async fn handle_input(sender: &Sender<Event>) -> Result<(), Box<dyn Error>> {
+ if poll(Duration::from_millis(TICK_RATE))? {
+ match read()? {
+ //crossterm::event::Event::FocusGained => todo!(),
+ //crossterm::event::Event::FocusLost => todo!(),
+ //crossterm::event::Event::Paste(_) => todo!(),
+ crossterm::event::Event::Key(key_event) => {
+ if key_event.code == KeyCode::Char('c')
+ && key_event.modifiers == KeyModifiers::CONTROL
+ {
+ sender.send(Event::Terminate).await?;
+ return Ok(());
+ }
+ if key_event.code == KeyCode::Backspace {
+ sender.send(Event::Backspace).await?;
+ return Ok(());
+ }
+ if let KeyCode::Char(c) = key_event.code {
+ sender.send(Event::KeyPress(c)).await?;
+ }
+ }
+ _ => (),
+ }
+ }
+ return Ok(());
+}
diff --git a/src/main.rs b/src/main.rs
index ba5277e..0365d5b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,6 +3,7 @@ pub mod event;
use std::{error::Error, fs::read_to_string, path::Path};
+use app::App;
use clap::Parser;
#[derive(Parser)]
@@ -44,8 +45,12 @@ fn generate_quotes(path: &Path) -> Result<Vec<Vec<String>>, Box<dyn Error>> {
}
#[tokio::main]
-async fn main() {
+async fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
let path = Path::new(&args.quote_folder);
let quotes = generate_quotes(&path).unwrap();
+ let mut app = App::new(&quotes);
+
+ app.run().await?;
+ return Ok(());
}
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj