Attach Menu: Fix uploading audio files (#4806)

This commit is contained in:
Alexander Zinchuk 2024-08-06 20:06:43 +02:00
parent f3743bd556
commit 4169b5c6ad
13 changed files with 49 additions and 44 deletions

View File

@ -27,7 +27,7 @@ import type {
} from '../../types'; } from '../../types';
import type { UniversalMessage } from './messages'; import type { UniversalMessage } from './messages';
import { SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, VIDEO_WEBM_TYPE } from '../../../config'; import { SUPPORTED_PHOTO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, VIDEO_WEBM_TYPE } from '../../../config';
import { pick } from '../../../util/iteratees'; import { pick } from '../../../util/iteratees';
import { import {
addMediaToLocalDb, addStoryToLocalDb, type MediaRepairContext, serializeBytes, addMediaToLocalDb, addStoryToLocalDb, type MediaRepairContext, serializeBytes,
@ -402,7 +402,7 @@ export function buildApiDocument(document: GramJs.TypeDocument): ApiDocument | u
height: photoSize.h, height: photoSize.h,
}; };
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType)) {
innerMediaType = 'photo'; innerMediaType = 'photo';
const imageAttribute = attributes const imageAttribute = attributes

View File

@ -39,7 +39,7 @@ import {
SERVICE_NOTIFICATIONS_USER_ID, SERVICE_NOTIFICATIONS_USER_ID,
SPONSORED_MESSAGE_CACHE_MS, SPONSORED_MESSAGE_CACHE_MS,
SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../config'; } from '../../../config';
import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage'; import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage';
@ -987,7 +987,7 @@ export function buildUploadingMedia(
if (!shouldSendAsFile) { if (!shouldSendAsFile) {
if (attachment.quick) { if (attachment.quick) {
// TODO Handle GIF as video, but support playback in <video> // TODO Handle GIF as video, but support playback in <video>
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType)) {
const { width, height } = attachment.quick; const { width, height } = attachment.quick;
return { return {
photo: { photo: {

View File

@ -37,7 +37,7 @@ import {
MENTION_UNREAD_SLICE, MENTION_UNREAD_SLICE,
PINNED_MESSAGES_LIMIT, PINNED_MESSAGES_LIMIT,
REACTION_UNREAD_SLICE, REACTION_UNREAD_SLICE,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../config'; } from '../../../config';
import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage'; import { getEmojiOnlyCountForMessage } from '../../../global/helpers/getEmojiOnlyCountForMessage';
@ -706,7 +706,7 @@ async function uploadMedia(message: ApiMessage, attachment: ApiAttachment, onPro
const attributes: GramJs.TypeDocumentAttribute[] = [new GramJs.DocumentAttributeFilename({ fileName: filename })]; const attributes: GramJs.TypeDocumentAttribute[] = [new GramJs.DocumentAttributeFilename({ fileName: filename })];
if (!shouldSendAsFile) { if (!shouldSendAsFile) {
if (quick) { if (quick) {
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType) && mimeType !== GIF_MIME_TYPE) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType) && mimeType !== GIF_MIME_TYPE) {
return new GramJs.InputMediaUploadedPhoto({ return new GramJs.InputMediaUploadedPhoto({
file: inputFile, file: inputFile,
spoiler: shouldSendAsSpoiler, spoiler: shouldSendAsSpoiler,

View File

@ -22,7 +22,7 @@ import {
MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN, MIN_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
MOBILE_SCREEN_MAX_WIDTH, MOBILE_SCREEN_MAX_WIDTH,
SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN, SAFE_SCREEN_WIDTH_FOR_STATIC_RIGHT_COLUMN,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
TMP_CHAT_ID, TMP_CHAT_ID,
} from '../../config'; } from '../../config';
import { requestMeasure, requestMutation } from '../../lib/fasterdom/fasterdom'; import { requestMeasure, requestMutation } from '../../lib/fasterdom/fasterdom';
@ -157,7 +157,7 @@ type StateProps = {
}; };
function isImage(item: DataTransferItem) { function isImage(item: DataTransferItem) {
return item.kind === 'file' && item.type && SUPPORTED_IMAGE_CONTENT_TYPES.has(item.type); return item.kind === 'file' && item.type && SUPPORTED_PHOTO_CONTENT_TYPES.has(item.type);
} }
const LAYER_ANIMATION_DURATION_MS = 450 + ANIMATION_END_DELAY; const LAYER_ANIMATION_DURATION_MS = 450 + ANIMATION_END_DELAY;

View File

@ -10,7 +10,7 @@ import type { ISettings, ThreadId } from '../../../types';
import { import {
CONTENT_TYPES_WITH_PREVIEW, DEBUG_LOG_FILENAME, SUPPORTED_AUDIO_CONTENT_TYPES, CONTENT_TYPES_WITH_PREVIEW, DEBUG_LOG_FILENAME, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../config'; } from '../../../config';
import { import {
@ -132,7 +132,7 @@ const AttachMenu: FC<OwnProps> = ({
const handleQuickSelect = useLastCallback(() => { const handleQuickSelect = useLastCallback(() => {
openSystemFilesDialog( openSystemFilesDialog(
Array.from(canSendVideoAndPhoto ? CONTENT_TYPES_WITH_PREVIEW : ( Array.from(canSendVideoAndPhoto ? CONTENT_TYPES_WITH_PREVIEW : (
canSendPhotos ? SUPPORTED_IMAGE_CONTENT_TYPES : SUPPORTED_VIDEO_CONTENT_TYPES canSendPhotos ? SUPPORTED_PHOTO_CONTENT_TYPES : SUPPORTED_VIDEO_CONTENT_TYPES
)).join(','), )).join(','),
(e) => handleFileSelect(e, true), (e) => handleFileSelect(e, true),
); );

View File

@ -15,11 +15,11 @@ import {
BASE_EMOJI_KEYWORD_LANG, BASE_EMOJI_KEYWORD_LANG,
EDITABLE_INPUT_MODAL_ID, EDITABLE_INPUT_MODAL_ID,
SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../config'; } from '../../../config';
import { requestMutation } from '../../../lib/fasterdom/fasterdom'; import { requestMutation } from '../../../lib/fasterdom/fasterdom';
import { getAttachmentType, isUserId } from '../../../global/helpers'; import { getAttachmentMediaType, isUserId } from '../../../global/helpers';
import { selectChatFullInfo, selectIsChatWithSelf } from '../../../global/selectors'; import { selectChatFullInfo, selectIsChatWithSelf } from '../../../global/selectors';
import { selectCurrentLimit } from '../../../global/selectors/limits'; import { selectCurrentLimit } from '../../../global/selectors/limits';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
@ -155,7 +155,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
const isEditing = editingMessage && Boolean(editingMessage); const isEditing = editingMessage && Boolean(editingMessage);
const isInAlbum = editingMessage && editingMessage?.groupedId; const isInAlbum = editingMessage && editingMessage?.groupedId;
const isEditingMessageFile = isEditing && attachments?.length && getAttachmentType(attachments[0]); const isEditingMessageFile = isEditing && attachments?.length && getAttachmentMediaType(attachments[0]);
const notEditingFile = isEditingMessageFile !== 'file'; const notEditingFile = isEditingMessageFile !== 'file';
const [isSymbolMenuOpen, openSymbolMenu, closeSymbolMenu] = useFlag(); const [isSymbolMenuOpen, openSymbolMenu, closeSymbolMenu] = useFlag();
@ -428,7 +428,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
const [areAllPhotos, areAllVideos, areAllAudios] = useMemo(() => { const [areAllPhotos, areAllVideos, areAllAudios] = useMemo(() => {
if (!isQuickGallery || !renderingAttachments) return [false, false, false]; if (!isQuickGallery || !renderingAttachments) return [false, false, false];
const everyPhoto = renderingAttachments.every((a) => SUPPORTED_IMAGE_CONTENT_TYPES.has(a.mimeType)); const everyPhoto = renderingAttachments.every((a) => SUPPORTED_PHOTO_CONTENT_TYPES.has(a.mimeType));
const everyVideo = renderingAttachments.every((a) => SUPPORTED_VIDEO_CONTENT_TYPES.has(a.mimeType)); const everyVideo = renderingAttachments.every((a) => SUPPORTED_VIDEO_CONTENT_TYPES.has(a.mimeType));
const everyAudio = renderingAttachments.every((a) => SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType)); const everyAudio = renderingAttachments.every((a) => SUPPORTED_AUDIO_CONTENT_TYPES.has(a.mimeType));
return [everyPhoto, everyVideo, everyAudio]; return [everyPhoto, everyVideo, everyAudio];

View File

@ -3,7 +3,7 @@ import React, { memo, useMemo } from '../../../lib/teact/teact';
import type { ApiAttachment } from '../../../api/types'; import type { ApiAttachment } from '../../../api/types';
import { SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES } from '../../../config'; import { SUPPORTED_PHOTO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES } from '../../../config';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import { formatMediaDuration } from '../../../util/dates/dateFormat'; import { formatMediaDuration } from '../../../util/dates/dateFormat';
import { getFileExtension } from '../../common/helpers/documentInfo'; import { getFileExtension } from '../../common/helpers/documentInfo';
@ -47,7 +47,7 @@ const AttachmentModalItem: FC<OwnProps> = ({
const content = useMemo(() => { const content = useMemo(() => {
switch (displayType) { switch (displayType) {
case 'image': case 'photo':
return ( return (
<img <img
className={styles.preview} className={styles.preview}
@ -135,8 +135,8 @@ const AttachmentModalItem: FC<OwnProps> = ({
export function getDisplayType(attachment: ApiAttachment, shouldDisplayCompressed?: boolean) { export function getDisplayType(attachment: ApiAttachment, shouldDisplayCompressed?: boolean) {
if (shouldDisplayCompressed && attachment.quick) { if (shouldDisplayCompressed && attachment.quick) {
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(attachment.mimeType)) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'image'; return 'photo';
} }
if (SUPPORTED_VIDEO_CONTENT_TYPES.has(attachment.mimeType)) { if (SUPPORTED_VIDEO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'video'; return 'video';

View File

@ -3,7 +3,7 @@ import type { ApiAttachment } from '../../../../api/types';
import { import {
GIF_MIME_TYPE, GIF_MIME_TYPE,
SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../../config'; } from '../../../../config';
import { parseAudioMetadata } from '../../../../util/audio'; import { parseAudioMetadata } from '../../../../util/audio';
@ -29,7 +29,7 @@ export default async function buildAttachment(
let previewBlobUrl; let previewBlobUrl;
let shouldSendAsFile; let shouldSendAsFile;
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType)) {
const img = await preloadImage(blobUrl); const img = await preloadImage(blobUrl);
const { width, height } = img; const { width, height } = img;
shouldSendAsFile = !validateAspectRatio(width, height); shouldSendAsFile = !validateAspectRatio(width, height);
@ -117,7 +117,7 @@ export function prepareAttachmentsToSend(
return { return {
...attach, ...attach,
shouldSendAsFile: !attach.voice ? true : undefined, shouldSendAsFile: !(attach.voice || attach.audio) || undefined,
shouldSendAsSpoiler: undefined, shouldSendAsSpoiler: undefined,
}; };
}); });

View File

@ -3,7 +3,7 @@ import { getActions } from '../../../../global';
import type { ApiAttachment, ApiMessage } from '../../../../api/types'; import type { ApiAttachment, ApiMessage } from '../../../../api/types';
import { canReplaceMessageMedia, getAttachmentType } from '../../../../global/helpers'; import { canReplaceMessageMedia, getAttachmentMediaType } from '../../../../global/helpers';
import { MEMO_EMPTY_ARRAY } from '../../../../util/memo'; import { MEMO_EMPTY_ARRAY } from '../../../../util/memo';
import buildAttachment from '../helpers/buildAttachment'; import buildAttachment from '../helpers/buildAttachment';
@ -55,11 +55,11 @@ export default function useAttachmentModal({
} }
if (newAttachments.some((attachment) => { if (newAttachments.some((attachment) => {
const type = getAttachmentType(attachment); const type = getAttachmentMediaType(attachment);
return (type === 'audio' && !canSendAudios && !canSendDocuments) return (type === 'audio' && !canSendAudios && !canSendDocuments)
|| (type === 'video' && !canSendVideos && !canSendDocuments) || (type === 'video' && !canSendVideos && !canSendDocuments)
|| (type === 'image' && !canSendPhotos && !canSendDocuments) || (type === 'photo' && !canSendPhotos && !canSendDocuments)
|| (type === 'file' && !canSendDocuments); || (type === 'file' && !canSendDocuments);
})) { })) {
showAllowedMessageTypesNotification({ chatId }); showAllowedMessageTypesNotification({ chatId });
@ -70,11 +70,11 @@ export default function useAttachmentModal({
} else { } else {
setAttachments(newAttachments); setAttachments(newAttachments);
const shouldForce = newAttachments.some((attachment) => { const shouldForce = newAttachments.some((attachment) => {
const type = getAttachmentType(attachment); const type = getAttachmentMediaType(attachment);
return (type === 'audio' && !canSendAudios) return (type === 'audio' && !canSendAudios)
|| (type === 'video' && !canSendVideos) || (type === 'video' && !canSendVideos)
|| (type === 'image' && !canSendPhotos); || (type === 'photo' && !canSendPhotos);
}); });
setShouldForceAsFile(Boolean(shouldForce && canSendDocuments)); setShouldForceAsFile(Boolean(shouldForce && canSendDocuments));

View File

@ -230,7 +230,7 @@ export const GIF_MIME_TYPE = 'image/gif';
export const LOTTIE_STICKER_MIME_TYPE = 'application/x-tgsticker'; export const LOTTIE_STICKER_MIME_TYPE = 'application/x-tgsticker';
export const VIDEO_STICKER_MIME_TYPE = VIDEO_WEBM_TYPE; export const VIDEO_STICKER_MIME_TYPE = VIDEO_WEBM_TYPE;
export const SUPPORTED_IMAGE_CONTENT_TYPES = new Set([ export const SUPPORTED_PHOTO_CONTENT_TYPES = new Set([
'image/png', 'image/jpeg', GIF_MIME_TYPE, 'image/png', 'image/jpeg', GIF_MIME_TYPE,
]); ]);
@ -251,7 +251,7 @@ export const SUPPORTED_AUDIO_CONTENT_TYPES = new Set([
]); ]);
export const CONTENT_TYPES_WITH_PREVIEW = new Set([ export const CONTENT_TYPES_WITH_PREVIEW = new Set([
...SUPPORTED_IMAGE_CONTENT_TYPES, ...SUPPORTED_PHOTO_CONTENT_TYPES,
...SUPPORTED_VIDEO_CONTENT_TYPES, ...SUPPORTED_VIDEO_CONTENT_TYPES,
]); ]);

View File

@ -31,7 +31,7 @@ import {
RE_TELEGRAM_LINK, RE_TELEGRAM_LINK,
SERVICE_NOTIFICATIONS_USER_ID, SERVICE_NOTIFICATIONS_USER_ID,
SUPPORTED_AUDIO_CONTENT_TYPES, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES,
} from '../../../config'; } from '../../../config';
import { copyTextToClipboardFromPromise } from '../../../util/clipboard'; import { copyTextToClipboardFromPromise } from '../../../util/clipboard';
@ -2246,10 +2246,10 @@ function getAttachmentType(attachment: ApiAttachment) {
const { const {
shouldSendAsFile, mimeType, shouldSendAsFile, mimeType,
} = attachment; } = attachment;
if (SUPPORTED_AUDIO_CONTENT_TYPES.has(mimeType)) return 'audio';
if (shouldSendAsFile) return 'file'; if (shouldSendAsFile) return 'file';
if (mimeType === GIF_MIME_TYPE) return 'gif'; if (mimeType === GIF_MIME_TYPE) return 'gif';
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType) || SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) return 'media'; if (SUPPORTED_PHOTO_CONTENT_TYPES.has(mimeType) || SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) return 'media';
if (SUPPORTED_AUDIO_CONTENT_TYPES.has(mimeType)) return 'audio';
if (attachment.voice) return 'voice'; if (attachment.voice) return 'voice';
return 'file'; return 'file';
} }

View File

@ -26,7 +26,7 @@ import {
MAX_BUFFER_SIZE, MAX_BUFFER_SIZE,
} from '../../util/windowEnvironment'; } from '../../util/windowEnvironment';
import { getDocumentHasPreview } from '../../components/common/helpers/documentInfo'; import { getDocumentHasPreview } from '../../components/common/helpers/documentInfo';
import { getAttachmentType, matchLinkInMessageText } from './messages'; import { getAttachmentMediaType, matchLinkInMessageText } from './messages';
export type MediaWithThumbs = ApiPhoto | ApiVideo | ApiDocument | ApiSticker | ApiMediaExtendedPreview; export type MediaWithThumbs = ApiPhoto | ApiVideo | ApiDocument | ApiSticker | ApiMediaExtendedPreview;
export type DownloadableMedia = ApiPhoto | ApiVideo | ApiDocument | ApiSticker | ApiAudio | ApiVoice | ApiWebDocument; export type DownloadableMedia = ApiPhoto | ApiVideo | ApiDocument | ApiSticker | ApiAudio | ApiVoice | ApiWebDocument;
@ -618,10 +618,10 @@ export function canReplaceMessageMedia(message: ApiMessage, attachment: ApiAttac
const isFile = Boolean(getMessageAudio(message) const isFile = Boolean(getMessageAudio(message)
|| getMessageVoice(message) || getMessageDocument(message)); || getMessageVoice(message) || getMessageDocument(message));
const fileType = getAttachmentType(attachment); const fileType = getAttachmentMediaType(attachment);
return ( return (
(isPhotoOrVideo && (fileType === 'image' || fileType === 'video')) (isPhotoOrVideo && (fileType === 'photo' || fileType === 'video'))
|| (isFile && (fileType === 'audio' || fileType === 'file')) || (isFile && (fileType === 'audio' || fileType === 'file'))
); );
} }

View File

@ -13,10 +13,15 @@ import type { ThreadId } from '../../types';
import { ApiMessageEntityTypes, MAIN_THREAD_ID } from '../../api/types'; import { ApiMessageEntityTypes, MAIN_THREAD_ID } from '../../api/types';
import { import {
CONTENT_NOT_SUPPORTED, LOTTIE_STICKER_MIME_TYPE, CONTENT_NOT_SUPPORTED,
LOTTIE_STICKER_MIME_TYPE,
RE_LINK_TEMPLATE, RE_LINK_TEMPLATE,
SERVICE_NOTIFICATIONS_USER_ID, SUPPORTED_AUDIO_CONTENT_TYPES, SERVICE_NOTIFICATIONS_USER_ID,
SUPPORTED_IMAGE_CONTENT_TYPES, SUPPORTED_VIDEO_CONTENT_TYPES, TME_LINK_PREFIX, VIDEO_STICKER_MIME_TYPE, SUPPORTED_AUDIO_CONTENT_TYPES,
SUPPORTED_PHOTO_CONTENT_TYPES,
SUPPORTED_VIDEO_CONTENT_TYPES,
TME_LINK_PREFIX,
VIDEO_STICKER_MIME_TYPE,
} from '../../config'; } from '../../config';
import { areSortedArraysIntersecting, unique } from '../../util/iteratees'; import { areSortedArraysIntersecting, unique } from '../../util/iteratees';
import { isLocalMessageId } from '../../util/messageKey'; import { isLocalMessageId } from '../../util/messageKey';
@ -321,21 +326,21 @@ export function isJoinedChannelMessage(message: ApiMessage) {
return message.content.action && message.content.action.type === 'joinedChannel'; return message.content.action && message.content.action.type === 'joinedChannel';
} }
export function getAttachmentType(attachment: ApiAttachment) { export function getAttachmentMediaType(attachment: ApiAttachment) {
if (SUPPORTED_AUDIO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'audio';
}
if (attachment.shouldSendAsFile) return 'file'; if (attachment.shouldSendAsFile) return 'file';
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(attachment.mimeType)) { if (SUPPORTED_PHOTO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'image'; return 'photo';
} }
if (SUPPORTED_VIDEO_CONTENT_TYPES.has(attachment.mimeType)) { if (SUPPORTED_VIDEO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'video'; return 'video';
} }
if (SUPPORTED_AUDIO_CONTENT_TYPES.has(attachment.mimeType)) {
return 'audio';
}
return 'file'; return 'file';
} }