From 0a5175f194a63bae6f42ac6a8a24522ab7bcaec9 Mon Sep 17 00:00:00 2001 From: Scott Hadfield Date: Wed, 1 Apr 2026 13:55:56 -0700 Subject: [PATCH] Implement draw offers, fix waitForOpponent Jetstream bug Draw offers: player writes drawOffered to their record, opponent sees accept/decline banner via Jetstream. Accepting writes draw result, declining just dismisses. Making a move implicitly declines. State persists across page reloads. Also fixes: waitForOpponent ignoring events with status != active (prevents premature transition when creating game as black), connectJetstream called before PDS write (prevents dead Jetstream if write fails), game controls hidden until first move played, explicit result tracking for resignation and draw by agreement. --- src/routes/game/[did]/[rkey]/+page.svelte | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/routes/game/[did]/[rkey]/+page.svelte b/src/routes/game/[did]/[rkey]/+page.svelte index 3930e79..517af62 100644 --- a/src/routes/game/[did]/[rkey]/+page.svelte +++ b/src/routes/game/[did]/[rkey]/+page.svelte @@ -293,14 +293,16 @@ blackDid: black, status: 'active' as const, }); + resolvePlayerHandles(white, black); + connectJetstream(opponentDid); + + // Persist to PDS after Jetstream is connected if (auth.agent && myRkey) { const updates: Record = { status: 'active' }; if (weAreWhite) updates.black = black; else updates.white = white; - await updateGame(auth.agent, myRkey, updates); + updateGame(auth.agent, myRkey, updates).catch(() => {}); } - resolvePlayerHandles(white, black); - connectJetstream(opponentDid); } }, onConnectionChange: (isConnected) => { @@ -491,6 +493,7 @@ if (!auth.agent || !auth.did || !myRkey) return; const result = game.myColor === 'white' ? '0-1' : '1-0'; + game.setResult(result, 'resignation'); game.setStatus('completed'); await updateGame(auth.agent, myRkey, { status: 'completed', @@ -863,9 +866,9 @@ {/if} - {#if !isSpectator} + {#if !isSpectator && game.status === 'active' && game.moveCount > 0} - {game.status === 'waiting' ? 'Cancel game' : `Claim win (opponent inactive ${daysSinceActivity}d)`} + Claim win (opponent inactive {daysSinceActivity}d) {/if} {/if} -- 2.51.2