feat: add y/n option to continue pmdr cycle or not
This commit is contained in:
parent
73c103b6e7
commit
d94926a235
|
@ -6,21 +6,31 @@ use std::fmt::{Display, Formatter, Result as FmtResult};
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default)]
|
static WORK_TIME: u64 = 1500; // Default: 1500 (25min)
|
||||||
pub struct Pomodoro {
|
static SHORT_BREAK_TIME: u64 = 300; // Default: 300 (5min)
|
||||||
|
static LONG_BREAK_TIME: u64 = 600; // Default: 600 (10min)
|
||||||
|
static POLLING_RATE: Duration = Duration::from_millis(100);
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct Domasi {
|
||||||
state: State,
|
state: State,
|
||||||
count: u64,
|
count: u64,
|
||||||
wait_start: Option<Instant>,
|
wait_start: Option<Instant>,
|
||||||
paused: PausedState,
|
paused: PausedState,
|
||||||
}
|
}
|
||||||
|
|
||||||
static POMODORO_CYCLES: u64 = 5;
|
impl Default for Domasi {
|
||||||
static WORK_TIME: u64 = 1500; // Default: 1500 (25min)
|
fn default() -> Self {
|
||||||
static SHORT_BREAK_TIME: u64 = 300; // Default: 300 (5min)
|
Self {
|
||||||
static LONG_BREAK_TIME: u64 = 600; // Default: 600 (10min)
|
state: State::Start,
|
||||||
|
count: 0,
|
||||||
|
wait_start: None,
|
||||||
|
paused: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static POLLING_RATE: Duration = Duration::from_millis(100);
|
impl Domasi {
|
||||||
impl Pomodoro {
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
@ -28,9 +38,26 @@ impl Pomodoro {
|
||||||
pub fn start(&mut self, maybe_alert: Option<Alert>) -> crossterm::Result<()> {
|
pub fn start(&mut self, maybe_alert: Option<Alert>) -> crossterm::Result<()> {
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
|
|
||||||
loop {
|
'main: loop {
|
||||||
if let Status::Complete = self.poll(maybe_alert.as_ref()) {
|
if let Status::Complete = self.poll(maybe_alert.as_ref()) {
|
||||||
break;
|
let _ = Self::print("Start next session? (Y/N)");
|
||||||
|
|
||||||
|
'input: loop {
|
||||||
|
if let Event::Key(key_event) = event::read()? {
|
||||||
|
match key_event.code {
|
||||||
|
KeyCode::Char('y') | KeyCode::Char('Y') => {
|
||||||
|
*self = Self {
|
||||||
|
count: self.count,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
break 'input;
|
||||||
|
}
|
||||||
|
KeyCode::Char('n') | KeyCode::Char('N') => break 'main,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if event::poll(POLLING_RATE)? {
|
if event::poll(POLLING_RATE)? {
|
||||||
|
@ -73,7 +100,7 @@ impl Pomodoro {
|
||||||
fn notify_complete(&self) -> Result<(), Box<dyn Error>> {
|
fn notify_complete(&self) -> Result<(), Box<dyn Error>> {
|
||||||
let mut toast = notify_rust::Notification::new();
|
let mut toast = notify_rust::Notification::new();
|
||||||
toast.summary("Pomodoro cycle complete!");
|
toast.summary("Pomodoro cycle complete!");
|
||||||
toast.body("domasi will now exit.");
|
toast.body("Continue?");
|
||||||
toast.show()?;
|
toast.show()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -92,7 +119,7 @@ impl Pomodoro {
|
||||||
0 => "Time for your 1st work session.",
|
0 => "Time for your 1st work session.",
|
||||||
1 => "Time for your 2nd work session.",
|
1 => "Time for your 2nd work session.",
|
||||||
2 => "Time for your 3rd work session.",
|
2 => "Time for your 3rd work session.",
|
||||||
3 => "Time for your 4th work session.",
|
3 => "Time for your last work session.",
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,7 +127,6 @@ impl Pomodoro {
|
||||||
let mut toast = notify_rust::Notification::new();
|
let mut toast = notify_rust::Notification::new();
|
||||||
|
|
||||||
match self.state {
|
match self.state {
|
||||||
State::Inactive => {}
|
|
||||||
State::Work => {
|
State::Work => {
|
||||||
toast
|
toast
|
||||||
.summary(session_num(self.count))
|
.summary(session_num(self.count))
|
||||||
|
@ -119,6 +145,7 @@ impl Pomodoro {
|
||||||
.body(&cycle_count(self.count))
|
.body(&cycle_count(self.count))
|
||||||
.show()?;
|
.show()?;
|
||||||
}
|
}
|
||||||
|
State::UserWait | State::Start => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -150,8 +177,9 @@ impl Pomodoro {
|
||||||
|
|
||||||
self.state = new_state;
|
self.state = new_state;
|
||||||
self.wait_start = match new_state {
|
self.wait_start = match new_state {
|
||||||
State::Inactive => None,
|
State::UserWait => None,
|
||||||
State::Work | State::ShortBreak | State::LongBreak => Some(Instant::now()),
|
State::Work | State::ShortBreak | State::LongBreak => Some(Instant::now()),
|
||||||
|
State::Start => unreachable!("Domasi#next should never return State::Start"),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(alert) = maybe_alert {
|
if let Some(alert) = maybe_alert {
|
||||||
|
@ -162,10 +190,8 @@ impl Pomodoro {
|
||||||
self.display_time();
|
self.display_time();
|
||||||
}
|
}
|
||||||
Status::Complete => {
|
Status::Complete => {
|
||||||
println!("\rPomodoro cycle complete!");
|
|
||||||
let _ = self.notify_complete();
|
let _ = self.notify_complete();
|
||||||
}
|
}
|
||||||
Status::Inactive => {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
status
|
status
|
||||||
|
@ -174,7 +200,7 @@ impl Pomodoro {
|
||||||
fn display_time(&self) {
|
fn display_time(&self) {
|
||||||
if let Some(start) = self.wait_start {
|
if let Some(start) = self.wait_start {
|
||||||
let remainder: Clock = (Self::wait_times(self.state) - (Instant::now() - start)).into();
|
let remainder: Clock = (Self::wait_times(self.state) - (Instant::now() - start)).into();
|
||||||
let _ = Self::print(&format!("\r{} {}", self.state, remainder));
|
let _ = Self::print(&format!("{} {}", self.state, remainder));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +209,7 @@ impl Pomodoro {
|
||||||
let stop_time: Clock = (Self::wait_times(self.state)
|
let stop_time: Clock = (Self::wait_times(self.state)
|
||||||
- ((Instant::now() - self.paused.duration) - start))
|
- ((Instant::now() - self.paused.duration) - start))
|
||||||
.into();
|
.into();
|
||||||
let _ = Self::print(&format!("\r[PAUSED] {} {}", self.state, stop_time));
|
let _ = Self::print(&format!("[PAUSED] {} {}", self.state, stop_time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,9 +220,10 @@ impl Pomodoro {
|
||||||
// Empty String so that we can clear line before writing
|
// Empty String so that we can clear line before writing
|
||||||
// from the most-left side of the terminal again.
|
// from the most-left side of the terminal again.
|
||||||
//
|
//
|
||||||
// We write 24 spaces so that the entire line is always
|
// We write 25 spaces so that the entire line is always
|
||||||
// written over
|
// written over
|
||||||
handle.write_all(b"\r ")?;
|
handle.write_all(b"\r ")?;
|
||||||
|
handle.write_all("\r".as_bytes())?;
|
||||||
handle.write_all(text.as_bytes())?;
|
handle.write_all(text.as_bytes())?;
|
||||||
handle.flush()?;
|
handle.flush()?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -213,8 +240,9 @@ impl Pomodoro {
|
||||||
|
|
||||||
(Count::Increase, state)
|
(Count::Increase, state)
|
||||||
}
|
}
|
||||||
State::ShortBreak | State::Inactive => (Count::Remain, State::Work),
|
State::ShortBreak | State::Start => (Count::Remain, State::Work),
|
||||||
State::LongBreak => (Count::Remain, State::Inactive),
|
State::LongBreak => (Count::Remain, State::UserWait),
|
||||||
|
_ => unreachable!("Domasi#next should never be called on State::Inactive"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,13 +261,10 @@ impl Pomodoro {
|
||||||
Status::Active
|
Status::Active
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => match self.state {
|
||||||
if self.count / 4 == POMODORO_CYCLES {
|
State::UserWait if self.count % 4 == 0 => Status::Complete,
|
||||||
Status::Complete
|
_ => Status::NextState,
|
||||||
} else {
|
},
|
||||||
Status::NextState
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +273,7 @@ impl Pomodoro {
|
||||||
State::Work => Duration::from_secs(WORK_TIME),
|
State::Work => Duration::from_secs(WORK_TIME),
|
||||||
State::ShortBreak => Duration::from_secs(SHORT_BREAK_TIME),
|
State::ShortBreak => Duration::from_secs(SHORT_BREAK_TIME),
|
||||||
State::LongBreak => Duration::from_secs(LONG_BREAK_TIME),
|
State::LongBreak => Duration::from_secs(LONG_BREAK_TIME),
|
||||||
_ => unreachable!("Can not have Pomodoro state = State::Inactive and wait_start = Some(...) at the same time.")
|
_ => unreachable!("Can not have Domasi state = State::Inactive and wait_start = Some(...) at the same time.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,13 +349,13 @@ enum Status {
|
||||||
Paused,
|
Paused,
|
||||||
Active,
|
Active,
|
||||||
NextState,
|
NextState,
|
||||||
Inactive,
|
|
||||||
Complete,
|
Complete,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum State {
|
enum State {
|
||||||
Inactive,
|
Start,
|
||||||
|
UserWait,
|
||||||
Work,
|
Work,
|
||||||
ShortBreak,
|
ShortBreak,
|
||||||
LongBreak,
|
LongBreak,
|
||||||
|
@ -338,7 +363,7 @@ enum State {
|
||||||
|
|
||||||
impl Default for State {
|
impl Default for State {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
State::Inactive
|
State::UserWait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +373,8 @@ impl Display for State {
|
||||||
State::Work => f.write_str("Working:"),
|
State::Work => f.write_str("Working:"),
|
||||||
State::ShortBreak => f.write_str("Resting:"),
|
State::ShortBreak => f.write_str("Resting:"),
|
||||||
State::LongBreak => f.write_str("REALLY Resting:"),
|
State::LongBreak => f.write_str("REALLY Resting:"),
|
||||||
State::Inactive => f.write_str("Inactive:"),
|
State::UserWait => f.write_str("Inactive:"),
|
||||||
|
_ => unreachable!("State::Start should never be displayed."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
pub use alert::Alert;
|
pub use alert::Alert;
|
||||||
pub use pomodoro::Pomodoro;
|
pub use domasi::Domasi;
|
||||||
mod alert;
|
mod alert;
|
||||||
mod pomodoro;
|
mod domasi;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use directories::ProjectDirs;
|
use directories::ProjectDirs;
|
||||||
use domasi::Alert;
|
use domasi::Alert;
|
||||||
use domasi::Pomodoro;
|
use domasi::Domasi;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut domasi: Pomodoro = Default::default();
|
let mut domasi: Domasi = Default::default();
|
||||||
|
|
||||||
match get_alert() {
|
match get_alert() {
|
||||||
Some(alert) => domasi.start(Some(alert)).unwrap(),
|
Some(alert) => domasi.start(Some(alert)).unwrap(),
|
||||||
|
|
Loading…
Reference in New Issue