Support 'q', Esc and 'C-c' user inputs

This commit is contained in:
Rekai Musuka 2020-05-25 01:51:07 -05:00
parent b1b469f91f
commit f95f0a846f
1 changed files with 63 additions and 16 deletions

View File

@ -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<Status>, Receiver<Status>) = channel();
let (tx, rx): (Sender<Status>, Receiver<Status>) = 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);
}