feat: open/close artifacts

This commit is contained in:
Danny Avila 2024-08-25 01:41:39 -04:00
parent 6a8d4e43db
commit 5aee9db6de
5 changed files with 52 additions and 15 deletions

View file

@ -7,6 +7,7 @@ import store from '~/store';
const ArtifactButton = ({ artifact }: { artifact: Artifact | null }) => {
const localize = useLocalize();
const setVisible = useSetRecoilState(store.artifactsVisible);
const setArtifactId = useSetRecoilState(store.currentArtifactId);
if (artifact === null || artifact === undefined) {
return null;
@ -17,7 +18,10 @@ const ArtifactButton = ({ artifact }: { artifact: Artifact | null }) => {
<div className="group relative my-4 rounded-xl text-sm text-text-primary">
<button
type="button"
onClick={() => setArtifactId(artifact.id)}
onClick={() => {
setArtifactId(artifact.id);
setVisible(true);
}}
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 ">

View file

@ -1,5 +1,6 @@
import { useRef, useState } from 'react';
import { useRef, useState, useEffect } from 'react';
import { RefreshCw } from 'lucide-react';
import { useSetRecoilState } from 'recoil';
import * as Tabs from '@radix-ui/react-tabs';
import { SandpackPreviewRef } from '@codesandbox/sandpack-react';
import useArtifacts from '~/hooks/Artifacts/useArtifacts';
@ -7,13 +8,19 @@ import { CodeMarkdown, CopyCodeButton } from './Code';
import { getFileExtension } from '~/utils/artifacts';
import { ArtifactPreview } from './ArtifactPreview';
import { cn } from '~/utils';
import store from '~/store';
export default function Artifacts() {
const previewRef = useRef<SandpackPreviewRef>();
const [isRefreshing, setIsRefreshing] = useState(false);
const [isVisible, setIsVisible] = useState(false);
const setArtifactsVisible = useSetRecoilState(store.artifactsVisible);
useEffect(() => {
setIsVisible(true);
}, []);
const {
isVisible,
activeTab,
isSubmitting,
setActiveTab,
@ -51,7 +58,13 @@ export default function Artifacts() {
{/* Header */}
<div className="flex items-center justify-between border-b border-border-medium bg-surface-primary-alt p-2">
<div className="flex items-center">
<button className="mr-2 text-text-secondary" onClick={() => cycleArtifact('prev')}>
<button
className="mr-2 text-text-secondary"
onClick={() => {
setIsVisible(false);
setTimeout(() => setArtifactsVisible(false), 300);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -95,7 +108,13 @@ export default function Artifacts() {
Code
</Tabs.Trigger>
</Tabs.List>
<button className="text-text-secondary">
<button
className="text-text-secondary"
onClick={() => {
setIsVisible(false);
setTimeout(() => setArtifactsVisible(false), 300);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"

View file

@ -25,6 +25,8 @@ export default function Presentation({
const artifacts = useRecoilValue(store.artifactsState);
const codeArtifacts = useRecoilValue(store.codeArtifacts);
const hideSidePanel = useRecoilValue(store.hideSidePanel);
const artifactsVisible = useRecoilValue(store.artifactsVisible);
const interfaceConfig = useMemo(
() => startupConfig?.interface ?? defaultInterface,
[startupConfig],
@ -96,7 +98,11 @@ export default function Presentation({
defaultCollapsed={defaultCollapsed}
fullPanelCollapse={fullCollapse}
artifacts={
codeArtifacts === true && Object.keys(artifacts ?? {}).length > 0 ? <Artifacts /> : null
artifactsVisible === true &&
codeArtifacts === true &&
Object.keys(artifacts ?? {}).length > 0 ? (
<Artifacts />
) : null
}
>
<main className="flex h-full flex-col" role="main">

View file

@ -8,7 +8,6 @@ import store from '~/store';
export default function useArtifacts() {
const { isSubmitting, latestMessage, conversation } = useChatContext();
const [isVisible, setIsVisible] = useState(false);
const [activeTab, setActiveTab] = useState('preview');
const artifacts = useRecoilValue(store.artifactsState);
const [currentArtifactId, setCurrentArtifactId] = useRecoilState(store.currentArtifactId);
@ -48,10 +47,6 @@ export default function useArtifacts() {
prevConversationIdRef.current = conversation?.conversationId ?? null;
}, [conversation, resetArtifacts, resetCurrentArtifactId]);
useEffect(() => {
setIsVisible(true);
}, []);
useEffect(() => {
if (orderedArtifactIds.length > 0) {
const latestArtifactId = orderedArtifactIds[orderedArtifactIds.length - 1];
@ -110,14 +105,12 @@ export default function useArtifacts() {
};
return {
isVisible,
setIsVisible,
activeTab,
setActiveTab,
currentArtifact,
currentIndex,
cycleArtifact,
isSubmitting,
cycleArtifact,
currentArtifact,
orderedArtifactIds,
};
}

View file

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