Attachmant Modal: Fix sending media with absurd aspect ratio (#2757)

This commit is contained in:
Alexander Zinchuk 2023-03-10 02:34:07 +01:00
parent c1eafdd9d5
commit 2d7d1a7fd8
2 changed files with 33 additions and 14 deletions

View File

@ -14,6 +14,7 @@ import {
import { scaleImage } from '../../../../util/imageResize';
const MAX_QUICK_IMG_SIZE = 1280; // px
const MAX_ASPECT_RATIO = 20;
const FILE_EXT_REGEX = /\.[^/.]+$/;
export default async function buildAttachment(
@ -24,32 +25,42 @@ export default async function buildAttachment(
let quick;
let audio;
let previewBlobUrl;
let shouldSendAsFile;
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(mimeType)) {
const img = await preloadImage(blobUrl);
const { width, height } = img;
shouldSendAsFile = !validateAspectRatio(width, height);
const shouldShrink = Math.max(width, height) > MAX_QUICK_IMG_SIZE;
const isGif = mimeType === GIF_MIME_TYPE;
if (!options?.compressedBlobUrl && !isGif && (shouldShrink || mimeType !== 'image/jpeg')) {
const resizedUrl = await scaleImage(
blobUrl, shouldShrink ? MAX_QUICK_IMG_SIZE / Math.max(width, height) : 1, 'image/jpeg',
);
URL.revokeObjectURL(blobUrl);
return buildAttachment(filename, blob, {
compressedBlobUrl: resizedUrl,
});
if (!shouldSendAsFile) {
if (!options?.compressedBlobUrl && !isGif && (shouldShrink || mimeType !== 'image/jpeg')) {
const resizedUrl = await scaleImage(
blobUrl, shouldShrink ? MAX_QUICK_IMG_SIZE / Math.max(width, height) : 1, 'image/jpeg',
);
URL.revokeObjectURL(blobUrl);
return buildAttachment(filename, blob, {
compressedBlobUrl: resizedUrl,
});
}
if (mimeType === 'image/jpeg') {
filename = filename.replace(FILE_EXT_REGEX, '.jpg');
}
quick = { width, height };
}
if (mimeType === 'image/jpeg') {
filename = filename.replace(FILE_EXT_REGEX, '.jpg');
}
quick = { width, height };
previewBlobUrl = blobUrl;
} else if (SUPPORTED_VIDEO_CONTENT_TYPES.has(mimeType)) {
const { videoWidth: width, videoHeight: height, duration } = await preloadVideo(blobUrl);
quick = { width, height, duration };
shouldSendAsFile = !validateAspectRatio(width, height);
if (!shouldSendAsFile) {
quick = { width, height, duration };
}
previewBlobUrl = await createPosterForVideo(blobUrl);
} else if (SUPPORTED_AUDIO_CONTENT_TYPES.has(mimeType)) {
@ -72,6 +83,7 @@ export default async function buildAttachment(
quick,
audio,
previewBlobUrl,
shouldSendAsFile: shouldSendAsFile || undefined,
uniqueId: `${Date.now()}-${Math.random()}`,
...options,
};
@ -98,3 +110,8 @@ export function prepareAttachmentsToSend(
};
});
}
function validateAspectRatio(width: number, height: number) {
const maxAspectRatio = Math.max(width, height) / Math.min(width, height);
return maxAspectRatio <= MAX_ASPECT_RATIO;
}

View File

@ -108,6 +108,8 @@ export default function useAttachmentModal({
}
function getAttachmentType(attachment: ApiAttachment) {
if (attachment.shouldSendAsFile) return 'file';
if (SUPPORTED_IMAGE_CONTENT_TYPES.has(attachment.mimeType)) {
return 'image';
}