From 54339dc59f278242a90fb07f898229469d1aacda Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Mon, 11 Nov 2024 23:06:49 +0100 Subject: [PATCH 01/10] feat: replace timer icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change timer icon from hourglass to stopwatch 🤖 --- cmd/client/helper/terminal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/client/helper/terminal.go b/cmd/client/helper/terminal.go index 49049c2..325db78 100644 --- a/cmd/client/helper/terminal.go +++ b/cmd/client/helper/terminal.go @@ -56,7 +56,7 @@ func TerminalOutput(pomodoro GoTomato.ServerMessage) string { minutes := pomodoro.TimeLeft / 60 seconds := pomodoro.TimeLeft % 60 - timerOutput = fmt.Sprintf("⏳ %02d:%02d", minutes, seconds) + "\n" + timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) } From a5afcd2507b548acf1c242cfef1c919842692728 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 09:43:58 +0100 Subject: [PATCH 02/10] refactor: merge client/helper package to client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove helper package and move functions to client package - merge `terminalOutput()` to `view.go` - move `desktopNotifications()` to `cmd/client` 🤖 --- cmd/client/helper/terminal.go | 71 ------------------------- cmd/client/{helper => }/notification.go | 4 +- cmd/client/view.go | 68 +++++++++++++++++++++-- 3 files changed, 67 insertions(+), 76 deletions(-) delete mode 100644 cmd/client/helper/terminal.go rename cmd/client/{helper => }/notification.go (93%) diff --git a/cmd/client/helper/terminal.go b/cmd/client/helper/terminal.go deleted file mode 100644 index 325db78..0000000 --- a/cmd/client/helper/terminal.go +++ /dev/null @@ -1,71 +0,0 @@ -package helper - -import ( - "fmt" - - "github.com/alecthomas/colour" - "github.com/charmbracelet/bubbles/progress" - - GoTomato "git.smsvc.net/pomodoro/GoTomato/pkg/models" -) - -var progressBar = progress.New(progress.WithDefaultGradient(), progress.WithoutPercentage()) - -func calc_percentage(message GoTomato.ServerMessage) float64 { - var duration float64 - - switch message.Mode { - case "Work": - duration = float64(message.Settings.Work) - case "ShortBreak": - duration = float64(message.Settings.ShortBreak) - case "LongBreak", "End": - duration = float64(message.Settings.LongBreak) - } - - timeLeft := float64(message.TimeLeft) - return 1.0 - (timeLeft / duration) -} - -// Return terminal output based on the passed ServerMessage -func TerminalOutput(pomodoro GoTomato.ServerMessage) string { - var ( - output string - - modePrefix string - timerOutput string - ) - - // header - output += colour.Sprintf("^D^4Work: %d ◊ Break: %d ◊ Longbreak: %d^R\n\n", - pomodoro.Settings.Work/60, - pomodoro.Settings.ShortBreak/60, - pomodoro.Settings.LongBreak/60, - ) - - //body - switch pomodoro.Mode { - case "Idle": - modePrefix = " " - timerOutput = "" - default: - modePrefix = " " - if pomodoro.Paused { - modePrefix = " " - } - minutes := pomodoro.TimeLeft / 60 - seconds := pomodoro.TimeLeft % 60 - - timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" - timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) - } - - output += fmt.Sprintf("Session: %d/%d\n", - pomodoro.Session, - pomodoro.Settings.Sessions, - ) - output += fmt.Sprintf("%s %s\n", modePrefix, pomodoro.Mode) + "\n" - output += timerOutput - - return output -} diff --git a/cmd/client/helper/notification.go b/cmd/client/notification.go similarity index 93% rename from cmd/client/helper/notification.go rename to cmd/client/notification.go index 956e6a2..7e5dfd6 100644 --- a/cmd/client/helper/notification.go +++ b/cmd/client/notification.go @@ -1,4 +1,4 @@ -package helper +package client import ( "fmt" @@ -8,7 +8,7 @@ import ( ) // Send desktop notifications on the start of each segment -func DesktopNotifications(pomodoro GoTomato.ServerMessage) { +func desktopNotifications(pomodoro GoTomato.ServerMessage) { var ( duration int notification string diff --git a/cmd/client/view.go b/cmd/client/view.go index c7e9eb7..884ea00 100644 --- a/cmd/client/view.go +++ b/cmd/client/view.go @@ -1,22 +1,25 @@ package client import ( + "fmt" "strings" "github.com/alecthomas/colour" - "git.smsvc.net/pomodoro/ChronoTomato/cmd/client/helper" GoTomato "git.smsvc.net/pomodoro/GoTomato/pkg/models" + "github.com/charmbracelet/bubbles/progress" ) +var progressBar = progress.New(progress.WithDefaultGradient(), progress.WithoutPercentage()) + func (a app) View() string { var body string var serverStatus string body = "Waiting for server message..." if a.pomodoro != (GoTomato.ServerMessage{}) { - body = helper.TerminalOutput(a.pomodoro) - helper.DesktopNotifications(a.pomodoro) + body = terminalOutput(a.pomodoro) + desktopNotifications(a.pomodoro) } serverStatus = colour.Sprintf("^D^1disconnected: %v^R\n", client.LastErr) @@ -29,3 +32,62 @@ func (a app) View() string { return body + strings.Repeat("\n", height) + serverStatus + helpView } + +// Return terminal output based on the passed ServerMessage +func terminalOutput(pomodoro GoTomato.ServerMessage) string { + var ( + output string + + modePrefix string + timerOutput string + ) + + // header + output += colour.Sprintf("^D^4Work: %d ◊ Break: %d ◊ Longbreak: %d^R\n\n", + pomodoro.Settings.Work/60, + pomodoro.Settings.ShortBreak/60, + pomodoro.Settings.LongBreak/60, + ) + + //body + switch pomodoro.Mode { + case "Idle": + modePrefix = " " + timerOutput = "" + default: + modePrefix = " " + if pomodoro.Paused { + modePrefix = " " + } + minutes := pomodoro.TimeLeft / 60 + seconds := pomodoro.TimeLeft % 60 + + timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" + timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) + } + + output += fmt.Sprintf("Session: %d/%d\n", + pomodoro.Session, + pomodoro.Settings.Sessions, + ) + output += fmt.Sprintf("%s %s\n", modePrefix, pomodoro.Mode) + "\n" + output += timerOutput + + return output +} + +func calc_percentage(message GoTomato.ServerMessage) float64 { + var duration float64 + + switch message.Mode { + case "Work": + duration = float64(message.Settings.Work) + case "ShortBreak": + duration = float64(message.Settings.ShortBreak) + case "LongBreak", "End": + duration = float64(message.Settings.LongBreak) + } + + timeLeft := float64(message.TimeLeft) + return 1.0 - (timeLeft / duration) +} From 9de86fc2175d07fa29a1386dc7eeca52ec47b1ba Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 17:16:50 +0100 Subject: [PATCH 03/10] feat: add read timeout for server messages --- internal/websocket/receive.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/websocket/receive.go b/internal/websocket/receive.go index e4638a6..7912de3 100644 --- a/internal/websocket/receive.go +++ b/internal/websocket/receive.go @@ -19,6 +19,7 @@ func (c *Client) ProcessServerMessages(channel chan<- GoTomato.ServerMessage) { defer close(Done) for { + c.Conn.SetReadDeadline(time.Now().Add(10 * time.Second)) _, message, err := c.Conn.ReadMessage() if err != nil { // On normal closure exit gracefully @@ -26,6 +27,7 @@ func (c *Client) ProcessServerMessages(channel chan<- GoTomato.ServerMessage) { return } + c.LastErr = err // Try to reconnect on unexpected disconnect for { channel <- prevMessage // send previous ServerMessage to update view From 21edd2d823080771eff13c885f6e1d71d6cfbbe2 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 17:17:39 +0100 Subject: [PATCH 04/10] feat: better error display in TUI - always show `client.LasErr` if not `nil` --- cmd/client/view.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/client/view.go b/cmd/client/view.go index 884ea00..0e7d9b9 100644 --- a/cmd/client/view.go +++ b/cmd/client/view.go @@ -22,8 +22,8 @@ func (a app) View() string { desktopNotifications(a.pomodoro) } - serverStatus = colour.Sprintf("^D^1disconnected: %v^R\n", client.LastErr) - if client.Connected() { + serverStatus = colour.Sprintf("^D^1%v^R\n", client.LastErr) + if client.Connected() && client.LastErr == nil { serverStatus = colour.Sprintf("^D^2connected to %s^R\n", client.Server) } From 57e71b1a5ea76d267b425c12a3259c9ef48ccc35 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 13 Nov 2024 18:51:02 +0000 Subject: [PATCH 05/10] chore: update module github.com/charmbracelet/bubbletea to v1.2.2 --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index da5bc03..a17e81c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( git.smsvc.net/pomodoro/GoTomato v0.3.1 github.com/alecthomas/colour v0.1.0 github.com/charmbracelet/bubbles v0.20.0 - github.com/charmbracelet/bubbletea v1.2.1 + github.com/charmbracelet/bubbletea v1.2.2 github.com/charmbracelet/log v0.4.0 github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4 github.com/gorilla/websocket v1.5.3 @@ -18,7 +18,7 @@ require ( github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/x/ansi v0.4.5 // indirect - github.com/charmbracelet/x/term v0.2.0 // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect @@ -35,8 +35,8 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.3.8 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/go.sum b/go.sum index 4f15eb3..f34a319 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= -github.com/charmbracelet/bubbletea v1.2.1 h1:J041h57zculJKEKf/O2pS4edXGIz+V0YvojvfGXePIk= -github.com/charmbracelet/bubbletea v1.2.1/go.mod h1:viLoDL7hG4njLJSKU2gw7kB3LSEmWsrM80rO1dBJWBI= +github.com/charmbracelet/bubbletea v1.2.2 h1:EMz//Ky/aFS2uLcKqpCst5UOE6z5CFDGRsUpyXz0chs= +github.com/charmbracelet/bubbletea v1.2.2/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= @@ -16,8 +16,8 @@ github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8 github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM= github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM= github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= -github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -64,12 +64,12 @@ github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG0 github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From 74f41f0e5664f19a58d560f4b42073021622317a Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Mon, 11 Nov 2024 23:06:49 +0100 Subject: [PATCH 06/10] fix: replace timer icon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - change timer icon from hourglass to stopwatch 🤖 --- cmd/client/helper/terminal.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/client/helper/terminal.go b/cmd/client/helper/terminal.go index 49049c2..325db78 100644 --- a/cmd/client/helper/terminal.go +++ b/cmd/client/helper/terminal.go @@ -56,7 +56,7 @@ func TerminalOutput(pomodoro GoTomato.ServerMessage) string { minutes := pomodoro.TimeLeft / 60 seconds := pomodoro.TimeLeft % 60 - timerOutput = fmt.Sprintf("⏳ %02d:%02d", minutes, seconds) + "\n" + timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) } From b494c2782ea790f6399f09535c151f7528abfef3 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 09:43:58 +0100 Subject: [PATCH 07/10] refactor: merge client/helper package to client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - remove helper package and move functions to client package - merge `terminalOutput()` to `view.go` - move `desktopNotifications()` to `cmd/client` 🤖 --- cmd/client/helper/terminal.go | 71 ------------------------- cmd/client/{helper => }/notification.go | 4 +- cmd/client/view.go | 68 +++++++++++++++++++++-- 3 files changed, 67 insertions(+), 76 deletions(-) delete mode 100644 cmd/client/helper/terminal.go rename cmd/client/{helper => }/notification.go (93%) diff --git a/cmd/client/helper/terminal.go b/cmd/client/helper/terminal.go deleted file mode 100644 index 325db78..0000000 --- a/cmd/client/helper/terminal.go +++ /dev/null @@ -1,71 +0,0 @@ -package helper - -import ( - "fmt" - - "github.com/alecthomas/colour" - "github.com/charmbracelet/bubbles/progress" - - GoTomato "git.smsvc.net/pomodoro/GoTomato/pkg/models" -) - -var progressBar = progress.New(progress.WithDefaultGradient(), progress.WithoutPercentage()) - -func calc_percentage(message GoTomato.ServerMessage) float64 { - var duration float64 - - switch message.Mode { - case "Work": - duration = float64(message.Settings.Work) - case "ShortBreak": - duration = float64(message.Settings.ShortBreak) - case "LongBreak", "End": - duration = float64(message.Settings.LongBreak) - } - - timeLeft := float64(message.TimeLeft) - return 1.0 - (timeLeft / duration) -} - -// Return terminal output based on the passed ServerMessage -func TerminalOutput(pomodoro GoTomato.ServerMessage) string { - var ( - output string - - modePrefix string - timerOutput string - ) - - // header - output += colour.Sprintf("^D^4Work: %d ◊ Break: %d ◊ Longbreak: %d^R\n\n", - pomodoro.Settings.Work/60, - pomodoro.Settings.ShortBreak/60, - pomodoro.Settings.LongBreak/60, - ) - - //body - switch pomodoro.Mode { - case "Idle": - modePrefix = " " - timerOutput = "" - default: - modePrefix = " " - if pomodoro.Paused { - modePrefix = " " - } - minutes := pomodoro.TimeLeft / 60 - seconds := pomodoro.TimeLeft % 60 - - timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" - timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) - } - - output += fmt.Sprintf("Session: %d/%d\n", - pomodoro.Session, - pomodoro.Settings.Sessions, - ) - output += fmt.Sprintf("%s %s\n", modePrefix, pomodoro.Mode) + "\n" - output += timerOutput - - return output -} diff --git a/cmd/client/helper/notification.go b/cmd/client/notification.go similarity index 93% rename from cmd/client/helper/notification.go rename to cmd/client/notification.go index 956e6a2..7e5dfd6 100644 --- a/cmd/client/helper/notification.go +++ b/cmd/client/notification.go @@ -1,4 +1,4 @@ -package helper +package client import ( "fmt" @@ -8,7 +8,7 @@ import ( ) // Send desktop notifications on the start of each segment -func DesktopNotifications(pomodoro GoTomato.ServerMessage) { +func desktopNotifications(pomodoro GoTomato.ServerMessage) { var ( duration int notification string diff --git a/cmd/client/view.go b/cmd/client/view.go index c7e9eb7..884ea00 100644 --- a/cmd/client/view.go +++ b/cmd/client/view.go @@ -1,22 +1,25 @@ package client import ( + "fmt" "strings" "github.com/alecthomas/colour" - "git.smsvc.net/pomodoro/ChronoTomato/cmd/client/helper" GoTomato "git.smsvc.net/pomodoro/GoTomato/pkg/models" + "github.com/charmbracelet/bubbles/progress" ) +var progressBar = progress.New(progress.WithDefaultGradient(), progress.WithoutPercentage()) + func (a app) View() string { var body string var serverStatus string body = "Waiting for server message..." if a.pomodoro != (GoTomato.ServerMessage{}) { - body = helper.TerminalOutput(a.pomodoro) - helper.DesktopNotifications(a.pomodoro) + body = terminalOutput(a.pomodoro) + desktopNotifications(a.pomodoro) } serverStatus = colour.Sprintf("^D^1disconnected: %v^R\n", client.LastErr) @@ -29,3 +32,62 @@ func (a app) View() string { return body + strings.Repeat("\n", height) + serverStatus + helpView } + +// Return terminal output based on the passed ServerMessage +func terminalOutput(pomodoro GoTomato.ServerMessage) string { + var ( + output string + + modePrefix string + timerOutput string + ) + + // header + output += colour.Sprintf("^D^4Work: %d ◊ Break: %d ◊ Longbreak: %d^R\n\n", + pomodoro.Settings.Work/60, + pomodoro.Settings.ShortBreak/60, + pomodoro.Settings.LongBreak/60, + ) + + //body + switch pomodoro.Mode { + case "Idle": + modePrefix = " " + timerOutput = "" + default: + modePrefix = " " + if pomodoro.Paused { + modePrefix = " " + } + minutes := pomodoro.TimeLeft / 60 + seconds := pomodoro.TimeLeft % 60 + + timerOutput = fmt.Sprintf("⏱ %02d:%02d", minutes, seconds) + "\n" + timerOutput += progressBar.ViewAs(calc_percentage(pomodoro)) + } + + output += fmt.Sprintf("Session: %d/%d\n", + pomodoro.Session, + pomodoro.Settings.Sessions, + ) + output += fmt.Sprintf("%s %s\n", modePrefix, pomodoro.Mode) + "\n" + output += timerOutput + + return output +} + +func calc_percentage(message GoTomato.ServerMessage) float64 { + var duration float64 + + switch message.Mode { + case "Work": + duration = float64(message.Settings.Work) + case "ShortBreak": + duration = float64(message.Settings.ShortBreak) + case "LongBreak", "End": + duration = float64(message.Settings.LongBreak) + } + + timeLeft := float64(message.TimeLeft) + return 1.0 - (timeLeft / duration) +} From d25ce3eead59e93fdbbd46daff863be8a6f855e2 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 17:16:50 +0100 Subject: [PATCH 08/10] feat: add read timeout for server messages --- internal/websocket/receive.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/internal/websocket/receive.go b/internal/websocket/receive.go index e4638a6..7912de3 100644 --- a/internal/websocket/receive.go +++ b/internal/websocket/receive.go @@ -19,6 +19,7 @@ func (c *Client) ProcessServerMessages(channel chan<- GoTomato.ServerMessage) { defer close(Done) for { + c.Conn.SetReadDeadline(time.Now().Add(10 * time.Second)) _, message, err := c.Conn.ReadMessage() if err != nil { // On normal closure exit gracefully @@ -26,6 +27,7 @@ func (c *Client) ProcessServerMessages(channel chan<- GoTomato.ServerMessage) { return } + c.LastErr = err // Try to reconnect on unexpected disconnect for { channel <- prevMessage // send previous ServerMessage to update view From b7fc646cc0a864f25d520b759c1cf27f1662d4c3 Mon Sep 17 00:00:00 2001 From: Sebastian Mark Date: Wed, 13 Nov 2024 17:17:39 +0100 Subject: [PATCH 09/10] fix: better error display in TUI - always show `client.LasErr` if not `nil` --- cmd/client/view.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/client/view.go b/cmd/client/view.go index 884ea00..0e7d9b9 100644 --- a/cmd/client/view.go +++ b/cmd/client/view.go @@ -22,8 +22,8 @@ func (a app) View() string { desktopNotifications(a.pomodoro) } - serverStatus = colour.Sprintf("^D^1disconnected: %v^R\n", client.LastErr) - if client.Connected() { + serverStatus = colour.Sprintf("^D^1%v^R\n", client.LastErr) + if client.Connected() && client.LastErr == nil { serverStatus = colour.Sprintf("^D^2connected to %s^R\n", client.Server) } From 646f460e6a8e18ccfac1f0cf131c6c56ca341c36 Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Wed, 13 Nov 2024 18:51:02 +0000 Subject: [PATCH 10/10] chore: update module github.com/charmbracelet/bubbletea to v1.2.2 --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index da5bc03..a17e81c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( git.smsvc.net/pomodoro/GoTomato v0.3.1 github.com/alecthomas/colour v0.1.0 github.com/charmbracelet/bubbles v0.20.0 - github.com/charmbracelet/bubbletea v1.2.1 + github.com/charmbracelet/bubbletea v1.2.2 github.com/charmbracelet/log v0.4.0 github.com/gen2brain/beeep v0.0.0-20240516210008-9c006672e7f4 github.com/gorilla/websocket v1.5.3 @@ -18,7 +18,7 @@ require ( github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/lipgloss v1.0.0 // indirect github.com/charmbracelet/x/ansi v0.4.5 // indirect - github.com/charmbracelet/x/term v0.2.0 // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-toast/toast v0.0.0-20190211030409-01e6764cf0a4 // indirect @@ -35,8 +35,8 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect golang.org/x/text v0.3.8 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect ) diff --git a/go.sum b/go.sum index 4f15eb3..f34a319 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= -github.com/charmbracelet/bubbletea v1.2.1 h1:J041h57zculJKEKf/O2pS4edXGIz+V0YvojvfGXePIk= -github.com/charmbracelet/bubbletea v1.2.1/go.mod h1:viLoDL7hG4njLJSKU2gw7kB3LSEmWsrM80rO1dBJWBI= +github.com/charmbracelet/bubbletea v1.2.2 h1:EMz//Ky/aFS2uLcKqpCst5UOE6z5CFDGRsUpyXz0chs= +github.com/charmbracelet/bubbletea v1.2.2/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= @@ -16,8 +16,8 @@ github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8 github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM= github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM= github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= -github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -64,12 +64,12 @@ github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af h1:6yITBqGTE2lEeTPG0 github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af/go.mod h1:4F09kP5F+am0jAwlQLddpoMDM+iewkxxt6nxUQ5nq5o= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=