Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 48 additions & 24 deletions web/src/app/chat/ChatPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ export function ChatPage({
setSelectedFiles,
folders: userFolders,
files: allUserFiles,
uploadFile,
currentMessageFiles,
setCurrentMessageFiles,
} = useDocumentsContext();
Expand Down Expand Up @@ -1987,34 +1986,59 @@ export function ChatPage({

updateChatState("uploading", currentSessionId());

for (let file of acceptedFiles) {
const formData = new FormData();
formData.append("files", file);
const response: FileResponse[] = await uploadFile(formData, null);

if (response.length > 0 && response[0] !== undefined) {
const uploadedFile = response[0];

const newFileDescriptor: FileDescriptor = {
// Use file_id (storage ID) if available, otherwise fallback to DB id
// Ensure it's a string as FileDescriptor expects
id: uploadedFile.file_id
? String(uploadedFile.file_id)
: String(uploadedFile.id),
type: uploadedFile.chat_file_type
? uploadedFile.chat_file_type
: ChatFileType.PLAIN_TEXT,
name: uploadedFile.name,
isUploading: false, // Mark as successfully uploaded
};
// Create placeholder files to show upload progress
const placeholderFiles: FileDescriptor[] = acceptedFiles.map((file, index) => ({
id: `placeholder-${Date.now()}-${index}`,
type: ChatFileType.PLAIN_TEXT,
name: file.name,
isUploading: true,
}));

setCurrentMessageFiles((prev) => [...prev, newFileDescriptor]);
} else {
// Add placeholder files to show upload progress
setCurrentMessageFiles((prev) => [...prev, ...placeholderFiles]);

// Upload all files at once using the chat upload API
try {
const [uploadedFiles, uploadError] = await uploadFilesForChat(acceptedFiles);

if (uploadError) {
// Remove all placeholders and show error
setCurrentMessageFiles((prev) =>
prev.filter((f) => !placeholderFiles.some(p => p.id === f.id))
);
setPopup({
type: "error",
message: "Failed to upload file",
message: uploadError,
});
return;
}

// Replace all placeholders with actual uploaded files
setCurrentMessageFiles((prev) => {
// Remove all placeholders
const withoutPlaceholders = prev.filter((f) =>
!placeholderFiles.some(p => p.id === f.id)
);

// Add the successfully uploaded files
const newFileDescriptors: FileDescriptor[] = uploadedFiles.map((uploadedFile) => ({
id: uploadedFile.id,
type: uploadedFile.type,
name: uploadedFile.name,
isUploading: false,
}));

return [...withoutPlaceholders, ...newFileDescriptors];
});
} catch (error) {
// Remove all placeholders and show error
setCurrentMessageFiles((prev) =>
prev.filter((f) => !placeholderFiles.some(p => p.id === f.id))
);
setPopup({
type: "error",
message: `Failed to upload files. ${error instanceof Error ? error.message : 'Unknown error'}`,
});
}

updateChatState("input", currentSessionId());
Expand Down
16 changes: 10 additions & 6 deletions web/src/app/chat/input/ChatInputBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -743,12 +743,16 @@ export function ChatInputBar({
<SourceChip
key={`${file.source}-${file.id}-${index}`}
icon={
<FileIcon
className={
file.source === "current" ? "text-red-500" : ""
}
size={16}
/>
file.isUploading ? (
<FiLoader className="animate-spin" />
) : (
<FileIcon
className={
file.source === "current" ? "text-red-500" : ""
}
size={16}
/>
)
}
title={file.name}
onRemove={() => {
Expand Down
Loading