mirror of
https://github.com/sst/opencode.git
synced 2025-07-08 00:25:00 +00:00
docs: share handle slow loading pages
This commit is contained in:
parent
5a0910ea79
commit
3e2a0c7281
2 changed files with 959 additions and 991 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue