TUI for The Lounge
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

116 lines
3.3 KiB

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...)
}