1 | package main
|
2 |
|
3 | import (
|
4 | "fmt"
|
5 | "github.com/gosuri/uilive"
|
6 | "time"
|
7 | )
|
8 |
|
9 | type TaskRunner struct {
|
10 | count int
|
11 | task *Task
|
12 | store *Store
|
13 | writer *uilive.Writer
|
14 | timer *time.Timer
|
15 | ticker *time.Ticker
|
16 | notifier Notifier
|
17 | }
|
18 |
|
19 | func NewTaskRunner(task *Task, store *Store) (*TaskRunner, error) {
|
20 | taskID, err := store.CreateTask(*task)
|
21 | if err != nil {
|
22 | return nil, err
|
23 | }
|
24 | task.ID = taskID
|
25 | tr := &TaskRunner{
|
26 | task: task,
|
27 | store: store,
|
28 | notifier: NewLibNotifier(),
|
29 | writer: uilive.New(),
|
30 | timer: time.NewTimer(task.Duration),
|
31 | ticker: time.NewTicker(RefreshInterval),
|
32 | }
|
33 | tr.writer.Start()
|
34 | return tr, nil
|
35 | }
|
36 |
|
37 | func (t *TaskRunner) Run() error {
|
38 | for t.count < t.task.NPomodoros {
|
39 | // ASCII spinner
|
40 | wheel := &Wheel{}
|
41 | // This pomodoro
|
42 | pomodoro := &Pomodoro{}
|
43 | prompt("press enter to begin")
|
44 | // Emit a desktop notification
|
45 | // that the task is beginning.
|
46 | t.notifier.Begin(t.count, *t.task)
|
47 | // Record task as started
|
48 | pomodoro.Start = time.Now()
|
49 | // Reset the timer
|
50 | t.timer.Reset(t.task.Duration)
|
51 | // Wait for either a tick to update
|
52 | // the UI for the timer to complete
|
53 | loop:
|
54 | select {
|
55 | case <-t.ticker.C:
|
56 | t.updateUI(Message{
|
57 | Start: pomodoro.Start,
|
58 | Duration: t.task.Duration,
|
59 | Pomodoros: t.task.NPomodoros,
|
60 | Wheel: wheel,
|
61 | CurrentPomodoro: t.count,
|
62 | })
|
63 | goto loop
|
64 | case <-t.timer.C:
|
65 | // Send a notification for the
|
66 | // user to take a break. We record
|
67 | // how long it actually takes for
|
68 | // them to initiate the break.
|
69 | t.notifier.Break(*t.task)
|
70 | prompt("press enter to take a break")
|
71 | // Record the task as complete
|
72 | pomodoro.End = time.Now()
|
73 | // Record the session in the db
|
74 | err := t.store.CreatePomodoro(t.task.ID, *pomodoro)
|
75 | if err != nil {
|
76 | return err
|
77 | }
|
78 | // Increment the count of completed pomodoros
|
79 | t.count++
|
80 | }
|
81 | }
|
82 | return nil
|
83 | }
|
84 |
|
85 | func (t *TaskRunner) updateUI(msg Message) {
|
86 | fmt.Fprintf(
|
87 | t.writer,
|
88 | "%s %s remaining [ pomodoro %d/%d ]\n",
|
89 | msg.Wheel,
|
90 | (msg.Duration - time.Since(msg.Start)).Truncate(time.Second),
|
91 | msg.CurrentPomodoro,
|
92 | msg.Pomodoros,
|
93 | )
|
94 | }
|
95 |
|
96 | /*
|
97 |
|
98 | // Task Starting..
|
99 | //
|
100 | // 20min remaning [pomodoro 1/4]
|
101 | // ..
|
102 | // 15min remaining [pomodoro 2/4]
|
103 | // ..
|
104 | // Task Completed!
|
105 | func display(writer io.Writer, msg Message) {
|
106 | fmt.Fprintf(
|
107 | writer,
|
108 | "%s %s remaining [ pomodoro %d/%d ]\n",
|
109 | msg.Wheel,
|
110 | (msg.Duration - time.Since(msg.Start)).Truncate(time.Second),
|
111 | msg.CurrentPomodoro,
|
112 | msg.Pomodoros,
|
113 | )
|
114 | }
|
115 |
|
116 | func run(task Task, notifier Notifier, db *Store) {
|
117 | taskID, err := db.CreateTask(task)
|
118 | maybe(err)
|
119 | writer := uilive.New()
|
120 | writer.Start()
|
121 | ticker := time.NewTicker(RefreshInterval)
|
122 | timer := time.NewTimer(task.Duration)
|
123 | wheel := &Wheel{}
|
124 | var p int
|
125 | for p < task.NPomodoros {
|
126 | pomodoro := &Pomodoro{}
|
127 | maybe(notifier.Begin(task))
|
128 | pomodoro.Start = time.Now()
|
129 | timer.Reset(task.Duration)
|
130 | loop:
|
131 | select {
|
132 | case <-ticker.C:
|
133 | display(writer, Message{
|
134 | Start: pomodoro.Start,
|
135 | Duration: task.Duration,
|
136 | Pomodoros: task.NPomodoros,
|
137 | Wheel: wheel,
|
138 | CurrentPomodoro: p,
|
139 | })
|
140 | goto loop
|
141 | case <-timer.C:
|
142 | maybe(notifier.Break(task))
|
143 | fmt.Println("press enter to take a break")
|
144 | pomodoro.End = time.Now()
|
145 | maybe(db.CreatePomodoro(taskID, *pomodoro))
|
146 | p++
|
147 | }
|
148 | }
|
149 | maybe(notifier.Finish(task))
|
150 | writer.Stop()
|
151 | }
|
152 | */
|