on main help sign in
refactor(ui): dialog: unify session and model switching dialogs
eed0b49Ayman Bagabas
internal/ui/dialog/commands.go+2−2
@@ -324,7 +324,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
324 Description: "Switch to a different session",
324 Description: "Switch to a different session",
325 Shortcut: "ctrl+s",
325 Shortcut: "ctrl+s",
326 Handler: func(cmd uicmd.Command) tea.Cmd {
326 Handler: func(cmd uicmd.Command) tea.Cmd {
327− return uiutil.CmdHandler(SwitchSessionsMsg{})
327+ return uiutil.CmdHandler(OpenDialogMsg{SessionsID})
328 },
328 },
329 },
329 },
330 {
330 {
@@ -333,7 +333,7 @@ func (c *Commands) defaultCommands() []uicmd.Command {
333 Description: "Switch to a different model",
333 Description: "Switch to a different model",
334 Shortcut: "ctrl+l",
334 Shortcut: "ctrl+l",
335 Handler: func(cmd uicmd.Command) tea.Cmd {
335 Handler: func(cmd uicmd.Command) tea.Cmd {
336− return uiutil.CmdHandler(SwitchModelMsg{})
336+ return uiutil.CmdHandler(OpenDialogMsg{ModelsID})
337 },
337 },
338 },
338 },
339 }
339 }
internal/ui/dialog/messages.go+5−2
@@ -12,6 +12,11 @@ type CloseMsg struct{}
12// QuitMsg is a message to quit the application.
12// QuitMsg is a message to quit the application.
13type QuitMsg = tea.QuitMsg
13type QuitMsg = tea.QuitMsg
14
14
15+// OpenDialogMsg is a message to open a dialog.
16+type OpenDialogMsg struct {
17+ DialogID string
18+}
19+
15// SessionSelectedMsg is a message indicating a session has been selected.
20// SessionSelectedMsg is a message indicating a session has been selected.
16type SessionSelectedMsg struct {
21type SessionSelectedMsg struct {
17 Session session.Session
22 Session session.Session
@@ -25,9 +30,7 @@ type ModelSelectedMsg struct {
25
30
26// Messages for commands
31// Messages for commands
27type (
32type (
28− SwitchSessionsMsg struct{}
29 NewSessionsMsg struct{}
33 NewSessionsMsg struct{}
30− SwitchModelMsg struct{}
31 OpenFilePickerMsg struct{}
34 OpenFilePickerMsg struct{}
32 ToggleHelpMsg struct{}
35 ToggleHelpMsg struct{}
33 ToggleCompactModeMsg struct{}
36 ToggleCompactModeMsg struct{}
internal/ui/model/ui.go+29−31
@@ -64,11 +64,6 @@ type openEditorMsg struct {
64 Text string
64 Text string
65}
65}
66
66
67−// listSessionsMsg is a message to list available sessions.
68−type listSessionsMsg struct {
69− sessions []session.Session
70−}
71−
72// UI represents the main user interface model.
67// UI represents the main user interface model.
73type UI struct {
68type UI struct {
74 com *common.Common
69 com *common.Common
@@ -190,10 +185,6 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
190 if !m.sendProgressBar {
185 if !m.sendProgressBar {
191 m.sendProgressBar = slices.Contains(msg, "WT_SESSION")
186 m.sendProgressBar = slices.Contains(msg, "WT_SESSION")
192 }
187 }
193− case listSessionsMsg:
194− if cmd := m.openSessionsDialog(msg.sessions); cmd != nil {
195− cmds = append(cmds, cmd)
196− }
197 case loadSessionMsg:
188 case loadSessionMsg:
198 m.state = uiChat
189 m.state = uiChat
199 m.session = msg.session
190 m.session = msg.session
@@ -499,11 +490,8 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
499 }
490 }
500 return true
491 return true
501 case key.Matches(msg, m.keyMap.Sessions):
492 case key.Matches(msg, m.keyMap.Sessions):
502− if m.dialog.ContainsDialog(dialog.SessionsID) {
493+ if cmd := m.openSessionsDialog(); cmd != nil {
503− // Bring to front
504− m.dialog.BringToFront(dialog.SessionsID)
505− } else {
506− cmds = append(cmds, m.listSessions)
494+ cmds = append(cmds, cmd)
507 }
495 }
508 return true
496 return true
509 }
497 }
@@ -536,15 +524,30 @@ func (m *UI) handleKeyPressMsg(msg tea.KeyPressMsg) tea.Cmd {
536 m.dialog.CloseDialog(dialog.SessionsID)
524 m.dialog.CloseDialog(dialog.SessionsID)
537 cmds = append(cmds, m.loadSession(msg.Session.ID))
525 cmds = append(cmds, m.loadSession(msg.Session.ID))
538
526
527+ // Open dialog message
528+ case dialog.OpenDialogMsg:
529+ switch msg.DialogID {
530+ case dialog.SessionsID:
531+ if cmd := m.openSessionsDialog(); cmd != nil {
532+ cmds = append(cmds, cmd)
533+ }
534+ case dialog.ModelsID:
535+ if cmd := m.openModelsDialog(); cmd != nil {
536+ cmds = append(cmds, cmd)
537+ }
538+ default:
539+ // Unknown dialog
540+ break
541+ }
542+
543+ m.dialog.CloseDialog(msg.DialogID)
544+
539 // Command dialog messages
545 // Command dialog messages
540 case dialog.ToggleYoloModeMsg:
546 case dialog.ToggleYoloModeMsg:
541 yolo := !m.com.App.Permissions.SkipRequests()
547 yolo := !m.com.App.Permissions.SkipRequests()
542 m.com.App.Permissions.SetSkipRequests(yolo)
548 m.com.App.Permissions.SetSkipRequests(yolo)
543 m.setEditorPrompt(yolo)
549 m.setEditorPrompt(yolo)
544 m.dialog.CloseDialog(dialog.CommandsID)
550 m.dialog.CloseDialog(dialog.CommandsID)
545− case dialog.SwitchSessionsMsg:
546− cmds = append(cmds, m.listSessions)
547− m.dialog.CloseDialog(dialog.CommandsID)
548 case dialog.NewSessionsMsg:
551 case dialog.NewSessionsMsg:
549 if m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
552 if m.com.App.AgentCoordinator != nil && m.com.App.AgentCoordinator.IsBusy() {
550 cmds = append(cmds, uiutil.ReportWarn("Agent is busy, please wait before starting a new session..."))
553 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 {
562 m.dialog.CloseDialog(dialog.CommandsID)
565 m.dialog.CloseDialog(dialog.CommandsID)
563 case dialog.QuitMsg:
566 case dialog.QuitMsg:
564 cmds = append(cmds, tea.Quit)
567 cmds = append(cmds, tea.Quit)
565− case dialog.SwitchModelMsg:
566− m.dialog.CloseDialog(dialog.CommandsID)
567− if cmd := m.openModelsDialog(); cmd != nil {
568− cmds = append(cmds, cmd)
569− }
570 case dialog.ModelSelectedMsg:
568 case dialog.ModelSelectedMsg:
571 // TODO: Handle model switching
569 // TODO: Handle model switching
572 }
570 }
@@ -1428,14 +1426,21 @@ func (m *UI) openCommandsDialog() tea.Cmd {
1428 return nil
1426 return nil
1429}
1427}
1430
1428
1431−// openSessionsDialog opens the sessions dialog with the given sessions.
1429+// openSessionsDialog opens the sessions dialog. If the dialog is already open,
1430+// it brings it to the front. Otherwise, it will list all the sessions and open
1431+// the dialog.
1432−func (m *UI) openSessionsDialog(sessions []session.Session) tea.Cmd {
1432+func (m *UI) openSessionsDialog() tea.Cmd {
1433 if m.dialog.ContainsDialog(dialog.SessionsID) {
1433 if m.dialog.ContainsDialog(dialog.SessionsID) {
1434 // Bring to front
1434 // Bring to front
1435 m.dialog.BringToFront(dialog.SessionsID)
1435 m.dialog.BringToFront(dialog.SessionsID)
1436 return nil
1436 return nil
1437 }
1437 }
1438
1438
1439+ sessions, err := m.com.App.Sessions.List(context.TODO())
1440+ if err != nil {
1441+ return uiutil.ReportError(err)
1442+ }
1443+
1439 dialog := dialog.NewSessions(m.com, sessions...)
1444 dialog := dialog.NewSessions(m.com, sessions...)
1440 // TODO: Get. Rid. Of. Magic numbers!
1445 // TODO: Get. Rid. Of. Magic numbers!
1441 dialog.SetSize(min(120, m.width-8), 30)
1446 dialog.SetSize(min(120, m.width-8), 30)
@@ -1444,13 +1449,6 @@ func (m *UI) openSessionsDialog(sessions []session.Session) tea.Cmd {
1444 return nil
1449 return nil
1445}
1450}
1446
1451
1447−// listSessions is a [tea.Cmd] that lists all sessions and returns them in a
1448−// [listSessionsMsg].
1449−func (m *UI) listSessions() tea.Msg {
1450− allSessions, _ := m.com.App.Sessions.List(context.TODO())
1451− return listSessionsMsg{sessions: allSessions}
1452−}
1453−
1454// newSession clears the current session state and prepares for a new session.
1452// newSession clears the current session state and prepares for a new session.
1455// The actual session creation happens when the user sends their first message.
1453// The actual session creation happens when the user sends their first message.
1456func (m *UI) newSession() {
1454func (m *UI) newSession() {