atmosphere explorer
0
fork

Configure Feed

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

collection anchor links

Juliet 0ccd5b5a 444bd20a

+58 -25
+58 -25
src/views/repo.tsx
··· 4 4 import { ActorIdentifier, Did, Handle, Nsid } from "@atcute/lexicons"; 5 5 import { A, useLocation, useNavigate, useParams } from "@solidjs/router"; 6 6 import { 7 + createEffect, 7 8 createResource, 8 9 createSignal, 9 10 ErrorBoundary, ··· 57 58 let pds: string; 58 59 const did = params.repo!; 59 60 61 + // Handle scrolling to a collection group when hash is like #collections:app.bsky 62 + createEffect(() => { 63 + const hash = location.hash; 64 + if (hash.startsWith("#collections:")) { 65 + const authority = hash.slice(13); 66 + requestAnimationFrame(() => { 67 + const element = document.getElementById(`collection-${authority}`); 68 + if (element) element.scrollIntoView({ behavior: "instant", block: "start" }); 69 + }); 70 + } 71 + }); 72 + 60 73 const RepoTab = (props: { 61 74 tab: "collections" | "backlinks" | "identity" | "blobs" | "logs"; 62 75 label: string; 63 - }) => ( 64 - <A class="flex items-center" href={`/at://${params.repo}#${props.tab}`}> 65 - <span 66 - classList={{ 67 - "flex items-center border-b-2": true, 68 - "border-transparent hover:border-neutral-400 dark:hover:border-neutral-600": 69 - (location.hash !== `#${props.tab}` && !!location.hash) || 70 - (!location.hash && 71 - ((!error() && props.tab !== "collections") || 72 - (!!error() && props.tab !== "identity"))), 73 - }} 74 - > 75 - {props.label} 76 - </span> 77 - </A> 78 - ); 76 + }) => { 77 + const isActive = () => { 78 + if (!location.hash) { 79 + if (!error() && props.tab === "collections") return true; 80 + if (!!error() && props.tab === "identity") return true; 81 + return false; 82 + } 83 + if (props.tab === "collections") 84 + return location.hash === "#collections" || location.hash.startsWith("#collections:"); 85 + return location.hash === `#${props.tab}`; 86 + }; 87 + 88 + return ( 89 + <A class="flex items-center" href={`/at://${params.repo}#${props.tab}`}> 90 + <span 91 + classList={{ 92 + "flex items-center border-b-2": true, 93 + "border-transparent hover:border-neutral-400 dark:hover:border-neutral-600": 94 + !isActive(), 95 + }} 96 + > 97 + {props.label} 98 + </span> 99 + </A> 100 + ); 101 + }; 79 102 80 103 const getRotationKeys = async () => { 81 104 const res = await fetch( ··· 271 294 <span>{error()}</span> 272 295 </div> 273 296 </Show> 274 - <Show when={!error() && (!location.hash || location.hash === "#collections")}> 297 + <Show when={!error() && (!location.hash || location.hash.startsWith("#collections"))}> 275 298 <Tooltip text="Filter collections"> 276 299 <button 277 300 class="flex items-center rounded-sm p-1.5 hover:bg-neutral-200 active:bg-neutral-300 dark:hover:bg-neutral-700 dark:active:bg-neutral-600" ··· 370 393 </Suspense> 371 394 </ErrorBoundary> 372 395 </Show> 373 - <Show when={nsids() && (!location.hash || location.hash === "#collections")}> 396 + <Show when={nsids() && (!location.hash || location.hash.startsWith("#collections"))}> 374 397 <Show when={showFilter()}> 375 398 <TextInput 376 399 name="filter" ··· 382 405 }} 383 406 /> 384 407 </Show> 385 - <div 386 - class="flex flex-col overflow-hidden text-sm" 387 - classList={{ "-mt-1": !showFilter() }} 388 - > 408 + <div class="flex flex-col text-sm wrap-anywhere" classList={{ "-mt-1": !showFilter() }}> 389 409 <For 390 410 each={Object.keys(nsids() ?? {}).filter((authority) => 391 411 filter() ? ··· 400 420 const reversedDomain = authority.split(".").reverse().join("."); 401 421 const [faviconLoaded, setFaviconLoaded] = createSignal(false); 402 422 423 + const isHighlighted = () => location.hash === `#collections:${authority}`; 424 + 403 425 return ( 404 - <div class="dark:hover:bg-dark-200 flex items-start gap-2 rounded-lg p-1 hover:bg-neutral-200"> 405 - <div class="flex h-5 w-4 shrink-0 items-center justify-center"> 426 + <div 427 + id={`collection-${authority}`} 428 + class="group flex items-start gap-2 rounded-lg p-1 transition-colors" 429 + classList={{ 430 + "dark:hover:bg-dark-200 hover:bg-neutral-200": !isHighlighted(), 431 + "bg-blue-100 dark:bg-blue-500/25": isHighlighted(), 432 + }} 433 + > 434 + <a 435 + href={`#collections:${authority}`} 436 + class="relative flex h-5 w-4 shrink-0 items-center justify-center hover:opacity-70" 437 + > 438 + <span class="iconify lucide--link absolute top-1/2 -left-5 -translate-y-1/2 opacity-0 transition-opacity group-hover:opacity-100" /> 406 439 <Show when={!faviconLoaded()}> 407 440 <span class="iconify lucide--globe size-4 text-neutral-400 dark:text-neutral-500" /> 408 441 </Show> ··· 418 451 onLoad={() => setFaviconLoaded(true)} 419 452 onError={() => setFaviconLoaded(false)} 420 453 /> 421 - </div> 454 + </a> 422 455 <div class="flex flex-1 flex-col"> 423 456 <For 424 457 each={nsids()?.[authority].nsids.filter((nsid) =>