feat: add snake multiplayer chat as sidebar with vivid player colors
Move chat to the right of the board using a flex wrapper that stacks vertically on narrow screens. Restore original snake player colors by removing the desaturation filter added with the dark theme.
This commit is contained in:
63
ui/snakechat.go
Normal file
63
ui/snakechat.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ryanhamamura/c4/snake"
|
||||
"github.com/ryanhamamura/via/h"
|
||||
)
|
||||
|
||||
type ChatMessage struct {
|
||||
Nickname string `json:"nickname"`
|
||||
Slot int `json:"slot"`
|
||||
Message string `json:"message"`
|
||||
Time int64 `json:"time"`
|
||||
}
|
||||
|
||||
func SnakeChat(messages []ChatMessage, msgBind, sendClick, sendKeyDown h.H) h.H {
|
||||
var msgEls []h.H
|
||||
for _, m := range messages {
|
||||
color := "#666"
|
||||
if m.Slot >= 0 && m.Slot < len(snake.SnakeColors) {
|
||||
color = snake.SnakeColors[m.Slot]
|
||||
}
|
||||
msgEls = append(msgEls, h.Div(h.Class("snake-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)),
|
||||
))
|
||||
}
|
||||
|
||||
// Auto-scroll chat history to bottom on new messages
|
||||
autoScroll := h.Script(h.Text(`
|
||||
(function(){
|
||||
var el = document.querySelector('.snake-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("snake-chat-history")}
|
||||
historyAttrs = append(historyAttrs, msgEls...)
|
||||
historyAttrs = append(historyAttrs, autoScroll)
|
||||
|
||||
return h.Div(h.Class("snake-chat"),
|
||||
h.Div(historyAttrs...),
|
||||
h.Div(h.Class("snake-chat-input"),
|
||||
h.Input(
|
||||
h.Type("text"),
|
||||
h.Attr("placeholder", "Chat..."),
|
||||
h.Attr("autocomplete", "off"),
|
||||
// Prevent key events from bubbling to the game's window-level handler
|
||||
h.Attr("onkeydown", "event.stopPropagation()"),
|
||||
msgBind,
|
||||
sendKeyDown,
|
||||
),
|
||||
h.Button(h.Type("button"), h.Text("Send"), sendClick),
|
||||
),
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user