用户引导沙箱优化
This commit is contained in:
1 parent
21f3787b8b
commit
910cee9e67
8 files changed
+604
-224
No files matched your search
@@ -77,6 +77,10 @@ import {
|
||||
useUpdateArtifactContent,
|
||||
} from "@/core/artifacts/hooks";
|
||||
import { resolveArtifactURL, urlOfArtifact } from "@/core/artifacts/utils";
|
||||
import {
|
||||
isSandboxStreamPerfEnabled,
|
||||
useSandboxFollowScroll,
|
||||
} from "@/core/artifacts/sandbox-stream-perf";
|
||||
import { isArtifactApiPath } from "@/core/artifacts/streaming-write-preview";
|
||||
import { useI18n } from "@/core/i18n/hooks";
|
||||
import { downloadMarkdownAsDocx } from "@/core/scheduled-tasks/markdown-docx";
|
||||
@@ -401,6 +405,14 @@ export function ArtifactFileDetail({
|
||||
: (canEditArtifact || (canUseAiEditor && hasLocalEdits)
|
||||
? draftContent
|
||||
: (content ?? ""));
|
||||
const streamPerfEnabled = isSandboxStreamPerfEnabled();
|
||||
const isLiveStreaming = thread.isLoading || documentRewriteActive;
|
||||
const sandboxDisplayText = useMemo(() => {
|
||||
const raw = displayContent ?? "";
|
||||
if (disableDesensitize) return raw;
|
||||
if (streamPerfEnabled && isLiveStreaming) return raw;
|
||||
return desensitize(raw);
|
||||
}, [disableDesensitize, displayContent, isLiveStreaming, streamPerfEnabled]);
|
||||
const artifactContentPending =
|
||||
isCodeFile &&
|
||||
!useWriteFileStreaming &&
|
||||
@@ -924,39 +936,12 @@ export function ArtifactFileDetail({
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(thread.isLoading || documentRewriteActive) || !autoScrollEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tick = () => {
|
||||
scrollArtifactToBottom("auto");
|
||||
};
|
||||
|
||||
tick();
|
||||
const intervalId = window.setInterval(tick, 180);
|
||||
return () => window.clearInterval(intervalId);
|
||||
}, [
|
||||
autoScrollEnabled,
|
||||
documentRewriteActive,
|
||||
scrollArtifactToBottom,
|
||||
thread.isLoading,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(thread.isLoading || documentRewriteActive) || !autoScrollEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
scrollArtifactToBottom("auto");
|
||||
}, [
|
||||
autoScrollEnabled,
|
||||
displayContent,
|
||||
documentRewriteActive,
|
||||
scrollArtifactToBottom,
|
||||
thread.isLoading,
|
||||
useSandboxFollowScroll({
|
||||
follow: isLiveStreaming && autoScrollEnabled,
|
||||
scrollToBottom: scrollArtifactToBottom,
|
||||
contentKey: sandboxDisplayText,
|
||||
viewMode,
|
||||
]);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const handleResumeEvent = () => {
|
||||
@@ -1741,7 +1726,7 @@ export function ArtifactFileDetail({
|
||||
language === "html" ||
|
||||
language === "mermaid") && (
|
||||
<ArtifactFilePreview
|
||||
content={disableDesensitize ? (displayContent ?? "") : desensitize(displayContent ?? "")}
|
||||
content={sandboxDisplayText}
|
||||
language={language ?? "text"}
|
||||
threadId={threadId}
|
||||
publicShareCode={publicShareCode}
|
||||
@@ -1778,7 +1763,7 @@ export function ArtifactFileDetail({
|
||||
value={
|
||||
canEditArtifact || disableDesensitize
|
||||
? (displayContent ?? "")
|
||||
: desensitize(displayContent ?? "")
|
||||
: sandboxDisplayText
|
||||
}
|
||||
readonly={!canEditArtifact || documentRewriteActive}
|
||||
onChange={
|
||||
@@ -1789,6 +1774,7 @@ export function ArtifactFileDetail({
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
isStreaming={thread.isLoading}
|
||||
streamingReadonlyFallback={!canEditArtifact}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -11,12 +11,11 @@ import { basicLightInit } from "@uiw/codemirror-theme-basic";
|
||||
import { monokaiInit } from "@uiw/codemirror-theme-monokai";
|
||||
import CodeMirror from "@uiw/react-codemirror";
|
||||
import { useTheme } from "next-themes";
|
||||
import { useMemo } from "react";
|
||||
import { memo, useMemo } from "react";
|
||||
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
import { useThread } from "./messages/context";
|
||||
const customDarkTheme = monokaiInit({
|
||||
settings: {
|
||||
background: "transparent",
|
||||
@@ -34,7 +33,7 @@ const customLightTheme = basicLightInit({
|
||||
},
|
||||
});
|
||||
|
||||
export function CodeEditor({
|
||||
export const CodeEditor = memo(function CodeEditor({
|
||||
className,
|
||||
placeholder,
|
||||
value,
|
||||
@@ -43,6 +42,7 @@ export function CodeEditor({
|
||||
disabled,
|
||||
autoFocus,
|
||||
settings,
|
||||
isStreaming = false,
|
||||
streamingReadonlyFallback = true,
|
||||
}: {
|
||||
className?: string;
|
||||
@@ -53,11 +53,10 @@ export function CodeEditor({
|
||||
disabled?: boolean;
|
||||
autoFocus?: boolean;
|
||||
settings?: unknown;
|
||||
/** Parent-owned streaming flag so this editor does not subscribe to `thread`. */
|
||||
isStreaming?: boolean;
|
||||
streamingReadonlyFallback?: boolean;
|
||||
}) {
|
||||
const {
|
||||
thread: { isLoading },
|
||||
} = useThread();
|
||||
const { resolvedTheme } = useTheme();
|
||||
|
||||
const extensions = useMemo(() => {
|
||||
@@ -81,7 +80,7 @@ export function CodeEditor({
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{isLoading && streamingReadonlyFallback ? (
|
||||
{isStreaming && streamingReadonlyFallback ? (
|
||||
<Textarea
|
||||
className={cn(
|
||||
"h-full overflow-auto font-mono [&_.cm-editor]:h-full [&_.cm-focused]:outline-none!",
|
||||
@@ -116,4 +115,4 @@ export function CodeEditor({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user