import prettierBytes from '@transloadit/prettier-bytes' import type { Body, Meta, State, Uppy } from '@uppy/core' import type { FileProcessingInfo, I18n } from '@uppy/utils' import { prettyETA } from '@uppy/utils' import classNames from 'classnames' import statusBarStates from './StatusBarStates.js' const DOT = `\u00B7` const renderDot = (): string => ` ${DOT} ` interface UploadBtnProps { newFiles: number isUploadStarted: boolean recoveredState: State['recoveredState'] i18n: I18n uploadState: string isSomeGhost: boolean startUpload: () => void } function UploadBtn( props: UploadBtnProps, ) { const { newFiles, isUploadStarted, recoveredState, i18n, uploadState, isSomeGhost, startUpload, } = props const uploadBtnClassNames = classNames( 'uppy-u-reset', 'uppy-c-btn', 'uppy-StatusBar-actionBtn', 'uppy-StatusBar-actionBtn--upload', { 'uppy-c-btn-primary': uploadState === statusBarStates.STATE_WAITING, }, { 'uppy-StatusBar-actionBtn--disabled': isSomeGhost }, ) const uploadBtnText = newFiles && isUploadStarted && !recoveredState ? i18n('uploadXNewFiles', { smart_count: newFiles }) : i18n('uploadXFiles', { smart_count: newFiles }) return ( ) } interface RetryBtnProps { i18n: I18n uppy: Uppy } function RetryBtn(props: RetryBtnProps) { const { i18n, uppy } = props return ( ) } interface CancelBtnProps { i18n: I18n uppy: Uppy } function CancelBtn( props: CancelBtnProps, ) { const { i18n, uppy } = props return ( ) } interface PauseResumeButtonProps { i18n: I18n uppy: Uppy isAllPaused: boolean isAllComplete: boolean resumableUploads: boolean } function PauseResumeButton( props: PauseResumeButtonProps, ) { const { isAllPaused, i18n, isAllComplete, resumableUploads, uppy } = props const title = isAllPaused ? i18n('resume') : i18n('pause') function togglePauseResume(): void { if (isAllComplete) return if (!resumableUploads) { uppy.cancelAll() return } if (isAllPaused) { uppy.resumeAll() return } uppy.pauseAll() } return ( ) } interface DoneBtnProps { i18n: I18n doneButtonHandler: (() => void) | undefined } function DoneBtn(props: DoneBtnProps) { const { i18n, doneButtonHandler } = props return ( ) } function LoadingSpinner() { return ( ) } interface ProgressBarProcessingProps { progress: FileProcessingInfo } function ProgressBarProcessing(props: ProgressBarProcessingProps) { const { progress } = props const { value, mode, message } = progress const dot = `\u00B7` return (
{mode === 'determinate' ? `${Math.round(value * 100)}% ${dot} ` : ''} {message}
) } interface ProgressDetailsProps { i18n: I18n numUploads: number complete: number totalUploadedSize: number totalSize: number | null totalETA: number | null } function ProgressDetails(props: ProgressDetailsProps) { const { numUploads, complete, totalUploadedSize, totalSize, totalETA, i18n } = props const ifShowFilesUploadedOfTotal = numUploads > 1 const totalUploadedSizeStr = prettierBytes(totalUploadedSize) return (
{ifShowFilesUploadedOfTotal && i18n('filesUploadedOfTotal', { complete, smart_count: numUploads, })} {/* When should we render this dot? 1. .-additionalInfo is shown (happens only on desktops) 2. AND 'filesUploadedOfTotal' was shown */} {ifShowFilesUploadedOfTotal && renderDot()} {totalSize != null ? i18n('dataUploadedOfTotal', { complete: totalUploadedSizeStr, total: prettierBytes(totalSize), }) : i18n('dataUploadedOfUnknown', { complete: totalUploadedSizeStr })} {renderDot()} {totalETA != null && i18n('xTimeLeft', { time: prettyETA(totalETA), })}
) } interface FileUploadCountProps { i18n: I18n complete: number numUploads: number } function FileUploadCount(props: FileUploadCountProps) { const { i18n, complete, numUploads } = props return (
{i18n('filesUploadedOfTotal', { complete, smart_count: numUploads })}
) } interface UploadNewlyAddedFilesProps { i18n: I18n newFiles: number startUpload: () => void } function UploadNewlyAddedFiles(props: UploadNewlyAddedFilesProps) { const { i18n, newFiles, startUpload } = props const uploadBtnClassNames = classNames( 'uppy-u-reset', 'uppy-c-btn', 'uppy-StatusBar-actionBtn', 'uppy-StatusBar-actionBtn--uploadNewlyAdded', ) return (
{i18n('xMoreFilesAdded', { smart_count: newFiles })}
) } interface ProgressBarUploadingProps { i18n: I18n supportsUploadProgress: boolean totalProgress: number hideProgressDetails: boolean | undefined isUploadStarted: boolean isAllComplete: boolean isAllPaused: boolean newFiles: number numUploads: number complete: number totalUploadedSize: number totalSize: number | null totalETA: number | null startUpload: () => void } function ProgressBarUploading(props: ProgressBarUploadingProps) { const { i18n, supportsUploadProgress, totalProgress, hideProgressDetails, isUploadStarted, isAllComplete, isAllPaused, newFiles, numUploads, complete, totalUploadedSize, totalSize, totalETA, startUpload, } = props const showUploadNewlyAddedFiles = newFiles && isUploadStarted if (!isUploadStarted || isAllComplete) { return null } const title = isAllPaused ? i18n('paused') : i18n('uploading') function renderProgressDetails() { if (!isAllPaused && !showUploadNewlyAddedFiles && !hideProgressDetails) { if (supportsUploadProgress) { return ( ) } return ( ) } return null } return (
{!isAllPaused ? : null}
{supportsUploadProgress && totalProgress !== 0 ? `${title}: ${totalProgress}%` : title}
{renderProgressDetails()} {showUploadNewlyAddedFiles ? ( ) : null}
) } interface ProgressBarCompleteProps { i18n: I18n } function ProgressBarComplete(props: ProgressBarCompleteProps) { const { i18n } = props return (
{i18n('complete')}
) } interface ProgressBarErrorProps { i18n: I18n error: any complete: number numUploads: number } function ProgressBarError(props: ProgressBarErrorProps) { const { error, i18n, complete, numUploads } = props function displayErrorAlert(): void { const errorMessage = `${i18n('uploadFailed')} \n\n ${error}` alert(errorMessage) // TODO: move to custom alert implementation } return (
{i18n('uploadFailed')}
) } export { UploadBtn, RetryBtn, CancelBtn, PauseResumeButton, DoneBtn, LoadingSpinner, ProgressDetails, ProgressBarProcessing, ProgressBarError, ProgressBarUploading, ProgressBarComplete, }