feat: global state for current artifact Id and set on artifact preview click

This commit is contained in:
Danny Avila 2024-08-23 22:07:15 -04:00
parent f2a516db02
commit 48ddf4039e
5 changed files with 47 additions and 13 deletions

View file

@ -1,7 +1,7 @@
import React, { useMemo, useState, useEffect, useRef } from 'react';
import { useRecoilValue } from 'recoil';
import * as Tabs from '@radix-ui/react-tabs';
import { Sandpack } from '@codesandbox/sandpack-react';
import { useRecoilValue, useRecoilState } from 'recoil';
import { removeNullishValues } from 'librechat-data-provider';
import { SandpackPreview, SandpackProvider } from '@codesandbox/sandpack-react/unstyled';
import type { Artifact } from '~/common';
@ -64,10 +64,10 @@ export default function Artifacts() {
const { isSubmitting, latestMessage } = useChatContext();
const [isVisible, setIsVisible] = useState(false);
const [activeTab, setActiveTab] = useState('code');
const [activeTab, setActiveTab] = useState('preview');
const artifacts = useRecoilValue(store.artifactsState);
const [currentArtifactId, setCurrentArtifactId] = useRecoilState(store.currentArtifactId);
const [currentArtifactId, setCurrentArtifactId] = useState<string | null>(null);
const orderedArtifactIds = useMemo(() => {
return Object.keys(artifacts).sort(
(a, b) => artifacts[a].lastUpdateTime - artifacts[b].lastUpdateTime,
@ -86,7 +86,7 @@ export default function Artifacts() {
const latestArtifactId = orderedArtifactIds[orderedArtifactIds.length - 1];
setCurrentArtifactId(latestArtifactId);
}
}, [orderedArtifactIds]);
}, [setCurrentArtifactId, orderedArtifactIds]);
useEffect(() => {
if (isSubmitting && orderedArtifactIds.length > 0) {
@ -99,7 +99,7 @@ export default function Artifacts() {
lastContentRef.current = latestArtifact.content ?? null;
}
}
}, [isSubmitting, orderedArtifactIds, artifacts]);
}, [setCurrentArtifactId, isSubmitting, orderedArtifactIds, artifacts]);
useEffect(() => {
if (latestMessage?.messageId !== lastRunMessageIdRef.current) {

View file

@ -1,27 +1,38 @@
import { useSetRecoilState } from 'recoil';
import type { Artifact } from '~/common';
import FilePreview from '~/components/Chat/Input/Files/FilePreview';
import { useLocalize } from '~/hooks';
import { getFileType } from '~/utils';
import store from '~/store';
const CodePreview = ({ artifact }: { artifact: Artifact | null }) => {
if (!artifact) {
const localize = useLocalize();
const setArtifactId = useSetRecoilState(store.currentArtifactId);
if (artifact === null || artifact === undefined) {
return null;
}
const fileType = getFileType('text/x-');
const fileType = getFileType('artifact');
return (
<div className="group relative inline-block text-sm text-text-primary">
<div className="relative overflow-hidden rounded-xl border border-border-medium">
<div className="w-60 bg-surface-active p-2">
<button
type="button"
onClick={() => setArtifactId(artifact.id)}
className="group relative inline-block rounded-xl text-sm text-text-primary"
>
<div className="relative overflow-hidden rounded-xl border border-border-medium transition-all duration-300 hover:border-border-xheavy hover:shadow-lg">
<div className="w-60 bg-surface-tertiary p-2 ">
<div className="flex flex-row items-center gap-2">
<FilePreview fileType={fileType} className="relative" />
<div className="overflow-hidden">
<div className="overflow-hidden text-left">
<div className="truncate font-medium">{artifact.title}</div>
<div className="truncate text-text-secondary">{fileType.title}</div>
<div className="truncate text-text-secondary">
{localize('com_ui_artifact_click')}
</div>
</div>
</div>
</div>
</div>
</div>
</button>
);
};

View file

@ -3,6 +3,7 @@
// file deepcode ignore HardcodedNonCryptoSecret: No hardcoded secrets present in this file
export default {
com_ui_artifact_click: 'Click to open',
com_a11y_start: 'The AI is replying.',
com_a11y_end: 'The AI has finished their reply.',
com_error_moderation:

View file

@ -31,3 +31,18 @@ export const artifactIdsState = atom<string[]>({
},
] as const,
});
export const currentArtifactId = atom<string | null>({
key: 'currentArtifactId',
default: null,
effects: [
({ onSet, node }) => {
onSet(async (newValue) => {
logger.log('artifacts', 'Recoil Effect: Setting currentArtifactId', {
key: node.key,
newValue,
});
});
},
] as const,
});

View file

@ -27,6 +27,12 @@ const codeFile = {
title: 'Code',
};
const artifact = {
paths: CodePaths,
fill: '#2D305C',
title: 'Code',
};
export const fileTypes = {
/* Category matches */
file: {
@ -41,6 +47,7 @@ export const fileTypes = {
csv: spreadsheet,
pdf: textDocument,
'text/x-': codeFile,
artifact: artifact,
/* Exact matches */
// 'application/json':,