MCPcopy
hub / github.com/docker/docker-agent / handleSwitchTab

Method handleSwitchTab

pkg/tui/tui.go:1523–1638  ·  view source on GitHub ↗

handleSwitchTab switches to a different session. Existing chat pages and editors are preserved (not recreated) so that in-flight streaming content and draft text are retained when switching back to a tab.

(sessionID string)

Source from the content-addressed store, hash-verified

1521// Existing chat pages and editors are preserved (not recreated) so that in-flight streaming
1522// content and draft text are retained when switching back to a tab.
1523func (m *appModel) handleSwitchTab(sessionID string) (tea.Model, tea.Cmd) {
1524 // If a background dialog (e.g. pending elicitation) is open on the
1525 // outgoing tab, capture both its originating event and the live dialog
1526 // instance before the supervisor flips activeID. We only commit the
1527 // re-stash after SwitchTo succeeds — otherwise a failed switch would
1528 // leave the supervisor with a stale pending event and the dialog still
1529 // on screen.
1530 //
1531 // Stashing the dialog instance (rather than rebuilding it from the event
1532 // on return) preserves any in-progress input the user typed — e.g. text
1533 // already entered into a user_prompt elicitation. See issue #2770.
1534 var (
1535 backgroundEvent tea.Msg
1536 backgroundDialog dialog.Dialog
1537 outgoingTabID string
1538 )
1539 if m.dialogMgr.Open() && m.dialogMgr.TopIsBackground() {
1540 backgroundEvent = m.dialogMgr.TopBackgroundEvent()
1541 backgroundDialog = m.dialogMgr.TopDialog()
1542 outgoingTabID = m.supervisor.ActiveID()
1543 }
1544
1545 runner := m.supervisor.SwitchTo(sessionID)
1546 if runner == nil {
1547 return m, notification.ErrorCmd("Session not found")
1548 }
1549
1550 // Now that the switch is committed, finalize the dialog hand-off.
1551 var closeBackgroundDialogCmd tea.Cmd
1552 if backgroundEvent != nil && outgoingTabID != "" && outgoingTabID != sessionID {
1553 m.supervisor.SetPendingEvent(outgoingTabID, backgroundEvent)
1554 if backgroundDialog != nil {
1555 m.stashedDialogs[outgoingTabID] = stashedDialog{
1556 dialog: backgroundDialog,
1557 event: backgroundEvent,
1558 }
1559 }
1560 closeBackgroundDialogCmd = core.CmdHandler(dialog.CloseDialogMsg{})
1561 }
1562
1563 // Blur current editor before switching
1564 m.editor.Blur()
1565
1566 // If this tab has a pending session restore, load it through
1567 // replaceActiveSession — the same code path as the /sessions command.
1568 if oldSessionID, ok := m.pendingRestores[sessionID]; ok {
1569 delete(m.pendingRestores, sessionID)
1570 m.application = runner.App
1571 if store := runner.App.SessionStore(); store != nil {
1572 if sess, err := store.GetSession(m.ctx(), oldSessionID); err == nil {
1573 m.persistActiveTab(sess.ID)
1574 model, cmd := m.replaceActiveSession(m.ctx(), sess)
1575
1576 if m.tuiStore != nil && sess.WorkingDir != "" {
1577 if err := m.tuiStore.UpdateTabWorkingDir(m.ctx(), oldSessionID, sess.WorkingDir); err != nil {
1578 slog.Warn("Failed to update persisted working dir", "error", err)
1579 }
1580 }

Callers 6

handleForkSessionMethod · 0.95
initMethod · 0.95
updateMethod · 0.95
handleLoadSessionMethod · 0.95
handleSpawnSessionMethod · 0.95
handleCloseTabMethod · 0.95

Calls 15

persistActiveTabMethod · 0.95
replaceActiveSessionMethod · 0.95
applySidebarCollapsedMethod · 0.95
initSessionComponentsMethod · 0.95
persistedSessionIDMethod · 0.95
resizeAllMethod · 0.95
replayPendingEventMethod · 0.95
ErrorCmdFunction · 0.92
CmdHandlerFunction · 0.92
NewFunction · 0.92
ActiveIDMethod · 0.80

Tested by

no test coverage detected