refactor: extract shared player, session, and chat packages #5
@@ -15,7 +15,6 @@ import (
|
|||||||
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
chatcomponents "github.com/ryanhamamura/games/chat/components"
|
||||||
"github.com/ryanhamamura/games/connect4"
|
"github.com/ryanhamamura/games/connect4"
|
||||||
"github.com/ryanhamamura/games/db/repository"
|
"github.com/ryanhamamura/games/db/repository"
|
||||||
"github.com/ryanhamamura/games/features/c4game/components"
|
|
||||||
"github.com/ryanhamamura/games/features/c4game/pages"
|
"github.com/ryanhamamura/games/features/c4game/pages"
|
||||||
"github.com/ryanhamamura/games/sessions"
|
"github.com/ryanhamamura/games/sessions"
|
||||||
)
|
)
|
||||||
@@ -113,8 +112,16 @@ func HandleGameEvents(store *connect4.Store, nc *nats.Conn, sm *scs.SessionManag
|
|||||||
chatCfg := c4ChatConfig(gameID)
|
chatCfg := c4ChatConfig(gameID)
|
||||||
room := chat.NewPersistentRoom(nc, connect4.ChatSubject(gameID), queries, gameID)
|
room := chat.NewPersistentRoom(nc, connect4.ChatSubject(gameID), queries, gameID)
|
||||||
|
|
||||||
|
patchAll := func() error {
|
||||||
|
myColor = gi.GetPlayerColor(playerID)
|
||||||
|
g := gi.GetGame()
|
||||||
|
return sse.PatchElementTempl(pages.GameContent(g, myColor, room.Messages(), chatCfg))
|
||||||
|
}
|
||||||
|
|
||||||
// Send initial render
|
// Send initial render
|
||||||
sendGameComponents(sse, gi, myColor, room, chatCfg)
|
if err := patchAll(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Subscribe to game state updates
|
// Subscribe to game state updates
|
||||||
gameCh := make(chan *nats.Msg, 64)
|
gameCh := make(chan *nats.Msg, 64)
|
||||||
@@ -137,14 +144,12 @@ func HandleGameEvents(store *connect4.Store, nc *nats.Conn, sm *scs.SessionManag
|
|||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-gameCh:
|
case <-gameCh:
|
||||||
myColor = gi.GetPlayerColor(playerID)
|
if err := patchAll(); err != nil {
|
||||||
sendGameComponents(sse, gi, myColor, room, chatCfg)
|
return
|
||||||
case msg := <-chatCh:
|
|
||||||
_, snapshot := room.Receive(msg.Data)
|
|
||||||
if snapshot == nil {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if err := sse.PatchElementTempl(chatcomponents.Chat(snapshot, chatCfg)); err != nil {
|
case msg := <-chatCh:
|
||||||
|
room.Receive(msg.Data)
|
||||||
|
if err := patchAll(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,13 +305,3 @@ func HandleRematch(store *connect4.Store, sm *scs.SessionManager) http.HandlerFu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendGameComponents patches all game-related SSE components.
|
|
||||||
func sendGameComponents(sse *datastar.ServerSentEventGenerator, gi *connect4.Instance, myColor int, room *chat.Room, chatCfg chatcomponents.Config) {
|
|
||||||
g := gi.GetGame()
|
|
||||||
|
|
||||||
sse.PatchElementTempl(components.Board(g, myColor)) //nolint:errcheck
|
|
||||||
sse.PatchElementTempl(components.StatusBanner(g, myColor)) //nolint:errcheck
|
|
||||||
sse.PatchElementTempl(components.PlayerInfo(g, myColor)) //nolint:errcheck
|
|
||||||
sse.PatchElementTempl(chatcomponents.Chat(room.Messages(), chatCfg)) //nolint:errcheck
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -17,21 +17,27 @@ templ GamePage(g *connect4.Game, myColor int, messages []chat.Message, chatCfg c
|
|||||||
data-signals="{chatMsg: ''}"
|
data-signals="{chatMsg: ''}"
|
||||||
data-init={ datastar.GetSSE("/games/%s/events", g.ID) }
|
data-init={ datastar.GetSSE("/games/%s/events", g.ID) }
|
||||||
>
|
>
|
||||||
@sharedcomponents.BackToLobby()
|
@GameContent(g, myColor, messages, chatCfg)
|
||||||
@sharedcomponents.StealthTitle("text-3xl font-bold")
|
|
||||||
@components.PlayerInfo(g, myColor)
|
|
||||||
@components.StatusBanner(g, myColor)
|
|
||||||
<div class="c4-game-area">
|
|
||||||
@components.Board(g, myColor)
|
|
||||||
@chatcomponents.Chat(messages, chatCfg)
|
|
||||||
</div>
|
|
||||||
if g.Status == connect4.StatusWaitingForPlayer {
|
|
||||||
@components.InviteLink(g.ID)
|
|
||||||
}
|
|
||||||
</main>
|
</main>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
templ GameContent(g *connect4.Game, myColor int, messages []chat.Message, chatCfg chatcomponents.Config) {
|
||||||
|
<div id="game-content">
|
||||||
|
@sharedcomponents.BackToLobby()
|
||||||
|
@sharedcomponents.StealthTitle("text-3xl font-bold")
|
||||||
|
@components.PlayerInfo(g, myColor)
|
||||||
|
@components.StatusBanner(g, myColor)
|
||||||
|
<div class="c4-game-area">
|
||||||
|
@components.Board(g, myColor)
|
||||||
|
@chatcomponents.Chat(messages, chatCfg)
|
||||||
|
</div>
|
||||||
|
if g.Status == connect4.StatusWaitingForPlayer {
|
||||||
|
@components.InviteLink(g.ID)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
templ JoinPage(gameID string) {
|
templ JoinPage(gameID string) {
|
||||||
@layouts.Base("Connect 4 - Join") {
|
@layouts.Base("Connect 4 - Join") {
|
||||||
@sharedcomponents.GameJoinPrompt(
|
@sharedcomponents.GameJoinPrompt(
|
||||||
|
|||||||
Reference in New Issue
Block a user