messages.go

  1package repl
  2
  3import (
  4	"github.com/charmbracelet/bubbles/key"
  5	"github.com/charmbracelet/bubbles/viewport"
  6	tea "github.com/charmbracelet/bubbletea"
  7	"github.com/charmbracelet/lipgloss"
  8	"github.com/kujtimiihoxha/termai/internal/app"
  9	"github.com/kujtimiihoxha/termai/internal/message"
 10	"github.com/kujtimiihoxha/termai/internal/pubsub"
 11	"github.com/kujtimiihoxha/termai/internal/session"
 12	"github.com/kujtimiihoxha/termai/internal/tui/layout"
 13)
 14
 15type MessagesCmp interface {
 16	tea.Model
 17	layout.Focusable
 18	layout.Bordered
 19	layout.Sizeable
 20	layout.Bindings
 21}
 22
 23type messagesCmp struct {
 24	app      *app.App
 25	messages []message.Message
 26	session  session.Session
 27	viewport viewport.Model
 28	width    int
 29	height   int
 30	focused  bool
 31}
 32
 33func (m *messagesCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 34	switch msg := msg.(type) {
 35	case pubsub.Event[message.Message]:
 36		if msg.Type == pubsub.CreatedEvent {
 37			m.messages = append(m.messages, msg.Payload)
 38		}
 39	case pubsub.Event[session.Session]:
 40		if msg.Type == pubsub.UpdatedEvent {
 41			if m.session.ID == msg.Payload.ID {
 42				m.session = msg.Payload
 43			}
 44		}
 45	case SelectedSessionMsg:
 46		m.session, _ = m.app.Sessions.Get(msg.SessionID)
 47		m.messages, _ = m.app.Messages.List(m.session.ID)
 48	}
 49	return m, nil
 50}
 51
 52func (i *messagesCmp) View() string {
 53	stringMessages := make([]string, len(i.messages))
 54	for idx, msg := range i.messages {
 55		stringMessages[idx] = msg.MessageData.Content
 56	}
 57	return lipgloss.JoinVertical(lipgloss.Top, stringMessages...)
 58}
 59
 60// BindingKeys implements MessagesCmp.
 61func (m *messagesCmp) BindingKeys() []key.Binding {
 62	return []key.Binding{}
 63}
 64
 65// Blur implements MessagesCmp.
 66func (m *messagesCmp) Blur() tea.Cmd {
 67	m.focused = false
 68	return nil
 69}
 70
 71// BorderText implements MessagesCmp.
 72func (m *messagesCmp) BorderText() map[layout.BorderPosition]string {
 73	title := m.session.Title
 74	if len(title) > 20 {
 75		title = title[:20] + "..."
 76	}
 77	return map[layout.BorderPosition]string{
 78		layout.TopLeftBorder: title,
 79	}
 80}
 81
 82// Focus implements MessagesCmp.
 83func (m *messagesCmp) Focus() tea.Cmd {
 84	m.focused = true
 85	return nil
 86}
 87
 88// GetSize implements MessagesCmp.
 89func (m *messagesCmp) GetSize() (int, int) {
 90	return m.width, m.height
 91}
 92
 93// IsFocused implements MessagesCmp.
 94func (m *messagesCmp) IsFocused() bool {
 95	return m.focused
 96}
 97
 98// SetSize implements MessagesCmp.
 99func (m *messagesCmp) SetSize(width int, height int) {
100	m.width = width
101	m.height = height
102}
103
104func (m *messagesCmp) Init() tea.Cmd {
105	return nil
106}
107
108func NewMessagesCmp(app *app.App) MessagesCmp {
109	return &messagesCmp{
110		app:      app,
111		messages: []message.Message{},
112	}
113}