feat: add in-game chat to Connect 4
All checks were successful
Deploy c4 / deploy (push) Successful in 43s

Add real-time chat alongside the game board, mirroring the snake chat
implementation. Fix mobile layout for both C4 and snake chats — expand
chat to full width and reduce history height on small screens.
This commit is contained in:
Ryan Hamamura
2026-02-13 10:54:19 -10:00
parent e45559ecb3
commit 9069530e47
4 changed files with 250 additions and 1 deletions

64
ui/c4chat.go Normal file
View File

@@ -0,0 +1,64 @@
package ui
import (
"fmt"
"github.com/ryanhamamura/via/h"
)
type C4ChatMessage struct {
Nickname string `json:"nickname"`
Color int `json:"color"` // 1=Red, 2=Yellow
Message string `json:"message"`
Time int64 `json:"time"`
}
var c4ChatColors = map[int]string{
1: "#4a2a3a",
2: "#2a4545",
}
func C4Chat(messages []C4ChatMessage, msgBind, sendClick, sendKeyDown h.H) h.H {
var msgEls []h.H
for _, m := range messages {
color := "#666"
if c, ok := c4ChatColors[m.Color]; ok {
color = c
}
msgEls = append(msgEls, h.Div(h.Class("c4-chat-msg"),
h.Span(
h.Attr("style", fmt.Sprintf("color:%s;font-weight:bold;", color)),
h.Text(m.Nickname+": "),
),
h.Span(h.Text(m.Message)),
))
}
autoScroll := h.Script(h.Text(`
(function(){
var el = document.querySelector('.c4-chat-history');
if (!el) return;
el.scrollTop = el.scrollHeight;
new MutationObserver(function(){ el.scrollTop = el.scrollHeight; })
.observe(el, {childList:true, subtree:true});
})();
`))
historyAttrs := []h.H{h.Class("c4-chat-history")}
historyAttrs = append(historyAttrs, msgEls...)
historyAttrs = append(historyAttrs, autoScroll)
return h.Div(h.Class("c4-chat"),
h.Div(historyAttrs...),
h.Div(h.Class("c4-chat-input"),
h.Input(
h.Type("text"),
h.Attr("placeholder", "Chat..."),
h.Attr("autocomplete", "off"),
msgBind,
sendKeyDown,
),
h.Button(h.Type("button"), h.Text("Send"), sendClick),
),
)
}