summaryrefslogtreecommitdiff
path: root/internal/client/ui/chat/chat.go
blob: c69d0fdf1c97e55958f13c7a41054b89fe801a6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package chat

import (
	"fmt"
	"log"
	"strings"

	"github.com/charmbracelet/bubbles/cursor"
	"github.com/charmbracelet/bubbles/textarea"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"

	"github.com/kyren223/eko/internal/client/api"
	"github.com/kyren223/eko/internal/client/ui/messagebox"
	"github.com/kyren223/eko/internal/data"
	"github.com/kyren223/eko/internal/packet"
)

type Model struct {
	messagebox messagebox.Model
	textarea   textarea.Model
	err        error
}

func New() Model {
	ta := textarea.New()
	ta.Placeholder = "Send a message..."
	ta.Focus()

	ta.Prompt = "┃ "
	ta.CharLimit = 280

	ta.SetWidth(30)
	ta.SetHeight(3)

	// Remove cursor line styling
	ta.FocusedStyle.CursorLine = lipgloss.NewStyle()

	ta.ShowLineNumbers = false

	ta.KeyMap.InsertNewline.SetEnabled(false)

	return Model{
		textarea:   ta,
		messagebox: messagebox.New(30, 20),
		err:        nil,
	}
}

func (m Model) Init() tea.Cmd {
	return tea.Batch(textarea.Blink, api.GetMessages)
}

func (m Model) View() string {
	return fmt.Sprintf(
		"%s\n%s",
		m.messagebox.View(),
		m.textarea.View(),
	) + ""
}

func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.WindowSizeMsg:
		m.messagebox.Viewport.Width = msg.Width
		m.messagebox.Viewport.Height = msg.Height - m.textarea.Height()
		m.messagebox.Viewport.GotoBottom()

		m.textarea.SetWidth(msg.Width)
		log.Println("resized to:", msg.Width, "x", msg.Height)

		var mbCmd, taCmd tea.Cmd
		m.messagebox, mbCmd = m.messagebox.Update(msg)
		m.textarea, taCmd = m.textarea.Update(msg)
		return m, tea.Batch(mbCmd, taCmd)

	case tea.KeyMsg:
		switch msg.Type {

		case tea.KeyEnter:
			value := m.textarea.Value()

			content := strings.TrimSpace(value)
			if content == "" {
				return m, nil
			}
			m.textarea.Reset()

			return m, api.SendMessage(content)

		default:
			var cmd tea.Cmd
			m.textarea, cmd = m.textarea.Update(msg)
			return m, cmd
		}

	case packet.Payload:
		switch msg := msg.(type) {
		case *packet.Messages:
			m.messagebox.SetMessages(msg.Messages)

			var cmd tea.Cmd
			m.messagebox, cmd = m.messagebox.Update(msg)
			return m, cmd

		default:
			return m, nil
		}

	case api.AppendMessage:
		m.messagebox.AppendMessage(data.Message(msg))

		var cmd tea.Cmd
		m.messagebox, cmd = m.messagebox.Update(msg)
		return m, cmd

	case api.UserProfileUpdate:
		var cmd tea.Cmd
		m.messagebox, cmd = m.messagebox.Update(msg)
		return m, cmd

	case cursor.BlinkMsg:
		var cmd tea.Cmd
		m.textarea, cmd = m.textarea.Update(msg)
		return m, cmd

	default:
		return m, nil
	}
}