diff --git a/internal/ui/root/model.go b/internal/ui/root/model.go index 6918dec..e651a9f 100644 --- a/internal/ui/root/model.go +++ b/internal/ui/root/model.go @@ -119,7 +119,11 @@ func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) { case keybind.Matches(msg, m.cfg.Keybinds.Suspend.Keybind): return m, suspend() case keybind.Matches(msg, m.cfg.Keybinds.Quit.Keybind): - return m, tview.Sequence(m.updateScreen(chat.QuitMsg{}), tview.Quit()) + return m, ui.ShowDialog( + "Are you sure you want to quit?", + ui.DialogButton{Label: "No"}, + ui.DialogButton{Label: "Yes", Cmd: m.quit()}, + ) } case tview.MouseMsg, tview.PasteMsg: if m.dialog != nil { diff --git a/internal/ui/root/model_test.go b/internal/ui/root/model_test.go index f1da765..e9d18fc 100644 --- a/internal/ui/root/model_test.go +++ b/internal/ui/root/model_test.go @@ -56,3 +56,26 @@ func TestNewModel(t *testing.T) { } }) } + +func TestModelQuit(t *testing.T) { + cfg, err := config.Load(filepath.Join(t.TempDir(), "missing.toml")) + if err != nil { + t.Fatal(err) + } + m := NewModel(cfg) + + m, cmd := m.Update(tcell.NewEventKey(tcell.KeyCtrlC, "", tcell.ModCtrl)) + if cmd == nil { + t.Fatal("quit did not ask") + } + m, _ = m.Update(cmd()) + if m.dialog == nil || m.dialog.Text != "Are you sure you want to quit?" { + t.Fatalf("dialog = %+v, want the quit confirmation", m.dialog) + } + if no, _ := m.Update(dialogDoneMsg(0)); no.dialog != nil { + t.Fatal("No left the dialog open") + } + if _, cmd = m.Update(dialogDoneMsg(1)); cmd == nil { + t.Fatal("Yes did not quit") + } +} diff --git a/internal/ui/root/msg.go b/internal/ui/root/msg.go index 93ba754..c3925ce 100644 --- a/internal/ui/root/msg.go +++ b/internal/ui/root/msg.go @@ -26,6 +26,10 @@ func useToken(token string) tview.Cmd { type loginMsg struct{} +func (m *Model) quit() tview.Cmd { + return tview.Sequence(m.updateScreen(chat.QuitMsg{}), tview.Quit()) +} + func getToken() tview.Cmd { return func() tview.Msg { token, err := keyring.Get(keyringService, keyringUser)