forked from kevinschoon/pomo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.go
119 lines (109 loc) · 2.47 KB
/
task.go
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"time"
)
type TaskRunner struct {
count int
taskID int
taskMessage string
nPomodoros int
origDuration time.Duration
state State
store *Store
started time.Time
pause chan bool
toggle chan bool
notifier Notifier
duration time.Duration
}
func NewTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) {
taskID, err := store.CreateTask(*task)
if err != nil {
return nil, err
}
tr := &TaskRunner{
taskID: taskID,
taskMessage: task.Message,
nPomodoros: task.NPomodoros,
origDuration: task.Duration,
store: store,
state: State(0),
pause: make(chan bool),
toggle: make(chan bool),
notifier: notifier,
duration: task.Duration,
}
return tr, nil
}
func (t *TaskRunner) Start() {
go t.run()
}
func (t *TaskRunner) TimeRemaining() time.Duration {
return (t.duration - time.Since(t.started)).Truncate(time.Second)
}
func (t *TaskRunner) run() error {
for t.count < t.nPomodoros {
// Create a new pomodoro where we
// track the start / end time of
// of this session.
pomodoro := &Pomodoro{}
// Start this pomodoro
pomodoro.Start = time.Now()
// Set state to RUNNING
t.state = RUNNING
// Create a new timer
timer := time.NewTimer(t.duration)
// Record our started time
t.started = pomodoro.Start
loop:
select {
case <-timer.C:
t.state = BREAKING
t.count++
case <-t.toggle:
// Catch any toggles when we
// are not expecting them
goto loop
case <-t.pause:
timer.Stop()
// Record the remaining time of the current pomodoro
remaining := t.TimeRemaining()
// Change state to PAUSED
t.state = PAUSED
// Wait for the user to press [p]
<-t.pause
// Resume the timer with previous
// remaining time
timer.Reset(remaining)
// Change duration
t.started = time.Now()
t.duration = remaining
// Restore state to RUNNING
t.state = RUNNING
goto loop
}
pomodoro.End = time.Now()
err := t.store.CreatePomodoro(t.taskID, *pomodoro)
if err != nil {
return err
}
// All pomodoros completed
if t.count == t.nPomodoros {
break
}
t.notifier.Notify("Pomo", "It is time to take a break!")
// Reset the duration incase it
// was paused.
t.duration = t.origDuration
// User concludes the break
<-t.toggle
}
t.state = COMPLETE
return nil
}
func (t *TaskRunner) Toggle() {
t.toggle <- true
}
func (t *TaskRunner) Pause() {
t.pause <- true
}