From f95f0a846fae18d313d5c48c27c7d75c1657304b Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Mon, 25 May 2020 01:51:07 -0500 Subject: [PATCH] Support 'q', Esc and 'C-c' user inputs --- src/main.rs | 79 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/src/main.rs b/src/main.rs index 697c3f3..c949309 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,11 @@ use async_std::task; use clap::{App, Arg, ArgMatches, SubCommand}; -use crossterm::{cursor, terminal::Clear, terminal::ClearType, QueueableCommand}; +use crossterm::{ + cursor, + event::{poll, read, Event, KeyCode, KeyEvent, KeyModifiers}, + terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType}, + QueueableCommand, +}; use domasi::pomodoro::{Alert, Clock, Config, Status}; use domasi::Pomodoro; use std::io::{stdout, Write}; @@ -52,29 +57,43 @@ pub fn start(args: &ArgMatches) { let alert = Alert::new(&audio_path, &default_device); let mut pomodoro = Pomodoro::new(&alert); - task::block_on(async { - let (tx, rx): (Sender, Receiver) = channel(); + let (tx, rx): (Sender, Receiver) = channel(); - thread::spawn(move || loop { - if let Ok(status) = rx.recv() { - loop { - let (remaining, string) = Clock::get_formatted_string(status); - print_overwrite(&string); + // UI Thread + thread::spawn(move || loop { + if let Ok(status) = rx.recv() { + loop { + let (remaining, string) = Clock::get_formatted_string(status); + print_overwrite(&string); - // Super fun race condition that you gotta handle better :) - if remaining < 1 { - break; - } - - thread::sleep(Clock::get_polling_interval()); + // Super fun race condition that you gotta handle better :) + if remaining < 1 { + break; } - } - }); + thread::sleep(Clock::get_polling_interval()); + } + } + }); + + // User Input Thread + thread::spawn(|| { + setup_user_input().unwrap(); + }); + + task::block_on(async { pomodoro.start(config, tx).await; }); } +fn setup_user_input() -> crossterm::Result<()> { + enable_raw_mode()?; + + get_user_input()?; + + disable_raw_mode() +} + fn print_overwrite(text: &str) { let mut stdout = stdout(); @@ -84,3 +103,31 @@ fn print_overwrite(text: &str) { stdout.queue(cursor::RestorePosition).unwrap(); stdout.flush().unwrap(); } + +fn get_user_input() -> crossterm::Result<()> { + loop { + if poll(Clock::get_polling_interval())? { + if let Event::Key(event) = read()? { + handle_key_event(event); + } + } + } +} + +fn handle_key_event(event: KeyEvent) { + match event.code { + KeyCode::Char('c') => { + if let KeyModifiers::CONTROL = event.modifiers { + exit_domasi(1) + } + } + KeyCode::Esc | KeyCode::Char('q') => exit_domasi(0), + _ => {} + } +} + +fn exit_domasi(code: i32) { + disable_raw_mode().unwrap(); + + std::process::exit(code); +}