Support 'q', Esc and 'C-c' user inputs
This commit is contained in:
		
							
								
								
									
										79
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -1,6 +1,11 @@
 | 
				
			|||||||
use async_std::task;
 | 
					use async_std::task;
 | 
				
			||||||
use clap::{App, Arg, ArgMatches, SubCommand};
 | 
					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::{Alert, Clock, Config, Status};
 | 
				
			||||||
use domasi::Pomodoro;
 | 
					use domasi::Pomodoro;
 | 
				
			||||||
use std::io::{stdout, Write};
 | 
					use std::io::{stdout, Write};
 | 
				
			||||||
@@ -52,29 +57,43 @@ pub fn start(args: &ArgMatches) {
 | 
				
			|||||||
    let alert = Alert::new(&audio_path, &default_device);
 | 
					    let alert = Alert::new(&audio_path, &default_device);
 | 
				
			||||||
    let mut pomodoro = Pomodoro::new(&alert);
 | 
					    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 {
 | 
					    // UI Thread
 | 
				
			||||||
            if let Ok(status) = rx.recv() {
 | 
					    thread::spawn(move || loop {
 | 
				
			||||||
                loop {
 | 
					        if let Ok(status) = rx.recv() {
 | 
				
			||||||
                    let (remaining, string) = Clock::get_formatted_string(status);
 | 
					            loop {
 | 
				
			||||||
                    print_overwrite(&string);
 | 
					                let (remaining, string) = Clock::get_formatted_string(status);
 | 
				
			||||||
 | 
					                print_overwrite(&string);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    // Super fun race condition that you gotta handle better :)
 | 
					                // Super fun race condition that you gotta handle better :)
 | 
				
			||||||
                    if remaining < 1 {
 | 
					                if remaining < 1 {
 | 
				
			||||||
                        break;
 | 
					                    break;
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    thread::sleep(Clock::get_polling_interval());
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                thread::sleep(Clock::get_polling_interval());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // User Input Thread
 | 
				
			||||||
 | 
					    thread::spawn(|| {
 | 
				
			||||||
 | 
					        setup_user_input().unwrap();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    task::block_on(async {
 | 
				
			||||||
        pomodoro.start(config, tx).await;
 | 
					        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) {
 | 
					fn print_overwrite(text: &str) {
 | 
				
			||||||
    let mut stdout = stdout();
 | 
					    let mut stdout = stdout();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,3 +103,31 @@ fn print_overwrite(text: &str) {
 | 
				
			|||||||
    stdout.queue(cursor::RestorePosition).unwrap();
 | 
					    stdout.queue(cursor::RestorePosition).unwrap();
 | 
				
			||||||
    stdout.flush().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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user