@@ -324,7 +324,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
Description: "Switch to a different session",
Shortcut: "ctrl+s",
Handler: func(cmd uicmd.Command) tea.Cmd {
- return uiutil.CmdHandler(SwitchSessionsMsg{})
+ return uiutil.CmdHandler(OpenDialogMsg{SessionsID})
},
},
{
@@ -333,7 +333,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
Description: "Switch to a different model",
Shortcut: "ctrl+l",
Handler: func(cmd uicmd.Command) tea.Cmd {
- return uiutil.CmdHandler(SwitchModelMsg{})
+ return uiutil.CmdHandler(OpenDialogMsg{ModelsID})
},
},
}
@@ -12,6 +12,11 @@ type CloseMsg struct{}
// QuitMsg is a message to quit the application.
type QuitMsg = tea.QuitMsg
+// OpenDialogMsg is a message to open a dialog.
+type OpenDialogMsg struct {
+ DialogID string
+}
+
// SessionSelectedMsg is a message indicating a session has been selected.
type SessionSelectedMsg struct {
Session session.Session
@@ -25,9 +30,7 @@ type ModelSelectedMsg struct {
// Messages for commands
type (
- SwitchSessionsMsg struct{}
NewSessionsMsg struct{}
- SwitchModelMsg struct{}
OpenFilePickerMsg struct{}
ToggleHelpMsg struct{}
ToggleCompactModeMsg struct{}
@@ -64,11 +64,6 @@ type openEditorMsg struct {
Text string
}
-// listSessionsMsg is a message to list available sessions.
-type listSessionsMsg struct {
- sessions []session.Session
-}
-
// UI represents the main user interface model.
type UI struct {
com *common.Common
@@ -190,10 +185,6 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
if !m.sendProgressBar {
m.sendProgressBar = slices.Contains(msg, "WT_SESSION")
}
- case listSessionsMsg:
- if cmd := m.openSessionsDialog(msg.sessions); cmd != nil {
- cmds = append(cmds, cmd)
- }
case loadSessionMsg:
m.state = uiChat
m.session = msg.session
@@ -499,11 +490,8 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
}
return true
case key.Matches(msg, m.keyMap.Sessions):
- if m.dialog.ContainsDialog(dialog.SessionsID) {
- // Bring to front
- m.dialog.BringToFront(dialog.SessionsID)
- } else {
- cmds = append(cmds, m.listSessions)
+ if cmd := m.openSessionsDialog(); cmd != nil {
+ cmds = append(cmds, cmd)
}
return true
}
@@ -536,15 +524,30 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
m.dialog.CloseDialog(dialog.SessionsID)
cmds = append(cmds, m.loadSession(msg.Session.ID))
+ // Open dialog message
+ case dialog.OpenDialogMsg:
+ switch msg.DialogID {
+ case dialog.SessionsID:
+ if cmd := m.openSessionsDialog(); cmd != nil {
+ cmds = append(cmds, cmd)
+ }
+ case dialog.ModelsID:
+ if cmd := m.openModelsDialog(); cmd != nil {
+ cmds = append(cmds, cmd)
+ }
+ default:
+ // Unknown dialog
+ break
+ }
+
+ m.dialog.CloseDialog(msg.DialogID)
+
// Command dialog messages
case dialog.ToggleYoloModeMsg:
yolo := !m.com.App.Permissions.SkipRequests()
m.com.App.Permissions.SetSkipRequests(yolo)
m.setEditorPrompt(yolo)
m.dialog.CloseDialog(dialog.CommandsID)
- case dialog.SwitchSessionsMsg:
- cmds = append(cmds, m.listSessions)
- m.dialog.CloseDialog(dialog.CommandsID)
case dialog.NewSessionsMsg:
if m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
cmds = append(cmds, uiutil.ReportWarn("Agent is busy, please wait before starting a new session..."))
@@ -562,11 +565,6 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
m.dialog.CloseDialog(dialog.CommandsID)
case dialog.QuitMsg:
cmds = append(cmds, tea.Quit)
- case dialog.SwitchModelMsg:
- m.dialog.CloseDialog(dialog.CommandsID)
- if cmd := m.openModelsDialog(); cmd != nil {
- cmds = append(cmds, cmd)
- }
case dialog.ModelSelectedMsg:
// TODO: Handle model switching
}
@@ -1428,14 +1426,21 @@ func (m *UI) openCommandsDialog() tea.Cmd {
return nil
}
-// openSessionsDialog opens the sessions dialog with the given sessions.
-func (m *UI) openSessionsDialog(sessions []session.Session) tea.Cmd {
+// openSessionsDialog opens the sessions dialog. If the dialog is already open,
+// it brings it to the front. Otherwise, it will list all the sessions and open
+// the dialog.
+func (m *UI) openSessionsDialog() tea.Cmd {
if m.dialog.ContainsDialog(dialog.SessionsID) {
// Bring to front
m.dialog.BringToFront(dialog.SessionsID)
return nil
}
+ sessions, err := m.com.App.Sessions.List(context.TODO())
+ if err != nil {
+ return uiutil.ReportError(err)
+ }
+
dialog := dialog.NewSessions(m.com, sessions...)
// TODO: Get. Rid. Of. Magic numbers!
dialog.SetSize(min(120, m.width-8), 30)
@@ -1444,13 +1449,6 @@ func (m *UI) openSessionsDialog(sessions []session.Session) tea.Cmd {
return nil
}
-// listSessions is a [tea.Cmd] that lists all sessions and returns them in a
-// [listSessionsMsg].
-func (m *UI) listSessions() tea.Msg {
- allSessions, _ := m.com.App.Sessions.List(context.TODO())
- return listSessionsMsg{sessions: allSessions}
-}
-
// newSession clears the current session state and prepares for a new session.
// The actual session creation happens when the user sends their first message.
func (m *UI) newSession() {