import React, { useState } from 'react'; import type { Message } from 'ai'; import { toast } from 'react-toastify'; import { MAX_FILES, isBinaryFile, shouldIncludeFile } from '~/utils/fileUtils'; import { createChatFromFolder } from '~/utils/folderImport'; interface ImportFolderButtonProps { className?: string; importChat?: (description: string, messages: Message[]) => Promise; } export const ImportFolderButton: React.FC = ({ className, importChat }) => { const [isLoading, setIsLoading] = useState(false); const handleFileChange = async (e: React.ChangeEvent) => { const allFiles = Array.from(e.target.files || []); if (allFiles.length > MAX_FILES) { toast.error( `This folder contains ${allFiles.length.toLocaleString()} files. This product is not yet optimized for very large projects. Please select a folder with fewer than ${MAX_FILES.toLocaleString()} files.`, ); return; } const folderName = allFiles[0]?.webkitRelativePath.split('/')[0] || 'Unknown Folder'; setIsLoading(true); const loadingToast = toast.loading(`Importing ${folderName}...`); try { const filteredFiles = allFiles.filter((file) => shouldIncludeFile(file.webkitRelativePath)); if (filteredFiles.length === 0) { toast.error('No files found in the selected folder'); return; } const fileChecks = await Promise.all( filteredFiles.map(async (file) => ({ file, isBinary: await isBinaryFile(file), })), ); const textFiles = fileChecks.filter((f) => !f.isBinary).map((f) => f.file); const binaryFilePaths = fileChecks .filter((f) => f.isBinary) .map((f) => f.file.webkitRelativePath.split('/').slice(1).join('/')); if (textFiles.length === 0) { toast.error('No text files found in the selected folder'); return; } if (binaryFilePaths.length > 0) { toast.info(`Skipping ${binaryFilePaths.length} binary files`); } const messages = await createChatFromFolder(textFiles, binaryFilePaths, folderName); if (importChat) { await importChat(folderName, [...messages]); } toast.success('Folder imported successfully'); } catch (error) { console.error('Failed to import folder:', error); toast.error('Failed to import folder'); } finally { setIsLoading(false); toast.dismiss(loadingToast); e.target.value = ''; // Reset file input } }; return ( <> ); };