mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 08:33:20 +00:00
(feat:attach) functionality to upload files
This commit is contained in:
@@ -22,6 +22,7 @@ interface MessageInputProps {
|
|||||||
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
||||||
onSubmit: () => void;
|
onSubmit: () => void;
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
onAttachmentChange?: (attachments: { fileName: string; id: string }[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UploadState {
|
interface UploadState {
|
||||||
@@ -38,6 +39,7 @@ export default function MessageInput({
|
|||||||
onChange,
|
onChange,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
loading,
|
loading,
|
||||||
|
onAttachmentChange,
|
||||||
}: MessageInputProps) {
|
}: MessageInputProps) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [isDarkTheme] = useDarkTheme();
|
const [isDarkTheme] = useDarkTheme();
|
||||||
@@ -199,7 +201,7 @@ export default function MessageInput({
|
|||||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
|
||||||
if (e.key === 'Enter' && !e.shiftKey) {
|
if (e.key === 'Enter' && !e.shiftKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
onSubmit();
|
handleSubmit();
|
||||||
if (inputRef.current) {
|
if (inputRef.current) {
|
||||||
inputRef.current.value = '';
|
inputRef.current.value = '';
|
||||||
handleInput();
|
handleInput();
|
||||||
@@ -211,18 +213,22 @@ export default function MessageInput({
|
|||||||
console.log('Selected document:', doc);
|
console.log('Selected document:', doc);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderUploadStatus = () => {
|
useEffect(() => {
|
||||||
const activeUploads = uploads.filter(u =>
|
if (onAttachmentChange) {
|
||||||
u.status === 'uploading' || u.status === 'processing'
|
const completedAttachments = uploads
|
||||||
);
|
.filter(upload => upload.status === 'completed' && upload.attachment_id)
|
||||||
|
.map(upload => ({
|
||||||
if (activeUploads.length === 0) {
|
fileName: upload.fileName,
|
||||||
return 'Attach';
|
id: upload.attachment_id as string
|
||||||
|
}));
|
||||||
|
onAttachmentChange(completedAttachments);
|
||||||
}
|
}
|
||||||
|
}, [uploads, onAttachmentChange]);
|
||||||
|
|
||||||
return `Uploading ${activeUploads.length} file(s)`;
|
const handleSubmit = () => {
|
||||||
|
onSubmit();
|
||||||
|
setUploads(prevUploads => prevUploads.filter(upload => upload.status !== 'completed'));
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full mx-2">
|
<div className="flex flex-col w-full mx-2">
|
||||||
<div className="flex flex-col w-full rounded-[23px] border dark:border-grey border-dark-gray bg-lotion dark:bg-transparent relative">
|
<div className="flex flex-col w-full rounded-[23px] border dark:border-grey border-dark-gray bg-lotion dark:bg-transparent relative">
|
||||||
@@ -332,7 +338,7 @@ export default function MessageInput({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={loading ? undefined : onSubmit}
|
onClick={loading ? undefined : handleSubmit}
|
||||||
aria-label={loading ? t('loading') : t('send')}
|
aria-label={loading ? t('loading') : t('send')}
|
||||||
className={`flex items-center justify-center p-2.5 rounded-full ${loading ? 'bg-gray-300 dark:bg-gray-600' : 'bg-black dark:bg-white'} ml-auto`}
|
className={`flex items-center justify-center p-2.5 rounded-full ${loading ? 'bg-gray-300 dark:bg-gray-600' : 'bg-black dark:bg-white'} ml-auto`}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ import { ActiveState } from '../models/misc';
|
|||||||
import ConversationMessages from './ConversationMessages';
|
import ConversationMessages from './ConversationMessages';
|
||||||
import MessageInput from '../components/MessageInput';
|
import MessageInput from '../components/MessageInput';
|
||||||
|
|
||||||
|
interface AttachmentState {
|
||||||
|
fileName: string;
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Conversation() {
|
export default function Conversation() {
|
||||||
const token = useSelector(selectToken);
|
const token = useSelector(selectToken);
|
||||||
const queries = useSelector(selectQueries);
|
const queries = useSelector(selectQueries);
|
||||||
@@ -45,6 +50,7 @@ export default function Conversation() {
|
|||||||
useState<ActiveState>('INACTIVE');
|
useState<ActiveState>('INACTIVE');
|
||||||
const [files, setFiles] = useState<File[]>([]);
|
const [files, setFiles] = useState<File[]>([]);
|
||||||
const [handleDragActive, setHandleDragActive] = useState<boolean>(false);
|
const [handleDragActive, setHandleDragActive] = useState<boolean>(false);
|
||||||
|
const [attachments, setAttachments] = useState<AttachmentState[]>([]);
|
||||||
|
|
||||||
const onDrop = useCallback((acceptedFiles: File[]) => {
|
const onDrop = useCallback((acceptedFiles: File[]) => {
|
||||||
setUploadModalState('ACTIVE');
|
setUploadModalState('ACTIVE');
|
||||||
@@ -95,21 +101,26 @@ export default function Conversation() {
|
|||||||
isRetry = false,
|
isRetry = false,
|
||||||
updated = null,
|
updated = null,
|
||||||
indx = undefined,
|
indx = undefined,
|
||||||
|
attachments = [],
|
||||||
}: {
|
}: {
|
||||||
question: string;
|
question: string;
|
||||||
isRetry?: boolean;
|
isRetry?: boolean;
|
||||||
updated?: boolean | null;
|
updated?: boolean | null;
|
||||||
indx?: number;
|
indx?: number;
|
||||||
|
attachments?: { fileName: string; id: string }[];
|
||||||
}) => {
|
}) => {
|
||||||
if (updated === true) {
|
if (updated === true) {
|
||||||
!isRetry &&
|
!isRetry &&
|
||||||
dispatch(resendQuery({ index: indx as number, prompt: question })); //dispatch only new queries
|
dispatch(resendQuery({ index: indx as number, prompt: question }));
|
||||||
fetchStream.current = dispatch(fetchAnswer({ question, indx }));
|
fetchStream.current = dispatch(fetchAnswer({ question, indx }));
|
||||||
} else {
|
} else {
|
||||||
question = question.trim();
|
question = question.trim();
|
||||||
if (question === '') return;
|
if (question === '') return;
|
||||||
!isRetry && dispatch(addQuery({ prompt: question })); //dispatch only new queries
|
!isRetry && dispatch(addQuery({ prompt: question, attachments }));
|
||||||
fetchStream.current = dispatch(fetchAnswer({ question }));
|
fetchStream.current = dispatch(fetchAnswer({
|
||||||
|
question,
|
||||||
|
attachments: attachments.map(a => a.id)
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,7 +171,11 @@ export default function Conversation() {
|
|||||||
isRetry: true,
|
isRetry: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
handleQuestion({ question: input });
|
handleQuestion({
|
||||||
|
question: input,
|
||||||
|
attachments: attachments
|
||||||
|
});
|
||||||
|
setAttachments([]);
|
||||||
}
|
}
|
||||||
setInput('');
|
setInput('');
|
||||||
}
|
}
|
||||||
@@ -245,6 +260,7 @@ export default function Conversation() {
|
|||||||
onChange={(e) => setInput(e.target.value)}
|
onChange={(e) => setInput(e.target.value)}
|
||||||
onSubmit={handleQuestionSubmission}
|
onSubmit={handleQuestionSubmission}
|
||||||
loading={status === 'loading'}
|
loading={status === 'loading'}
|
||||||
|
onAttachmentChange={setAttachments}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user