import {
ComponentPropsWithoutRef,
CSSProperties,
memo,
ReactElement,
useMemo,
useState,
} from 'react';
import {AnimatePresence, m} from 'framer-motion';
import {FileTypeIcon} from '@common/uploads/file-type-icon/file-type-icon';
import {prettyBytes} from '@common/uploads/utils/pretty-bytes';
import {IconButton} from '@common/ui/buttons/icon-button';
import {CloseIcon} from '@common/icons/material/Close';
import {ProgressCircle} from '@common/ui/progress/progress-circle';
import {CheckCircleIcon} from '@common/icons/material/CheckCircle';
import {UploadedFile} from '@common/uploads/uploaded-file';
import {useFileUploadStore} from '@common/uploads/uploader/file-upload-provider';
import {Trans} from '@common/i18n/trans';
import {MixedText} from '@common/i18n/mixed-text';
import {Tooltip} from '@common/ui/tooltip/tooltip';
import {ErrorIcon} from '@common/icons/material/Error';
import {WarningIcon} from '@common/icons/material/Warning';
import {message} from '@common/i18n/message';
interface UploadQueueProps {
file: UploadedFile;
style: CSSProperties;
}
export const UploadQueueItem = memo(({file, style}: UploadQueueProps) => {
return (
);
});
interface SizeInfoProps {
file: UploadedFile;
}
function SizeInfo({file}: SizeInfoProps) {
const fileUpload = useFileUploadStore(s => s.fileUploads.get(file.id));
const bytesUploaded = fileUpload?.bytesUploaded || 0;
const totalBytes = useMemo(() => prettyBytes(file.size), [file]);
const uploadedBytes = useMemo(
() => prettyBytes(bytesUploaded),
[bytesUploaded]
);
let statusMessage: ReactElement;
if (fileUpload?.status === 'completed') {
statusMessage = ;
} else if (fileUpload?.status === 'aborted') {
statusMessage = ;
} else if (fileUpload?.status === 'failed') {
statusMessage = ;
} else {
statusMessage = (
);
}
return {statusMessage}
;
}
interface FileStatusProps {
file: UploadedFile;
}
function FileStatus({file}: FileStatusProps) {
const fileUpload = useFileUploadStore(s => s.fileUploads.get(file.id));
const abortUpload = useFileUploadStore(s => s.abortUpload);
const percentage = fileUpload?.percentage || 0;
const status = fileUpload?.status;
const errorMessage = fileUpload?.errorMessage;
const [isHovered, setIsHovered] = useState(false);
const abortButton = (
{
abortUpload(file.id);
}}
>
);
const progressButton = (
);
let statusButton: ReactElement;
if (status === 'failed') {
const errMessage =
errorMessage || message('This file could not be uploaded');
statusButton = (
}>
);
} else if (status === 'aborted') {
statusButton = (
);
} else if (status === 'completed') {
statusButton = (
);
} else {
statusButton = (
{
if (e.pointerType === 'mouse') {
setIsHovered(true);
}
}}
onPointerLeave={e => {
if (e.pointerType === 'mouse') {
setIsHovered(false);
}
}}
>
{isHovered ? abortButton : progressButton}
);
}
return {statusButton};
}
interface AnimatedStatusProps
extends Omit<
ComponentPropsWithoutRef<'div'>,
'onAnimationStart' | 'onDragStart' | 'onDragEnd' | 'onDrag'
> {
children: ReactElement;
}
function AnimatedStatus({children, ...domProps}: AnimatedStatusProps) {
return (
{children}
);
}