refactor: patch connection indicator with timestamp
All checks were successful
CI / Deploy / test (pull_request) Successful in 14s
CI / Deploy / lint (pull_request) Successful in 26s
CI / Deploy / deploy (pull_request) Has been skipped

Server patches the ConnectionIndicator element with a timestamp on
each heartbeat. Client-side JS checks every second if the timestamp
is stale (>20s) and toggles red/green accordingly.

This properly detects connection loss since the indicator will turn
red if no patches are received.
This commit is contained in:
Ryan Hamamura
2026-03-03 10:25:04 -10:00
parent 99f14ca170
commit 19c48d593a
5 changed files with 30 additions and 13 deletions

View File

@@ -1,6 +1,10 @@
package components
import "github.com/starfederation/datastar-go/datastar"
import (
"fmt"
"github.com/starfederation/datastar-go/datastar"
)
templ BackToLobby() {
<a class="link text-sm opacity-70" href="/">&larr; Back</a>
@@ -45,18 +49,29 @@ templ NicknamePrompt(returnPath string) {
}
// ConnectionIndicator shows a small dot indicating SSE connection status.
// It requires a `lastPing` signal (unix ms timestamp) to be set by the server.
templ ConnectionIndicator() {
// Server patches this with a timestamp; client JS detects staleness.
templ ConnectionIndicator(lastPing int64) {
<div
id="connection-indicator"
class="fixed top-2 right-2 flex items-center gap-1 text-xs text-gray-500"
title="Connection status"
data-last-ping={ fmt.Sprintf("%d", lastPing) }
>
<span
class="w-2 h-2 rounded-full transition-colors duration-300"
data-class="{'bg-green-500': Date.now() - $lastPing < 20000, 'bg-red-500': Date.now() - $lastPing >= 20000}"
></span>
<span id="connection-dot" class="w-2 h-2 rounded-full bg-green-500"></span>
</div>
@connectionWatcher()
}
script connectionWatcher() {
setInterval(function() {
var el = document.getElementById('connection-indicator');
var dot = document.getElementById('connection-dot');
if (!el || !dot) return;
var lastPing = parseInt(el.dataset.lastPing, 10) || 0;
var stale = Date.now() - lastPing > 20000;
dot.classList.toggle('bg-green-500', !stale);
dot.classList.toggle('bg-red-500', stale);
}, 1000);
}
templ GameJoinPrompt(loginURL string, registerURL string, gamePath string) {