🚀 feat: Enhance Message Editing with File Resubmission (#2347)

* chore: fix type issue with File Table fakeData

* refactor: new lazy loading image strategy and load images/files as part of Message Container

* feat: resubmit files when editing messages with attached files
This commit is contained in:
Danny Avila 2024-04-07 13:25:24 -04:00 committed by GitHub
parent caabab4489
commit 3411d7a543
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 122 additions and 90 deletions

View file

@ -1,7 +1,6 @@
import { Fragment, Suspense } from 'react';
import type { TResPlugin, TFile } from 'librechat-data-provider';
import type { TMessageContentProps, TText, TDisplayProps } from '~/common';
import FileContainer from '~/components/Chat/Input/Files/FileContainer';
import type { TMessage, TResPlugin } from 'librechat-data-provider';
import type { TMessageContentProps, TDisplayProps } from '~/common';
import Plugin from '~/components/Messages/Content/Plugin';
import Error from '~/components/Messages/Content/Error';
import { DelayedRender } from '~/components/ui';
@ -9,11 +8,14 @@ import EditMessage from './EditMessage';
import Container from './Container';
import Markdown from './Markdown';
import { cn } from '~/utils';
import Image from './Image';
export const ErrorMessage = ({ text, className = '' }: TText) => {
export const ErrorMessage = ({
text,
message,
className = '',
}: Pick<TDisplayProps, 'text' | 'className' | 'message'>) => {
return (
<Container>
<Container message={message}>
<div
className={cn(
'rounded-md border border-red-500 bg-red-500/10 px-3 py-2 text-sm text-gray-600 dark:text-gray-200',
@ -28,31 +30,8 @@ export const ErrorMessage = ({ text, className = '' }: TText) => {
// Display Message Component
const DisplayMessage = ({ text, isCreatedByUser, message, showCursor }: TDisplayProps) => {
const files: TFile[] = [];
const imageFiles = message?.files
? message.files.filter((file) => {
if (file.type && file.type.startsWith('image/')) {
return true;
}
files.push(file);
})
: null;
return (
<Container>
{files.length > 0 && files.map((file) => <FileContainer key={file.file_id} file={file} />)}
{imageFiles &&
imageFiles.map((file) => (
<Image
key={file.file_id}
imagePath={file?.preview ?? file.filepath ?? ''}
height={file.height ?? 1920}
width={file.width ?? 1080}
altText={file.filename ?? 'Uploaded Image'}
// n={imageFiles.length}
// i={i}
/>
))}
<Container message={message}>
<div
className={cn(
showCursor && !!text?.length ? 'result-streaming' : '',
@ -71,8 +50,11 @@ const DisplayMessage = ({ text, isCreatedByUser, message, showCursor }: TDisplay
};
// Unfinished Message Component
export const UnfinishedMessage = () => (
<ErrorMessage text="The response is incomplete; it's either still processing, was cancelled, or censored. Refresh or try a different prompt." />
export const UnfinishedMessage = ({ message }: { message: TMessage }) => (
<ErrorMessage
message={message}
text="The response is incomplete; it's either still processing, was cancelled, or censored. Refresh or try a different prompt."
/>
);
// Content Component
@ -86,7 +68,7 @@ const MessageContent = ({
...props
}: TMessageContentProps) => {
if (error) {
return <ErrorMessage text={text} />;
return <ErrorMessage message={props.message} text={text} />;
} else if (edit) {
return <EditMessage text={text} isSubmitting={isSubmitting} {...props} />;
} else {
@ -143,7 +125,7 @@ const MessageContent = ({
{!isSubmitting && unfinished && (
<Suspense>
<DelayedRender delay={250}>
<UnfinishedMessage key={`unfinished-${messageId}-${idx}`} />
<UnfinishedMessage message={message} key={`unfinished-${messageId}-${idx}`} />
</DelayedRender>
</Suspense>
)}