atmosphere explorer

inline handle verification

handle.invalid 5280dd5b b99cdcdd

verified
+119 -124
+119 -124
src/views/repo.tsx
··· 23 NavMenu, 24 } from "../components/dropdown.jsx"; 25 import { Favicon } from "../components/favicon.jsx"; 26 - import { Modal } from "../components/modal.jsx"; 27 import { 28 addNotification, 29 removeNotification, ··· 56 const [filter, setFilter] = createSignal<string>(); 57 const [validHandles, setValidHandles] = createStore<Record<string, boolean>>({}); 58 const [rotationKeys, setRotationKeys] = createSignal<Array<string>>([]); 59 - const [handleModalAlias, setHandleModalAlias] = createSignal<string | null>(null); 60 const [handleDetailedResult, setHandleDetailedResult] = createSignal<{ 61 dns: HandleResolveResult; 62 http: HandleResolveResult; ··· 512 </div> 513 } 514 > 515 - <button 516 - class="-ml-1 flex w-fit items-center gap-1 rounded px-1 py-0.5 text-sm text-neutral-700 hover:bg-neutral-200 active:bg-neutral-200 dark:text-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-700" 517 - onClick={async () => { 518 - setHandleDetailedResult(null); 519 - setHandleModalAlias(alias); 520 - const handle = alias.replace("at://", "") as Handle; 521 - const result = await resolveHandleDetailed(handle); 522 - if (handleModalAlias() === alias) setHandleDetailedResult(result); 523 - }} 524 - > 525 - <span>{alias}</span> 526 - <span 527 - classList={{ 528 - "iconify text-base lucide--check text-green-600 dark:text-green-400": 529 - validHandles[alias] === true, 530 - "iconify lucide--x text-red-500 dark:text-red-400": 531 - validHandles[alias] === false, 532 - "iconify lucide--loader-circle animate-spin": 533 - validHandles[alias] === undefined, 534 }} 535 - ></span> 536 - </button> 537 - </Show> 538 - )} 539 - </For> 540 - </div> 541 - </Show> 542 543 - {/* Handle Verification Modal */} 544 - <Modal 545 - open={handleModalAlias() !== null} 546 - onClose={() => setHandleModalAlias(null)} 547 - contentClass="dark:bg-dark-300 dark:shadow-dark-700 pointer-events-auto min-w-[min(24rem,90vw)] max-w-[90vw] rounded-lg border-[0.5px] border-neutral-300 bg-white p-4 shadow-md sm:max-w-xl dark:border-neutral-700" 548 - > 549 - <div class="mb-2 flex items-center justify-between gap-4"> 550 - <p class="truncate font-semibold"> 551 - {handleModalAlias()?.replace("at://", "")} 552 - </p> 553 - <button 554 - onclick={() => setHandleModalAlias(null)} 555 - class="flex shrink-0 items-center rounded-md p-1.5 text-neutral-500 hover:bg-neutral-100 hover:text-neutral-700 active:bg-neutral-200 dark:text-neutral-400 dark:hover:bg-neutral-700 dark:hover:text-neutral-200 dark:active:bg-neutral-600" 556 - > 557 - <span class="iconify lucide--x"></span> 558 - </button> 559 - </div> 560 - <div class="flex flex-col gap-2"> 561 - <Show 562 - when={handleDetailedResult()} 563 - fallback={ 564 - <div class="flex items-center gap-2 py-2"> 565 - <span class="iconify lucide--loader-circle animate-spin"></span> 566 - <span>Resolving handle...</span> 567 - </div> 568 - } 569 - > 570 - {(result) => { 571 - const expectedDid = didDocument().id; 572 - const dnsOk = () => 573 - result().dns.success && result().dns.did === expectedDid; 574 - const httpOk = () => 575 - result().http.success && result().http.did === expectedDid; 576 - const dnsMismatch = () => 577 - result().dns.success && result().dns.did !== expectedDid; 578 - const httpMismatch = () => 579 - result().http.success && result().http.did !== expectedDid; 580 581 - return ( 582 - <div class="grid grid-cols-[auto_1fr] items-center gap-x-1.5"> 583 - {/* DNS Result */} 584 - <span 585 - classList={{ 586 - "iconify lucide--check text-green-600 dark:text-green-400": 587 - dnsOk(), 588 - "iconify lucide--x text-red-500 dark:text-red-400": !dnsOk(), 589 - }} 590 - ></span> 591 - <span class="font-medium">DNS (TXT record)</span> 592 - <span></span> 593 - <div class="mb-2 text-sm wrap-anywhere text-neutral-500 dark:text-neutral-400"> 594 - <Show 595 - when={result().dns.success} 596 - fallback={ 597 - <div class="text-red-500 dark:text-red-400"> 598 - {result().dns.error} 599 - </div> 600 - } 601 - > 602 - <div>{result().dns.did}</div> 603 - <Show when={dnsMismatch()}> 604 - <div class="text-red-500 dark:text-red-400"> 605 - Expected: {expectedDid} 606 - </div> 607 - </Show> 608 - </Show> 609 - </div> 610 611 - {/* HTTP Result */} 612 - <span 613 - classList={{ 614 - "iconify lucide--check text-green-600 dark:text-green-400": 615 - httpOk(), 616 - "iconify lucide--x text-red-500 dark:text-red-400": !httpOk(), 617 - }} 618 - ></span> 619 - <span class="font-medium">HTTP (.well-known)</span> 620 - <span></span> 621 - <div class="text-sm wrap-anywhere text-neutral-500 dark:text-neutral-400"> 622 - <Show 623 - when={result().http.success} 624 - fallback={ 625 - <div class="text-red-500 dark:text-red-400"> 626 - {result().http.error} 627 - </div> 628 - } 629 - > 630 - <div>{result().http.did}</div> 631 - <Show when={httpMismatch()}> 632 - <div class="text-red-500 dark:text-red-400"> 633 - Expected: {expectedDid} 634 - </div> 635 </Show> 636 - </Show> 637 - </div> 638 </div> 639 - ); 640 - }} 641 - </Show> 642 </div> 643 - </Modal> 644 645 {/* Services Section */} 646 <Show when={didDocument().service}>
··· 23 NavMenu, 24 } from "../components/dropdown.jsx"; 25 import { Favicon } from "../components/favicon.jsx"; 26 import { 27 addNotification, 28 removeNotification, ··· 55 const [filter, setFilter] = createSignal<string>(); 56 const [validHandles, setValidHandles] = createStore<Record<string, boolean>>({}); 57 const [rotationKeys, setRotationKeys] = createSignal<Array<string>>([]); 58 + const [expandedAlias, setExpandedAlias] = createSignal<string | null>(null); 59 const [handleDetailedResult, setHandleDetailedResult] = createSignal<{ 60 dns: HandleResolveResult; 61 http: HandleResolveResult; ··· 511 </div> 512 } 513 > 514 + <div class="flex flex-col gap-2"> 515 + <button 516 + class="-ml-1 flex w-fit items-center gap-1 rounded px-1 py-0.5 text-sm text-neutral-700 hover:bg-neutral-200 active:bg-neutral-200 dark:text-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-700" 517 + onClick={async () => { 518 + if (expandedAlias() === alias) { 519 + setExpandedAlias(null); 520 + } else { 521 + setHandleDetailedResult(null); 522 + setExpandedAlias(alias); 523 + const handle = alias.replace("at://", "") as Handle; 524 + const result = await resolveHandleDetailed(handle); 525 + if (expandedAlias() === alias) 526 + setHandleDetailedResult(result); 527 + } 528 }} 529 + > 530 + <span>{alias}</span> 531 + <span 532 + classList={{ 533 + "iconify text-base lucide--check text-green-600 dark:text-green-400": 534 + validHandles[alias] === true, 535 + "iconify lucide--x text-red-500 dark:text-red-400": 536 + validHandles[alias] === false, 537 + "iconify lucide--loader-circle animate-spin": 538 + validHandles[alias] === undefined, 539 + }} 540 + ></span> 541 + </button> 542 543 + {/* Inline expansion */} 544 + <Show when={expandedAlias() === alias}> 545 + <div class="mb-2 rounded-lg border border-neutral-200 bg-neutral-50 p-3 dark:border-neutral-700 dark:bg-neutral-800/50"> 546 + <Show 547 + when={handleDetailedResult()} 548 + fallback={ 549 + <div class="flex items-center gap-2 py-2 text-sm"> 550 + <span class="iconify lucide--loader-circle animate-spin"></span> 551 + <span>Resolving handle...</span> 552 + </div> 553 + } 554 + > 555 + {(result) => { 556 + const expectedDid = didDocument().id; 557 + const dnsOk = () => 558 + result().dns.success && result().dns.did === expectedDid; 559 + const httpOk = () => 560 + result().http.success && 561 + result().http.did === expectedDid; 562 + const dnsMismatch = () => 563 + result().dns.success && result().dns.did !== expectedDid; 564 + const httpMismatch = () => 565 + result().http.success && 566 + result().http.did !== expectedDid; 567 568 + return ( 569 + <div class="grid grid-cols-[auto_1fr] items-center gap-x-1.5 text-sm"> 570 + {/* DNS Result */} 571 + <span 572 + classList={{ 573 + "iconify lucide--check text-green-600 dark:text-green-400": 574 + dnsOk(), 575 + "iconify lucide--x text-red-500 dark:text-red-400": 576 + !dnsOk(), 577 + }} 578 + ></span> 579 + <span class="font-medium">DNS (TXT record)</span> 580 + <span></span> 581 + <div class="mb-2 text-sm wrap-anywhere text-neutral-500 dark:text-neutral-400"> 582 + <Show 583 + when={result().dns.success} 584 + fallback={ 585 + <div class="text-red-500 dark:text-red-400"> 586 + {result().dns.error} 587 + </div> 588 + } 589 + > 590 + <div>{result().dns.did}</div> 591 + <Show when={dnsMismatch()}> 592 + <div class="text-red-500 dark:text-red-400"> 593 + Expected: {expectedDid} 594 + </div> 595 + </Show> 596 + </Show> 597 + </div> 598 599 + {/* HTTP Result */} 600 + <span 601 + classList={{ 602 + "iconify lucide--check text-green-600 dark:text-green-400": 603 + httpOk(), 604 + "iconify lucide--x text-red-500 dark:text-red-400": 605 + !httpOk(), 606 + }} 607 + ></span> 608 + <span class="font-medium">HTTP (.well-known)</span> 609 + <span></span> 610 + <div class="text-sm wrap-anywhere text-neutral-500 dark:text-neutral-400"> 611 + <Show 612 + when={result().http.success} 613 + fallback={ 614 + <div class="text-red-500 dark:text-red-400"> 615 + {result().http.error} 616 + </div> 617 + } 618 + > 619 + <div>{result().http.did}</div> 620 + <Show when={httpMismatch()}> 621 + <div class="text-red-500 dark:text-red-400"> 622 + Expected: {expectedDid} 623 + </div> 624 + </Show> 625 + </Show> 626 + </div> 627 + </div> 628 + ); 629 + }} 630 </Show> 631 + </div> 632 + </Show> 633 </div> 634 + </Show> 635 + )} 636 + </For> 637 </div> 638 + </Show> 639 640 {/* Services Section */} 641 <Show when={didDocument().service}>