From cedcadfe3cd75bc209fefbe85ea745a3ecba5920 Mon Sep 17 00:00:00 2001 From: Ryan Hamamura <58859899+ryanhamamura@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:34:13 -1000 Subject: [PATCH] feat: re-enable connection indicator for SSE status Add ConnectionIndicator to Connect 4 game page (Snake already had it). Both games now patch the indicator on initial connect and every 10s heartbeat, giving users visual feedback that SSE is connected. --- features/c4game/handlers.go | 11 +++++++++-- features/c4game/pages/game.templ | 1 + features/snakegame/handlers.go | 11 +++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/features/c4game/handlers.go b/features/c4game/handlers.go index 3c94474..2515eef 100644 --- a/features/c4game/handlers.go +++ b/features/c4game/handlers.go @@ -14,6 +14,7 @@ import ( "github.com/ryanhamamura/games/connect4" "github.com/ryanhamamura/games/features/c4game/pages" "github.com/ryanhamamura/games/features/c4game/services" + sharedcomponents "github.com/ryanhamamura/games/features/common/components" "github.com/ryanhamamura/games/sessions" ) @@ -112,7 +113,10 @@ func HandleGameEvents(store *connect4.Store, svc *services.GameService, sm *scs. return sse.PatchElementTempl(pages.GameContent(g, myColor, room.Messages(), chatCfg)) } - // Send initial state + // Send initial connection indicator and state + if err := sse.PatchElementTempl(sharedcomponents.ConnectionIndicator(time.Now().UnixMilli())); err != nil { + return + } if err := patchAll(); err != nil { return } @@ -147,7 +151,10 @@ func HandleGameEvents(store *connect4.Store, svc *services.GameService, sm *scs. } case <-heartbeat.C: - // Heartbeat just keeps the connection alive by triggering a game state refresh + // Heartbeat updates connection indicator and refreshes game state + if err := sse.PatchElementTempl(sharedcomponents.ConnectionIndicator(time.Now().UnixMilli())); err != nil { + return + } if err := patchAll(); err != nil { return } diff --git a/features/c4game/pages/game.templ b/features/c4game/pages/game.templ index c5d9f11..455c91d 100644 --- a/features/c4game/pages/game.templ +++ b/features/c4game/pages/game.templ @@ -18,6 +18,7 @@ templ GamePage(g *connect4.Game, myColor int, messages []chat.Message, chatCfg c data-signals="{chatMsg: ''}" data-init={ fmt.Sprintf("@get('/games/%s/events',{requestCancellation:'disabled'})", g.ID) } > + @sharedcomponents.ConnectionIndicator(0) @GameContent(g, myColor, messages, chatCfg) } diff --git a/features/snakegame/handlers.go b/features/snakegame/handlers.go index 99d11fd..7808327 100644 --- a/features/snakegame/handlers.go +++ b/features/snakegame/handlers.go @@ -12,6 +12,7 @@ import ( "github.com/ryanhamamura/games/chat" chatcomponents "github.com/ryanhamamura/games/chat/components" + sharedcomponents "github.com/ryanhamamura/games/features/common/components" "github.com/ryanhamamura/games/features/snakegame/pages" "github.com/ryanhamamura/games/features/snakegame/services" "github.com/ryanhamamura/games/sessions" @@ -117,7 +118,10 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, svc *services.GameService, return sse.PatchElementTempl(pages.GameContent(sg, mySlot, chatMessages(), chatCfg, gameID)) } - // Send initial render + // Send initial connection indicator and render + if err := sse.PatchElementTempl(sharedcomponents.ConnectionIndicator(time.Now().UnixMilli())); err != nil { + return + } if err := patchAll(); err != nil { return } @@ -141,7 +145,10 @@ func HandleSnakeEvents(snakeStore *snake.SnakeStore, svc *services.GameService, return case <-heartbeat.C: - // Heartbeat just refreshes game state + // Heartbeat updates connection indicator and refreshes game state + if err := sse.PatchElementTempl(sharedcomponents.ConnectionIndicator(time.Now().UnixMilli())); err != nil { + return + } if err := patchAll(); err != nil { return }