atmosphere explorer pds.ls
tool typescript atproto

add more app redirects

handle.invalid b795c7a6 60c9e3a6

verified
+37 -30
+1 -1
src/components/favicon.tsx
··· 9 9 10 10 const content = ( 11 11 <Switch> 12 - <Match when={domain() === "tangled.sh"}> 12 + <Match when={domain() === "tangled.sh" || domain() === "tangled.org"}> 13 13 <span class="iconify i-tangled size-4" /> 14 14 </Match> 15 15 <Match when={["bsky.app", "bsky.chat"].includes(domain())}>
-4
src/styles/index.css
··· 41 41 --svg: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22400%22%20height%3D%22400%22%20viewBox%3D%220%200%2025%2025%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22currentColor%22%20style%3D%22stroke-width%3A.111183%22%20d%3D%22m16.349%2024.1-.065-.038-.202-.01-.202-.011-.276-.026-.275-.026v-.053l-.205-.04-.205-.04-.167-.081-.168-.08-.001-.042-.002-.041-.266-.144-.266-.144-.277-.203-.276-.203-.262-.252-.262-.252-.22-.285-.222-.285-.17-.284-.17-.285-.014-.014-.013-.015-.142.162-.142.161-.223.214-.223.215-.186.146-.186.146-.253.163-.252.163-.25.116-.248.115.005.032.005.033-.171.046-.172.046-.338.1-.338.102-.178.045-.178.045-.391.026-.392.026-.355-.035-.356-.035-.038-.03-.037-.03-.077.02-.077.02-.05-.051-.05-.05-.21-.047-.208-.046-.297-.103-.298-.104-.325-.163-.326-.163-.327-.228-.327-.228-.304-.288-.305-.289-.224-.29-.225-.289-.127-.213-.127-.214-.106-.213-.107-.214-.125-.338-.126-.337-.083-.392-.084-.391v-.694l.001-.694.064-.319.065-.319.108-.339.11-.34.157-.319.157-.319.07-.113.07-.114-.098-.068-.099-.067-.178-.102-.178-.101-.267-.196-.267-.195-.262-.252-.262-.252-.189-.235-.188-.235-.16-.247-.16-.246-.129-.266-.129-.266-.12-.338-.12-.338-.083-.391-.083-.391.002-.694.002-.694.1-.426.099-.426.132-.342.133-.341.167-.307.167-.306.218-.296.219-.295.252-.263.252-.262.231-.185.232-.185.231-.151.231-.151.321-.156.321-.155.177-.065.177-.065.178-.338.178-.337.213-.303.212-.302.314-.325.314-.326.257-.195.256-.196.304-.179.305-.179.316-.13.316-.132.21-.067.21-.067.397-.079.397-.08.587.004.587.003.444.092.445.093.303.11.302.11.33.165.33.165.24-.232.239-.231.16-.126.16-.126.16-.102.16-.102.142-.083.143-.082.23-.109.232-.109.267-.099.267-.098.32-.074.32-.073.356-.042.356-.042.427.024.427.024.355.07.356.072.285.093.284.092.286.131.285.131.238.145.238.145.26.195.259.196.29.297.291.296.152.195.152.194.135.215.136.215.154.32.155.32.094.268.094.268.07.331.07.332.01.008.011.009.445.217.445.217.31.216.309.216.31.293.31.294.187.234.187.235.167.258.166.257.153.326.153.326.09.267.09.267.082.391.083.392v.658l-.001.658-.064.316-.063.315-.09.29-.091.289-.123.281-.123.281-.146.253-.147.252-.19.259-.19.258-.256.269-.255.268-.287.223-.286.223-.32.188-.32.188-.044.035-.044.035.057.13.056.13.087.213.088.214.19.73.19.729.064.302.065.302-.001.676-.002.676-.08.374-.08.373-.09.267-.09.267-.19.392-.191.39-.223.321-.223.32-.304.316-.304.315-.284.22-.285.221-.22.133-.22.132-.243.107-.242.106-.089.048-.089.047-.249.072-.249.073-.322.057-.322.058-.283-.003-.283-.003-.07-.003-.072-.003-.178-.004-.178-.003-.124.025-.125.026zm-4.47-5.35.215-.018.206-.068.207-.068.244-.117.245-.118.274-.207.275-.207.229-.257.23-.257.218-.285.22-.285.188-.284.189-.285.214-.373.215-.374.134-.312.134-.312.028-.018.029-.017.197.262.197.262.164.15.164.152.202.092.201.093.303.014.302.014.214-.08.213-.08.2-.205.201-.204.093-.28.092-.278.058-.303.058-.302-.019-.427-.018-.427-.077-.426-.076-.426-.086-.321-.086-.321-.141-.402-.141-.403-.167-.309-.166-.31-.118-.16-.117-.16-.124-.12-.125-.119.019-.183.019-.182-.061-.25-.062-.248-.134-.285-.133-.285-.183-.202-.183-.201-.173-.128-.174-.127-.204.123-.204.123-.267.06-.267.06-.206-.022-.206-.022-.235-.088-.235-.089-.118-.09-.119-.09h-.079l-.055.116-.055.117-.159.181-.159.182-.17.108-.17.108-.221.074-.221.074h-.56l-.196-.067-.195-.067-.114-.059-.113-.058-.24-.222-.24-.22-.095-.085-.096-.085-.219.198-.219.198-.165.079-.165.078-.178.048-.178.048h-.439l-.224-.07-.225-.07-.102.097-.101.097-.121.164-.121.164-.17.063-.17.063-.115.086-.115.086-.11.114-.109.114-.355.529-.355.528-.216.45-.216.45-.222.462-.222.463-.145.338-.146.338-.056.22-.055.22-.016.207-.016.207.034.243.034.243.097.196.096.197.144.125.143.125.188.088.187.087.275.002.275.002.232-.098.23-.097.108-.076.106-.076.368-.294.368-.294.027.017.027.016.023.467.024.467.088.513.089.513.089.365.089.364.131.302.132.303.105.16.105.16.11.119.111.119.285.205.284.206.145.073.144.073.215.056.215.055.245.031.246.03.204-.012.205-.012zm.686-3.498-.113-.06-.106-.135-.106-.134-.044-.184-.044-.183.024-.554.024-.554.035-.427.036-.427.072-.374.072-.373.054-.211.054-.212.068-.132.067-.132.133-.11.132-.108.188-.042.187-.042.17.064.17.065.115.124.114.124.042.185.041.185-.111.46-.111.46-.034.266-.034.266-.04.818-.04.818-.037.152-.038.151-.111.111-.111.11-.115.05-.114.049-.188-.002-.188-.001zm-2.809-.358-.146-.069-.088-.12-.088-.119-.039-.106-.038-.107-.023-.135-.022-.135-.032-.47-.032-.47.036-.444.037-.445.048-.215.05-.216.075-.203.076-.203.094-.112.094-.11.143-.066.144-.066h.285l.142.066.142.066.093.103.093.102.04.12.041.122v.305l-.033.088-.034.088-.057.275-.056.276v.86l.043.393.043.393-.092.2-.092.201-.149.099-.148.098-.202.012-.201.012z%22%2F%3E%3C%2Fsvg%3E"); 42 42 } 43 43 44 - .i-pinksea { 45 - --svg: url("data:image/svg+xml,%3Csvg%20width%3D%22800%22%20height%3D%22800%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m3%206%203.106-1.553a2%202%200%200%201%201.788%200l1.423.711a6%206%200%200%200%205.366%200l1.423-.71a2%202%200%200%201%201.788%200L21%206M3%2010.5l3.106-1.553a2%202%200%200%201%201.788%200l1.423.711a6%206%200%200%200%205.366%200l1.423-.71a2%202%200%200%201%201.788%200L21%2010.5M3%2015l3.106-1.553a2%202%200%200%201%201.788%200l1.423.711a6%206%200%200%200%205.366%200l1.423-.71a2%202%200%200%201%201.788%200L21%2015M3%2019.5l3.106-1.553a2%202%200%200%201%201.788%200l1.423.711a6%206%200%200%200%205.366%200l1.423-.71a2%202%200%200%201%201.788%200L21%2019.5%22%20stroke%3D%22%23ffe5ea%22%20stroke-width%3D%223%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); 46 - } 47 - 48 44 .simple-icons--bluesky { 49 45 --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M5.202 2.857C7.954 4.922 10.913 9.11 12 11.358c1.087-2.247 4.046-6.436 6.798-8.501C20.783 1.366 24 .213 24 3.883c0 .732-.42 6.156-.667 7.037c-.856 3.061-3.978 3.842-6.755 3.37c4.854.826 6.089 3.562 3.422 6.299c-5.065 5.196-7.28-1.304-7.847-2.97c-.104-.305-.152-.448-.153-.327c0-.121-.05.022-.153.327c-.568 1.666-2.782 8.166-7.847 2.97c-2.667-2.737-1.432-5.473 3.422-6.3c-2.777.473-5.899-.308-6.755-3.369C.42 10.04 0 4.615 0 3.883c0-3.67 3.217-2.517 5.202-1.026'/%3E%3C/svg%3E"); 50 46 }
+17 -13
src/utils/templates.ts
··· 1 1 export type AtUri = { repo: string; collection: string; rkey: string }; 2 - type TemplateFn = (uri: AtUri, record?: any) => { label: string; link: string; icon?: string }; 2 + type TemplateFn = (uri: AtUri, record?: any) => { label: string; link: string }; 3 3 type TemplateMap = Record<string, TemplateFn>; 4 4 5 5 export const uriTemplates: TemplateMap = { 6 6 "app.bsky.actor.profile": (uri) => ({ 7 7 label: "Bluesky", 8 8 link: `https://bsky.app/profile/${uri.repo}`, 9 - icon: "simple-icons--bluesky text-[#0085ff]", 10 9 }), 11 10 "app.bsky.feed.post": (uri) => ({ 12 11 label: "Bluesky", 13 12 link: `https://bsky.app/profile/${uri.repo}/post/${uri.rkey}`, 14 - icon: "simple-icons--bluesky text-[#0085ff]", 15 13 }), 16 14 "app.bsky.graph.list": (uri) => ({ 17 15 label: "Bluesky", 18 16 link: `https://bsky.app/profile/${uri.repo}/lists/${uri.rkey}`, 19 - icon: "simple-icons--bluesky text-[#0085ff]", 20 17 }), 21 18 "app.bsky.feed.generator": (uri) => ({ 22 19 label: "Bluesky", 23 20 link: `https://bsky.app/profile/${uri.repo}/feed/${uri.rkey}`, 24 - icon: "simple-icons--bluesky text-[#0085ff]", 25 - }), 26 - "fyi.unravel.frontpage.post": (uri) => ({ 27 - label: "Frontpage", 28 - link: `https://frontpage.fyi/post/${uri.repo}/${uri.rkey}`, 29 21 }), 30 22 "com.shinolabs.pinksea.oekaki": (uri) => ({ 31 23 label: "PinkSea", 32 24 link: `https://pinksea.art/${uri.repo}/oekaki/${uri.rkey}`, 33 - icon: "i-pinksea", 34 25 }), 35 26 "com.shinolabs.pinksea.profile": (uri) => ({ 36 27 label: "PinkSea", 37 28 link: `https://pinksea.art/${uri.repo}`, 38 - icon: "i-pinksea", 39 29 }), 40 30 "sh.tangled.actor.profile": (uri) => ({ 41 31 label: "Tangled", 42 32 link: `https://tangled.org/${uri.repo}`, 43 - icon: "i-tangled", 44 33 }), 45 34 "sh.tangled.repo": (uri, record) => ({ 46 35 label: "Tangled", 47 36 link: `https://tangled.org/${uri.repo}/${record.name}`, 48 - icon: "i-tangled", 37 + }), 38 + "app.blento.card": (uri) => ({ 39 + label: "blento", 40 + link: `https://blento.app/${uri.repo}`, 41 + }), 42 + "social.popfeed.actor.profile": (uri) => ({ 43 + label: "Popfeed", 44 + link: `https://popfeed.social/profile/${uri.repo}`, 45 + }), 46 + "social.popfeed.feed.review": (uri) => ({ 47 + label: "Popfeed", 48 + link: `https://popfeed.social/review/at:/${uri.repo}/${uri.collection}/${uri.rkey}`, 49 + }), 50 + "social.popfeed.feed.list": (uri) => ({ 51 + label: "Popfeed", 52 + link: `https://popfeed.social/list/at:/${uri.repo}/${uri.collection}/${uri.rkey}`, 49 53 }), 50 54 };
+19 -12
src/views/record.tsx
··· 20 20 MenuSeparator, 21 21 NavMenu, 22 22 } from "../components/dropdown.jsx"; 23 + import { Favicon } from "../components/favicon.jsx"; 23 24 import { JSONValue } from "../components/json.jsx"; 24 25 import { LexiconSchemaView } from "../components/lexicon-schema.jsx"; 25 26 import { Modal } from "../components/modal.jsx"; ··· 396 397 <Show when={record()} keyed> 397 398 <div class="flex w-full flex-col items-center"> 398 399 <div class="mb-3 flex w-full justify-between px-2 text-sm sm:text-base"> 399 - <div class="flex items-center gap-4"> 400 + <div class="flex items-center gap-3 sm:gap-4"> 400 401 <RecordTab tab="record" label="Record" /> 401 402 <RecordTab tab="schema" label="Schema" /> 402 403 <RecordTab tab="backlinks" label="Backlinks" /> 403 404 <RecordTab tab="info" label="Info" error /> 404 405 </div> 405 - <div class="flex gap-0.5"> 406 + <div class="flex sm:gap-0.5"> 406 407 <Show when={agent() && agent()?.sub === record()?.uri.split("/")[2]}> 407 408 <RecordEditor 408 409 create={false} ··· 436 437 </div> 437 438 </Modal> 438 439 </Show> 440 + <Show when={externalLink()}> 441 + {(link) => ( 442 + <a 443 + href={link().link} 444 + target="_blank" 445 + class="flex rounded-sm p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600" 446 + > 447 + <Favicon 448 + authority={new URL(link().link).hostname.split(".").reverse().join(".")} 449 + wrapper={(children) => ( 450 + <div class="flex size-4 items-center justify-center">{children}</div> 451 + )} 452 + /> 453 + </a> 454 + )} 455 + </Show> 439 456 <MenuProvider> 440 457 <DropdownMenu icon="lucide--ellipsis" buttonClass="rounded-sm p-1.5"> 441 458 <CopyMenu ··· 452 469 {(cid) => <CopyMenu content={cid()} label="Copy CID" icon="lucide--copy" />} 453 470 </Show> 454 471 <MenuSeparator /> 455 - <Show when={externalLink()}> 456 - {(externalLink) => ( 457 - <NavMenu 458 - href={externalLink()?.link} 459 - icon={`${externalLink().icon ?? "lucide--app-window"}`} 460 - label={`Open on ${externalLink().label}`} 461 - newTab 462 - /> 463 - )} 464 - </Show> 465 472 <NavMenu 466 473 href={`https://${pds()}/xrpc/com.atproto.repo.getRecord?repo=${params.repo}&collection=${params.collection}&rkey=${params.rkey}`} 467 474 icon="lucide--external-link"