From 24672d396e5e942d70bf7d94a75f55c8ccdc94f3 Mon Sep 17 00:00:00 2001 From: Kevin Schoon Date: Sat, 20 Jan 2018 20:03:23 +0800 Subject: [PATCH] dynamically update display --- main.go | 27 +++----------------------- task.go | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ types.go | 18 +++++++++++++++-- 3 files changed, 78 insertions(+), 26 deletions(-) create mode 100644 task.go diff --git a/main.go b/main.go index aff5eeb..5b4ac99 100644 --- a/main.go +++ b/main.go @@ -15,33 +15,12 @@ func maybe(err error) { } } -func startTask(task Task, prompter Prompter, db *Store) { - taskID, err := db.CreateTask(task) - maybe(err) - for i := 0; i < task.count; i++ { - // Create a record for - // this particular stent of work - record := &Record{} - // Prompt the client - maybe(prompter.Prompt("Begin Working!")) - record.Start = time.Now() - // Wait the specified interval - time.Sleep(task.duration) - maybe(prompter.Prompt("Take a Break!")) - // Record how long the user waited - // until closing the notification - record.End = time.Now() - maybe(db.CreateRecord(taskID, *record)) - } - -} - func start(path *string) func(*cli.Cmd) { return func(cmd *cli.Cmd) { cmd.Spec = "[OPTIONS] MESSAGE" var ( duration = cmd.StringOpt("d duration", "25m", "duration of each stent") - count = cmd.IntOpt("c count", 4, "number of working stents") + stents = cmd.IntOpt("s stents", 4, "number of working stents") message = cmd.StringArg("MESSAGE", "", "descriptive name of the given task") tags = cmd.StringsOpt("t tag", []string{}, "tags associated with this task") ) @@ -54,10 +33,10 @@ func start(path *string) func(*cli.Cmd) { task := Task{ Message: *message, Tags: *tags, - count: *count, + stents: *stents, duration: parsed, } - startTask(task, &I3{}, db) + run(task, &I3{}, db) } } } diff --git a/task.go b/task.go new file mode 100644 index 0000000..7e06797 --- /dev/null +++ b/task.go @@ -0,0 +1,59 @@ +package main + +import ( + "fmt" + "github.com/gosuri/uilive" + "io" + "time" +) + +// Task Starting.. +// +// 20min remaning [stent 1/4] +// .. +// 15min remaining [stent 2/4] +// .. +// Task Completed! +func display(writer io.Writer, msg Message) { + fmt.Fprintf( + writer, + "%s remaining [ stent %d/%d ]\n", + (msg.Duration - time.Since(msg.Start)).Truncate(time.Second), + msg.CurrentStent, + msg.Stents, + ) +} + +func run(task Task, prompter Prompter, db *Store) { + taskID, err := db.CreateTask(task) + maybe(err) + writer := uilive.New() + writer.Start() + ticker := time.NewTicker(RefreshInterval) + timer := time.NewTimer(task.duration) + var currentStent int + for currentStent < task.stents { + record := &Record{} + maybe(prompter.Prompt("Begin working!")) + record.Start = time.Now() + timer.Reset(task.duration) + loop: + select { + case <-ticker.C: + display(writer, Message{ + Start: record.Start, + Duration: task.duration, + Stents: task.stents, + CurrentStent: currentStent, + }) + goto loop + case <-timer.C: + maybe(prompter.Prompt("Take a break!")) + record.End = time.Now() + maybe(db.CreateRecord(taskID, *record)) + currentStent++ + } + maybe(db.CreateRecord(taskID, *record)) + } + writer.Stop() +} diff --git a/types.go b/types.go index 86eda07..c0a9a3e 100644 --- a/types.go +++ b/types.go @@ -5,14 +5,28 @@ import ( "time" ) +// RefreshInterval is the frequency at which +// the display is updated. +const RefreshInterval = 800 * time.Millisecond + +// Message is used internally for updating +// the display. +type Message struct { + Start time.Time + Duration time.Duration + Stents int + CurrentStent int +} + // Task describes some activity type Task struct { ID int `json:"id"` Message string `json:"message"` Records []*Record `json:"records"` // Free-form tags associated with this task - Tags []string `json:"tags"` - count int + Tags []string `json:"tags"` + // Number of iterations to perform the task + stents int duration time.Duration }