summaryrefslogtreecommitdiff
path: root/internal/tui/screenrouter.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-12 22:47:20 +0300
committerPaul Buetow <paul@buetow.org>2026-05-12 22:47:20 +0300
commit35df301fceabfadc8b8a4ae221cc0c2391e233cd (patch)
tree2d5da8031aacd588e31db1aad05c2956412f7566 /internal/tui/screenrouter.go
parenta2c067cc49b96968da81031275de9c44c4ba2ee9 (diff)
extract TUI Model god class into focused sub-controllers
Split the 1389-line tui.go Model into three focused sub-controllers that each own a single concern: - filterstack.go (filterStack): owns the filter chain, undo history, and label stack; provides push/pop/rebindProcessFilters API so the Model never manipulates filter slices directly. - tracelifecycle.go (traceLifecycle): owns trace start/stop and the active context.CancelFunc; provides beginCmd/stop API; also houses the recorder helpers (recorderStart/Stop/Active/Status) and the auto-reset cycle logic (nextAutoResetInterval, autoResetCycle). - screenrouter.go (screenRouter): owns the picker-return bookmark (pickerReturn) and the applyWindowSizeToPicker helper so screen transition code in tui.go delegates to it. The Model.Update switch is split into dispatchTypedMsg (framework messages) and dispatchAppMsg (app messages) to keep each helper under the 50-line limit. View is split into viewPickerScreen and viewDashboardScreen for the same reason. All functions are ≤50 lines. go test ./internal/tui/... passes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/tui/screenrouter.go')
-rw-r--r--internal/tui/screenrouter.go60
1 files changed, 60 insertions, 0 deletions
diff --git a/internal/tui/screenrouter.go b/internal/tui/screenrouter.go
new file mode 100644
index 0000000..9a110c8
--- /dev/null
+++ b/internal/tui/screenrouter.go
@@ -0,0 +1,60 @@
+package tui
+
+import (
+ "ior/internal/tui/pidpicker"
+
+ tea "charm.land/bubbletea/v2"
+)
+
+// screenRouter owns screen-transition state for the TUI. It tracks the picker
+// return bookmark used when the user navigates from the dashboard to the PID or
+// TID picker and may want to cancel back to the original dashboard view.
+type screenRouter struct {
+ // pickerReturn is non-nil while the user has navigated from the dashboard
+ // back to the PID/TID picker. The stored values are used to restart the
+ // trace if the user presses Esc to cancel the picker navigation.
+ pickerReturn *pickerReturnState
+}
+
+// newScreenRouter creates an empty screenRouter with no pending return state.
+func newScreenRouter() screenRouter {
+ return screenRouter{}
+}
+
+// savePendingReturn records the current pid/tid so Esc can restore the
+// dashboard if the user decides not to select a new process.
+func (r *screenRouter) savePendingReturn(pid, tid int) {
+ r.pickerReturn = &pickerReturnState{
+ pidFilter: pid,
+ tidFilter: tid,
+ }
+}
+
+// takePendingReturn consumes and returns the stored picker return state,
+// clearing it in the process. Returns (zero, false) when no pending state exists.
+func (r *screenRouter) takePendingReturn() (pickerReturnState, bool) {
+ if r.pickerReturn == nil {
+ return pickerReturnState{}, false
+ }
+ state := *r.pickerReturn
+ r.pickerReturn = nil
+ return state, true
+}
+
+// hasPendingReturn reports whether the user navigated from the dashboard to
+// the picker (meaning Esc should return to the dashboard instead of quitting).
+func (r *screenRouter) hasPendingReturn() bool {
+ return r.pickerReturn != nil
+}
+
+// applyWindowSizeToPicker sends the current window size to the pid picker when
+// valid dimensions are available. Returns the updated picker and an optional
+// size command.
+func applyWindowSizeToPicker(picker pidpicker.Model, width, height int) (pidpicker.Model, tea.Cmd) {
+ if width <= 0 || height <= 0 {
+ return picker, nil
+ }
+ msg := tea.WindowSizeMsg{Width: width, Height: height}
+ next, cmd := picker.Update(msg)
+ return next.(pidpicker.Model), cmd
+}