aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-12-15 01:47:23 +0300
committerAlexander Kiryukhin <a.kiryukhin@mail.ru>2021-12-15 01:47:23 +0300
commita6c52444e9bcab479fcae1d9a55b0d004dac5ecd (patch)
tree3ab36667cc5a6f274a8e91c8ff3d8324a66f5dfb
parentabf98dab7da8e5f0b7a81f3156985f7cc5498976 (diff)
Added control keysHEADv0.0.2master
-rw-r--r--go.mod4
-rw-r--r--go.sum4
-rw-r--r--main.go98
3 files changed, 93 insertions, 13 deletions
diff --git a/go.mod b/go.mod
index 9ef95fd..b1c39ae 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,7 @@
module github.com/neonxp/pomodoro
go 1.17
+
+require github.com/eiannone/keyboard v0.0.0-20200508000154-caf4b762e807
+
+require golang.org/x/sys v0.0.0-20211214170744-3b038e5940ed // indirect
diff --git a/go.sum b/go.sum
index e69de29..5ef1b86 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/main.go b/main.go
index b8e6914..c757d23 100644
--- a/main.go
+++ b/main.go
@@ -1,8 +1,13 @@
package main
import (
+ "context"
"fmt"
+ "os"
+ "os/signal"
"time"
+
+ "github.com/eiannone/keyboard"
)
type state int
@@ -11,26 +16,60 @@ const (
Working state = iota
Break
LongBreak
+ Pause
)
var (
currentState = Working
+ prevState = Working
currentDuration = 25 * 60
pomodoros = 1
)
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 {
- clearline()
- switch currentState {
- case Working:
- fmt.Printf("🍅 #%d Working (%s)", pomodoros, secondsToMinutes(currentDuration))
- case Break:
- fmt.Printf("☕️ #%d Break (%s)", pomodoros, secondsToMinutes(currentDuration))
- case LongBreak:
- fmt.Printf("☕️ #%d Long break (%s)", pomodoros, secondsToMinutes(currentDuration))
+ char, _, err := keyboard.GetKey()
+ if err != nil {
+ panic(err)
+ }
+ switch string(char) {
+ case "p":
+ if currentState != Pause {
+ 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 {
switch currentState {
case Working:
@@ -48,16 +87,49 @@ func main() {
}
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 displayTimer() {
+ 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 getStateText(state state) string {
+ 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("\a")
+ fmt.Print("\u0007")
}
-func clearline() {
- fmt.Print("\x1b[2K\r")
+func clear() {
+ fmt.Print("\u001B[2K\u001B[F\u001B[2K\r")
}
func secondsToMinutes(inSeconds int) string {