117 lines
3.3 KiB
Go
117 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
te "github.com/muesli/termenv"
|
|
"github.com/charmbracelet/bubbles/textinput"
|
|
)
|
|
|
|
type chatModel struct {
|
|
scroll int
|
|
chatInput textinput.Model
|
|
}
|
|
|
|
func doSendMessage(conn *loungeConnection, channel int, text string) tea.Cmd {
|
|
return func() tea.Msg {
|
|
loungeChannelSend(conn, channel, text)
|
|
return 1
|
|
}
|
|
}
|
|
|
|
func getMessageString(channelName string, message loungeMessage) string {
|
|
timestamp := message.Time[11:16]
|
|
switch message.Type {
|
|
case messageMessage, messageNotice:
|
|
if message.From.Nick == "" {
|
|
return timestamp + " " + message.Text + "\n"
|
|
} else {
|
|
return timestamp + " <" + message.From.Mode + message.From.Nick + "> " + message.Text + "\n"
|
|
}
|
|
case messageAction:
|
|
return timestamp + " " + te.String(message.From.Mode + message.From.Nick + " " + message.Text).Italic().String() + "\n"
|
|
case messageTopic:
|
|
return timestamp + " " + te.String(message.From.Mode + message.From.Nick + " changed the topic to: " + message.Text).Italic().String() + "\n"
|
|
case messageError:
|
|
return timestamp + " " + te.String(message.Text).Foreground(color(errorColor)).String() + "\n"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getMessageCounts(m mainModel) (int, int, int) {
|
|
maxMessages := m.height - 2
|
|
messageCount := maxMessages
|
|
if messageCount > len(m.conn.Channel.Filtered) {
|
|
messageCount = len(m.conn.Channel.Filtered)
|
|
}
|
|
maxScroll := len(m.conn.Channel.Filtered) - messageCount
|
|
return maxMessages, messageCount, maxScroll
|
|
}
|
|
|
|
func chatModelInit() chatModel {
|
|
input := textinput.NewModel()
|
|
input.Placeholder = "Enter a chat message"
|
|
input.CharLimit = 256
|
|
input.Focus()
|
|
return chatModel{0, input}
|
|
}
|
|
|
|
func (m mainModel) chatInit() tea.Cmd {
|
|
return nil
|
|
}
|
|
|
|
func (m mainModel) chatView() string {
|
|
channel := m.conn.Channel
|
|
if channel == nil {
|
|
return "No channel open"
|
|
}
|
|
s := te.String(channel.Name).Reverse().String() + " "
|
|
maxTopicLen := m.width - len(channel.Name) - 1
|
|
if maxTopicLen < 3 {
|
|
s += "\n"
|
|
} else if len(channel.Topic) <= maxTopicLen {
|
|
s += highlightText(channel.Topic) + "\n"
|
|
} else {
|
|
s += highlightText(channel.Topic[:maxTopicLen-3] + "...") + "\n"
|
|
}
|
|
maxMessages, messageCount, maxScroll := getMessageCounts(m)
|
|
if m.chatModel.scroll > maxScroll {
|
|
m.chatModel.scroll = maxScroll
|
|
}
|
|
for i := 0; i < messageCount; i++ {
|
|
index := len(channel.Filtered) - messageCount - m.chatModel.scroll + i
|
|
s += getMessageString(channel.Name, channel.Filtered[index])
|
|
}
|
|
s += strings.Repeat("\n", maxMessages - messageCount)
|
|
s += m.chatModel.chatInput.View()
|
|
return s
|
|
}
|
|
|
|
func (m mainModel) chatUpdate(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|
var (
|
|
cmd tea.Cmd
|
|
cmds []tea.Cmd
|
|
)
|
|
switch msg := msg.(type) {
|
|
case tea.KeyMsg:
|
|
if msg.Type == tea.KeyEnter && m.chatModel.chatInput.Value() != "" {
|
|
cmd = doSendMessage(m.conn, m.conn.Channel.Id, m.chatModel.chatInput.Value())
|
|
cmds = append(cmds, cmd)
|
|
m.chatModel.chatInput.SetValue("")
|
|
}
|
|
_, _, maxScroll := getMessageCounts(m)
|
|
if m.chatModel.scroll > maxScroll {
|
|
m.chatModel.scroll = maxScroll
|
|
}
|
|
if msg.Type == tea.KeyUp {
|
|
m.chatModel.scroll += 1
|
|
}
|
|
if msg.Type == tea.KeyDown && m.chatModel.scroll > 0 {
|
|
m.chatModel.scroll -= 1
|
|
}
|
|
}
|
|
m.chatModel.chatInput, cmd = m.chatModel.chatInput.Update(msg)
|
|
cmds = append(cmds, cmd)
|
|
return m, tea.Batch(cmds...)
|
|
}
|