From b97562c242f31c8d41396a32d635961e27981cab Mon Sep 17 00:00:00 2001 From: huyz Date: Tue, 5 May 2026 13:28:04 -0500 Subject: [PATCH 1/3] UptimeRobot: colorize percentage to work with both dark and light backgrounds --- modules/uptimerobot/widget.go | 25 ++++++++++++++----------- utils/colors.go | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/modules/uptimerobot/widget.go b/modules/uptimerobot/widget.go index bd0b48212..a093e235d 100644 --- a/modules/uptimerobot/widget.go +++ b/modules/uptimerobot/widget.go @@ -5,11 +5,14 @@ import ( "errors" "fmt" "io" + "math" "net/http" "net/url" + "strconv" "strings" "github.com/rivo/tview" + "github.com/wtfutil/wtf/utils" "github.com/wtfutil/wtf/view" ) @@ -111,8 +114,7 @@ func (widget *Widget) contentFrom(monitors []Monitor) string { prefix += "[yellow] ~ " } - str += fmt.Sprintf(`%s%s [gray](%s)[white] -`, + str += fmt.Sprintf("%s%s [white](%s)\n", prefix, monitor.Name, formatUptimes(monitor.Uptime), @@ -124,17 +126,18 @@ func (widget *Widget) contentFrom(monitors []Monitor) string { func formatUptimes(str string) string { splits := strings.Split(str, "-") - str = "" - for i, s := range splits { - if i != 0 { - str += "|" + parts := make([]string, 0, len(splits)) + for _, s := range splits { + if f, err := strconv.ParseFloat(s, 64); err == nil { + parts = append(parts, utils.ColorizeUptimePercent(math.Round(f*10)/10)+"%") + } else { + s = s[:5] + s = strings.TrimRight(s, "0") + s = strings.TrimRight(s, ".") + "%" + parts = append(parts, s) } - s = s[:5] - s = strings.TrimRight(s, "0") - s = strings.TrimRight(s, ".") + "%" - str += s } - return str + return strings.Join(parts, "|") } type Monitor struct { diff --git a/utils/colors.go b/utils/colors.go index 0707b90d1..4b504b1ff 100644 --- a/utils/colors.go +++ b/utils/colors.go @@ -20,3 +20,23 @@ func ColorizePercent(percent float64) string { return fmt.Sprintf("[%s]%v[%s]", color, percent, "white") } + +// ColorizeUptimePercent colorizes uptime percentages where near-100% is expected. +func ColorizeUptimePercent(percent float64) string { + var color string + + switch { + case percent >= 99: + color = "green" + case percent >= 95: + color = "yellow" + case percent >= 80: + color = "orange" + case percent < 0: + color = "grey" + default: + color = "red" + } + + return fmt.Sprintf("[%s]%v[%s]", color, percent, "white") +} From 4f486a535b40becb66ea129d2c95dd3697727075 Mon Sep 17 00:00:00 2001 From: huyz Date: Tue, 5 May 2026 13:42:16 -0500 Subject: [PATCH 2/3] UptimeRobot: Increase precision of percentage to 2 decimals --- modules/uptimerobot/widget.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/uptimerobot/widget.go b/modules/uptimerobot/widget.go index a093e235d..597a82ca5 100644 --- a/modules/uptimerobot/widget.go +++ b/modules/uptimerobot/widget.go @@ -129,7 +129,7 @@ func formatUptimes(str string) string { parts := make([]string, 0, len(splits)) for _, s := range splits { if f, err := strconv.ParseFloat(s, 64); err == nil { - parts = append(parts, utils.ColorizeUptimePercent(math.Round(f*10)/10)+"%") + parts = append(parts, utils.ColorizeUptimePercent(math.Round(f*100)/100)+"%") } else { s = s[:5] s = strings.TrimRight(s, "0") From de342caae494530876b6a1e5401fc6f9ac6f64c8 Mon Sep 17 00:00:00 2001 From: huyz Date: Tue, 5 May 2026 13:42:40 -0500 Subject: [PATCH 3/3] Colors utils: add unit tests --- utils/colors_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/utils/colors_test.go b/utils/colors_test.go index 37999c3bb..10a294e99 100644 --- a/utils/colors_test.go +++ b/utils/colors_test.go @@ -41,3 +41,44 @@ func Test_ColorizePercent(t *testing.T) { }) } } + +func Test_ColorizeUptimePercent(t *testing.T) { + tests := []struct { + name string + percent float64 + expected string + }{ + { + name: "with excellent uptime", + percent: 99, + expected: "[green]99[white]", + }, + { + name: "with good uptime", + percent: 95, + expected: "[yellow]95[white]", + }, + { + name: "with acceptable uptime", + percent: 80, + expected: "[orange]80[white]", + }, + { + name: "with poor uptime", + percent: 50, + expected: "[red]50[white]", + }, + { + name: "with negative percent", + percent: -1, + expected: "[grey]-1[white]", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := ColorizeUptimePercent(tt.percent) + assert.Equal(t, tt.expected, actual) + }) + } +}