Chat QoL updates

This commit is contained in:
bdnugget 2025-01-13 21:29:06 +01:00
parent 1a7b0eff42
commit afc44710f2

View File

@ -10,11 +10,12 @@ import (
) )
const ( const (
maxMessages = 50 maxMessages = 50
chatWindowWidth = 400 chatMargin = 10 // Margin from screen edges
chatHeight = 200 chatHeight = 200
messageHeight = 20 messageHeight = 20
inputHeight = 30 inputHeight = 30
runeLimit = 256
) )
type Chat struct { type Chat struct {
@ -29,7 +30,7 @@ type Chat struct {
func NewChat() *Chat { func NewChat() *Chat {
return &Chat{ return &Chat{
messages: make([]types.ChatMessage, 0, maxMessages), messages: make([]types.ChatMessage, 0, maxMessages),
inputBuffer: make([]rune, 0, 256), inputBuffer: make([]rune, 0, runeLimit),
} }
} }
@ -63,6 +64,12 @@ func (c *Chat) HandleServerMessages(messages []*pb.ChatMessage) {
} }
c.messages = append(c.messages, localMsg) c.messages = append(c.messages, localMsg)
// Scroll to latest message if it's not already visible
visibleMessages := int((chatHeight - inputHeight) / messageHeight)
if len(c.messages) > visibleMessages {
c.scrollOffset = len(c.messages) - visibleMessages
}
// Add floating message to the player // Add floating message to the player
if game, ok := c.userData.(*Game); ok { if game, ok := c.userData.(*Game); ok {
if msg.PlayerId == game.Player.ID { if msg.PlayerId == game.Player.ID {
@ -86,17 +93,29 @@ func (c *Chat) HandleServerMessages(messages []*pb.ChatMessage) {
} }
func (c *Chat) Draw(screenWidth, screenHeight int32) { func (c *Chat) Draw(screenWidth, screenHeight int32) {
// Calculate chat window width based on screen width
chatWindowWidth := screenWidth - (chatMargin * 2)
// Draw chat window background // Draw chat window background
chatX := float32(10) chatX := float32(chatMargin)
chatY := float32(screenHeight - chatHeight - 10) chatY := float32(screenHeight - chatHeight - chatMargin)
rl.DrawRectangle(int32(chatX), int32(chatY), chatWindowWidth, chatHeight, rl.ColorAlpha(rl.Black, 0.5)) rl.DrawRectangle(int32(chatX), int32(chatY), chatWindowWidth, chatHeight, rl.ColorAlpha(rl.Black, 0.5))
// Draw messages // Draw messages from oldest to newest
messageY := chatY + 5 messageY := chatY + 5
startIdx := len(c.messages) - 1 - c.scrollOffset visibleMessages := int((chatHeight - inputHeight) / messageHeight)
endIdx := max(0, startIdx-int((chatHeight-inputHeight)/messageHeight))
for i := startIdx; i >= endIdx && i >= 0; i-- { // Auto-scroll to bottom if no manual scrolling has occurred
if c.scrollOffset == 0 {
if len(c.messages) > visibleMessages {
c.scrollOffset = len(c.messages) - visibleMessages
}
}
startIdx := max(0, c.scrollOffset)
endIdx := min(len(c.messages), startIdx+visibleMessages)
for i := startIdx; i < endIdx; i++ {
msg := c.messages[i] msg := c.messages[i]
text := fmt.Sprintf("[%d]: %s", msg.PlayerID, msg.Content) text := fmt.Sprintf("[%d]: %s", msg.PlayerID, msg.Content)
rl.DrawText(text, int32(chatX)+5, int32(messageY), 20, rl.White) rl.DrawText(text, int32(chatX)+5, int32(messageY), 20, rl.White)
@ -136,19 +155,20 @@ func (c *Chat) Update() (string, bool) {
key := rl.GetCharPressed() key := rl.GetCharPressed()
for key > 0 { for key > 0 {
if len(c.inputBuffer) < 256 { if len(c.inputBuffer) < runeLimit {
c.inputBuffer = append(c.inputBuffer[:c.cursorPos], append([]rune{key}, c.inputBuffer[c.cursorPos:]...)...) c.inputBuffer = append(c.inputBuffer[:c.cursorPos], append([]rune{key}, c.inputBuffer[c.cursorPos:]...)...)
c.cursorPos++ c.cursorPos++
} }
key = rl.GetCharPressed() key = rl.GetCharPressed()
} }
if rl.IsKeyPressed(rl.KeyEnter) { if rl.IsKeyPressed(rl.KeyEnter) || rl.IsKeyPressed(rl.KeyKpEnter) {
if len(c.inputBuffer) > 0 { if len(c.inputBuffer) > 0 {
message := string(c.inputBuffer) message := string(c.inputBuffer)
c.inputBuffer = c.inputBuffer[:0] c.inputBuffer = c.inputBuffer[:0]
c.cursorPos = 0 c.cursorPos = 0
c.isTyping = false c.isTyping = false
return message, true return message, true
} }
c.isTyping = false c.isTyping = false
@ -183,6 +203,13 @@ func max(a, b int) int {
return b return b
} }
func min(a, b int) int {
if a < b {
return a
}
return b
}
func clamp(value, min, max int) int { func clamp(value, min, max int) int {
if value < min { if value < min {
return min return min