mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-03-15 20:26:33 +01:00
feat: memoize ArtifactPreview, add html support
This commit is contained in:
parent
10f436521e
commit
0dd0354a4e
2 changed files with 34 additions and 6 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useMemo, useState, useEffect, useRef } from 'react';
|
import React, { useMemo, useState, useEffect, useRef, memo } from 'react';
|
||||||
import * as Tabs from '@radix-ui/react-tabs';
|
import * as Tabs from '@radix-ui/react-tabs';
|
||||||
import { Sandpack } from '@codesandbox/sandpack-react';
|
import { Sandpack } from '@codesandbox/sandpack-react';
|
||||||
import { removeNullishValues } from 'librechat-data-provider';
|
import { removeNullishValues } from 'librechat-data-provider';
|
||||||
|
|
@ -8,6 +8,7 @@ import type { Artifact } from '~/common';
|
||||||
import {
|
import {
|
||||||
sharedFiles,
|
sharedFiles,
|
||||||
sharedProps,
|
sharedProps,
|
||||||
|
getTemplate,
|
||||||
sharedOptions,
|
sharedOptions,
|
||||||
getFileExtension,
|
getFileExtension,
|
||||||
getArtifactFilename,
|
getArtifactFilename,
|
||||||
|
|
@ -17,7 +18,7 @@ import { useChatContext } from '~/Providers';
|
||||||
import { cn } from '~/utils';
|
import { cn } from '~/utils';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
|
|
||||||
export function ArtifactPreview({
|
const ArtifactPreview = memo(function ({
|
||||||
showEditor = false,
|
showEditor = false,
|
||||||
artifact,
|
artifact,
|
||||||
}: {
|
}: {
|
||||||
|
|
@ -28,6 +29,11 @@ export function ArtifactPreview({
|
||||||
return removeNullishValues({ [getArtifactFilename(artifact.type ?? '')]: artifact.content });
|
return removeNullishValues({ [getArtifactFilename(artifact.type ?? '')]: artifact.content });
|
||||||
}, [artifact.type, artifact.content]);
|
}, [artifact.type, artifact.content]);
|
||||||
|
|
||||||
|
const template = useMemo(
|
||||||
|
() => getTemplate(artifact.type ?? '', artifact.language),
|
||||||
|
[artifact.type, artifact.language],
|
||||||
|
);
|
||||||
|
|
||||||
if (Object.keys(files).length === 0) {
|
if (Object.keys(files).length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +51,7 @@ export function ArtifactPreview({
|
||||||
...sharedFiles,
|
...sharedFiles,
|
||||||
}}
|
}}
|
||||||
{...sharedProps}
|
{...sharedProps}
|
||||||
|
template={template}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<SandpackProvider
|
<SandpackProvider
|
||||||
|
|
@ -54,11 +61,12 @@ export function ArtifactPreview({
|
||||||
}}
|
}}
|
||||||
options={{ ...sharedOptions }}
|
options={{ ...sharedOptions }}
|
||||||
{...sharedProps}
|
{...sharedProps}
|
||||||
|
template={template}
|
||||||
>
|
>
|
||||||
<SandpackPreview showOpenInCodeSandbox={false} showRefreshButton={false} tabIndex={0} />
|
<SandpackPreview showOpenInCodeSandbox={false} showRefreshButton={false} tabIndex={0} />
|
||||||
</SandpackProvider>
|
</SandpackProvider>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export default function Artifacts() {
|
export default function Artifacts() {
|
||||||
const { isSubmitting, latestMessage, conversation } = useChatContext();
|
const { isSubmitting, latestMessage, conversation } = useChatContext();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
import dedent from 'dedent';
|
import dedent from 'dedent';
|
||||||
|
import type {
|
||||||
|
SandpackProviderProps,
|
||||||
|
SandpackPredefinedTemplate,
|
||||||
|
} from '@codesandbox/sandpack-react';
|
||||||
// import * as shadcnComponents from '~/utils/shadcn';
|
// import * as shadcnComponents from '~/utils/shadcn';
|
||||||
|
|
||||||
const artifactFilename = {
|
const artifactFilename = {
|
||||||
|
|
@ -11,6 +15,17 @@ const artifactFilename = {
|
||||||
// 'tsx': 'tsx',
|
// 'tsx': 'tsx',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const artifactTemplate: Record<string, SandpackPredefinedTemplate | undefined> = {
|
||||||
|
'text/html': 'static',
|
||||||
|
'application/vnd.react': 'react-ts',
|
||||||
|
'application/vnd.code-html': 'static',
|
||||||
|
// 'css': 'css',
|
||||||
|
// 'javascript': 'js',
|
||||||
|
// 'typescript': 'ts',
|
||||||
|
// 'jsx': 'jsx',
|
||||||
|
// 'tsx': 'tsx',
|
||||||
|
};
|
||||||
|
|
||||||
export function getArtifactFilename(type: string): string {
|
export function getArtifactFilename(type: string): string {
|
||||||
return artifactFilename[type] ?? 'App.tsx';
|
return artifactFilename[type] ?? 'App.tsx';
|
||||||
}
|
}
|
||||||
|
|
@ -34,8 +49,13 @@ export function getFileExtension(language?: string): string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sharedProps = {
|
export function getTemplate(type: string, language?: string): SandpackPredefinedTemplate {
|
||||||
template: 'react-ts',
|
return (
|
||||||
|
artifactTemplate[`${type}${(language?.length ?? 0) > 0 ? `-${language}` : ''}`] ?? 'react-ts'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const sharedProps: Partial<SandpackProviderProps> = {
|
||||||
customSetup: {
|
customSetup: {
|
||||||
dependencies: {
|
dependencies: {
|
||||||
'lucide-react': '^0.394.0',
|
'lucide-react': '^0.394.0',
|
||||||
|
|
@ -78,7 +98,7 @@ export const sharedProps = {
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const sharedOptions = {
|
export const sharedOptions: SandpackProviderProps['options'] = {
|
||||||
externalResources: ['https://unpkg.com/@tailwindcss/ui/dist/tailwind-ui.min.css'],
|
externalResources: ['https://unpkg.com/@tailwindcss/ui/dist/tailwind-ui.min.css'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue