refactor: extract shared player, session, and chat packages #5
@@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ryanhamamura/games/chat"
|
"github.com/ryanhamamura/games/chat"
|
||||||
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
||||||
"github.com/ryanhamamura/games/features/snakegame/components"
|
|
||||||
"github.com/ryanhamamura/games/features/snakegame/pages"
|
"github.com/ryanhamamura/games/features/snakegame/pages"
|
||||||
"github.com/ryanhamamura/games/sessions"
|
"github.com/ryanhamamura/games/sessions"
|
||||||
"github.com/ryanhamamura/games/snake"
|
"github.com/ryanhamamura/games/snake"
|
||||||
@@ -100,16 +99,33 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess
|
|||||||
|
|
||||||
chatCfg := snakeChatConfig(gameID)
|
chatCfg := snakeChatConfig(gameID)
|
||||||
|
|
||||||
// Send initial render
|
// Chat room (multiplayer only)
|
||||||
|
var room *chat.Room
|
||||||
sg := si.GetGame()
|
sg := si.GetGame()
|
||||||
sse.PatchElementTempl(components.Board(sg)) //nolint:errcheck
|
|
||||||
sse.PatchElementTempl(components.StatusBanner(sg, mySlot, gameID)) //nolint:errcheck
|
|
||||||
sse.PatchElementTempl(components.PlayerList(sg, mySlot)) //nolint:errcheck
|
|
||||||
if sg.Mode == snake.ModeMultiplayer {
|
if sg.Mode == snake.ModeMultiplayer {
|
||||||
sse.PatchElementTempl(chatcomponents.Chat(nil, chatCfg)) //nolint:errcheck
|
room = chat.NewRoom(nc, snake.ChatSubject(gameID))
|
||||||
if sg.Status == snake.StatusWaitingForPlayers || sg.Status == snake.StatusCountdown {
|
|
||||||
sse.PatchElementTempl(components.InviteLink(gameID)) //nolint:errcheck
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chatMessages := func() []chat.Message {
|
||||||
|
if room == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return room.Messages()
|
||||||
|
}
|
||||||
|
|
||||||
|
patchAll := func() error {
|
||||||
|
si, ok = snakeStore.Get(gameID)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("game not found")
|
||||||
|
}
|
||||||
|
mySlot = si.GetPlayerSlot(playerID)
|
||||||
|
sg = si.GetGame()
|
||||||
|
return sse.PatchElementTempl(pages.GameContent(sg, mySlot, chatMessages(), chatCfg, gameID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send initial render
|
||||||
|
if err := patchAll(); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribe to game updates via NATS
|
// Subscribe to game updates via NATS
|
||||||
@@ -123,10 +139,8 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess
|
|||||||
// Chat subscription (multiplayer only)
|
// Chat subscription (multiplayer only)
|
||||||
var chatCh chan *nats.Msg
|
var chatCh chan *nats.Msg
|
||||||
var chatSub *nats.Subscription
|
var chatSub *nats.Subscription
|
||||||
var room *chat.Room
|
|
||||||
|
|
||||||
if sg.Mode == snake.ModeMultiplayer {
|
if room != nil {
|
||||||
room = chat.NewRoom(nc, snake.ChatSubject(gameID))
|
|
||||||
chatCh, chatSub, err = room.Subscribe()
|
chatCh, chatSub, err = room.Subscribe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
@@ -150,19 +164,7 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
drained:
|
drained:
|
||||||
si, ok = snakeStore.Get(gameID)
|
if err := patchAll(); err != nil {
|
||||||
if !ok {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
mySlot = si.GetPlayerSlot(playerID)
|
|
||||||
sg = si.GetGame()
|
|
||||||
if err := sse.PatchElementTempl(components.Board(sg)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := sse.PatchElementTempl(components.StatusBanner(sg, mySlot, gameID)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := sse.PatchElementTempl(components.PlayerList(sg, mySlot)); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,11 +172,8 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, nc *nats.Conn, sm *scs.Sess
|
|||||||
if msg == nil {
|
if msg == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, snapshot := room.Receive(msg.Data)
|
room.Receive(msg.Data)
|
||||||
if snapshot == nil {
|
if err := patchAll(); err != nil {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if err := sse.PatchElementTempl(chatcomponents.Chat(snapshot, chatCfg)); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,13 @@ templ GamePage(sg *snake.SnakeGame, mySlot int, messages []chat.Message, chatCfg
|
|||||||
data-on:keydown.throttle_100ms={ keydownScript(gameID) }
|
data-on:keydown.throttle_100ms={ keydownScript(gameID) }
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
@GameContent(sg, mySlot, messages, chatCfg, gameID)
|
||||||
|
</main>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
templ GameContent(sg *snake.SnakeGame, mySlot int, messages []chat.Message, chatCfg chatcomponents.Config, gameID string) {
|
||||||
|
<div id="game-content">
|
||||||
@components.BackToLobby()
|
@components.BackToLobby()
|
||||||
<h1 class="text-3xl font-bold">~~~~</h1>
|
<h1 class="text-3xl font-bold">~~~~</h1>
|
||||||
@snakecomponents.PlayerList(sg, mySlot)
|
@snakecomponents.PlayerList(sg, mySlot)
|
||||||
@@ -56,8 +63,7 @@ templ GamePage(sg *snake.SnakeGame, mySlot int, messages []chat.Message, chatCfg
|
|||||||
if sg.Mode == snake.ModeMultiplayer && (sg.Status == snake.StatusWaitingForPlayers || sg.Status == snake.StatusCountdown) {
|
if sg.Mode == snake.ModeMultiplayer && (sg.Status == snake.StatusWaitingForPlayers || sg.Status == snake.StatusCountdown) {
|
||||||
@snakecomponents.InviteLink(gameID)
|
@snakecomponents.InviteLink(gameID)
|
||||||
}
|
}
|
||||||
</main>
|
</div>
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ JoinPage(gameID string) {
|
templ JoinPage(gameID string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user