Drop Area: Show error for multiple files (#5973)

This commit is contained in:
zubiden 2025-06-04 20:41:40 +02:00 committed by Alexander Zinchuk
parent 3cc0fffef4
commit 3dd37f9737
5 changed files with 56 additions and 20 deletions

View File

@ -1318,6 +1318,8 @@
"FileDropZoneTitle" = "Drop files here to send them";
"FileDropZoneQuick" = "in a quick way";
"FileDropZoneNoCompression" = "without compression";
"MediaReplaceInvalidError_one" = "This media cannot be replaced with the selected file";
"MediaReplaceInvalidError_other" = "This media cannot be replaced with the selected files";
"GifPickerBlocked" = "Sending GIFs is not allowed in this chat";
"GifPickerEmpty" = "No saved GIFs";
"AriaCancelPollCreation" = "Cancel poll creation";

View File

@ -10,8 +10,8 @@ import captureEscKeyListener from '../../../util/captureEscKeyListener';
import buildAttachment from './helpers/buildAttachment';
import getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
@ -39,12 +39,11 @@ const DROP_LEAVE_TIMEOUT_MS = 150;
const DropArea: FC<OwnProps> = ({
isOpen, withQuick, onHide, onFileSelect, editingMessage,
}) => {
const lang = useOldLang();
const lang = useLang();
const { showNotification } = getActions();
const hideTimeoutRef = useRef<number>();
const prevWithQuick = usePreviousDeprecated(withQuick);
const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isOpen);
const isInAlbum = editingMessage && editingMessage?.groupedId;
useEffect(() => (isOpen ? captureEscKeyListener(onHide) : undefined), [isOpen, onHide]);
@ -56,28 +55,53 @@ const DropArea: FC<OwnProps> = ({
files = files.concat(Array.from(dt.files));
} else if (dt.items && dt.items.length > 0) {
const folderFiles = await getFilesFromDataTransferItems(dt.items);
const newAttachment = folderFiles && await buildAttachment(folderFiles[0].name, folderFiles[0]);
const canReplace = editingMessage && newAttachment && canReplaceMessageMedia(editingMessage, newAttachment);
if (canReplace) {
showNotification({ message: lang(isInAlbum ? 'lng_edit_media_album_error' : 'lng_edit_media_invalid_file') });
return;
}
if (folderFiles?.length) {
files = files.concat(folderFiles);
}
}
if (editingMessage) {
if (files.length > 1) {
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
return;
}
if (files.length === 1) {
const newAttachment = await buildAttachment(files[0].name, files[0]);
const canReplace = editingMessage && newAttachment && canReplaceMessageMedia(editingMessage, newAttachment);
if (!canReplace) {
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
return;
}
}
}
onHide();
onFileSelect(files, withQuick ? false : undefined);
});
const handleQuickFilesDrop = useLastCallback((e: React.DragEvent<HTMLDivElement>) => {
const handleQuickFilesDrop = useLastCallback(async (e: React.DragEvent<HTMLDivElement>) => {
const { dataTransfer: dt } = e;
if (dt.files && dt.files.length > 0) {
const files = Array.from(dt.files);
if (editingMessage) {
if (files.length > 1) {
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
return;
}
if (files.length === 1) {
const newAttachment = await buildAttachment(files[0].name, files[0]);
const canReplace = editingMessage && newAttachment && canReplaceMessageMedia(editingMessage, newAttachment);
if (!canReplace) {
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
return;
}
}
}
onHide();
onFileSelect(Array.from(dt.files), true);
onFileSelect(files, true);
}
});

View File

@ -7,8 +7,8 @@ import { canReplaceMessageMedia, getAttachmentMediaType } from '../../../../glob
import { MEMO_EMPTY_ARRAY } from '../../../../util/memo';
import buildAttachment from '../helpers/buildAttachment';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
export default function useAttachmentModal({
attachments,
@ -35,7 +35,7 @@ export default function useAttachmentModal({
insertNextText: VoidFunction;
editedMessage: ApiMessage | undefined;
}) {
const lang = useOldLang();
const lang = useLang();
const { openLimitReachedModal, showAllowedMessageTypesNotification, showNotification } = getActions();
const [shouldForceAsFile, setShouldForceAsFile] = useState<boolean>(false);
const [shouldForceCompression, setShouldForceCompression] = useState<boolean>(false);
@ -92,7 +92,7 @@ export default function useAttachmentModal({
if (canReplace) {
handleSetAttachments([newAttachment]);
} else {
showNotification({ message: lang('lng_edit_media_album_error') });
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
}
} else {
handleSetAttachments([newAttachment]);
@ -114,7 +114,7 @@ export default function useAttachmentModal({
if (canReplace) {
handleSetAttachments([newAttachment]);
} else {
showNotification({ message: lang('lng_edit_media_album_error') });
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
}
} else {
handleSetAttachments([newAttachment]);

View File

@ -14,7 +14,7 @@ import buildAttachment from '../helpers/buildAttachment';
import { preparePastedHtml } from '../helpers/cleanHtml';
import getFilesFromDataTransferItems from '../helpers/getFilesFromDataTransferItems';
import useOldLang from '../../../../hooks/useOldLang';
import useLang from '../../../../hooks/useLang';
const TYPE_HTML = 'text/html';
const DOCUMENT_TYPE_WORD = 'urn:schemas-microsoft-com:office:word';
@ -33,7 +33,7 @@ const useClipboardPaste = (
onCustomEmojiStripped?: VoidFunction,
) => {
const { showNotification } = getActions();
const lang = useOldLang();
const lang = useLang();
useEffect(() => {
if (!isActive) {
@ -104,15 +104,24 @@ const useClipboardPaste = (
const isUploadingDocumentSticker = isUploadingFileSticker(newAttachments[0]);
const isInAlbum = editedMessage && editedMessage?.groupedId;
if (editedMessage && newAttachments?.length > 1) {
showNotification({
message: lang('MediaReplaceInvalidError', undefined, { pluralValue: newAttachments.length }),
});
return;
}
if (editedMessage && isUploadingDocumentSticker) {
showNotification({ message: lang(isInAlbum ? 'lng_edit_media_album_error' : 'lng_edit_media_invalid_file') });
showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: 1 }) });
return;
}
if (isInAlbum) {
shouldSetAttachments = canReplace;
if (!shouldSetAttachments) {
showNotification({ message: lang('lng_edit_media_album_error') });
showNotification({
message: lang('MediaReplaceInvalidError', undefined, { pluralValue: newAttachments.length }),
});
return;
}
}

View File

@ -2497,6 +2497,7 @@ export interface LangPairPlural {
'DeleteForMeChatHint': undefined;
'DeleteForEveryoneHint': undefined;
'PreviewDraggingAddItems': undefined;
'MediaReplaceInvalidError': undefined;
}
export interface LangPairPluralWithVariables<V = LangVariable> {