This repository has no description
0

Configure Feed

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

resolve lint errors

author
pds.dad
date (Jul 3, 2026, 4:33 PM -0500) commit 872d75dc parent 1b865501 change-id vloymmkn
+43 -34
+2
client/eslint.config.js
··· 11 11 12 12 export default defineConfig( 13 13 includeIgnoreFile(gitignorePath), 14 + // Auto-generated lexicon client code (regenerated by `pnpm lexgen`); also ignored in .prettierignore 15 + { ignores: ['src/lib/lexicon/**'] }, 14 16 js.configs.recommended, 15 17 ...ts.configs.recommended, 16 18 ...svelte.configs.recommended,
+6 -5
client/src/lib/components/Navbar.svelte
··· 1 1 <script lang="ts"> 2 2 import { page } from '$app/state'; 3 + import { resolve } from '$app/paths'; 3 4 import { auth } from '$lib/auth/auth.svelte'; 4 5 import { closeOnOutsideClick } from '$lib/attachments/closeOnOutsideClick'; 5 6 import LoginModal from './LoginModal.svelte'; ··· 7 8 let loginOpen = $state(false); 8 9 9 10 const links = [ 10 - { href: '/', label: 'Play' }, 11 - { href: '/ranked', label: 'Ranked' }, 12 - { href: '/leaderboard', label: 'Leaderboard' }, 13 - { href: '/about', label: 'About' } 11 + { href: resolve('/'), label: 'Play' }, 12 + { href: resolve('/ranked'), label: 'Ranked' }, 13 + { href: resolve('/leaderboard'), label: 'Leaderboard' }, 14 + { href: resolve('/about'), label: 'About' } 14 15 ]; 15 16 16 17 const displayName = $derived(auth.handle ?? (auth.did ? `${auth.did.slice(0, 16)}…` : '')); ··· 53 54 {@render navLinks()} 54 55 </ul> 55 56 </details> 56 - <a href="/" class="btn btn-ghost btn-sm text-base font-bold lg:btn-md lg:text-lg"> 57 + <a href={resolve('/')} class="btn btn-ghost btn-sm text-base font-bold lg:btn-md lg:text-lg"> 57 58 <span class="relative -top-0.5">♜</span> PuzzleMeThis 58 59 </a> 59 60 </div>
+1 -1
client/src/lib/components/PuzzlePlayer.svelte
··· 165 165 class="btn btn-outline sm:btn-sm" 166 166 href={shareHref} 167 167 target="_blank" 168 - rel="noopener noreferrer" 168 + rel="external noopener noreferrer" 169 169 > 170 170 <svg viewBox="0 0 600 530" class="h-4 w-4 fill-current" aria-hidden="true"> 171 171 <path
+2
client/src/lib/puzzle/engine.svelte.ts
··· 37 37 turnColor = $state<Color>('white'); 38 38 check = $state(false); 39 39 lastMove = $state<[Key, Key] | undefined>(undefined); 40 + // eslint-disable-next-line svelte/prefer-svelte-reactivity -- $state.raw, reassigned wholesale, never mutated 40 41 dests = $state.raw<Map<Key, Key[]>>(new Map()); 41 42 /** True while the solution is being replayed after a fail. */ 42 43 replaying = $state(false); ··· 166 167 this.turnColor = this.chess.turn() === 'w' ? 'white' : 'black'; 167 168 this.check = this.chess.inCheck(); 168 169 this.lastMove = lastMove; 170 + // eslint-disable-next-line svelte/prefer-svelte-reactivity -- $state.raw, reassigned wholesale, never mutated 169 171 this.dests = this.status === 'playerTurn' ? buildDests(this.chess) : new Map(); 170 172 } 171 173 }
+2 -1
client/src/routes/+error.svelte
··· 1 1 <script lang="ts"> 2 2 import { page } from '$app/state'; 3 + import { resolve } from '$app/paths'; 3 4 </script> 4 5 5 6 <svelte:head><title>{page.status} — PuzzleMeThis</title></svelte:head> ··· 7 8 <div class="mx-auto flex max-w-2xl flex-col items-center gap-4 p-4 py-16 text-center"> 8 9 <h1 class="text-4xl font-bold">{page.status}</h1> 9 10 <p class="opacity-70">{page.error?.message ?? 'Something went wrong.'}</p> 10 - <a href="/" class="btn btn-primary btn-sm">Play a random puzzle</a> 11 + <a href={resolve('/')} class="btn btn-primary btn-sm">Play a random puzzle</a> 11 12 </div>
+1 -1
client/src/routes/+layout.svelte
··· 62 62 <div class="alert alert-warning rounded-none"> 63 63 <span> 64 64 Sign-in only works from the loopback address — 65 - <a class="link font-semibold" href={loopbackUrl}>switch to 127.0.0.1</a> 65 + <a class="link font-semibold" href={loopbackUrl} rel="external">switch to 127.0.0.1</a> 66 66 </span> 67 67 </div> 68 68 {/if}
+20 -19
client/src/routes/+page.svelte
··· 1 1 <script lang="ts"> 2 - import { replaceState } from "$app/navigation"; 3 - import { page } from "$app/state"; 4 - import type { PuzzleView } from "$lib/lexicon/types/org/lichess/puzzle/defs"; 5 - import CasualPuzzle from "$lib/components/CasualPuzzle.svelte"; 2 + import { replaceState } from '$app/navigation'; 3 + import { resolve } from '$app/paths'; 4 + import { page } from '$app/state'; 5 + import type { PuzzleView } from '$lib/lexicon/types/org/lichess/puzzle/defs'; 6 + import CasualPuzzle from '$lib/components/CasualPuzzle.svelte'; 6 7 7 - let current = $state<PuzzleView | null>(null); 8 + let current = $state<PuzzleView | null>(null); 8 9 9 - // Reflect the loaded puzzle in the address bar (shallow routing — no 10 - // navigation, no remount) so users can copy/share a /puzzle/<id> link. 11 - // Guard against rewriting to the URL we're already on: that avoids calling 12 - // replaceState before the client router is initialized on the first paint. 13 - function reflect(puzzle: PuzzleView) { 14 - current = puzzle; 15 - const path = `/puzzle/${puzzle.id}`; 16 - if (page.url.pathname !== path) replaceState(path, {}); 17 - } 10 + // Reflect the loaded puzzle in the address bar (shallow routing — no 11 + // navigation, no remount) so users can copy/share a /puzzle/<id> link. 12 + // Guard against rewriting to the URL we're already on: that avoids calling 13 + // replaceState before the client router is initialized on the first paint. 14 + function reflect(puzzle: PuzzleView) { 15 + current = puzzle; 16 + const path = `/puzzle/${puzzle.id}`; 17 + if (page.url.pathname !== path) replaceState(resolve('/puzzle/[id]', { id: puzzle.id }), {}); 18 + } 18 19 </script> 19 20 20 21 <svelte:head> 21 - {#if current} 22 - <title>Puzzle {current.id} — PuzzleMeThis</title> 23 - {:else} 24 - <title>PuzzleMeThis — casual practice</title> 25 - {/if} 22 + {#if current} 23 + <title>Puzzle {current.id} — PuzzleMeThis</title> 24 + {:else} 25 + <title>PuzzleMeThis — casual practice</title> 26 + {/if} 26 27 </svelte:head> 27 28 28 29 <CasualPuzzle onPuzzle={reflect} />
+6 -5
client/src/routes/about/+page.svelte
··· 1 1 <script lang="ts"> 2 2 import { PUBLIC_API_URL } from '$env/static/public'; 3 + import { resolve } from '$app/paths'; 3 4 4 5 const repoUrl = 'https://tangled.org/pds.dad/puzzle-me-this'; 5 6 </script> ··· 20 21 >lichess's Puzzle Database</a 21 22 >. What does atproto mean? Well, you can interact with our 22 23 <a class="link" href="https://atproto.com/specs/xrpc">XRPC</a> 23 - endpoint at <a class="link" href={PUBLIC_API_URL}>{PUBLIC_API_URL}</a>. You can make calls 24 - like 25 - <a class="link" href="{PUBLIC_API_URL}/xrpc/org.lichess.puzzle.getRandom" 24 + endpoint at <a class="link" href={PUBLIC_API_URL} rel="external">{PUBLIC_API_URL}</a>. You can 25 + make calls like 26 + <a class="link" href="{PUBLIC_API_URL}/xrpc/org.lichess.puzzle.getRandom" rel="external" 26 27 >{PUBLIC_API_URL}/xrpc/org.lichess.puzzle.getRandom</a 27 28 > 28 29 to get a random puzzle. Or login with the same account you use with other Atmosphere apps to save 29 30 your attempts to your public 30 31 <a class="link" href="https://atproto.com/specs/repository">atproto repo</a>, you can even 31 32 submit them to our XRPC service to show up on the 32 - <a class="link" href="/leaderboard">leaderboard</a>. You can see all of the endpoints I 33 - support and types 33 + <a class="link" href={resolve('/leaderboard')}>leaderboard</a>. You can see all of the 34 + endpoints I support and types 34 35 <a class="link" href="https://tangled.org/pds.dad/puzzle-me-this/tree/main/lexicons" 35 36 >right here in our git repo</a 36 37 >. They're <a class="link" href="https://atproto.com/specs/lexicon">lexicon schema files</a> meaning
+2 -1
client/src/routes/puzzle/[id]/+page.svelte
··· 1 1 <script lang="ts"> 2 2 import { page } from '$app/state'; 3 3 import { replaceState } from '$app/navigation'; 4 + import { resolve } from '$app/paths'; 4 5 import { PUBLIC_API_URL } from '$env/static/public'; 5 6 import type { PuzzleView } from '$lib/lexicon/types/org/lichess/puzzle/defs'; 6 7 import CasualPuzzle from '$lib/components/CasualPuzzle.svelte'; ··· 35 36 function reflect(puzzle: PuzzleView) { 36 37 current = puzzle; 37 38 const path = `/puzzle/${puzzle.id}`; 38 - if (page.url.pathname !== path) replaceState(path, {}); 39 + if (page.url.pathname !== path) replaceState(resolve('/puzzle/[id]', { id: puzzle.id }), {}); 39 40 } 40 41 </script> 41 42
+1 -1
client/vite.config.ts
··· 8 8 // auth.svelte.ts). Vite's default `localhost` host resolves to IPv6 [::1] 9 9 // only on macOS, so serving on IPv4 127.0.0.1 is required — otherwise the 10 10 // client redirects the page to 127.0.0.1 and nothing is listening there. 11 - server: { host: '127.0.0.1' }, 11 + server: { host: '127.0.0.1', allowedHosts: ['client.pds.dad'] }, 12 12 plugins: [ 13 13 tailwindcss(), 14 14 sveltekit({