Added control keys

This commit is contained in:
Alexander Kiryukhin 2021-12-15 01:47:23 +03:00
parent abf98dab7d
commit a6c52444e9
No known key found for this signature in database
GPG key ID: 6DF7A2910D0699E9
3 changed files with 94 additions and 14 deletions

4
go.mod
View file

@ -1,3 +1,7 @@
module github.com/neonxp/pomodoro module github.com/neonxp/pomodoro
go 1.17 go 1.17
require github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807
require golang.org/x/sys v0.0.0-20211214170744-3b038e5940ed // indirect

4
go.sum
View file

@ -0,0 +1,4 @@
github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807 h1:jdjd5e68T4R/j4PWxfZqcKY8KtT9oo8IPNVuV4bSXDQ=
github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807/go.mod h1:Xoiu5VdKMvbRgHuY7+z64lhu/7lvax/22nzASF6GrO8=
golang.org/x/sys v0.0.0-20211214170744-3b038e5940ed h1:d5glpD+GMms2DMbu1doSYibjbKasYNvnhq885nOnRz8=
golang.org/x/sys v0.0.0-20211214170744-3b038e5940ed/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

100
main.go
View file

@ -1,8 +1,13 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"os"
"os/signal"
"time" "time"
"github.com/eiannone/keyboard"
) )
type state int type state int
@ -11,26 +16,60 @@ const (
Working state = iota Working state = iota
Break Break
LongBreak LongBreak
Pause
) )
var ( var (
currentState = Working currentState = Working
prevState = Working
currentDuration = 25 * 60 currentDuration = 25 * 60
pomodoros = 1 pomodoros = 1
) )
func main() { func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Kill, os.Interrupt)
defer cancel()
go timer(ctx)
go keys(cancel)
<-ctx.Done()
}
func keys(cancel func()) {
if err := keyboard.Open(); err != nil {
panic(err)
}
defer func() {
_ = keyboard.Close()
}()
for { for {
clearline() char, _, err := keyboard.GetKey()
switch currentState { if err != nil {
case Working: panic(err)
fmt.Printf("🍅 #%d Working (%s)", pomodoros, secondsToMinutes(currentDuration)) }
case Break: switch string(char) {
fmt.Printf("☕️ #%d Break (%s)", pomodoros, secondsToMinutes(currentDuration)) case "p":
case LongBreak: if currentState != Pause {
fmt.Printf("☕️ #%d Long break (%s)", pomodoros, secondsToMinutes(currentDuration)) prevState = currentState
currentState = Pause
} else {
currentState = prevState
}
case "n":
currentDuration = 0
case "q":
cancel()
return
}
}
}
func timer(ctx context.Context) {
needClear := false
for {
if currentState != Pause {
currentDuration--
} }
currentDuration--
if currentDuration < 0 { if currentDuration < 0 {
switch currentState { switch currentState {
case Working: case Working:
@ -48,16 +87,49 @@ func main() {
} }
bell() bell()
} }
<-time.After(1 * time.Second) if needClear {
clear()
}
needClear = true
displayTimer()
select {
case <-time.After(1 * time.Second):
// Do nothing
case <-ctx.Done():
return
}
} }
} }
func bell() { func displayTimer() {
fmt.Print("\a") stateText := ""
if currentState == Pause {
stateText = fmt.Sprintf("[Paused] %s", getStateText(prevState))
} else {
stateText = getStateText(currentState)
}
fmt.Printf("%s %s\n(keys: p - pause/resume timer, n - next phase, q - quit)", stateText, secondsToMinutes(currentDuration))
} }
func clearline() { func getStateText(state state) string {
fmt.Print("\x1b[2K\r") switch state {
case Working:
return fmt.Sprintf("🍅 #%d Working", pomodoros)
case Break:
return fmt.Sprintf("☕️ #%d Break", pomodoros)
case LongBreak:
return fmt.Sprintf("☕️ #%d Long break", pomodoros)
}
return ""
}
func bell() {
fmt.Print("\u0007")
}
func clear() {
fmt.Print("\u001B[2K\u001B[F\u001B[2K\r")
} }
func secondsToMinutes(inSeconds int) string { func secondsToMinutes(inSeconds int) string {