diff options
author | T <t@tjp.lol> | 2025-08-05 11:37:02 -0600 |
---|---|---|
committer | T <t@tjp.lol> | 2025-08-05 11:37:08 -0600 |
commit | 665bd389a0a1c8adadcaa1122e846cc81f5ead31 (patch) | |
tree | f34f9ec77891308c600c680683f60951599429c3 /internal/tui/keys.go | |
parent | dc895cec9d8a84af89ce2501db234dff33c757e2 (diff) |
WIP TUI
Diffstat (limited to 'internal/tui/keys.go')
-rw-r--r-- | internal/tui/keys.go | 229 |
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{} +} |