UNPKG

uppy

Version:

Extensible JavaScript file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Instagram, Dropbox, Google Drive, S3 and more :dog:

159 lines (152 loc) 6.55 kB
const { getETA, getSpeed, prettyETA, getFileNameAndExtension, truncateString, copyToClipboard } = require('../../core/Utils') const prettyBytes = require('prettier-bytes') const FileItemProgress = require('./FileItemProgress') const getFileTypeIcon = require('./getFileTypeIcon') const { iconEdit, iconCopy, iconRetry } = require('./icons') const classNames = require('classnames') const { h } = require('preact') module.exports = function fileItem (props) { const file = props.file const acquirers = props.acquirers const isProcessing = file.progress.preprocess || file.progress.postprocess const isUploaded = file.progress.uploadComplete && !isProcessing && !file.error const uploadInProgressOrComplete = file.progress.uploadStarted || isProcessing const uploadInProgress = (file.progress.uploadStarted && !file.progress.uploadComplete) || isProcessing const isPaused = file.isPaused || false const error = file.error || false const fileName = getFileNameAndExtension(file.meta.name).name const truncatedFileName = props.isWide ? truncateString(fileName, 14) : fileName const onPauseResumeCancelRetry = (ev) => { if (isUploaded) return if (error) { props.retryUpload(file.id) return } if (props.resumableUploads) { props.pauseUpload(file.id) } else { props.cancelUpload(file.id) } } const dashboardItemClass = classNames( 'uppy-DashboardItem', { 'is-inprogress': uploadInProgress }, { 'is-processing': isProcessing }, { 'is-complete': isUploaded }, { 'is-paused': isPaused }, { 'is-error': error }, { 'is-resumable': props.resumableUploads } ) return <li class={dashboardItemClass} id={`uppy_${file.id}`} title={file.meta.name}> <div class="uppy-DashboardItem-preview"> <div class="uppy-DashboardItem-previewInnerWrap" style={{ backgroundColor: getFileTypeIcon(file.type).color }}> {file.preview ? <img alt={file.name} src={file.preview} /> : <div class="uppy-DashboardItem-previewIconWrap"> <span class="uppy-DashboardItem-previewIcon" style={{ color: getFileTypeIcon(file.type).color }}>{getFileTypeIcon(file.type).icon}</span> <svg class="uppy-DashboardItem-previewIconBg" width="72" height="93" viewBox="0 0 72 93"><g><path d="M24.08 5h38.922A2.997 2.997 0 0 1 66 8.003v74.994A2.997 2.997 0 0 1 63.004 86H8.996A2.998 2.998 0 0 1 6 83.01V22.234L24.08 5z" fill="#FFF" /><path d="M24 5L6 22.248h15.007A2.995 2.995 0 0 0 24 19.244V5z" fill="#E4E4E4" /></g></svg> </div> } </div> <div class="uppy-DashboardItem-progress"> {isUploaded ? <div class="uppy-DashboardItem-progressIndicator"> {FileItemProgress({ progress: file.progress.percentage, fileID: file.id })} </div> : <button class="uppy-DashboardItem-progressIndicator" type="button" title={isUploaded ? 'upload complete' : props.resumableUploads ? file.isPaused ? 'resume upload' : 'pause upload' : 'cancel upload' } onclick={onPauseResumeCancelRetry}> {error ? iconRetry() : FileItemProgress({ progress: file.progress.percentage, fileID: file.id }) } </button> } {props.showProgressDetails && <div class="uppy-DashboardItem-progressInfo" title={props.i18n('fileProgress')} aria-label={props.i18n('fileProgress')}> {(!file.isPaused && !isUploaded) && <span>{prettyETA(getETA(file.progress))} ・ ↑ {prettyBytes(getSpeed(file.progress))}/s</span> } </div> } </div> </div> <div class="uppy-DashboardItem-info"> <h4 class="uppy-DashboardItem-name" title={fileName}> {file.uploadURL ? <a href={file.uploadURL} target="_blank"> {file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName} </a> : file.extension ? truncatedFileName + '.' + file.extension : truncatedFileName } </h4> <div class="uppy-DashboardItem-status"> {file.data.size && <div class="uppy-DashboardItem-statusSize">{prettyBytes(file.data.size)}</div>} {file.source && <div class="uppy-DashboardItem-sourceIcon"> {acquirers.map(acquirer => { if (acquirer.id === file.source) return <span title={`${props.i18n('fileSource')}: ${acquirer.name}`}>{acquirer.icon()}</span> })} </div> } </div> {!uploadInProgressOrComplete && <button class="uppy-DashboardItem-edit" type="button" aria-label={props.i18n('editFile')} title={props.i18n('editFile')} onclick={(e) => props.showFileCard(file.id)}> {iconEdit()} </button> } {file.uploadURL && <button class="uppy-DashboardItem-copyLink" type="button" aria-label={props.i18n('copyLink')} title={props.i18n('copyLink')} onclick={() => { copyToClipboard(file.uploadURL, props.i18n('copyLinkToClipboardFallback')) .then(() => { props.log('Link copied to clipboard.') props.info(props.i18n('copyLinkToClipboardSuccess'), 'info', 3000) }) .catch(props.log) }}>{iconCopy()}</button> } </div> <div class="uppy-DashboardItem-action"> {!isUploaded && <button class="uppy-DashboardItem-remove" type="button" aria-label={props.i18n('removeFile')} title={props.i18n('removeFile')} onclick={() => props.removeFile(file.id)}> <svg aria-hidden="true" class="UppyIcon" width="60" height="60" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg"> <path stroke="#FFF" stroke-width="1" fill-rule="nonzero" vector-effect="non-scaling-stroke" d="M30 1C14 1 1 14 1 30s13 29 29 29 29-13 29-29S46 1 30 1z" /> <path fill="#FFF" vector-effect="non-scaling-stroke" d="M42 39.667L39.667 42 30 32.333 20.333 42 18 39.667 27.667 30 18 20.333 20.333 18 30 27.667 39.667 18 42 20.333 32.333 30z" /> </svg> </button> } </div> </li> }