mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-31 23:58:50 +01:00
refactor: add order prop to Artifact
This commit is contained in:
parent
068ec2fceb
commit
8ce70a41b7
3 changed files with 31 additions and 30 deletions
|
|
@ -6,6 +6,7 @@ export interface CodeBlock {
|
|||
|
||||
export interface Artifact {
|
||||
id: string;
|
||||
order: number;
|
||||
identifier?: string;
|
||||
language?: string;
|
||||
content?: string;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue