chat.go

  1package page
  2
  3import (
  4	tea "github.com/charmbracelet/bubbletea"
  5	"github.com/kujtimiihoxha/termai/internal/app"
  6	"github.com/kujtimiihoxha/termai/internal/message"
  7	"github.com/kujtimiihoxha/termai/internal/session"
  8	"github.com/kujtimiihoxha/termai/internal/tui/components/chat"
  9	"github.com/kujtimiihoxha/termai/internal/tui/layout"
 10	"github.com/kujtimiihoxha/termai/internal/tui/util"
 11)
 12
 13var ChatPage PageID = "chat"
 14
 15type chatPage struct {
 16	app     *app.App
 17	layout  layout.SplitPaneLayout
 18	session session.Session
 19}
 20
 21func (p *chatPage) Init() tea.Cmd {
 22	return p.layout.Init()
 23}
 24
 25func (p *chatPage) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 26	switch msg := msg.(type) {
 27	case tea.WindowSizeMsg:
 28		p.layout.SetSize(msg.Width, msg.Height)
 29	case chat.SendMsg:
 30		cmd := p.sendMessage(msg.Text)
 31		if cmd != nil {
 32			return p, cmd
 33		}
 34	}
 35	u, cmd := p.layout.Update(msg)
 36	p.layout = u.(layout.SplitPaneLayout)
 37	if cmd != nil {
 38		return p, cmd
 39	}
 40	return p, nil
 41}
 42
 43func (p *chatPage) setSidebar() tea.Cmd {
 44	sidebarContainer := layout.NewContainer(
 45		chat.NewSidebarCmp(p.session),
 46		layout.WithPadding(1, 1, 1, 1),
 47	)
 48	p.layout.SetRightPanel(sidebarContainer)
 49	width, height := p.layout.GetSize()
 50	p.layout.SetSize(width, height)
 51	return sidebarContainer.Init()
 52}
 53
 54func (p *chatPage) sendMessage(text string) tea.Cmd {
 55	var cmds []tea.Cmd
 56	if p.session.ID == "" {
 57		session, err := p.app.Sessions.Create("New Session")
 58		if err != nil {
 59			return util.ReportError(err)
 60		}
 61
 62		p.session = session
 63		cmd := p.setSidebar()
 64		if cmd != nil {
 65			cmds = append(cmds, cmd)
 66		}
 67		cmds = append(cmds, util.CmdHandler(chat.SessionSelectedMsg(session)))
 68	}
 69	// TODO: actually call agent
 70	p.app.Messages.Create(p.session.ID, message.CreateMessageParams{
 71		Role: message.User,
 72		Parts: []message.ContentPart{
 73			message.TextContent{
 74				Text: text,
 75			},
 76		},
 77	})
 78	return tea.Batch(cmds...)
 79}
 80
 81func (p *chatPage) View() string {
 82	return p.layout.View()
 83}
 84
 85func NewChatPage(app *app.App) tea.Model {
 86	messagesContainer := layout.NewContainer(
 87		chat.NewMessagesCmp(app),
 88		layout.WithPadding(1, 1, 1, 1),
 89	)
 90
 91	editorContainer := layout.NewContainer(
 92		chat.NewEditorCmp(),
 93		layout.WithBorder(true, false, false, false),
 94	)
 95	return &chatPage{
 96		app: app,
 97		layout: layout.NewSplitPane(
 98			layout.WithLeftPanel(messagesContainer),
 99			layout.WithBottomPanel(editorContainer),
100		),
101	}
102}