summaryrefslogtreecommitdiff
path: root/internal/tui/keys.go
diff options
context:
space:
mode:
authorT <t@tjp.lol>2025-08-05 11:37:02 -0600
committerT <t@tjp.lol>2025-08-05 11:37:08 -0600
commit665bd389a0a1c8adadcaa1122e846cc81f5ead31 (patch)
treef34f9ec77891308c600c680683f60951599429c3 /internal/tui/keys.go
parentdc895cec9d8a84af89ce2501db234dff33c757e2 (diff)
WIP TUI
Diffstat (limited to 'internal/tui/keys.go')
-rw-r--r--internal/tui/keys.go229
1 files changed, 229 insertions, 0 deletions
diff --git a/internal/tui/keys.go b/internal/tui/keys.go
new file mode 100644
index 0000000..7f23407
--- /dev/null
+++ b/internal/tui/keys.go
@@ -0,0 +1,229 @@
+package tui
+
+import (
+ tea "github.com/charmbracelet/bubbletea"
+)
+
+// KeyAction represents the action to take for a key press
+type KeyAction int
+
+const (
+ // Global actions
+ ActionNone KeyAction = iota
+ ActionNextPane
+ ActionPrevPane
+ ActionPunchToggle
+ ActionSearch
+ ActionRefresh
+ ActionQuit
+
+ // Timer pane actions
+ ActionTimerEnter
+ ActionTimerDescribe
+
+ // Projects pane actions
+ ActionProjectsNext
+ ActionProjectsPrev
+ ActionProjectsEnter
+ ActionProjectsNewProject
+ ActionProjectsNewClient
+
+ // History pane actions (level 1)
+ ActionHistoryNext
+ ActionHistoryPrev
+ ActionHistoryEnter
+
+ // History pane actions (level 2)
+ ActionHistoryEdit
+ ActionHistoryDelete
+ ActionHistoryResume
+ ActionHistoryBack
+)
+
+// KeyHandler processes key messages and returns the appropriate action
+func HandleKeyPress(msg tea.KeyMsg, selectedBox BoxType, historyLevel HistoryViewLevel, hasActiveTimer bool) KeyAction {
+ key := msg.String()
+
+ // Global keybindings (always available)
+ switch key {
+ case "ctrl+n":
+ return ActionNextPane
+ case "ctrl+p":
+ return ActionPrevPane
+ case "p":
+ return ActionPunchToggle
+ case "/":
+ return ActionSearch
+ case "r":
+ return ActionRefresh
+ case "q", "ctrl+c", "ctrl+d":
+ return ActionQuit
+ }
+
+ // Context-specific keybindings based on selected box
+ switch selectedBox {
+ case TimerBox:
+ return handleTimerKeys(key, hasActiveTimer)
+ case ClientsProjectsBox:
+ return handleProjectsKeys(key)
+ case HistoryBox:
+ return handleHistoryKeys(key, historyLevel)
+ }
+
+ return ActionNone
+}
+
+// handleTimerKeys handles keys specific to the timer box
+func handleTimerKeys(key string, hasActiveTimer bool) KeyAction {
+ switch key {
+ case "enter":
+ return ActionTimerEnter
+ case "d":
+ if hasActiveTimer {
+ return ActionTimerDescribe
+ }
+ }
+ return ActionNone
+}
+
+// handleProjectsKeys handles keys specific to the projects box
+func handleProjectsKeys(key string) KeyAction {
+ switch key {
+ case "j", "down":
+ return ActionProjectsNext
+ case "k", "up":
+ return ActionProjectsPrev
+ case "enter":
+ return ActionProjectsEnter
+ case "n":
+ return ActionProjectsNewProject
+ case "N":
+ return ActionProjectsNewClient
+ }
+ return ActionNone
+}
+
+// handleHistoryKeys handles keys specific to the history box
+func handleHistoryKeys(key string, level HistoryViewLevel) KeyAction {
+ switch level {
+ case HistoryLevelSummary:
+ return handleHistoryLevel1Keys(key)
+ case HistoryLevelDetails:
+ return handleHistoryLevel2Keys(key)
+ }
+ return ActionNone
+}
+
+// handleHistoryLevel1Keys handles keys for history summary view
+func handleHistoryLevel1Keys(key string) KeyAction {
+ switch key {
+ case "j", "down":
+ return ActionHistoryNext
+ case "k", "up":
+ return ActionHistoryPrev
+ case "enter":
+ return ActionHistoryEnter
+ }
+ return ActionNone
+}
+
+// handleHistoryLevel2Keys handles keys for history details view
+func handleHistoryLevel2Keys(key string) KeyAction {
+ switch key {
+ case "j", "down":
+ return ActionHistoryNext
+ case "k", "up":
+ return ActionHistoryPrev
+ case "e":
+ return ActionHistoryEdit
+ case "d":
+ return ActionHistoryDelete
+ case "enter":
+ return ActionHistoryResume
+ case "b", "escape":
+ return ActionHistoryBack
+ }
+ return ActionNone
+}
+
+// GetContextualKeyBindings returns the key bindings that should be shown in the bottom bar
+func GetContextualKeyBindings(selectedBox BoxType, historyLevel HistoryViewLevel, hasActiveTimer bool) []KeyBinding {
+ var bindings []KeyBinding
+
+ // Global bindings (always shown)
+ bindings = append(bindings, []KeyBinding{
+ {"Ctrl+n", "Next"},
+ {"Ctrl+p", "Prev"},
+ }...)
+
+ // Add punch toggle binding
+ if hasActiveTimer {
+ bindings = append(bindings, KeyBinding{"p", "Punch Out"})
+ } else {
+ bindings = append(bindings, KeyBinding{"p", "Punch In"})
+ }
+
+ // Add search and refresh bindings
+ bindings = append(bindings, []KeyBinding{
+ {"/", "Search"},
+ {"r", "Refresh"},
+ }...)
+
+ // Context-specific bindings
+ switch selectedBox {
+ case TimerBox:
+ bindings = append(bindings, getTimerKeyBindings(hasActiveTimer)...)
+ case ClientsProjectsBox:
+ bindings = append(bindings, getProjectsKeyBindings()...)
+ case HistoryBox:
+ bindings = append(bindings, getHistoryKeyBindings(historyLevel)...)
+ }
+
+ // Always end with quit
+ bindings = append(bindings, KeyBinding{"q", "Quit"})
+
+ return bindings
+}
+
+// getTimerKeyBindings returns key bindings for the timer box
+func getTimerKeyBindings(hasActiveTimer bool) []KeyBinding {
+ if hasActiveTimer {
+ return []KeyBinding{
+ {"Enter", "Punch Out"},
+ {"d", "Describe"},
+ }
+ }
+ return []KeyBinding{
+ {"Enter", "Resume Recent"},
+ }
+}
+
+// getProjectsKeyBindings returns key bindings for the projects box
+func getProjectsKeyBindings() []KeyBinding {
+ return []KeyBinding{
+ {"j/k", "Navigate"},
+ {"Enter", "Select"},
+ {"n", "New Project"},
+ {"N", "New Client"},
+ }
+}
+
+// getHistoryKeyBindings returns key bindings for the history box
+func getHistoryKeyBindings(level HistoryViewLevel) []KeyBinding {
+ switch level {
+ case HistoryLevelSummary:
+ return []KeyBinding{
+ {"j/k", "Navigate"},
+ {"Enter", "Details"},
+ }
+ case HistoryLevelDetails:
+ return []KeyBinding{
+ {"j/k", "Navigate"},
+ {"Enter", "Resume"},
+ {"e", "Edit"},
+ {"d", "Delete"},
+ {"b", "Back"},
+ }
+ }
+ return []KeyBinding{}
+}