fix: MR detail 404, wire up fork buttons on import page - Fix listPullComments to pass pull AT-URI instead of separate params - Add xrpcProcedure helper for POST endpoints - Wire up Fork buttons to call dev.cospan.repo.fork and navigate
Author: Aaron Steven White
Commit
602218228d6e1c5dab9d4a7964d625a3886a28eaParent: a99c1a6dea
Structural diff unavailable
These commits were pushed via plain git push, so no pre-parsed
schemas are available. Install git-remote-cospan and re-push via panproto:// to
see scope-level changes, breaking change detection, and semantic diffs.
brew install panproto/tap/git-remote-cospan3 files changed +62 -5
@@ -54,3 +54,31 @@ export async function xrpcQuery<T>(
5454 5555 return response.json() as Promise<T>; 5656 } 57+ 58+export async function xrpcProcedure<T>( 59+ nsid: string, 60+ body: Record<string, unknown> 61+): Promise<T> { 62+ const base = getAppviewUrl(); 63+ const url = `${base || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000')}/xrpc/${nsid}`; 64+ 65+ const response = await fetch(url, { 66+ method: 'POST', 67+ headers: { 'Content-Type': 'application/json' }, 68+ body: JSON.stringify(body), 69+ credentials: 'include', 70+ }); 71+ 72+ if (!response.ok) { 73+ let error = 'Unknown'; 74+ let message = response.statusText; 75+ try { 76+ const b = await response.json(); 77+ error = b.error ?? error; 78+ message = b.message ?? message; 79+ } catch {} 80+ throw new XRPCError(response.status, error, message); 81+ } 82+ 83+ return response.json() as Promise<T>; 84+}
@@ -55,9 +55,10 @@ export async function listPullComments(params: {
5555 limit?: number; 5656 cursor?: string; 5757 }): Promise<PullCommentListResponse> { 58+ const pullUri = `at://${params.did}/dev.cospan.repo.pull/${params.rkey}`; 5859 const raw = await xrpcQuery<RawPullCommentListResponse>( 5960 'dev.cospan.repo.pull.comment.list', 60- params 61+ { pull: pullUri, limit: params.limit, cursor: params.cursor } 6162 ); 6263 return { items: raw.comments ?? [], cursor: raw.cursor ?? null }; 6364 }
@@ -5,11 +5,31 @@
55 import type { Repo } from '$lib/api/repo.js'; 66 import { listRepos } from '$lib/api/repo.js'; 77 import { resolveHandle } from '$lib/api/handle.js'; 8+ import { xrpcProcedure } from '$lib/api/client.js'; 89 import { getAuth } from '$lib/stores/auth.svelte'; 910 1011 let { data } = $props(); 1112 1213 let auth = $derived(getAuth()); 14+ let forkingRepo = $state<string | null>(null); 15+ let forkError = $state<string | null>(null); 16+ 17+ async function forkRepo(repo: Repo) { 18+ if (!auth.authenticated || !auth.did) return; 19+ forkingRepo = `${repo.did}/${repo.name}`; 20+ forkError = null; 21+ try { 22+ const sourceUri = `at://${repo.did}/dev.cospan.repo/${repo.rkey ?? repo.name}`; 23+ await xrpcProcedure('dev.cospan.repo.fork', { 24+ sourceRepo: sourceUri, 25+ did: auth.did, 26+ }); 27+ goto(`/${auth.did}/${repo.name}`); 28+ } catch (e: any) { 29+ forkError = e.message ?? 'Fork failed'; 30+ forkingRepo = null; 31+ } 32+ } 1333 let searchQuery = $state(''); 1434 let activeTab = $state<'all' | 'mine'>('all'); 1535
@@ -216,8 +236,12 @@
216236 <p class="mt-0.5 truncate text-[12px] text-ghost">{repo.description}</p> 217237 {/if} 218238 </div> 219- <button class="shrink-0 rounded-md bg-focus px-3 py-1 text-[12px] font-medium text-white transition-all hover:bg-focus-bright"> 220- Fork 239+ <button 240+ onclick={() => forkRepo(repo)} 241+ disabled={forkingRepo === `${repo.did}/${repo.name}`} 242+ class="shrink-0 rounded-md bg-focus px-3 py-1 text-[12px] font-medium text-white transition-all hover:bg-focus-bright disabled:opacity-50" 243+ > 244+ {forkingRepo === `${repo.did}/${repo.name}` ? 'Forking…' : 'Fork'} 221245 </button> 222246 </div> 223247 {/each}
@@ -269,8 +293,12 @@
269293 View on Tangled ↗ 270294 </a> 271295 </div> 272- <button class="shrink-0 rounded-md border border-line px-2.5 py-1 text-[11px] font-medium text-caption transition-all hover:border-line-bright hover:text-ink"> 273- Fork 296+ <button 297+ onclick={() => forkRepo(repo)} 298+ disabled={!auth.authenticated || forkingRepo === `${repo.did}/${repo.name}`} 299+ class="shrink-0 rounded-md border border-line px-2.5 py-1 text-[11px] font-medium text-caption transition-all hover:border-line-bright hover:text-ink disabled:opacity-50" 300+ > 301+ {forkingRepo === `${repo.did}/${repo.name}` ? 'Forking…' : 'Fork'} 274302 </button> 275303 </div> 276304 {/each}