Skip to content

Commit fcd4ad7

Browse files
Ajaxyclaude
andcommitted
Composer: Fix FLAC files sent as documents in Firefox (#7404)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 28b238d commit fcd4ad7

4 files changed

Lines changed: 28 additions & 14 deletions

File tree

‎src/components/middle/composer/DropArea.tsx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { canReplaceMessageMedia } from '../../../global/helpers';
77
import { revokeAttachmentUrls } from '../../../util/attachments';
88
import buildClassName from '../../../util/buildClassName';
99
import captureEscKeyListener from '../../../util/captureEscKeyListener';
10+
import { validateFiles } from '../../../util/files';
1011
import buildAttachment from './helpers/buildAttachment';
1112
import getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems';
1213

@@ -49,7 +50,7 @@ const DropArea = ({
4950
let files: File[] = [];
5051

5152
if (dt.files && dt.files.length > 0 && (!dt.items || !dt.items.length)) {
52-
files = files.concat(Array.from(dt.files));
53+
files = files.concat(validateFiles(dt.files) ?? []);
5354
} else if (dt.items && dt.items.length > 0) {
5455
const folderFiles = await getFilesFromDataTransferItems(dt.items);
5556
if (folderFiles?.length) {
@@ -67,8 +68,8 @@ const DropArea = ({
6768
const handleQuickFilesDrop = useLastCallback(async (e: React.DragEvent<HTMLDivElement>) => {
6869
const { dataTransfer: dt } = e;
6970

70-
if (dt.files && dt.files.length > 0) {
71-
const files = Array.from(dt.files);
71+
const files = validateFiles(dt.files);
72+
if (files?.length) {
7273
if (!await validateReplacement(files)) return;
7374

7475
onHide();

‎src/components/middle/composer/helpers/richEditor.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import type { RichEditorTooltipsConfig } from '../../../common/tooltips/types';
4141
import type { RichEditorMediaEditHandler, RichEditorMediaFilesHandler } from '../richEditorTypes';
4242

4343
import { requestMutation } from '../../../../lib/fasterdom/fasterdom';
44+
import { validateFiles } from '../../../../util/files';
4445
import { CODE_HIGHLIGHTING_CHANGED_META, lowlight } from '../../../../util/highlightCode';
4546
import { addLocalizationCallback, getTranslationFn } from '../../../../util/localization';
4647
import {
@@ -599,8 +600,12 @@ function handleRichEditorDrop(
599600
getIsRichInputExpanded: () => boolean,
600601
onMediaFiles: RichEditorMediaFilesHandler,
601602
) {
602-
const files = Array.from(event.dataTransfer?.files || []);
603-
if (!getIsRichInputExpanded() || !files.length) {
603+
if (!event.dataTransfer || !getIsRichInputExpanded()) {
604+
return false;
605+
}
606+
607+
const files = validateFiles(event.dataTransfer.files);
608+
if (!files?.length) {
604609
return false;
605610
}
606611

‎src/components/middle/composer/richInput/EditableMedia.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { RichEditorMediaEditHandler, RichEditorMediaFilesHandler } from '..
1414
import { getRichTextPlainText } from '../../../../global/helpers/richMessage';
1515
import { selectTheme } from '../../../../global/selectors';
1616
import buildClassName from '../../../../util/buildClassName';
17+
import { validateFiles } from '../../../../util/files';
1718
import { openSystemFilesDialog } from '../../../../util/systemFilesDialog';
1819
import { NodeViewContent, TeactNodeViewRenderer } from '../../../../util/tiptap';
1920
import { MEDIA_NODE_NAME } from '../../../../util/tiptap/constants';
@@ -165,8 +166,8 @@ const EditableMedia = ({
165166
if (typeof position !== 'number') return;
166167

167168
openSystemFilesDialog(MEDIA_FILE_TYPES, (event) => {
168-
const files = Array.from((event.target as HTMLInputElement).files || []);
169-
if (files.length) {
169+
const files = validateFiles((event.target as HTMLInputElement).files);
170+
if (files?.length) {
170171
(extension.options.onMediaFiles as RichEditorMediaFilesHandler)(files, position, true);
171172
}
172173
});

‎src/util/files.ts‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,14 +124,21 @@ export function validateFiles(files: File[] | FileList | null): File[] | undefin
124124
if (!files?.length) {
125125
return undefined;
126126
}
127-
return Array.from(files).map(fixMovMime).filter((file) => file.size);
127+
return Array.from(files).map(fixMimeType).filter((file) => file.size);
128128
}
129129

130-
// .mov MIME type not reported sometimes https://developer.mozilla.org/en-US/docs/Web/API/File/type#sect1
131-
function fixMovMime(file: File) {
132-
const ext = file.name.split('.').pop()!;
133-
if (!file.type && ext.toLowerCase() === 'mov') {
134-
return new File([file], file.name, { type: 'video/quicktime' });
130+
const MIME_TYPE_BY_EXTENSION: Record<string, string> = {
131+
mov: 'video/quicktime',
132+
flac: 'audio/flac',
133+
};
134+
135+
// Browsers may omit the type or take a non-standard one from the OS (e.g. Firefox reports `audio/x-flac` on Windows)
136+
// https://developer.mozilla.org/en-US/docs/Web/API/File/type#sect1
137+
function fixMimeType(file: File) {
138+
const ext = file.name.split('.').pop()?.toLowerCase();
139+
const expectedType = ext && MIME_TYPE_BY_EXTENSION[ext];
140+
if (!expectedType || file.type === expectedType) {
141+
return file;
135142
}
136-
return file;
143+
return new File([file], file.name, { type: expectedType });
137144
}

0 commit comments

Comments
 (0)