The script was being re-added on every SSE patch, creating multiple setInterval timers. Split into ConnectionIndicator (for patches) and ConnectionIndicatorWithScript (for initial page render).
124 lines
3.6 KiB
Plaintext
124 lines
3.6 KiB
Plaintext
package components
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/starfederation/datastar-go/datastar"
|
|
)
|
|
|
|
templ BackToLobby() {
|
|
<a class="link text-sm opacity-70" href="/">← Back</a>
|
|
}
|
|
|
|
templ StealthTitle(class string) {
|
|
<span class={ class }>
|
|
<span style="color:#4a2a3a">●</span>
|
|
<span style="color:#2a4545">●</span>
|
|
<span style="color:#4a2a3a">●</span>
|
|
<span style="color:#2a4545">●</span>
|
|
</span>
|
|
}
|
|
|
|
templ NicknamePrompt(returnPath string) {
|
|
<main class="max-w-sm mx-auto mt-8 text-center" data-signals="{nickname: ''}">
|
|
<h1 class="text-3xl font-bold">Join Game</h1>
|
|
<p class="mb-4">Enter your nickname to join the game.</p>
|
|
<form>
|
|
<fieldset class="fieldset">
|
|
<label class="label" for="nickname">Your Nickname</label>
|
|
<input
|
|
class="input input-bordered w-full"
|
|
id="nickname"
|
|
type="text"
|
|
placeholder="Enter your nickname"
|
|
data-bind="nickname"
|
|
data-on:keydown={ "evt.key === 'Enter' && " + datastar.PostSSE("%s", returnPath) }
|
|
required
|
|
autofocus
|
|
/>
|
|
</fieldset>
|
|
<button
|
|
class="btn btn-primary w-full"
|
|
type="button"
|
|
data-on:click={ datastar.PostSSE("%s", returnPath) }
|
|
>
|
|
Join
|
|
</button>
|
|
</form>
|
|
</main>
|
|
}
|
|
|
|
func isStale(lastPing int64) bool {
|
|
return lastPing == 0
|
|
}
|
|
|
|
// ConnectionIndicator shows a small dot indicating SSE connection status.
|
|
// Server patches this with a timestamp; client JS detects staleness.
|
|
// Use ConnectionIndicatorWithScript for initial render, ConnectionIndicator for patches.
|
|
templ ConnectionIndicator(lastPing int64) {
|
|
<div
|
|
id="connection-indicator"
|
|
class="fixed top-2 right-2"
|
|
data-last-ping={ fmt.Sprintf("%d", lastPing) }
|
|
>
|
|
<div class="inline-grid *:[grid-area:1/1]">
|
|
<div
|
|
id="connection-ping"
|
|
class={
|
|
"status status-sm",
|
|
templ.KV("status-success animate-ping", !isStale(lastPing)),
|
|
templ.KV("status-error", isStale(lastPing)),
|
|
}
|
|
></div>
|
|
<div
|
|
id="connection-dot"
|
|
class={
|
|
"status status-sm",
|
|
templ.KV("status-success", !isStale(lastPing)),
|
|
templ.KV("status-error", isStale(lastPing)),
|
|
}
|
|
></div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
// ConnectionIndicatorWithScript renders the indicator with the staleness watcher script.
|
|
// Use this for initial page render only.
|
|
templ ConnectionIndicatorWithScript(lastPing int64) {
|
|
@ConnectionIndicator(lastPing)
|
|
@connectionWatcher()
|
|
}
|
|
|
|
script connectionWatcher() {
|
|
setInterval(function() {
|
|
var el = document.getElementById('connection-indicator');
|
|
var dot = document.getElementById('connection-dot');
|
|
var ping = document.getElementById('connection-ping');
|
|
if (!el || !dot || !ping) return;
|
|
|
|
var lastPing = parseInt(el.dataset.lastPing, 10) || 0;
|
|
var stale = Date.now() - lastPing > 20000;
|
|
|
|
dot.classList.toggle('status-success', !stale);
|
|
dot.classList.toggle('status-error', stale);
|
|
ping.classList.toggle('status-success', !stale);
|
|
ping.classList.toggle('status-error', stale);
|
|
ping.classList.toggle('animate-ping', !stale);
|
|
}, 1000);
|
|
}
|
|
|
|
templ GameJoinPrompt(loginURL string, registerURL string, gamePath string) {
|
|
<main class="max-w-sm mx-auto mt-8 text-center">
|
|
<h1 class="text-3xl font-bold">Join Game</h1>
|
|
<p class="mb-4">Log in to track your game history, or continue as a guest.</p>
|
|
<div class="flex flex-col gap-2 my-4">
|
|
<a class="btn btn-primary w-full" href={ templ.SafeURL(loginURL) }>Login</a>
|
|
<a class="btn btn-secondary w-full" href={ templ.SafeURL(gamePath + "?guest=1") }>Continue as Guest</a>
|
|
</div>
|
|
<p class="text-sm opacity-60">
|
|
Don't have an account?
|
|
<a class="link" href={ templ.SafeURL(registerURL) }>Register</a>
|
|
</p>
|
|
</main>
|
|
}
|