extremely claude-assisted go game based on atproto! working on cleaning up and giving a more unique design, still has a bit of a slop vibe to it.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix login button visibility and Enter key submission

- Create spectating store for cross-component state sharing
- Show header login button when spectating on homepage
- Remove "Want to play?" banner (replaced by header login button)
- Add explicit Enter key handler to main login form input

Fixes:
- Login button now shows when spectating (games view)
- No login button on home login screen (avoids duplicate UI)
- Enter key explicitly triggers login on main form

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

+14 -6
+4 -2
src/lib/components/Header.svelte
··· 4 4 import { fetchUserProfile, type UserProfile } from '$lib/atproto-client'; 5 5 import ProfileDropdown from './ProfileDropdown.svelte'; 6 6 import { Card, Modal, Input, Button } from '$lib/components/ui'; 7 + import { spectating } from '$lib/stores/spectating'; 7 8 8 9 type Session = { did: string } | null; 9 10 ··· 14 15 let handle = $state(''); 15 16 let isLoggingIn = $state(false); 16 17 17 - // Don't show login button on homepage (login form is already there) 18 + // Show login button when: not on homepage, OR on homepage but spectating 18 19 let isHomepage = $derived($page.url.pathname === '/'); 20 + let showLoginButton = $derived(!isHomepage || $spectating); 19 21 20 22 onMount(async () => { 21 23 if (session) { ··· 65 67 {:else if session} 66 68 <!-- Loading profile --> 67 69 <div class="avatar-placeholder"></div> 68 - {:else if !isHomepage} 70 + {:else if showLoginButton} 69 71 <button class="login-link" onclick={() => showLoginModal = true}>Login</button> 70 72 {/if} 71 73 </div>
+3
src/lib/stores/spectating.ts
··· 1 + import { writable } from 'svelte/store'; 2 + 3 + export const spectating = writable(false);
+7 -4
src/routes/+page.svelte
··· 8 8 import { getSoundManager } from '$lib/sound-manager'; 9 9 import { gameTitle } from '$lib/game-titles'; 10 10 import { browser } from '$app/environment'; 11 + import { spectating as spectatingStore } from '$lib/stores/spectating'; 11 12 12 13 let { data }: { data: PageData } = $props(); 13 14 ··· 24 25 let colorChoice = $state<'black' | 'white' | 'random'>('black'); 25 26 let handicap = $state(0); 26 27 let showExtraOptions = $state(false); 28 + 29 + // Sync local spectating state with store 30 + $effect(() => { 31 + spectatingStore.set(spectating); 32 + }); 27 33 28 34 // Svelte action to sync input value changes with state 29 35 function syncValue(node: HTMLInputElement, callback: (value: string) => void) { ··· 593 599 use:syncValue={(val) => handle = val} 594 600 oninput={(e) => handle = e.currentTarget.value} 595 601 onchange={(e) => handle = e.currentTarget.value} 602 + onkeydown={(e) => { if (e.key === 'Enter' && !isLoggingIn) { e.preventDefault(); login(); } }} 596 603 placeholder="your-handle.bsky.social" 597 604 disabled={isLoggingIn} 598 605 class="input" ··· 608 615 </button> 609 616 </div> 610 617 {:else} 611 - <div class="login-banner"> 612 - <span>Want to play? <button class="login-banner-link" onclick={() => spectating = false}>Login with Bluesky</button></span> 613 - </div> 614 - 615 618 {#if isLoadingGames} 616 619 <div class="loading-state">Loading games...</div> 617 620 {:else}