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}