1 import { c } from 'ttag';
3 import type { IconName } from '@proton/components';
4 import { Icon, Tooltip } from '@proton/components';
5 import clsx from '@proton/utils/clsx';
11 isTransferManuallyPaused,
13 } from '../../utils/transfer';
14 import type { Download, Upload } from './transfer';
15 import { TransferState, TransferType } from './transfer';
18 transfer: Upload | Download;
23 const getErrorText = (error: any) => {
24 if (error?.data?.Error) {
25 return error.data.Error;
27 return error?.message || c('Info').t`Something went wrong, please try again later.`;
30 const TransferStateIndicator = ({ transfer, type, speed }: Props) => {
31 const shouldShowDirection =
32 isTransferProgress(transfer) ||
33 isTransferManuallyPaused(transfer) ||
34 isTransferCanceled(transfer) ||
35 isTransferDone(transfer);
37 const statuses: { [key in TransferState]: { text: string; icon?: IconName } } = {
38 [TransferState.Initializing]: {
39 text: c('Info').t`Initializing`,
41 [TransferState.Conflict]: {
42 text: c('Info').t`Conflict`,
44 [TransferState.Pending]: {
45 text: c('Info').t`Queued`,
48 [TransferState.Progress]: {
50 type === TransferType.Upload && transfer.meta.mimeType === 'Folder'
51 ? c('Info').t`Creating`
52 : c('Info').t`${speed}/s`,
53 icon: type === TransferType.Download ? 'arrow-down-line' : 'arrow-up-line',
55 [TransferState.Paused]: {
56 text: c('Info').t`Paused`,
59 [TransferState.Done]: {
60 text: type === TransferType.Download ? c('Info').t`Downloaded` : c('Info').t`Uploaded`,
63 [TransferState.Error]: {
64 text: c('Info').t`Failed`,
65 icon: 'exclamation-circle',
67 [TransferState.SignatureIssue]: {
68 text: c('Info').t`Signature issue`,
70 [TransferState.ScanIssue]: {
71 text: c('Info').t`Scan issue`,
73 [TransferState.NetworkError]: {
74 text: c('Info').t`Network issue`,
75 icon: 'exclamation-circle',
77 [TransferState.Skipped]: {
78 text: c('Info').t`Skipped`,
81 [TransferState.Canceled]: {
82 text: c('Info').t`Canceled`,
85 [TransferState.Finalizing]: {
86 text: c('Info').t`Finalizing`,
91 const statusInfo = statuses[transfer.state];
93 const progressTitle = type === TransferType.Download ? c('Info').t`Downloading` : c('Info').t`Uploading`;
94 const transferTitle = isTransferProgress(transfer) ? progressTitle : statusInfo.text;
95 const errorText = transfer.error && getErrorText(transfer.error);
100 'text-ellipsis flex *:min-size-auto items-center flex-nowrap',
101 isTransferManuallyPaused(transfer) && 'color-info',
102 isTransferDone(transfer) && 'color-success',
103 isTransferError(transfer) && 'color-danger',
106 title={transferTitle}
109 {statusInfo.icon && !isTransferProgress(transfer) && (
110 <Tooltip title={errorText} originalPlacement="top">
111 <span className="shrink-0 md:hidden">
112 <Icon name={errorText ? 'info-circle' : statusInfo.icon} alt={statusInfo.text} />
118 <span className="hidden md:inline-flex text-ellipsis" data-testid="transfer-item-status">
120 <Tooltip title={errorText} originalPlacement="top">
121 <span className="flex items-center mr-2">
122 <Icon name="info-circle" />
129 {shouldShowDirection && (
131 name={type === TransferType.Download ? 'arrow-down-line' : 'arrow-up-line'}
132 className={clsx(['shrink-0 ml-2', isTransferDone(transfer) && 'md:hidden'])}
137 {/* Hidden Info for screen readers */}
138 <span className="sr-only" aria-atomic="true" aria-live="assertive">
139 {transfer.meta.filename} {transferTitle}
145 export default TransferStateIndicator;