mirror of
https://github.com/Kyren223/eko.git
synced 2026-07-11 23:09:32 +00:00
133 lines
2.7 KiB
Go
133 lines
2.7 KiB
Go
package messagebox
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/charmbracelet/bubbles/viewport"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
|
"github.com/kyren223/eko/internal/client/api"
|
|
"github.com/kyren223/eko/internal/data"
|
|
"github.com/kyren223/eko/pkg/snowflake"
|
|
)
|
|
|
|
type user struct {
|
|
name string
|
|
isFetching bool
|
|
}
|
|
|
|
type Model struct {
|
|
Viewport viewport.Model
|
|
messages []data.Message
|
|
|
|
senderStyle lipgloss.Style
|
|
timestampStyle lipgloss.Style
|
|
|
|
users map[snowflake.ID]user
|
|
}
|
|
|
|
func New(width, height int) Model {
|
|
return Model{
|
|
Viewport: viewport.New(width, height),
|
|
messages: nil,
|
|
senderStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("5")).Bold(true),
|
|
timestampStyle: lipgloss.NewStyle().Foreground(lipgloss.Color("#585c62")).Italic(true),
|
|
users: make(map[snowflake.ID]user),
|
|
}
|
|
}
|
|
|
|
func (m Model) Init() tea.Cmd {
|
|
return api.GetMessages
|
|
}
|
|
|
|
func (m Model) View() string {
|
|
return m.Viewport.View()
|
|
}
|
|
|
|
func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
|
|
var cmds []tea.Cmd
|
|
|
|
for id, user := range m.users {
|
|
if !user.isFetching && user.name == "" {
|
|
cmds = append(cmds, api.GetUserById(id))
|
|
user.isFetching = true
|
|
m.users[id] = user
|
|
}
|
|
}
|
|
|
|
var cmd tea.Cmd
|
|
m.Viewport, cmd = m.Viewport.Update(msg)
|
|
cmds = append(cmds, cmd)
|
|
|
|
switch msg := msg.(type) {
|
|
case api.UserProfileUpdate:
|
|
m.users[msg.ID] = user{msg.Name, false}
|
|
m.UpdateMessages()
|
|
}
|
|
|
|
return m, tea.Batch(cmds...)
|
|
}
|
|
|
|
func (m *Model) AppendMessage(message data.Message) {
|
|
m.messages = append(m.messages, message)
|
|
m.UpdateMessages()
|
|
}
|
|
|
|
func (m *Model) SetMessages(messages []data.Message) {
|
|
m.messages = messages
|
|
m.UpdateMessages()
|
|
}
|
|
|
|
func (m *Model) UpdateMessages() {
|
|
for _, message := range m.messages {
|
|
if _, exists := m.users[message.SenderID]; !exists {
|
|
m.users[message.SenderID] = user{name: "", isFetching: false}
|
|
}
|
|
}
|
|
|
|
m.sortMessages()
|
|
m.updateContent()
|
|
m.Viewport.GotoBottom()
|
|
}
|
|
|
|
func (m *Model) sortMessages() {
|
|
slices.SortFunc(m.messages, func(a, b data.Message) int {
|
|
if a.ID-b.ID < 0 {
|
|
return -1
|
|
} else {
|
|
return 1
|
|
}
|
|
})
|
|
}
|
|
|
|
func (m *Model) updateContent() {
|
|
if len(m.messages) == 0 {
|
|
return
|
|
}
|
|
|
|
var builder strings.Builder
|
|
|
|
for _, message := range m.messages {
|
|
sender := m.users[message.SenderID].name
|
|
builder.WriteString(m.senderStyle.Render(sender))
|
|
builder.WriteByte(' ')
|
|
|
|
timestamp := timestampFromID(message.ID)
|
|
builder.WriteString(m.timestampStyle.Render(timestamp))
|
|
builder.WriteByte('\n')
|
|
|
|
builder.WriteString(message.Content)
|
|
builder.WriteByte('\n')
|
|
}
|
|
|
|
m.Viewport.SetContent(builder.String()[:builder.Len()-1])
|
|
}
|
|
|
|
func timestampFromID(id snowflake.ID) string {
|
|
localTime := time.UnixMilli(id.Time())
|
|
return localTime.Format("02/01/2006 3:04 PM")
|
|
}
|