summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-04 00:05:49 +0200
committerPaul Buetow <paul@buetow.org>2026-03-04 00:05:49 +0200
commitc6a9ee27141fd1a57813fcc7f54fe370408bae14 (patch)
tree12c8332d0f63f14fce5d9d423743bdee84b28b1c /internal
parentadd16f3c268a7a001259e50ebd1b393ede3cb0a7 (diff)
worktime: centralize active category status logic
Diffstat (limited to 'internal')
-rw-r--r--internal/cli/work.go30
-rw-r--r--internal/tui/timer.go20
-rw-r--r--internal/worktime/entries.go26
-rw-r--r--internal/worktime/entries_test.go16
4 files changed, 43 insertions, 49 deletions
diff --git a/internal/cli/work.go b/internal/cli/work.go
index 775a0d7..1f34cf9 100644
--- a/internal/cli/work.go
+++ b/internal/cli/work.go
@@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
- "sort"
"strconv"
"strings"
"time"
@@ -296,7 +295,7 @@ func newWorkStatusCmd() *cobra.Command {
return err
}
- active := activeCategories(entries)
+ active := worktime.ActiveCategories(entries)
if len(active) == 0 {
return printOutput(cmd, "Not logged in.")
}
@@ -396,33 +395,6 @@ func parseAtOrNow(value string) (time.Time, error) {
return timefmt.Parse(value)
}
-func activeCategories(entries []worktime.Entry) []string {
- status := map[string]bool{}
-
- for _, entry := range entries {
- category := strings.TrimSpace(entry.What)
- if category == "" {
- category = "work"
- }
-
- switch strings.ToLower(strings.TrimSpace(entry.Action)) {
- case "login":
- status[category] = true
- case "logout":
- status[category] = false
- }
- }
-
- active := make([]string, 0)
- for category, isActive := range status {
- if isActive {
- active = append(active, category)
- }
- }
- sort.Strings(active)
- return active
-}
-
func importReportFile(ctx workContext, report io.Reader) (int, error) {
return worktime.ImportReport(ctx.dbDir, ctx.host, report)
}
diff --git a/internal/tui/timer.go b/internal/tui/timer.go
index d02a890..4a1af3c 100644
--- a/internal/tui/timer.go
+++ b/internal/tui/timer.go
@@ -260,22 +260,10 @@ func (w *workIntegration) refreshStatus() {
}
func workCategoryLoggedIn(entries []worktime.Entry) bool {
- loggedIn := false
- for _, entry := range entries {
- category := strings.TrimSpace(entry.What)
- if category == "" {
- category = "work"
- }
- if category != "work" {
- continue
- }
-
- switch strings.ToLower(strings.TrimSpace(entry.Action)) {
- case "login":
- loggedIn = true
- case "logout":
- loggedIn = false
+ for _, category := range worktime.ActiveCategories(entries) {
+ if category == "work" {
+ return true
}
}
- return loggedIn
+ return false
}
diff --git a/internal/worktime/entries.go b/internal/worktime/entries.go
index b9a7e40..fd116ba 100644
--- a/internal/worktime/entries.go
+++ b/internal/worktime/entries.go
@@ -3,6 +3,7 @@ package worktime
import (
"errors"
"fmt"
+ "sort"
"strings"
"time"
)
@@ -186,18 +187,35 @@ func isLoggedIn(dbDir, category string) (bool, error) {
return false, err
}
+ for _, active := range ActiveCategories(entries) {
+ if active == category {
+ return true, nil
+ }
+ }
+ return false, nil
+}
+
+// ActiveCategories returns sorted categories that are currently logged in.
+func ActiveCategories(entries []Entry) []string {
status := map[string]bool{}
for _, entry := range entries {
- cat := normalizeCategory(entry.What)
+ category := normalizeCategory(entry.What)
switch strings.ToLower(strings.TrimSpace(entry.Action)) {
case actionLogin:
- status[cat] = true
+ status[category] = true
case actionLogout:
- status[cat] = false
+ status[category] = false
}
}
- return status[category], nil
+ active := make([]string, 0, len(status))
+ for category, loggedIn := range status {
+ if loggedIn {
+ active = append(active, category)
+ }
+ }
+ sort.Strings(active)
+ return active
}
func normalizeCategory(category string) string {
diff --git a/internal/worktime/entries_test.go b/internal/worktime/entries_test.go
index f49dbd8..c0caf4a 100644
--- a/internal/worktime/entries_test.go
+++ b/internal/worktime/entries_test.go
@@ -2,6 +2,7 @@ package worktime
import (
"errors"
+ "reflect"
"testing"
"time"
)
@@ -51,6 +52,21 @@ func TestLoginValidationIsCategoryScoped(t *testing.T) {
}
}
+func TestActiveCategories(t *testing.T) {
+ entries := []Entry{
+ {Action: "login", What: "work"},
+ {Action: "login", What: "lunch"},
+ {Action: "logout", What: "lunch"},
+ {Action: "login", What: ""},
+ }
+
+ got := ActiveCategories(entries)
+ want := []string{"work"}
+ if !reflect.DeepEqual(got, want) {
+ t.Fatalf("ActiveCategories() = %v, want %v", got, want)
+ }
+}
+
func TestAddSubAndUseBuffer(t *testing.T) {
dbDir := t.TempDir()
host := "host-a"