atmosphere explorer
0
fork

Configure Feed

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

add plc log timestamp links

Juliet a47bb864 77436e15

+45 -16
+43 -13
src/views/logs.tsx
··· 4 4 IndexedEntry, 5 5 IndexedEntryLog, 6 6 } from "@atcute/did-plc"; 7 + import { useLocation } from "@solidjs/router"; 7 8 import { createEffect, createResource, createSignal, For, onCleanup, Show } from "solid-js"; 8 9 import { localDateFromTimestamp } from "../utils/date.js"; 9 10 import { createOperationHistory, DiffEntry, groupBy } from "../utils/plc-logs.js"; ··· 13 14 type PlcEvent = "handle" | "rotation_key" | "service" | "verification_method"; 14 15 15 16 export const PlcLogView = (props: { did: string }) => { 17 + const location = useLocation(); 16 18 const [activePlcEvent, setActivePlcEvent] = createSignal<PlcEvent | undefined>(); 17 19 const [validLog, setValidLog] = createSignal<boolean | undefined>(undefined); 18 20 const [rawLogs, setRawLogs] = createSignal<IndexedEntryLog | undefined>(undefined); ··· 50 52 worker = undefined; 51 53 }; 52 54 worker.postMessage({ did: props.did, logs }); 55 + } 56 + }); 57 + 58 + createEffect(() => { 59 + const hash = location.hash; 60 + if (hash.startsWith("#logs:")) { 61 + const createdAt = hash.slice(6); 62 + requestAnimationFrame(() => { 63 + const element = document.getElementById(`log-${createdAt}`); 64 + if (element) element.scrollIntoView({ behavior: "instant", block: "start" }); 65 + }); 53 66 } 54 67 }); 55 68 ··· 275 288 </div> 276 289 <div class="flex flex-col gap-3"> 277 290 <For each={plcOps()}> 278 - {([entry, diffs]) => ( 279 - <Show when={shouldShowEntry(diffs)}> 280 - <div class="flex flex-col gap-1"> 281 - <span class="text-sm font-semibold text-neutral-700 dark:text-neutral-300"> 282 - {localDateFromTimestamp(new Date(entry.createdAt).getTime())} 283 - </span> 284 - <div class="flex flex-col gap-2 rounded-lg border-[0.5px] border-neutral-300 bg-neutral-50 p-3 text-sm dark:border-neutral-700 dark:bg-neutral-800"> 285 - <For each={diffs.filter(shouldShowDiff)}> 286 - {(diff) => <DiffItem diff={diff} />} 287 - </For> 291 + {([entry, diffs]) => { 292 + const isHighlighted = () => location.hash === `#logs:${entry.createdAt}`; 293 + return ( 294 + <Show when={shouldShowEntry(diffs)}> 295 + <div 296 + id={`log-${entry.createdAt}`} 297 + class="group flex scroll-mt-3 flex-col gap-1 rounded-lg transition-colors" 298 + > 299 + <span class="relative text-sm font-semibold text-neutral-700 dark:text-neutral-300"> 300 + <a href={`#logs:${entry.createdAt}`} class="relative hover:underline"> 301 + <span class="absolute top-1/2 -left-4.5 flex -translate-y-1/2 items-center text-neutral-500 opacity-0 transition-opacity group-hover:opacity-100 dark:text-neutral-400"> 302 + <span class="iconify lucide--link text-xs"></span> 303 + </span> 304 + {localDateFromTimestamp(new Date(entry.createdAt).getTime())} 305 + </a> 306 + </span> 307 + <div 308 + class="flex flex-col gap-2 rounded-md border bg-neutral-50 p-3 text-sm dark:bg-neutral-800" 309 + classList={{ 310 + "border-neutral-200 dark:border-neutral-700": !isHighlighted(), 311 + "border-blue-500 dark:border-blue-400": isHighlighted(), 312 + }} 313 + > 314 + <For each={diffs.filter(shouldShowDiff)}> 315 + {(diff) => <DiffItem diff={diff} />} 316 + </For> 317 + </div> 288 318 </div> 289 - </div> 290 - </Show> 291 - )} 319 + </Show> 320 + ); 321 + }} 292 322 </For> 293 323 </div> 294 324 </div>
+2 -3
src/views/repo.tsx
··· 93 93 if (!!error() && props.tab === "identity") return true; 94 94 return false; 95 95 } 96 - if (props.tab === "collections") return location.hash.startsWith("#collections"); 97 - return location.hash === `#${props.tab}`; 96 + return location.hash.startsWith(`#${props.tab}`); 98 97 }; 99 98 100 99 return ( ··· 390 389 </div> 391 390 </div> 392 391 <div class="flex w-full flex-col gap-1 px-2"> 393 - <Show when={location.hash === "#logs"}> 392 + <Show when={location.hash.startsWith("#logs")}> 394 393 <ErrorBoundary 395 394 fallback={(err) => <div class="wrap-break-word">Error: {err.message}</div>} 396 395 >