import React, { useEffect } from 'react'; import { Box, Chip, Icon, IconButton, Icons, Text, color, config, toRem } from 'folds'; import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard'; import { UploadStatus, UploadSuccess, useBindUploadAtom } from '../../state/upload'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { TUploadContent } from '../../utils/matrix'; import { bytesToSize, getFileTypeIcon } from '../../utils/common'; import { roomUploadAtomFamily, TUploadItem, TUploadMetadata, } from '../../state/room/roomInputDrafts'; import { useObjectURL } from '../../hooks/useObjectURL'; import { useMediaConfig } from '../../hooks/useMediaConfig'; type ImagePreviewProps = { fileItem: TUploadItem; onSpoiler: (marked: boolean) => void }; function ImagePreview({ fileItem, onSpoiler }: ImagePreviewProps) { const { originalFile, metadata } = fileItem; const fileUrl = useObjectURL(originalFile); return fileUrl ? ( {originalFile.name} } onClick={() => onSpoiler(!metadata.markedAsSpoiler)} > Spoiler ) : null; } type UploadCardRendererProps = { isEncrypted?: boolean; fileItem: TUploadItem; setMetadata: (fileItem: TUploadItem, metadata: TUploadMetadata) => void; onRemove: (file: TUploadContent) => void; onComplete?: (upload: UploadSuccess) => void; }; export function UploadCardRenderer({ isEncrypted, fileItem, setMetadata, onRemove, onComplete, }: UploadCardRendererProps) { const mx = useMatrixClient(); const mediaConfig = useMediaConfig(); const allowSize = mediaConfig['m.upload.size'] || Infinity; const uploadAtom = roomUploadAtomFamily(fileItem.file); const { metadata } = fileItem; const { upload, startUpload, cancelUpload } = useBindUploadAtom(mx, uploadAtom, isEncrypted); const { file } = upload; const fileSizeExceeded = file.size >= allowSize; if (upload.status === UploadStatus.Idle && !fileSizeExceeded) { startUpload(); } const handleSpoiler = (marked: boolean) => { setMetadata(fileItem, { ...metadata, markedAsSpoiler: marked }); }; const removeUpload = () => { cancelUpload(); onRemove(file); }; useEffect(() => { if (upload.status === UploadStatus.Success) { onComplete?.(upload); } }, [upload, onComplete]); return ( } after={ <> {upload.status === UploadStatus.Error && ( Retry )} } bottom={ <> {fileItem.originalFile.type.startsWith('image') && ( )} {upload.status === UploadStatus.Idle && !fileSizeExceeded && ( )} {upload.status === UploadStatus.Loading && ( )} {upload.status === UploadStatus.Error && ( {upload.error.message} )} {upload.status === UploadStatus.Idle && fileSizeExceeded && ( The file size exceeds the limit. Maximum allowed size is{' '} {bytesToSize(allowSize)}, but the uploaded file is{' '} {bytesToSize(file.size)}. )} } > {file.name} {upload.status === UploadStatus.Success && ( )} ); }