kevinschoon-pomo/task.go

170 lines
3.7 KiB
Go
Raw Normal View History

2018-01-20 13:03:23 +01:00
package main
import (
"time"
)
type TaskRunner struct {
2018-01-27 16:58:56 +01:00
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) (*TaskRunner, error) {
taskID, err := store.CreateTask(*task)
if err != nil {
return nil, err
}
tr := &TaskRunner{
2018-01-27 16:58:56 +01:00
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: NewLibNotifier(),
duration: task.Duration,
}
return tr, nil
}
2018-01-26 16:07:38 +01:00
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 {
2018-01-27 16:58:56 +01:00
for t.count < t.nPomodoros {
2018-01-26 16:07:38 +01:00
// 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
2018-01-27 16:58:56 +01:00
t.count++
2018-01-26 16:07:38 +01:00
case <-t.toggle:
// Catch any toggles when we
// are not expecting them
goto loop
case <-t.pause:
timer.Stop()
2018-01-27 16:58:56 +01:00
// Record the remaining time of the current pomodoro
2018-01-26 16:07:38 +01:00
remaining := t.TimeRemaining()
// Change state to PAUSED
t.state = PAUSED
// Wait for the user to press [p]
<-t.pause
2018-01-27 16:58:56 +01:00
// Resume the timer with previous
2018-01-26 16:07:38 +01:00
// remaining time
timer.Reset(remaining)
2018-01-27 16:58:56 +01:00
// Change duration
2018-01-26 16:07:38 +01:00
t.started = time.Now()
t.duration = remaining
// Restore state to RUNNING
t.state = RUNNING
goto loop
}
pomodoro.End = time.Now()
2018-01-27 16:58:56 +01:00
err := t.store.CreatePomodoro(t.taskID, *pomodoro)
2018-01-26 16:07:38 +01:00
if err != nil {
return err
}
2018-01-27 16:58:56 +01:00
// All pomodoros completed
if t.count == t.nPomodoros {
break
}
// Reset the duration incase it
// was paused.
t.duration = t.origDuration
// User concludes the break
<-t.toggle
2018-01-26 16:07:38 +01:00
}
t.state = COMPLETE
return nil
}
func (t *TaskRunner) Toggle() {
t.toggle <- true
}
func (t *TaskRunner) Pause() {
t.pause <- true
}
/*
func (t *TaskRunner) Run() error {
for t.count < t.task.NPomodoros {
// ASCII spinner
wheel := &Wheel{}
// This pomodoro
pomodoro := &Pomodoro{}
2018-01-26 16:07:38 +01:00
//prompt("press enter to begin")
// Emit a desktop notification
// that the task is beginning.
t.notifier.Begin(t.count, *t.task)
// Record task as started
pomodoro.Start = time.Now()
// Reset the timer
t.timer.Reset(t.task.Duration)
// Wait for either a tick to update
// the UI for the timer to complete
loop:
select {
case <-t.ticker.C:
2018-01-26 16:07:38 +01:00
t.msgCh <- Message{
Start: pomodoro.Start,
Duration: t.task.Duration,
Pomodoros: t.task.NPomodoros,
Wheel: wheel,
CurrentPomodoro: t.count,
2018-01-26 16:07:38 +01:00
State: RUNNING,
}
goto loop
case <-t.timer.C:
// Send a notification for the
// user to take a break. We record
// how long it actually takes for
// them to initiate the break.
2018-01-26 16:07:38 +01:00
//t.notifier.Break(*t.task)
//prompt("press enter to take a break")
// Record the task as complete
pomodoro.End = time.Now()
// Record the session in the db
err := t.store.CreatePomodoro(t.task.ID, *pomodoro)
if err != nil {
return err
}
// Increment the count of completed pomodoros
t.count++
}
}
return nil
}
2018-01-26 16:07:38 +01:00
*/