fix: Disable upload-as-text attachment previews

This commit is contained in:
Danny Avila 2026-05-11 17:03:24 -04:00
parent d42959ad06
commit 55d8d31081
3 changed files with 109 additions and 7 deletions

View file

@ -14,6 +14,7 @@ const FileContainer = ({
containerClassName,
onDelete,
onClick,
disabled,
}: {
file: Partial<ExtendedFile | TFile>;
overrideType?: string;
@ -36,6 +37,7 @@ const FileContainer = ({
containerClassName?: string;
onDelete?: () => void;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
disabled?: boolean;
}) => {
const fileType = getFileType(overrideType ?? file.type);
const visibleName = displayName ?? file.filename ?? '';
@ -47,9 +49,11 @@ const FileContainer = ({
<button
type="button"
onClick={onClick}
disabled={disabled}
aria-label={visibleName}
className={cn(
'relative overflow-hidden rounded-2xl border border-border-light bg-surface-hover-alt',
disabled && 'cursor-default',
buttonClassName,
)}
>

View file

@ -1,9 +1,13 @@
import { useMemo, useState, useCallback, memo } from 'react';
import { FileContext, FileSources } from 'librechat-data-provider';
import type { TFile, TMessage } from 'librechat-data-provider';
import FileContainer from '~/components/Chat/Input/Files/FileContainer';
import FilePreviewDialog from './FilePreviewDialog';
import Image from './Image';
const isUploadAsTextAttachment = (file: Partial<TFile>) =>
file.source === FileSources.text && file.context === FileContext.message_attachment;
const Files = ({ message }: { message?: TMessage }) => {
const imageFiles = useMemo(() => {
return message?.files?.filter((file) => file.type?.startsWith('image/')) || [];
@ -24,13 +28,17 @@ const Files = ({ message }: { message?: TMessage }) => {
return (
<>
{otherFiles.length > 0 &&
otherFiles.map((file) => (
<FileContainer
key={file.file_id}
file={file as TFile}
onClick={() => setSelectedFile(file)}
/>
))}
otherFiles.map((file) => {
const previewDisabled = isUploadAsTextAttachment(file);
return (
<FileContainer
key={file.file_id}
file={file as TFile}
disabled={previewDisabled}
onClick={previewDisabled ? undefined : () => setSelectedFile(file)}
/>
);
})}
{imageFiles.length > 0 &&
imageFiles.map((file) => (
<Image

View file

@ -0,0 +1,90 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { FileContext, FileSources } from 'librechat-data-provider';
import type { TFile, TMessage } from 'librechat-data-provider';
import Files from '../Files';
jest.mock('~/components/Chat/Input/Files/FileContainer', () => ({
__esModule: true,
default: ({
file,
disabled,
onClick,
}: {
file: Partial<TFile>;
disabled?: boolean;
onClick?: React.MouseEventHandler<HTMLButtonElement>;
}) => (
<button
type="button"
data-testid={`file-chip-${file.file_id}`}
disabled={disabled}
onClick={onClick}
>
{file.filename}
</button>
),
}));
jest.mock('../FilePreviewDialog', () => ({
__esModule: true,
default: ({ open, fileId }: { open: boolean; fileId?: string }) =>
open ? <div data-testid="file-preview-dialog" data-file-id={fileId} /> : null,
}));
jest.mock('../Image', () => ({
__esModule: true,
default: ({ altText }: { altText: string }) => <img alt={altText} />,
}));
const messageWithFile = (file: Partial<TFile>): TMessage =>
({
messageId: 'message-1',
files: [
{
file_id: 'file-1',
filename: 'example.txt',
type: 'text/plain',
bytes: 12,
...file,
},
],
}) as TMessage;
describe('message file previews', () => {
it('disables previewing upload-as-text message attachments', () => {
render(
<Files
message={messageWithFile({
source: FileSources.text,
context: FileContext.message_attachment,
})}
/>,
);
const chip = screen.getByTestId('file-chip-file-1');
expect(chip).toBeDisabled();
fireEvent.click(chip);
expect(screen.queryByTestId('file-preview-dialog')).not.toBeInTheDocument();
});
it('keeps normal message attachments previewable', () => {
render(
<Files
message={messageWithFile({
source: FileSources.local,
context: FileContext.message_attachment,
})}
/>,
);
const chip = screen.getByTestId('file-chip-file-1');
expect(chip).not.toBeDisabled();
fireEvent.click(chip);
expect(screen.getByTestId('file-preview-dialog')).toHaveAttribute('data-file-id', 'file-1');
});
});