1 import * as React from 'react';
3 import { FileIcon, FileNameDisplay, Loader } from '@proton/components';
4 import humanSize, { shortHumanSize } from '@proton/shared/lib/helpers/humanSize';
5 import clsx from '@proton/utils/clsx';
11 isTransferInitializing,
16 } from '../../utils/transfer';
17 import ProgressBar from './ProgressBar';
18 import TransferControls from './TransferControls';
19 import TransferStateIndicator from './TransferStateIndicator';
20 import type { TransferProps } from './interfaces';
21 import { TransferType } from './transfer';
23 type Props<T extends TransferType> = React.HTMLAttributes<HTMLDivElement> &
31 const Transfer = <T extends TransferType>({ stats, transfer, type, className, ...rest }: Props<T>) => {
32 const isInitializing = isTransferInitializing(transfer);
33 const isNameUnresolved = isInitializing || isTransferPending(transfer);
34 const isProgress = isTransferProgress(transfer);
35 const isPaused = isTransferPaused(transfer);
36 const isCanceled = isTransferCanceled(transfer);
37 const isSkipped = isTransferSkipped(transfer);
38 const isDone = isTransferDone(transfer);
40 const fileSize = transfer.meta.size;
41 const progressLimit = fileSize || 1;
42 const percentageDone = isDone ? 100 : !fileSize ? 0 : Math.floor(100 * (stats.progress / fileSize));
44 const progress = isDone ? progressLimit : stats.progress;
45 const speed = humanSize({ bytes: stats.speed });
47 const isUploadingFolder = type === TransferType.Upload && transfer.meta.mimeType === 'Folder';
52 'transfers-manager-list-item p-4',
53 (isCanceled || isSkipped) && 'transfers-manager-list-item--canceled',
56 data-testid="transfer-item-row"
59 <div className="transfers-manager-list-item-name flex flex-nowrap items-center text-ellipsis">
60 <span className="transfers-manager-list-item-icon flex shrink-0 mr-2">
61 {isInitializing ? <Loader size="small" /> : <FileIcon mimeType={transfer.meta.mimeType} />}
63 <span className={clsx(['flex', isNameUnresolved && 'color-weak'])} data-testid="transfer-item-name">
64 <FileNameDisplay text={transfer.meta.filename} />
68 {!isUploadingFolder && (
69 <div className="transfers-manager-list-item-size text-right text-ellipsis" title={`${percentageDone}%`}>
70 {(isProgress || isPaused) && progress > 0 && (
71 <span className="hidden lg:inline">{shortHumanSize(progress)} / </span>
73 {fileSize !== undefined
74 ? shortHumanSize(fileSize)
75 : isProgress && <Loader className="inline" size="small" />}
79 <div className="transfers-manager-list-item-status flex flex-nowrap items-center justify-end text-ellipsis">
80 <TransferStateIndicator transfer={transfer} type={type} speed={speed} />
83 <TransferControls transfer={transfer} type={type} />
86 status={getProgressBarStatus(transfer.state)}
87 aria-describedby={transfer.id}
88 value={isCanceled ? 0 : progress}
95 export default Transfer;