refactor: add order prop to Artifact

This commit is contained in:
Danny Avila 2024-08-23 19:54:22 -04:00
parent 068ec2fceb
commit 8ce70a41b7
3 changed files with 31 additions and 30 deletions

View file

@ -6,6 +6,7 @@ export interface CodeBlock {
export interface Artifact {
id: string;
order: number;
identifier?: string;
language?: string;
content?: string;

View file

@ -1,7 +1,7 @@
import React, { useEffect, useCallback, useRef, useState } from 'react';
import throttle from 'lodash/throttle';
import { visit } from 'unist-util-visit';
import { useSetRecoilState } from 'recoil';
import { useSetRecoilState, useRecoilValue } from 'recoil';
import type { Pluggable } from 'unified';
import type { Artifact } from '~/common';
import { artifactsState, artifactIdsState } from '~/store/artifacts';
@ -45,6 +45,7 @@ export function Artifact({
}) {
const setArtifacts = useSetRecoilState(artifactsState);
const setArtifactIds = useSetRecoilState(artifactIdsState);
const currentArtifacts = useRecoilValue(artifactsState);
const [artifact, setArtifact] = useState<Artifact | null>(null);
const throttledUpdateRef = useRef(
@ -66,18 +67,24 @@ export function Artifact({
const artifactKey = `${identifier}_${type}_${title}`.replace(/\s+/g, '_').toLowerCase();
throttledUpdateRef.current(() => {
const currentArtifact = {
const existingArtifact = currentArtifacts[artifactKey];
const order =
existingArtifact != null ? existingArtifact.order : Object.keys(currentArtifacts).length;
const currentArtifact: Artifact = {
id: artifactKey,
identifier,
title,
type,
content,
order,
};
setArtifacts((prevArtifacts) => {
if (
(prevArtifacts as Record<string, Artifact | undefined>)[artifactKey] != null &&
prevArtifacts[artifactKey].content === content
prevArtifacts[artifactKey] != null &&
prevArtifacts[artifactKey].content === content &&
prevArtifacts[artifactKey].order === order
) {
return prevArtifacts;
}
@ -90,14 +97,24 @@ export function Artifact({
setArtifactIds((prevIds) => {
if (!prevIds.includes(artifactKey)) {
return [...prevIds, artifactKey];
const newIds = [...prevIds, artifactKey];
const definedIds = newIds.filter((id) => currentArtifacts[id] != null);
return definedIds.sort((a, b) => currentArtifacts[a].order - currentArtifacts[b].order);
}
return prevIds;
});
setArtifact(currentArtifact);
});
}, [props.children, props.title, props.type, props.identifier, setArtifacts, setArtifactIds]);
}, [
props.children,
props.title,
props.type,
props.identifier,
setArtifacts,
setArtifactIds,
currentArtifacts,
]);
useEffect(() => {
updateArtifact();
@ -105,10 +122,3 @@ export function Artifact({
return <CodePreview artifact={artifact} />;
}
// <div className="artifact">
// <b>{props.title ?? 'Untitled Artifact'}</b>
// <p>Type: {props.type ?? 'unknown'}</p>
// <p>Identifier: {props.identifier ?? 'No identifier'}</p>
// {props.children as React.ReactNode}
// </div>

View file

@ -68,8 +68,10 @@ export default function Artifacts() {
const artifacts = useRecoilValue(store.artifactsState);
const [currentArtifactId, setCurrentArtifactId] = useState<string | null>(null);
const [orderedArtifactIds, setOrderedArtifactIds] = useState<string[]>([]);
const prevArtifactsRef = useRef({});
const orderedArtifactIds = useMemo(() => {
return Object.keys(artifacts).sort((a, b) => artifacts[a].order - artifacts[b].order);
}, [artifacts]);
const lastRunMessageIdRef = useRef<string | null>(null);
const lastContentRef = useRef<string | null>(null);
@ -99,22 +101,10 @@ export default function Artifacts() {
}, [activeTab, currentArtifactId, isSubmitting, latestMessage, orderedArtifactIds, artifacts]);
useEffect(() => {
const artifactIds = Object.keys(artifacts);
const newArtifacts = artifactIds.filter((id) => !orderedArtifactIds.includes(id));
if (newArtifacts.length > 0) {
setOrderedArtifactIds((prevIds) => [...prevIds, ...newArtifacts]);
setCurrentArtifactId(newArtifacts[newArtifacts.length - 1]);
} else if (isSubmitting && currentArtifactId != null) {
// If submitting and content changed, move current artifact to the end
setOrderedArtifactIds((prevIds) => {
const newIds = prevIds.filter((id) => id !== currentArtifactId);
return [...newIds, currentArtifactId];
});
if (orderedArtifactIds.length > 0 && !(currentArtifactId ?? '')) {
setCurrentArtifactId(orderedArtifactIds[orderedArtifactIds.length - 1]);
}
prevArtifactsRef.current = artifacts;
}, [artifacts, isSubmitting, currentArtifactId, orderedArtifactIds]);
}, [orderedArtifactIds, currentArtifactId]);
const currentArtifact = currentArtifactId != null ? artifacts[currentArtifactId] : null;