dev vouch dev on at. thats about it atvouch.dev
8
fork

Configure Feed

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

let users delete vouches

Luna 102548f7 bfa9dd3f

+42 -2
+14
frontend/src/App.css
··· 358 358 font-variant-numeric: tabular-nums; 359 359 } 360 360 361 + .vouch-delete { 362 + background: none; 363 + border: none; 364 + cursor: pointer; 365 + padding: 0 0.25rem; 366 + font-size: 14px; 367 + opacity: 0.5; 368 + flex-shrink: 0; 369 + } 370 + 371 + .vouch-delete:hover { 372 + opacity: 1; 373 + } 374 + 361 375 /* ── responsive ── */ 362 376 363 377 @media (max-width: 640px) {
+13 -1
frontend/src/App.tsx
··· 10 10 import { 11 11 getSessionInfo, 12 12 createVouch, 13 + deleteVouch, 13 14 listVouches, 14 15 checkVouchPaths, 15 16 type CheckResult, ··· 193 194 ) : ( 194 195 <ul className="vouch-list"> 195 196 {vouches?.map((v) => ( 196 - <li key={v.did}> 197 + <li key={v.rkey}> 197 198 <span className="vouch-handle">{v.handle ?? v.did}</span> 198 199 <span className="vouch-date"> 199 200 {new Date(v.createdAt).toISOString().slice(0, 10)} 200 201 </span> 202 + <button 203 + className="vouch-delete" 204 + title="Delete vouch" 205 + onClick={async () => { 206 + if (!confirm(`Remove vouch for ${v.handle ?? v.did}?`)) return; 207 + await deleteVouch(agent, v.rkey); 208 + refreshVouches(); 209 + }} 210 + > 211 + &#x1f5d1; 212 + </button> 201 213 </li> 202 214 ))} 203 215 </ul>
+15 -1
frontend/src/api.ts
··· 87 87 }; 88 88 } 89 89 90 + export async function deleteVouch(agent: OAuthUserAgent, rkey: string): Promise<void> { 91 + const rpc = new XRPC({ handler: agent }); 92 + await rpc.call("com.atproto.repo.deleteRecord", { 93 + data: { 94 + repo: agent.sub, 95 + collection: "dev.atvouch.graph.vouch", 96 + rkey, 97 + }, 98 + }); 99 + } 100 + 90 101 // List all DIDs the user has vouched for 91 102 async function listMyVouches(agent: OAuthUserAgent): Promise<string[]> { 92 103 const rpc = new XRPC({ handler: agent }); ··· 123 134 did: string; 124 135 handle: string | null; 125 136 createdAt: string; 137 + rkey: string; 126 138 } 127 139 128 140 export async function listVouches(agent: OAuthUserAgent): Promise<VouchEntry[]> { ··· 141 153 }); 142 154 143 155 const data = resp.data as unknown as { 144 - records: Array<{ value: { subject: string; createdAt: string } }>; 156 + records: Array<{ uri: string; value: { subject: string; createdAt: string } }>; 145 157 cursor?: string; 146 158 }; 147 159 148 160 for (const rec of data.records) { 149 161 if (rec.value.subject) { 162 + const rkey = rec.uri.split("/").pop()!; 150 163 entries.push({ 151 164 did: rec.value.subject, 152 165 handle: null, 153 166 createdAt: rec.value.createdAt, 167 + rkey, 154 168 }); 155 169 } 156 170 }