atproto explorer

validate handles in identity tab

handle.invalid 0492e5e9 5c04389f

verified
+50 -31
+2 -27
src/components/navbar.tsx
··· 1 - import { Did, Handle } from "@atcute/lexicons"; 2 1 import { A, Params, useLocation } from "@solidjs/router"; 3 2 import { createEffect, createSignal, Show } from "solid-js"; 4 - import { didDocCache, labelerCache, validateHandle } from "../utils/api"; 3 + import { didDocCache, labelerCache } from "../utils/api"; 5 4 import { CopyMenu, DropdownMenu, MenuProvider } from "./dropdown"; 6 5 import Tooltip from "./tooltip"; 7 6 ··· 29 28 const NavBar = (props: { params: Params }) => { 30 29 const location = useLocation(); 31 30 const [handle, setHandle] = createSignal(props.params.repo); 32 - const [validHandle, setValidHandle] = createSignal<boolean | undefined>(undefined); 33 31 const [fullCid, setFullCid] = createSignal(false); 34 32 const [showHandle, setShowHandle] = createSignal(localStorage.showHandle === "true"); 35 33 ··· 43 41 didDocCache[props.params.repo]?.alsoKnownAs 44 42 ?.filter((alias) => alias.startsWith("at://"))[0] 45 43 .split("at://")[1] ?? props.params.repo; 46 - if (hdl !== handle() || validHandle() === undefined) { 47 - setValidHandle(undefined); 48 - setHandle(hdl); 49 - setValidHandle(await validateHandle(hdl as Handle, props.params.repo as Did)); 50 - } 44 + if (hdl !== handle()) setHandle(hdl); 51 45 } 52 46 }); 53 47 ··· 112 106 {showHandle() ? handle() : props.params.repo} 113 107 </A> 114 108 : <span>{showHandle() ? handle() : props.params.repo}</span>} 115 - <Show when={showHandle()}> 116 - <Tooltip 117 - text={ 118 - validHandle() === true ? "Valid handle" 119 - : validHandle() === undefined ? 120 - "Validating" 121 - : "Invalid handle" 122 - } 123 - > 124 - <span 125 - classList={{ 126 - "iconify lucide--circle-check": validHandle() === true, 127 - "iconify lucide--circle-x text-red-500 dark:text-red-400": 128 - validHandle() === false, 129 - "iconify lucide--loader-circle animate-spin": validHandle() === undefined, 130 - }} 131 - ></span> 132 - </Tooltip> 133 - </Show> 134 109 </div> 135 110 </div> 136 111 <Tooltip text={showHandle() ? "Show DID" : "Show handle"}>
+48 -4
src/views/repo.tsx
··· 7 7 processIndexedEntryLog, 8 8 } from "@atcute/did-plc"; 9 9 import { DidDocument } from "@atcute/identity"; 10 - import { ActorIdentifier, Handle } from "@atcute/lexicons"; 10 + import { ActorIdentifier, Did, Handle } from "@atcute/lexicons"; 11 11 import { A, useLocation, useNavigate, useParams } from "@solidjs/router"; 12 - import { createResource, createSignal, ErrorBoundary, For, Show, Suspense } from "solid-js"; 12 + import { 13 + createEffect, 14 + createResource, 15 + createSignal, 16 + ErrorBoundary, 17 + For, 18 + Show, 19 + Suspense, 20 + } from "solid-js"; 21 + import { createStore } from "solid-js/store"; 13 22 import { Backlinks } from "../components/backlinks.jsx"; 14 23 import { Button } from "../components/button.jsx"; 15 24 import { TextInput } from "../components/text-input.jsx"; 16 25 import Tooltip from "../components/tooltip.jsx"; 17 - import { didDocCache, resolveHandle, resolvePDS } from "../utils/api.js"; 26 + import { didDocCache, resolveHandle, resolvePDS, validateHandle } from "../utils/api.js"; 18 27 import { localDateFromTimestamp } from "../utils/date.js"; 19 28 import { createOperationHistory, DiffEntry, groupBy } from "../utils/plc-logs.js"; 20 29 import { BlobView } from "./blob.jsx"; ··· 164 173 const [showPlcLogs, setShowPlcLogs] = createSignal(false); 165 174 const [loading, setLoading] = createSignal(false); 166 175 const [notice, setNotice] = createSignal<string>(); 176 + const [validHandles, setValidHandles] = createStore<Record<string, boolean>>({}); 167 177 let rpc: Client; 168 178 let pds: string; 169 179 const did = params.repo; ··· 264 274 [authority]: { ...nsids()![authority], hidden: !nsids()![authority].hidden }, 265 275 }); 266 276 }; 277 + 278 + createEffect(async () => { 279 + for (const alias of didDoc()?.alsoKnownAs ?? []) { 280 + if (alias.startsWith("at://")) 281 + setValidHandles( 282 + alias, 283 + await validateHandle(alias.replace("at://", "") as Handle, did as Did), 284 + ); 285 + } 286 + }); 267 287 268 288 return ( 269 289 <Show when={repo()}> ··· 410 430 </div> 411 431 <ul> 412 432 <For each={didDocument().alsoKnownAs}> 413 - {(alias) => <li class="text-sm">{alias}</li>} 433 + {(alias) => ( 434 + <li class="flex items-center gap-1 text-sm"> 435 + <span>{alias}</span> 436 + <Show when={alias.startsWith("at://")}> 437 + <Tooltip 438 + text={ 439 + validHandles[alias] === true ? "Valid handle" 440 + : validHandles[alias] === undefined ? 441 + "Validating" 442 + : "Invalid handle" 443 + } 444 + > 445 + <span 446 + classList={{ 447 + "iconify lucide--circle-check": validHandles[alias] === true, 448 + "iconify lucide--circle-x text-red-500 dark:text-red-400": 449 + validHandles[alias] === false, 450 + "iconify lucide--loader-circle animate-spin": 451 + validHandles[alias] === undefined, 452 + }} 453 + ></span> 454 + </Tooltip> 455 + </Show> 456 + </li> 457 + )} 414 458 </For> 415 459 </ul> 416 460 </div>