TUI refactor
- Clean up, improved startup logic, initial conversation load - Moved converation/message business logic (mostly) into `model/tui`
This commit is contained in:
@@ -9,33 +9,42 @@ package tui
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.mlow.ca/mlow/lmcli/pkg/api"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/lmcli"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/tui/model"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/tui/shared"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/tui/views/chat"
|
||||
"git.mlow.ca/mlow/lmcli/pkg/tui/views/conversations"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
)
|
||||
|
||||
// Application model
|
||||
type Model struct {
|
||||
shared.Shared
|
||||
|
||||
state shared.View
|
||||
chat chat.Model
|
||||
conversations conversations.Model
|
||||
type LaunchOptions struct {
|
||||
InitialConversation *api.Conversation
|
||||
InitialView shared.View
|
||||
}
|
||||
|
||||
func initialModel(ctx *lmcli.Context, values shared.Values) Model {
|
||||
type Model struct {
|
||||
App *model.AppModel
|
||||
view shared.View
|
||||
chat chat.Model
|
||||
conversations conversations.Model
|
||||
Width int
|
||||
Height int
|
||||
}
|
||||
|
||||
func initialModel(ctx *lmcli.Context, opts LaunchOptions) Model {
|
||||
m := Model{
|
||||
Shared: shared.Shared{
|
||||
Ctx: ctx,
|
||||
Values: &values,
|
||||
App: &model.AppModel{
|
||||
Ctx: ctx,
|
||||
Conversation: opts.InitialConversation,
|
||||
},
|
||||
view: opts.InitialView,
|
||||
}
|
||||
|
||||
m.state = shared.StateChat
|
||||
m.chat = chat.Chat(m.Shared)
|
||||
m.conversations = conversations.Conversations(m.Shared)
|
||||
sharedData := shared.Shared{}
|
||||
|
||||
m.chat = chat.Chat(m.App, sharedData)
|
||||
m.conversations = conversations.Conversations(m.App, sharedData)
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -44,16 +53,14 @@ func (m Model) Init() tea.Cmd {
|
||||
m.conversations.Init(),
|
||||
m.chat.Init(),
|
||||
func() tea.Msg {
|
||||
return shared.MsgViewChange(m.state)
|
||||
return shared.MsgViewChange(m.view)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (m *Model) handleGlobalInput(msg tea.KeyMsg) (bool, tea.Cmd) {
|
||||
// delegate input to the active child state first, only handling it at the
|
||||
// global level if the child state does not
|
||||
var cmds []tea.Cmd
|
||||
switch m.state {
|
||||
switch m.view {
|
||||
case shared.StateChat:
|
||||
handled, cmd := m.chat.HandleInput(msg)
|
||||
cmds = append(cmds, cmd)
|
||||
@@ -88,8 +95,8 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
return m, cmd
|
||||
}
|
||||
case shared.MsgViewChange:
|
||||
m.state = shared.View(msg)
|
||||
switch m.state {
|
||||
m.view = shared.View(msg)
|
||||
switch m.view {
|
||||
case shared.StateChat:
|
||||
m.chat.HandleResize(m.Width, m.Height)
|
||||
case shared.StateConversations:
|
||||
@@ -101,7 +108,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
switch m.state {
|
||||
switch m.view {
|
||||
case shared.StateConversations:
|
||||
m.conversations, cmd = m.conversations.Update(msg)
|
||||
case shared.StateChat:
|
||||
@@ -115,7 +122,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
}
|
||||
|
||||
func (m Model) View() string {
|
||||
switch m.state {
|
||||
switch m.view {
|
||||
case shared.StateConversations:
|
||||
return m.conversations.View()
|
||||
case shared.StateChat:
|
||||
@@ -124,9 +131,30 @@ func (m Model) View() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func Launch(ctx *lmcli.Context, convShortname string) error {
|
||||
p := tea.NewProgram(initialModel(ctx, shared.Values{ConvShortname: convShortname}), tea.WithAltScreen())
|
||||
if _, err := p.Run(); err != nil {
|
||||
type LaunchOption func(*LaunchOptions)
|
||||
|
||||
func WithInitialConversation(conv *api.Conversation) LaunchOption {
|
||||
return func(opts *LaunchOptions) {
|
||||
opts.InitialConversation = conv
|
||||
}
|
||||
}
|
||||
|
||||
func WithInitialView(view shared.View) LaunchOption {
|
||||
return func(opts *LaunchOptions) {
|
||||
opts.InitialView = view
|
||||
}
|
||||
}
|
||||
|
||||
func Launch(ctx *lmcli.Context, options ...LaunchOption) error {
|
||||
opts := &LaunchOptions{
|
||||
InitialView: shared.StateChat,
|
||||
}
|
||||
for _, opt := range options {
|
||||
opt(opts)
|
||||
}
|
||||
|
||||
program := tea.NewProgram(initialModel(ctx, *opts), tea.WithAltScreen())
|
||||
if _, err := program.Run(); err != nil {
|
||||
return fmt.Errorf("Error running program: %v", err)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user