From a5f30b8e80dad18241e8eb28eae6827a77b380f5 Mon Sep 17 00:00:00 2001 From: seveibar Date: Thu, 10 Oct 2024 15:51:01 -0700 Subject: [PATCH] refactor previewcontent --- src/components/CodeAndPreview.tsx | 60 ++++------ src/components/ErrorTabContent.tsx | 2 +- src/components/PreviewContent.tsx | 119 ++++++++++++++++++++ src/hooks/use-run-tsx/construct-circuit.tsx | 1 - src/hooks/use-run-tsx/index.tsx | 36 ++++-- src/pages/ai.tsx | 4 +- src/pages/view-snippet.tsx | 8 +- 7 files changed, 171 insertions(+), 59 deletions(-) create mode 100644 src/components/PreviewContent.tsx diff --git a/src/components/CodeAndPreview.tsx b/src/components/CodeAndPreview.tsx index f32f453a..054a798c 100644 --- a/src/components/CodeAndPreview.tsx +++ b/src/components/CodeAndPreview.tsx @@ -15,11 +15,12 @@ import { useAxios } from "@/hooks/use-axios" import { TypeBadge } from "./TypeBadge" import { useToast } from "@/hooks/use-toast" import { useMutation, useQueryClient } from "react-query" -import { ClipboardIcon, Share, Eye, EyeOff } from "lucide-react" +import { ClipboardIcon, Share, Eye, EyeOff, PlayIcon } from "lucide-react" import { MagicWandIcon } from "@radix-ui/react-icons" import { ErrorBoundary } from "react-error-boundary" import { ErrorTabContent } from "./ErrorTabContent" import { cn } from "@/lib/utils" +import { PreviewContent } from "./PreviewContent" interface Props { snippet?: Snippet | null @@ -41,10 +42,16 @@ export function CodeAndPreview({ snippet }: Props) { }, [snippet?.code]) const { toast } = useToast() - const { message, circuitJson, compiledJs } = useRunTsx( + const { + message, + circuitJson, + compiledJs, + triggerRunTsx, + tsxRunTriggerCount, + } = useRunTsx({ code, - snippet?.snippet_type, - ) + type: snippet?.snippet_type, + }) const qc = useQueryClient() const updateSnippetMutation = useMutation({ @@ -113,43 +120,14 @@ export function CodeAndPreview({ snippet }: Props) { /> {showPreview && ( -
- - - PCB - 3D - JSON - - Errors - {message && ( - - 1 - - )} - - - -
- -
-
- -
- Error loading 3D viewer
}> - - -
- - -
- -
-
- - - - - + )} diff --git a/src/components/ErrorTabContent.tsx b/src/components/ErrorTabContent.tsx index 3538f478..7b86f260 100644 --- a/src/components/ErrorTabContent.tsx +++ b/src/components/ErrorTabContent.tsx @@ -12,7 +12,7 @@ export const ErrorTabContent = ({ }: { code?: string isStreaming?: boolean - errorMessage?: string + errorMessage?: string | null }) => { const anthropic = useAiApi() const simplifiedErrorMessage = useAsyncMemo(async () => { diff --git a/src/components/PreviewContent.tsx b/src/components/PreviewContent.tsx new file mode 100644 index 00000000..94ebff6f --- /dev/null +++ b/src/components/PreviewContent.tsx @@ -0,0 +1,119 @@ +import { useEffect, useMemo, useState } from "react" +import { CodeEditor } from "@/components/CodeEditor" +import { PCBViewer } from "@tscircuit/pcb-viewer" +import { CadViewer } from "@tscircuit/3d-viewer" +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" +import { defaultCodeForBlankPage } from "@/lib/defaultCodeForBlankCode" +import { decodeUrlHashToText } from "@/lib/decodeUrlHashToText" +import { encodeTextToUrlHash } from "@/lib/encodeTextToUrlHash" +import { Button } from "@/components/ui/button" +import { useRunTsx } from "@/hooks/use-run-tsx" +import EditorNav from "./EditorNav" +import { CircuitJsonTableViewer } from "./TableViewer/CircuitJsonTableViewer" +import { Snippet } from "fake-snippets-api/lib/db/schema" +import { useAxios } from "@/hooks/use-axios" +import { TypeBadge } from "./TypeBadge" +import { useToast } from "@/hooks/use-toast" +import { useMutation, useQueryClient } from "react-query" +import { ClipboardIcon, Share, Eye, EyeOff, PlayIcon } from "lucide-react" +import { MagicWandIcon } from "@radix-ui/react-icons" +import { ErrorBoundary } from "react-error-boundary" +import { ErrorTabContent } from "./ErrorTabContent" +import { cn } from "@/lib/utils" + +export interface PreviewContentProps { + code: string + triggerRunTsx: () => void + hasUnsavedChanges: boolean + tsxRunTriggerCount: number + errorMessage: string | null + circuitJson: any +} + +const PreviewEmptyState = ({ + triggerRunTsx, +}: { triggerRunTsx: () => void }) => ( +
+ No circuit json loaded + +
+) + +export const PreviewContent = ({ + code, + triggerRunTsx, + hasUnsavedChanges, + tsxRunTriggerCount, + errorMessage, + circuitJson, +}: PreviewContentProps) => { + return ( +
+ +
+ +
+ + PCB + 3D + JSON + + Errors + {errorMessage && ( + + 1 + + )} + + +
+ +
+ Error loading PCB viewer
}> + {circuitJson ? ( + + ) : ( + + )} + +
+ + +
+ Error loading 3D viewer
}> + {circuitJson ? ( + + ) : ( + + )} + +
+ + +
+ Error loading 3D viewer
}> + {circuitJson ? ( + + ) : ( + + )} + + +
+ + + + + + ) +} diff --git a/src/hooks/use-run-tsx/construct-circuit.tsx b/src/hooks/use-run-tsx/construct-circuit.tsx index c291465f..60c66dfd 100644 --- a/src/hooks/use-run-tsx/construct-circuit.tsx +++ b/src/hooks/use-run-tsx/construct-circuit.tsx @@ -4,7 +4,6 @@ import * as React from "react" import { useCompiledTsx } from "../use-compiled-tsx" import { createJSCADRenderer } from "jscad-fiber" import { jscadPlanner } from "jscad-planner" -import { getImportsFromCode } from "@tscircuit/prompt-benchmarks/code-runner-utils" export const constructCircuit = ( UserElm: any, diff --git a/src/hooks/use-run-tsx/index.tsx b/src/hooks/use-run-tsx/index.tsx index 77552e19..0287238c 100644 --- a/src/hooks/use-run-tsx/index.tsx +++ b/src/hooks/use-run-tsx/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState } from "react" +import { useEffect, useMemo, useReducer, useState } from "react" import * as React from "react" import { useCompiledTsx } from "../use-compiled-tsx" import { Circuit } from "@tscircuit/core" @@ -17,13 +17,24 @@ type RunTsxResult = { isLoading: boolean } -export const useRunTsx = ( - code?: string, - type?: "board" | "footprint" | "package" | "model", - { isStreaming = false }: { isStreaming?: boolean } = {}, -): RunTsxResult => { +export const useRunTsx = ({ + code, + type, + isStreaming = false, +}: { + code?: string + type?: "board" | "footprint" | "package" | "model" + isStreaming?: boolean +} = {}): RunTsxResult & { + triggerRunTsx: () => void + tsxRunTriggerCount: number +} => { type ??= "board" const compiledJs = useCompiledTsx(code, { isStreaming }) + const [tsxRunTriggerCount, incTsxRunTriggerCount] = useReducer( + (c) => c + 1, + 0, + ) const [tsxResult, setTsxResult] = useState({ compiledModule: null, message: "", @@ -33,6 +44,7 @@ export const useRunTsx = ( const apiBaseUrl = useSnippetsBaseApiUrl() useEffect(() => { + if (tsxRunTriggerCount === 0) return async function run() { if (isStreaming || !compiledJs || !code) { setTsxResult({ @@ -61,11 +73,9 @@ export const useRunTsx = ( ).then((res) => res.json()) try { - console.log("importedSnippet", importedSnippet) - // eval the imported snippet compiled_js preSuppliedImports[importName] = evalCompiledJs( importedSnippet.compiled_js, - ) + ).default.exports } catch (e) { console.error("Error importing snippet", e) } @@ -127,7 +137,11 @@ export const useRunTsx = ( } } run() - }, [compiledJs, isStreaming]) + }, [tsxRunTriggerCount, compiledJs, isStreaming]) - return tsxResult + return { + ...tsxResult, + triggerRunTsx: incTsxRunTriggerCount, + tsxRunTriggerCount, + } } diff --git a/src/pages/ai.tsx b/src/pages/ai.tsx index 8d4d340a..c1647ff4 100644 --- a/src/pages/ai.tsx +++ b/src/pages/ai.tsx @@ -19,7 +19,9 @@ export const AiPage = () => { const [code, setCode] = useState("") const [dts, setDts] = useState("") const [isStreaming, setIsStreaming] = useState(false) - const { message: errorMessage, circuitJson } = useRunTsx(code, "board", { + const { message: errorMessage, circuitJson } = useRunTsx({ + code, + type: "board", isStreaming, }) const { saveSnippet, isLoading: isSaving } = useSaveSnippet() diff --git a/src/pages/view-snippet.tsx b/src/pages/view-snippet.tsx index 4178920a..d8db8258 100644 --- a/src/pages/view-snippet.tsx +++ b/src/pages/view-snippet.tsx @@ -18,10 +18,10 @@ export const ViewSnippetPage = () => { const { author, snippetName } = useParams() const { snippet } = useCurrentSnippet() - const { circuitJson, message } = useRunTsx( - snippet?.code ?? "", - snippet?.snippet_type, - ) + const { circuitJson, message } = useRunTsx({ + code: snippet?.code ?? "", + type: snippet?.snippet_type, + }) return (