docs: share handle slow loading pages

This commit is contained in:
Jay V 2025-07-03 13:15:18 -04:00
parent 5a0910ea79
commit 3e2a0c7281
2 changed files with 959 additions and 991 deletions

View file

@ -1,8 +1,6 @@
import {
type JSX,
onCleanup,
splitProps,
createEffect,
createResource,
} from "solid-js"
import { codeToHtml } from "shiki"
@ -12,15 +10,15 @@ import { transformerNotationDiff } from "@shikijs/transformers"
interface CodeBlockProps extends JSX.HTMLAttributes<HTMLDivElement> {
code: string
lang?: string
onRendered?: () => void
}
function CodeBlock(props: CodeBlockProps) {
const [local, rest] = splitProps(props, ["code", "lang", "onRendered"])
let containerRef!: HTMLDivElement
const [local, rest] = splitProps(props, ["code", "lang"])
const [html] = createResource(
() => [local.code, local.lang],
async ([code, lang]) => {
// TODO: For testing delays
// await new Promise((resolve) => setTimeout(resolve, 3000))
return (await codeToHtml(code || "", {
lang: lang || "text",
themes: {
@ -32,25 +30,7 @@ function CodeBlock(props: CodeBlockProps) {
},
)
onCleanup(() => {
if (containerRef) containerRef.innerHTML = ""
})
createEffect(() => {
if (html() && containerRef) {
containerRef.innerHTML = html() as string
local.onRendered?.()
}
})
return (
<>
{html() ? (
<div ref={containerRef} class={styles.codeblock} {...rest}></div>
) : null}
</>
)
return <div innerHTML={html()} class={styles.codeblock} {...rest}></div >
}
export default CodeBlock

View file

@ -5,11 +5,13 @@ import {
Match,
Switch,
onMount,
Suspense,
onCleanup,
splitProps,
createMemo,
createEffect,
createSignal,
SuspenseList,
} from "solid-js"
import map from "lang-map"
import { DateTime } from "luxon"
@ -22,7 +24,6 @@ import {
IconAnthropic,
} from "./icons/custom"
import {
IconFolder,
IconHashtag,
IconSparkles,
IconGlobeAlt,
@ -486,6 +487,7 @@ function TerminalPart(props: TerminalPartProps) {
}
onMount(() => {
checkOverflow()
window.addEventListener("resize", checkOverflow)
})
@ -510,7 +512,6 @@ function TerminalPart(props: TerminalPartProps) {
<CodeBlock
data-section="error"
lang="text"
onRendered={checkOverflow}
ref={(el) => (preEl = el)}
code={local.error || ""}
/>
@ -518,7 +519,6 @@ function TerminalPart(props: TerminalPartProps) {
<Match when={local.result}>
<CodeBlock
lang="console"
onRendered={checkOverflow}
ref={(el) => (preEl = el)}
code={local.result || ""}
/>
@ -596,7 +596,6 @@ export default function Share(props: {
messages: Record<string, Message.Info>
}) {
let lastScrollY = 0
let hasScrolled = false
let scrollTimeout: number | undefined
const id = props.id
@ -606,12 +605,6 @@ export default function Share(props: {
const [showScrollButton, setShowScrollButton] = createSignal(false)
const [isButtonHovered, setIsButtonHovered] = createSignal(false)
const anchorId = createMemo<string | null>(() => {
const raw = window.location.hash.slice(1)
const [id] = raw.split("-")
return id
})
const [store, setStore] = createStore<{
info?: Session.Info
messages: Record<string, Message.Info>
@ -677,11 +670,6 @@ export default function Share(props: {
if (type === "message") {
const [, messageID] = splits
setStore("messages", messageID, reconcile(d.content))
if (!hasScrolled && messageID === anchorId()) {
scrollToAnchor(window.location.hash.slice(1))
hasScrolled = true
}
}
} catch (error) {
console.error("Error parsing WebSocket message:", error)
@ -789,20 +777,8 @@ export default function Share(props: {
for (let i = 0; i < messages().length; i++) {
const msg = messages()[i]
// TODO: Cleanup
// const system = result.messages.length === 0 && msg.role === "system"
const assistant = msg.metadata?.assistant
// if (system) {
// for (const part of msg.parts) {
// if (part.type === "text") {
// result.system.push(part.text)
// }
// }
// result.created = msg.metadata?.time.created
// continue
// }
result.messages.push(msg)
if (assistant) {
@ -889,8 +865,10 @@ export default function Share(props: {
fallback={<p>Waiting for messages...</p>}
>
<div class={styles.parts}>
<SuspenseList>
<For each={data().messages}>
{(msg, msgIndex) => (
<Suspense>
<For each={msg.parts}>
{(part, partIndex) => {
if (
@ -930,6 +908,14 @@ export default function Share(props: {
return { metadata, args, result, duration }
})
onMount(() => {
const hash = window.location.hash.slice(1)
if (hash !== "" && hash === anchor()) {
scrollToAnchor(hash)
}
})
return (
<Switch>
{/* User text */}
@ -1875,8 +1861,10 @@ export default function Share(props: {
)
}}
</For>
</Suspense>
)}
</For>
</SuspenseList>
<div data-section="part" data-part-type="summary">
<div data-section="decoration">
<span data-status={connectionStatus()[0]}></span>