feat: Basic UI for Pominal

This commit is contained in:
Dan Anglin 2020-01-18 19:24:35 +00:00
parent 0f19832fca
commit 45ad772818
No known key found for this signature in database
GPG key ID: 7AC2B18EC1D09F27
5 changed files with 105 additions and 33 deletions

7
go.mod
View file

@ -1,5 +1,8 @@
module gitlab.com/dananglin/Pominal
go 1.12
go 1.13
require github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21
require (
github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21
github.com/rivo/tview v0.0.0-20191129065140-82b05c9fb329
)

21
go.sum
View file

@ -1,2 +1,23 @@
github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21 h1:moSC7ACaTejHmVRRwfDTMgByRSwjg2vZooncdWLj7o8=
github.com/0xAX/notificator v0.0.0-20181105090803-d81462e38c21/go.mod h1:NtXa9WwQsukMHZpjNakTTz0LArxvGYdPA9CjIcUSZ6s=
github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM=
github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM=
github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/rivo/tview v0.0.0-20191129065140-82b05c9fb329 h1:MubHhHJ4mB0A5wMcc2am0/51RydztIDoumyOd0r0yBw=
github.com/rivo/tview v0.0.0-20191129065140-82b05c9fb329/go.mod h1:/rBeY22VG2QprWnEqG57IBC8biVu3i0DOIjRLc9I8H0=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191018095205-727590c5006e h1:ZtoklVMHQy6BFRHkbG6JzK+S6rX82//Yeok1vMlizfQ=
golang.org/x/sys v0.0.0-20191018095205-727590c5006e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

27
main.go
View file

@ -22,8 +22,9 @@ import (
"flag"
"fmt"
"os"
"os/exec"
"time"
"github.com/rivo/tview"
)
const (
@ -83,22 +84,14 @@ func main() {
maxWorkSessions,
)
pominal.Run()
}
app := tview.NewApplication()
infoUI := newInfoUI()
timerUI := newTimerUI(app)
flex := newFlex(infoUI, timerUI)
// printScreen prints the details of the Pominal session on screen including
// the current work session number, the timer's current label and the current countdoen.
// TODO: To be removed when TUI is implemented.
func printScreen(countdown float64, pominalCount, workSessionCount, maxWorkSession int, label string) {
clearScreen()
fmt.Printf("Pominal cycle: %d\nWork session: %d of %d\n\n", pominalCount, workSessionCount, maxWorkSession)
fmt.Printf("Session: %s\nTime remaining: %02d:%02d", label, int(countdown)/60, int(countdown)%60)
}
go pominal.Run(infoUI, timerUI)
if err := app.SetRoot(flex, true).SetFocus(flex).Run(); err != nil {
panic(err)
}
// clearScreen clears the terminal screen
// TODO: To be removed when TUI is implemented
func clearScreen() {
cmd := exec.Command("clear")
cmd.Stdout = os.Stdout
cmd.Run()
}

View file

@ -19,11 +19,12 @@
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/rivo/tview"
)
type Pominal struct {
@ -70,35 +71,29 @@ func NewPominal(w, s, l float64, m int) Pominal {
}
// Run Pominal
func (p *Pominal) Run() {
func (p *Pominal) Run(infoUI, timerUI *tview.TextView) {
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM)
p.UpdateSession()
p.UpdateSession(infoUI)
t := time.NewTicker(1 * time.Second)
infinite:
for {
select {
case sig := <-s:
fmt.Printf("\n\nReceived signal '%s'. Closing Pominal.\n", sig)
case <-s:
// fmt.Printf("\n\nReceived signal '%s'. Closing Pominal.\n", sig)
t.Stop()
break infinite
case <-t.C:
p.countdown--
if p.countdown < 0 {
fmt.Printf("\n%s session has finished.\n", p.label)
t.Stop()
p.UpdateSession()
p.UpdateSession(infoUI)
time.Sleep(1 * time.Second)
t = time.NewTicker(1 * time.Second)
} else {
printScreen(p.countdown,
p.cycle,
p.workSession,
p.maxWorkSessions,
p.label,
)
drawTimer(timerUI, p.countdown)
}
}
}
@ -110,7 +105,7 @@ infinite:
// If a 'long break' session is over then the Pominal cycle
// is incremented and the work session counter is reset
// to 1.
func (p *Pominal) UpdateSession() {
func (p *Pominal) UpdateSession(i *tview.TextView) {
switch p.label {
case workTimerLabel:
if p.workSession >= p.maxWorkSessions {
@ -133,6 +128,7 @@ func (p *Pominal) UpdateSession() {
p.countdown = p.work
p.label = workTimerLabel
}
drawInfo(i, p.cycle, p.workSession, p.maxWorkSessions, p.label)
alert(p.label)
}

59
ui.go Normal file
View file

@ -0,0 +1,59 @@
/*
Pominal
Copyright (C) 2019 Daniel Anglin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"fmt"
"github.com/rivo/tview"
)
func newInfoUI() *tview.TextView {
i := tview.NewTextView()
i.SetBorder(true)
i.SetTitle(" Pominal ")
i.SetTitleAlign(tview.AlignLeft)
return i
}
func newTimerUI(app *tview.Application) *tview.TextView {
t := tview.NewTextView().SetTextAlign(tview.AlignCenter).SetChangedFunc(func() {
app.Draw()
})
t.SetBorder(true)
return t
}
func newFlex(info, timer *tview.TextView) *tview.Flex {
f := tview.NewFlex().AddItem(info, 30, 1, false).AddItem(timer, 50, 1, false)
return f
}
func drawInfo(t *tview.TextView, pominalCycle, workSessions, maxWorkSessions int, label string) {
t.Clear()
fmt.Fprintf(t, "\nPominal cycle: %d\nWork session: %d of %d\nSession: %s", pominalCycle, workSessions, maxWorkSessions, label)
}
func drawTimer(t *tview.TextView, countdown float64) {
t.Clear()
fmt.Fprintf(t, "\nTime remaining:\n%02d:%02d", int(countdown)/60, int(countdown)%60)
}