diff --git a/client/src/components/Artifacts/ArtifactPreview.tsx b/client/src/components/Artifacts/ArtifactPreview.tsx index 3a565ee76c..9ea370691b 100644 --- a/client/src/components/Artifacts/ArtifactPreview.tsx +++ b/client/src/components/Artifacts/ArtifactPreview.tsx @@ -2,6 +2,7 @@ import React, { useMemo, memo } from 'react'; import { Sandpack } from '@codesandbox/sandpack-react'; import { removeNullishValues } from 'librechat-data-provider'; import { SandpackPreview, SandpackProvider } from '@codesandbox/sandpack-react/unstyled'; +import type { SandpackPreviewRef } from '@codesandbox/sandpack-react/unstyled'; import type { Artifact } from '~/common'; import { sharedFiles, @@ -14,9 +15,11 @@ import { export const ArtifactPreview = memo(function ({ showEditor = false, artifact, + previewRef, }: { showEditor?: boolean; artifact: Artifact; + previewRef: React.MutableRefObject; }) { const files = useMemo(() => { return removeNullishValues({ [getArtifactFilename(artifact.type ?? '')]: artifact.content }); @@ -56,7 +59,12 @@ export const ArtifactPreview = memo(function ({ {...sharedProps} template={template} > - + ); }); diff --git a/client/src/components/Artifacts/Artifacts.tsx b/client/src/components/Artifacts/Artifacts.tsx index d0b52e44ac..bed1b18a11 100644 --- a/client/src/components/Artifacts/Artifacts.tsx +++ b/client/src/components/Artifacts/Artifacts.tsx @@ -1,4 +1,7 @@ +import { useRef, useState } from 'react'; +import { RefreshCw } from 'lucide-react'; import * as Tabs from '@radix-ui/react-tabs'; +import { SandpackPreviewRef } from '@codesandbox/sandpack-react'; import useArtifacts from '~/hooks/Artifacts/useArtifacts'; import { CodeMarkdown, CopyCodeButton } from './Code'; import { getFileExtension } from '~/utils/artifacts'; @@ -6,6 +9,9 @@ import { ArtifactPreview } from './ArtifactPreview'; import { cn } from '~/utils'; export default function Artifacts() { + const previewRef = useRef(); + const [isRefreshing, setIsRefreshing] = useState(false); + const { isVisible, activeTab, @@ -21,6 +27,15 @@ export default function Artifacts() { return null; } + const handleRefresh = () => { + setIsRefreshing(true); + const client = previewRef.current?.getClient(); + if (client != null) { + client.dispatch({ type: 'refresh' }); + } + setTimeout(() => setIsRefreshing(false), 750); + }; + return ( {/* Main Parent */} @@ -50,6 +65,22 @@ export default function Artifacts() {

{currentArtifact.title}

+ {/* Refresh button */} + {activeTab === 'preview' && ( + + )} - + } + /> {/* Footer */}