signal-desktop/ts/components/CompositionUpload.tsx

138 lines
4.1 KiB
TypeScript
Raw Normal View History

2021-09-24 20:02:30 +00:00
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { ChangeEventHandler } from 'react';
import React, { forwardRef, useState } from 'react';
2021-09-24 20:02:30 +00:00
import type {
InMemoryAttachmentDraftType,
AttachmentDraftType,
} from '../types/Attachment';
import { isVideoAttachment, isImageAttachment } from '../types/Attachment';
2021-09-24 20:02:30 +00:00
import { AttachmentToastType } from '../types/AttachmentToastType';
import type { LocalizerType } from '../types/Util';
2021-09-24 20:02:30 +00:00
import { ToastCannotMixMultiAndNonMultiAttachments } from './ToastCannotMixMultiAndNonMultiAttachments';
2021-09-24 20:02:30 +00:00
import { ToastDangerousFileType } from './ToastDangerousFileType';
import { ToastFileSize } from './ToastFileSize';
import { ToastMaxAttachments } from './ToastMaxAttachments';
import { ToastUnsupportedMultiAttachment } from './ToastUnsupportedMultiAttachment';
2021-09-24 20:02:30 +00:00
import { ToastUnableToLoadAttachment } from './ToastUnableToLoadAttachment';
import type { HandleAttachmentsProcessingArgsType } from '../util/handleAttachmentsProcessing';
import {
getSupportedImageTypes,
getSupportedVideoTypes,
} from '../util/GoogleChrome';
2021-09-24 20:02:30 +00:00
export type PropsType = {
addAttachment: (
conversationId: string,
attachment: InMemoryAttachmentDraftType
2021-09-24 20:02:30 +00:00
) => unknown;
addPendingAttachment: (
conversationId: string,
pendingAttachment: AttachmentDraftType
2021-09-24 20:02:30 +00:00
) => unknown;
conversationId: string;
draftAttachments: ReadonlyArray<AttachmentDraftType>;
2021-09-24 20:02:30 +00:00
i18n: LocalizerType;
processAttachments: (options: HandleAttachmentsProcessingArgsType) => unknown;
removeAttachment: (conversationId: string, filePath: string) => unknown;
};
export const CompositionUpload = forwardRef<HTMLInputElement, PropsType>(
2022-11-18 00:45:19 +00:00
function CompositionUploadInner(
2021-09-24 20:02:30 +00:00
{
addAttachment,
addPendingAttachment,
conversationId,
draftAttachments,
i18n,
processAttachments,
removeAttachment,
},
ref
2022-11-18 00:45:19 +00:00
) {
2021-09-24 20:02:30 +00:00
const [toastType, setToastType] = useState<
AttachmentToastType | undefined
>();
2022-03-22 20:45:34 +00:00
const onFileInputChange: ChangeEventHandler<
HTMLInputElement
> = async event => {
const files = event.target.files || [];
2021-09-24 20:02:30 +00:00
2022-03-22 20:45:34 +00:00
await processAttachments({
addAttachment,
addPendingAttachment,
conversationId,
files: Array.from(files),
draftAttachments,
onShowToast: setToastType,
removeAttachment,
});
};
2021-09-24 20:02:30 +00:00
function closeToast() {
setToastType(undefined);
}
let toast;
if (toastType === AttachmentToastType.ToastFileSize) {
toast = (
<ToastFileSize
i18n={i18n}
limit={100}
onClose={closeToast}
units="MB"
/>
);
} else if (toastType === AttachmentToastType.ToastDangerousFileType) {
toast = <ToastDangerousFileType i18n={i18n} onClose={closeToast} />;
} else if (toastType === AttachmentToastType.ToastMaxAttachments) {
toast = <ToastMaxAttachments i18n={i18n} onClose={closeToast} />;
} else if (
toastType === AttachmentToastType.ToastUnsupportedMultiAttachment
) {
toast = (
<ToastUnsupportedMultiAttachment i18n={i18n} onClose={closeToast} />
);
2021-09-24 20:02:30 +00:00
} else if (
toastType ===
AttachmentToastType.ToastCannotMixMultiAndNonMultiAttachments
2021-09-24 20:02:30 +00:00
) {
toast = (
<ToastCannotMixMultiAndNonMultiAttachments
2021-09-24 20:02:30 +00:00
i18n={i18n}
onClose={closeToast}
/>
);
} else if (toastType === AttachmentToastType.ToastUnableToLoadAttachment) {
toast = <ToastUnableToLoadAttachment i18n={i18n} onClose={closeToast} />;
}
const anyVideoOrImageAttachments = draftAttachments.some(attachment => {
return isImageAttachment(attachment) || isVideoAttachment(attachment);
});
const acceptContentTypes = anyVideoOrImageAttachments
? [...getSupportedImageTypes(), ...getSupportedVideoTypes()]
: null;
2021-09-24 20:02:30 +00:00
return (
<>
{toast}
<input
hidden
multiple
onChange={onFileInputChange}
ref={ref}
type="file"
accept={acceptContentTypes?.join(',')}
2021-09-24 20:02:30 +00:00
/>
</>
);
}
);