aboutsummaryrefslogtreecommitdiff
path: root/src/pomd.rs
blob: 5a6679f22aabd8638098c0648e77d42cd333ab08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::time::Duration;

use pausable_clock::{PausableClock, PausableInstant};

use notify_rust::Notification;

use crate::config::PomdConfig;

/// Represents the current state of the program
pub struct Pomd {
    pub config: PomdConfig,
    pub duration: Duration,
    pub iteration: u8,
    pub on_break: bool,
    pub clock: PausableClock,
    pub start: PausableInstant,
}

impl Pomd {
    /// Creates a new instance of this struct with a given configuration
    pub fn new(config: PomdConfig) -> Self {
        let clock = PausableClock::new(Duration::ZERO, true);
        let start = clock.now();
        Self {
            config,
            duration: Duration::from_secs_f32(config.work_duration),
            iteration: 0,
            on_break: false,
            clock,
            start,
        }
    }

    /// Check whether sufficient time has elapsed to enter next iteration of cycle
    pub fn update(&mut self) {
        if self.duration < self.start.elapsed(&self.clock) {
            if self.config.notify {
                self.notify();
            }
            self.setup_next_iteration();
        }
    }

    /// Resets state for next iteration
    pub fn setup_next_iteration(&mut self) {
        // Stop clock until user restarts it
        self.clock.pause();

        self.start = self.clock.now();
        self.on_break ^= true;
        self.duration = if self.on_break {
            // Long break on last iteration
            if self.iteration == self.config.num_iterations - 1 {
                Duration::from_secs_f32(self.config.long_break_duration)
            } else {
                Duration::from_secs_f32(self.config.short_break_duration)
            }
        } else {
            self.iteration = (self.iteration + 1) % self.config.num_iterations;
            Duration::from_secs_f32(self.config.work_duration)
        }
    }

    /// Displays a system notification
    pub fn notify(&self) {
        Notification::new()
            .summary(
                &(if self.on_break {
                    "Break Complete".to_string()
                } else {
                    format!(
                        "Pomodoro Complete ({}/{})",
                        self.iteration + 1,
                        self.config.num_iterations
                    )
                }),
            )
            .body("Click to dismiss")
            .show()
            .unwrap();
    }
}