Gotask.go -rw-r--r-- 3.3 KiB
1package main
2
3import (
4 "fmt"
5 "github.com/gosuri/uilive"
6 "time"
7)
8
9type 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
19func 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
37func (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
85func (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!
105func 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
116func 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*/