🕑 fix: Add Suspense to Connection Error Messages (#3074)

This commit is contained in:
Danny Avila 2024-06-15 16:16:06 -04:00 committed by GitHub
parent 0294cfc881
commit 2cf5228021
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 72 additions and 8 deletions

View file

@ -5,6 +5,7 @@ import Plugin from '~/components/Messages/Content/Plugin';
import Error from '~/components/Messages/Content/Error';
import { DelayedRender } from '~/components/ui';
import EditMessage from './EditMessage';
import { useLocalize } from '~/hooks';
import Container from './Container';
import Markdown from './Markdown';
import { cn } from '~/utils';
@ -14,6 +15,38 @@ export const ErrorMessage = ({
message,
className = '',
}: Pick<TDisplayProps, 'text' | 'className' | 'message'>) => {
const localize = useLocalize();
if (text === 'Error connecting to server, try refreshing the page.') {
console.log('error message', message);
return (
<Suspense
fallback={
<div className="text-message mb-[0.625rem] mt-1 flex min-h-[20px] flex-col items-start gap-3 overflow-x-auto">
<div className="markdown prose dark:prose-invert light w-full break-words dark:text-gray-100">
<div className="absolute">
<p className="relative">
<span className="result-thinking" />
</p>
</div>
</div>
</div>
}
>
<DelayedRender delay={5500}>
<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',
className,
)}
>
{localize('com_ui_error_connection')}
</div>
</Container>
</DelayedRender>
</Suspense>
);
}
return (
<Container message={message}>
<div

View file

@ -58,7 +58,11 @@ export default function HoverButtons({
return null;
}
const { isCreatedByUser } = message;
const { isCreatedByUser, error } = message;
if (error) {
return null;
}
const onEdit = () => {
if (isEditing) {

View file

@ -22,6 +22,7 @@ export default function Message(props: TMessageProps) {
edit,
index,
isLast,
assistant,
enterEdit,
handleScroll,
conversation,
@ -44,6 +45,8 @@ export default function Message(props: TMessageProps) {
let messageLabel = '';
if (isCreatedByUser) {
messageLabel = UsernameDisplay ? user?.name || user?.username : localize('com_user_message');
} else if (assistant) {
messageLabel = assistant.name ?? 'Assistant';
} else {
messageLabel = message.sender;
}
@ -61,7 +64,7 @@ export default function Message(props: TMessageProps) {
<div>
<div className="pt-0.5">
<div className="flex h-6 w-6 items-center justify-center overflow-hidden rounded-full">
<Icon message={message} conversation={conversation} />
<Icon message={message} conversation={conversation} assistant={assistant} />
</div>
</div>
</div>

View file

@ -1,14 +1,37 @@
import { useState, useEffect } from 'react';
import { useState, useRef, useEffect } from 'react';
import type { ReactNode } from 'react';
const useDelayedRender = (delay: number) => {
const [delayed, setDelayed] = useState(true);
const timerPromiseRef = useRef<Promise<void> | null>(null);
useEffect(() => {
const timeout = setTimeout(() => setDelayed(false), delay);
return () => clearTimeout(timeout);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (fn: () => ReactNode) => !delayed && fn();
if (delayed) {
const timerPromise = new Promise<void>((resolve) => {
const timeout = setTimeout(() => {
setDelayed(false);
resolve();
}, delay);
return () => {
clearTimeout(timeout);
};
});
timerPromiseRef.current = timerPromise;
}
return () => {
timerPromiseRef.current = null;
};
}, [delay, delayed]);
return (fn: () => ReactNode) => {
if (delayed && timerPromiseRef.current) {
throw timerPromiseRef.current;
}
return fn();
};
};
export default useDelayedRender;

View file

@ -117,6 +117,7 @@ export default {
com_ui_instructions: 'Instructions',
com_ui_description: 'Description',
com_ui_error: 'Error',
com_ui_error_connection: 'Error connecting to server, try refreshing the page.',
com_ui_select: 'Select',
com_ui_input: 'Input',
com_ui_close: 'Close',