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{} }