summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/tui/tui.go140
1 files changed, 88 insertions, 52 deletions
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index c1ba700..aaad69c 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -328,7 +328,7 @@ func initialWindowSizeCmd() tea.Cmd {
// Update routes messages, transitions screens, and manages tracing startup state.
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
- normalizedMsg, ok := m.normalizeKeyEvent(msg)
+ normalizedMsg, ok := m.keyNormalizer(msg)
if !ok {
return m, nil
}
@@ -361,34 +361,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.dashboard.SetFocused(false)
return m, nil
case tea.KeyPressMsg:
- if key.Matches(msg, m.keys.Quit) {
- m.quitting = true
- m.stopTrace()
- return m, tea.Quit
- }
- if m.helpOverlayVisible {
- if isHelpOverlayCloseKey(msg) || isHelpOverlayOpenKey(msg) {
- m.helpOverlayVisible = false
- }
- return m, nil
- }
- if isHelpOverlayOpenKey(msg) && !m.attaching && m.lastErr == nil {
- m.helpOverlayVisible = true
- return m, nil
- }
- if m.exportEnabled && m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.Export) && !m.exporter.Visible() && !m.probeModal.Visible() && !m.dashboard.BlocksGlobalShortcuts(msg) {
- m.exporter = m.exporter.Open()
- return m, nil
- }
- if m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.Probes) && !m.exporter.Visible() && !m.probeModal.Visible() && !m.dashboard.BlocksGlobalShortcuts(msg) {
- m.probeModal = probes.NewModel(m.runtime.currentProbeManager()).SetDarkMode(m.isDark).Open()
- return m, nil
- }
- if m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.SelectPID) && !m.exporter.Visible() && !m.probeModal.Visible() && !m.dashboard.BlocksGlobalShortcuts(msg) {
- return m.reselectPID()
- }
- if m.screen == ScreenDashboard && !m.attaching && m.lastErr == nil && key.Matches(msg, m.keys.SelectTID) && !m.exporter.Visible() && !m.probeModal.Visible() && !m.dashboard.BlocksGlobalShortcuts(msg) {
- return m.reselectTID()
+ if next, cmd, handled := m.handleGlobalKeyPress(msg); handled {
+ return next, cmd
}
case tuiexport.RequestMsg:
return m, runExportCmd(m.exportEnabled, msg.Option, m.dashboard.LatestSnapshot())
@@ -427,37 +401,99 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, nil
}
+ if next, cmd, handled := m.handleModalDispatch(msg); handled {
+ return next, cmd
+ }
+
+ return m.updateActiveModel(msg)
+}
+
+func (m *Model) keyNormalizer(msg tea.Msg) (tea.Msg, bool) {
+ return m.normalizeKeyEvent(msg)
+}
+
+func (m Model) canHandleDashboardShortcut(msg tea.KeyPressMsg) bool {
+ return m.screen == ScreenDashboard &&
+ !m.attaching &&
+ m.lastErr == nil &&
+ !m.exporter.Visible() &&
+ !m.probeModal.Visible() &&
+ !m.dashboard.BlocksGlobalShortcuts(msg)
+}
+
+func (m Model) handleGlobalKeyPress(msg tea.KeyPressMsg) (tea.Model, tea.Cmd, bool) {
+ if key.Matches(msg, m.keys.Quit) {
+ m.quitting = true
+ m.stopTrace()
+ return m, tea.Quit, true
+ }
+ if m.helpOverlayVisible {
+ if isHelpOverlayCloseKey(msg) || isHelpOverlayOpenKey(msg) {
+ m.helpOverlayVisible = false
+ }
+ return m, nil, true
+ }
+ if isHelpOverlayOpenKey(msg) && !m.attaching && m.lastErr == nil {
+ m.helpOverlayVisible = true
+ return m, nil, true
+ }
+ if m.exportEnabled && m.canHandleDashboardShortcut(msg) && key.Matches(msg, m.keys.Export) {
+ m.exporter = m.exporter.Open()
+ return m, nil, true
+ }
+ if m.canHandleDashboardShortcut(msg) && key.Matches(msg, m.keys.Probes) {
+ m.probeModal = probes.NewModel(m.runtime.currentProbeManager()).SetDarkMode(m.isDark).Open()
+ return m, nil, true
+ }
+ if m.canHandleDashboardShortcut(msg) && key.Matches(msg, m.keys.SelectPID) {
+ next, cmd := m.reselectPID()
+ return next, cmd, true
+ }
+ if m.canHandleDashboardShortcut(msg) && key.Matches(msg, m.keys.SelectTID) {
+ next, cmd := m.reselectTID()
+ return next, cmd, true
+ }
+ return m, nil, false
+}
+
+func (m Model) updateDashboardForModal(msg tea.Msg) (Model, tea.Cmd) {
+ if _, isKey := msg.(tea.KeyPressMsg); isKey || m.screen != ScreenDashboard {
+ return m, nil
+ }
+ next, cmd := m.dashboard.Update(msg)
+ m.dashboard = next.(dashboardui.Model)
+ return m, cmd
+}
+
+func (m Model) updateProbeModal(msg tea.Msg) (tea.Model, tea.Cmd) {
+ m, dashboardCmd := m.updateDashboardForModal(msg)
+ var cmd tea.Cmd
+ m.probeModal, cmd = m.probeModal.Update(msg)
+ return m, tea.Batch(dashboardCmd, cmd)
+}
+
+func (m Model) updateExportModal(msg tea.Msg) (tea.Model, tea.Cmd) {
+ m, dashboardCmd := m.updateDashboardForModal(msg)
+ var cmd tea.Cmd
+ m.exporter, cmd = m.exporter.Update(msg)
+ return m, tea.Batch(dashboardCmd, cmd)
+}
+
+func (m Model) handleModalDispatch(msg tea.Msg) (tea.Model, tea.Cmd, bool) {
if m.attaching {
var cmd tea.Cmd
m.spin, cmd = m.spin.Update(msg)
- return m, cmd
+ return m, cmd, true
}
if m.probeModal.Visible() {
- var dashboardCmd tea.Cmd
- // Keep dashboard refresh/data flow alive while probe modal is open.
- if _, isKey := msg.(tea.KeyPressMsg); !isKey && m.screen == ScreenDashboard {
- next, cmd := m.dashboard.Update(msg)
- m.dashboard = next.(dashboardui.Model)
- dashboardCmd = cmd
- }
- var cmd tea.Cmd
- m.probeModal, cmd = m.probeModal.Update(msg)
- return m, tea.Batch(dashboardCmd, cmd)
+ next, cmd := m.updateProbeModal(msg)
+ return next, cmd, true
}
if m.exporter.Visible() {
- var dashboardCmd tea.Cmd
- // Keep dashboard refresh/data flow alive while export modal is open.
- if _, isKey := msg.(tea.KeyPressMsg); !isKey && m.screen == ScreenDashboard {
- next, cmd := m.dashboard.Update(msg)
- m.dashboard = next.(dashboardui.Model)
- dashboardCmd = cmd
- }
- var cmd tea.Cmd
- m.exporter, cmd = m.exporter.Update(msg)
- return m, tea.Batch(dashboardCmd, cmd)
+ next, cmd := m.updateExportModal(msg)
+ return next, cmd, true
}
-
- return m.updateActiveModel(msg)
+ return m, nil, false
}
func (m *Model) normalizeKeyEvent(msg tea.Msg) (tea.Msg, bool) {