Private
Public Access
1
0

TUI view management and input handling cleanup

This commit is contained in:
2024-09-16 15:40:04 +00:00
parent 24b5cdbbf6
commit 463ca9ef40
7 changed files with 169 additions and 154 deletions

View File

@@ -1,11 +1,5 @@
package tui
// The terminal UI for lmcli, launched from the `lmcli chat` command
// TODO:
// - change model
// - rename conversation
// - set system prompt
import (
"fmt"
@@ -24,117 +18,81 @@ type LaunchOptions struct {
}
type Model struct {
App *model.AppModel
view shared.View
App *model.AppModel
// views
chat chat.Model
conversations conversations.Model
activeView shared.View
views map[shared.View]shared.ViewModel
}
func initialModel(ctx *lmcli.Context, opts LaunchOptions) Model {
m := Model{
App: &model.AppModel{
Ctx: ctx,
Conversation: opts.InitialConversation,
},
view: opts.InitialView,
sharedData := shared.ViewState{}
app := &model.AppModel{
Ctx: ctx,
Conversation: opts.InitialConversation,
}
sharedData := shared.Shared{}
m := Model{
App: app,
activeView: opts.InitialView,
views: map[shared.View]shared.ViewModel{
shared.ViewChat: chat.Chat(app, sharedData),
shared.ViewConversations: conversations.Conversations(app, sharedData),
},
}
m.chat = chat.Chat(m.App, sharedData)
m.conversations = conversations.Conversations(m.App, sharedData)
return m
}
func (m Model) Init() tea.Cmd {
return tea.Batch(
func() tea.Msg {
return shared.MsgViewChange(m.view)
return shared.MsgViewChange(m.activeView)
},
)
}
func (m *Model) handleGlobalInput(msg tea.KeyMsg) (bool, tea.Cmd) {
var cmds []tea.Cmd
switch m.view {
case shared.StateChat:
handled, cmd := m.chat.HandleInput(msg)
cmds = append(cmds, cmd)
if handled {
m.chat, cmd = m.chat.Update(nil)
cmds = append(cmds, cmd)
return true, tea.Batch(cmds...)
}
case shared.StateConversations:
handled, cmd := m.conversations.HandleInput(msg)
cmds = append(cmds, cmd)
if handled {
m.conversations, cmd = m.conversations.Update(nil)
cmds = append(cmds, cmd)
return true, tea.Batch(cmds...)
}
func (m *Model) handleGlobalInput(msg tea.KeyMsg) tea.Cmd {
view, cmd := m.views[m.activeView].Update(msg)
m.views[m.activeView] = view
if cmd != nil {
return cmd
}
switch msg.String() {
case "ctrl+c", "ctrl+q":
return true, tea.Quit
return tea.Quit
}
return false, nil
return nil
}
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
handled, cmd := m.handleGlobalInput(msg)
if handled {
cmd := m.handleGlobalInput(msg)
if cmd != nil {
return m, cmd
}
case shared.MsgViewChange:
m.view = shared.View(msg)
m.activeView = shared.View(msg)
view := m.views[m.activeView]
var cmds []tea.Cmd
switch m.view {
case shared.StateConversations:
if !m.conversations.Initialized {
cmds = append(cmds, m.conversations.Init())
m.conversations.Initialized = true
}
case shared.StateChat:
if !m.chat.Initialized {
cmds = append(cmds, m.chat.Init())
m.chat.Initialized = true
}
if !view.Initialized() {
cmds = append(cmds, view.Init())
}
cmds = append(cmds, tea.WindowSize(), shared.ViewEnter())
return m, tea.Batch(cmds...)
}
var cmd tea.Cmd
switch m.view {
case shared.StateConversations:
m.conversations, cmd = m.conversations.Update(msg)
case shared.StateChat:
m.chat, cmd = m.chat.Update(msg)
}
if cmd != nil {
cmds = append(cmds, cmd)
}
return m, tea.Batch(cmds...)
view, cmd := m.views[m.activeView].Update(msg)
m.views[m.activeView] = view
return m, cmd
}
func (m Model) View() string {
switch m.view {
case shared.StateConversations:
return m.conversations.View()
case shared.StateChat:
return m.chat.View()
}
return ""
return m.views[m.activeView].View()
}
type LaunchOption func(*LaunchOptions)
@@ -153,7 +111,7 @@ func WithInitialView(view shared.View) LaunchOption {
func Launch(ctx *lmcli.Context, options ...LaunchOption) error {
opts := &LaunchOptions{
InitialView: shared.StateChat,
InitialView: shared.ViewChat,
}
for _, opt := range options {
opt(opts)