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"; "FileDropZoneTitle" = "Drop files here to send them";
"FileDropZoneQuick" = "in a quick way"; "FileDropZoneQuick" = "in a quick way";
"FileDropZoneNoCompression" = "without compression"; "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"; "GifPickerBlocked" = "Sending GIFs is not allowed in this chat";
"GifPickerEmpty" = "No saved GIFs"; "GifPickerEmpty" = "No saved GIFs";
"AriaCancelPollCreation" = "Cancel poll creation"; "AriaCancelPollCreation" = "Cancel poll creation";

View File

@ -10,8 +10,8 @@ import captureEscKeyListener from '../../../util/captureEscKeyListener';
import buildAttachment from './helpers/buildAttachment'; import buildAttachment from './helpers/buildAttachment';
import getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems'; import getFilesFromDataTransferItems from './helpers/getFilesFromDataTransferItems';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated'; import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
@ -39,12 +39,11 @@ const DROP_LEAVE_TIMEOUT_MS = 150;
const DropArea: FC<OwnProps> = ({ const DropArea: FC<OwnProps> = ({
isOpen, withQuick, onHide, onFileSelect, editingMessage, isOpen, withQuick, onHide, onFileSelect, editingMessage,
}) => { }) => {
const lang = useOldLang(); const lang = useLang();
const { showNotification } = getActions(); const { showNotification } = getActions();
const hideTimeoutRef = useRef<number>(); const hideTimeoutRef = useRef<number>();
const prevWithQuick = usePreviousDeprecated(withQuick); const prevWithQuick = usePreviousDeprecated(withQuick);
const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isOpen); const { shouldRender, transitionClassNames } = useShowTransitionDeprecated(isOpen);
const isInAlbum = editingMessage && editingMessage?.groupedId;
useEffect(() => (isOpen ? captureEscKeyListener(onHide) : undefined), [isOpen, onHide]); useEffect(() => (isOpen ? captureEscKeyListener(onHide) : undefined), [isOpen, onHide]);
@ -56,28 +55,53 @@ const DropArea: FC<OwnProps> = ({
files = files.concat(Array.from(dt.files)); files = files.concat(Array.from(dt.files));
} else if (dt.items && dt.items.length > 0) { } else if (dt.items && dt.items.length > 0) {
const folderFiles = await getFilesFromDataTransferItems(dt.items); 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) { if (folderFiles?.length) {
files = files.concat(folderFiles); 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(); onHide();
onFileSelect(files, withQuick ? false : undefined); onFileSelect(files, withQuick ? false : undefined);
}); });
const handleQuickFilesDrop = useLastCallback((e: React.DragEvent<HTMLDivElement>) => { const handleQuickFilesDrop = useLastCallback(async (e: React.DragEvent<HTMLDivElement>) => {
const { dataTransfer: dt } = e; const { dataTransfer: dt } = e;
if (dt.files && dt.files.length > 0) { 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(); 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 { MEMO_EMPTY_ARRAY } from '../../../../util/memo';
import buildAttachment from '../helpers/buildAttachment'; import buildAttachment from '../helpers/buildAttachment';
import useLang from '../../../../hooks/useLang';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
export default function useAttachmentModal({ export default function useAttachmentModal({
attachments, attachments,
@ -35,7 +35,7 @@ export default function useAttachmentModal({
insertNextText: VoidFunction; insertNextText: VoidFunction;
editedMessage: ApiMessage | undefined; editedMessage: ApiMessage | undefined;
}) { }) {
const lang = useOldLang(); const lang = useLang();
const { openLimitReachedModal, showAllowedMessageTypesNotification, showNotification } = getActions(); const { openLimitReachedModal, showAllowedMessageTypesNotification, showNotification } = getActions();
const [shouldForceAsFile, setShouldForceAsFile] = useState<boolean>(false); const [shouldForceAsFile, setShouldForceAsFile] = useState<boolean>(false);
const [shouldForceCompression, setShouldForceCompression] = useState<boolean>(false); const [shouldForceCompression, setShouldForceCompression] = useState<boolean>(false);
@ -92,7 +92,7 @@ export default function useAttachmentModal({
if (canReplace) { if (canReplace) {
handleSetAttachments([newAttachment]); handleSetAttachments([newAttachment]);
} else { } else {
showNotification({ message: lang('lng_edit_media_album_error') }); showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
} }
} else { } else {
handleSetAttachments([newAttachment]); handleSetAttachments([newAttachment]);
@ -114,7 +114,7 @@ export default function useAttachmentModal({
if (canReplace) { if (canReplace) {
handleSetAttachments([newAttachment]); handleSetAttachments([newAttachment]);
} else { } else {
showNotification({ message: lang('lng_edit_media_album_error') }); showNotification({ message: lang('MediaReplaceInvalidError', undefined, { pluralValue: files.length }) });
} }
} else { } else {
handleSetAttachments([newAttachment]); handleSetAttachments([newAttachment]);

View File

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

View File

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