chat / client /src /components /SidePanel /Files /PanelFileCell.tsx
Zhitomir's picture
chat init
aa2e6af
Raw
History Blame Contribute Delete
3.75 kB
import { useCallback } from 'react';
import {
fileConfig as defaultFileConfig,
checkOpenAIStorage,
mergeFileConfig,
megabyte,
isAssistantsEndpoint,
} from 'librechat-data-provider';
import type { Row } from '@tanstack/react-table';
import type { TFile } from 'librechat-data-provider';
import { useFileMapContext, useChatContext, useToastContext } from '~/Providers';
import ImagePreview from '~/components/Chat/Input/Files/ImagePreview';
import FilePreview from '~/components/Chat/Input/Files/FilePreview';
import { useUpdateFiles, useLocalize } from '~/hooks';
import { useGetFileConfig } from '~/data-provider';
import { getFileType } from '~/utils';
export default function PanelFileCell({ row }: { row: Row<TFile> }) {
const localize = useLocalize();
const fileMap = useFileMapContext();
const { showToast } = useToastContext();
const { setFiles, conversation } = useChatContext();
const { data: fileConfig = defaultFileConfig } = useGetFileConfig({
select: (data) => mergeFileConfig(data),
});
const { addFile } = useUpdateFiles(setFiles);
const handleFileClick = useCallback(() => {
const file = row.original;
const endpoint = conversation?.endpoint;
const fileData = fileMap?.[file.file_id];
if (!fileData) {
return;
}
if (!endpoint) {
return showToast({ message: localize('com_ui_attach_error'), status: 'error' });
}
if (checkOpenAIStorage(fileData?.source ?? '') && !isAssistantsEndpoint(endpoint)) {
return showToast({
message: localize('com_ui_attach_error_openai'),
status: 'error',
});
} else if (!checkOpenAIStorage(fileData?.source ?? '') && isAssistantsEndpoint(endpoint)) {
showToast({
message: localize('com_ui_attach_warn_endpoint'),
status: 'warning',
});
}
const { fileSizeLimit, supportedMimeTypes } =
fileConfig.endpoints[endpoint] ?? fileConfig.endpoints.default;
if (fileData.bytes > fileSizeLimit) {
return showToast({
message: `${localize('com_ui_attach_error_size')} ${
fileSizeLimit / megabyte
} MB (${endpoint})`,
status: 'error',
});
}
const isSupportedMimeType = defaultFileConfig.checkType(file.type, supportedMimeTypes);
if (!isSupportedMimeType) {
return showToast({
message: `${localize('com_ui_attach_error_type')} ${file.type} (${endpoint})`,
status: 'error',
});
}
addFile({
progress: 1,
attached: true,
file_id: fileData.file_id,
filepath: fileData.filepath,
preview: fileData.filepath,
type: fileData.type,
height: fileData.height,
width: fileData.width,
filename: fileData.filename,
source: fileData.source,
size: fileData.bytes,
});
}, [addFile, fileMap, row.original, conversation, localize, showToast, fileConfig.endpoints]);
const file = row.original;
if (file.type?.startsWith('image')) {
return (
<div
onClick={handleFileClick}
className="flex cursor-pointer gap-2 rounded-md dark:hover:bg-gray-700"
>
<ImagePreview
url={file.filepath}
className="relative h-10 w-10 shrink-0 overflow-hidden rounded-md"
source={file.source}
/>
<span className="self-center truncate text-xs">{file.filename}</span>
</div>
);
}
const fileType = getFileType(file.type);
return (
<div
onClick={handleFileClick}
className="flex cursor-pointer gap-2 rounded-md dark:hover:bg-gray-700"
>
{fileType && <FilePreview fileType={fileType} className="relative" file={file} />}
<span className="self-center truncate">{file.filename}</span>
</div>
);
}