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:

308 lines (271 loc) 9.59 kB
'use strict'; var throttle = require('lodash.throttle'); var _require = require('preact'), h = _require.h; function progressDetails(props) { return h( 'span', null, props.totalProgress || 0, '%\u30FB', props.complete, ' / ', props.inProgress, '\u30FB', props.totalUploadedSize, ' / ', props.totalSize, '\u30FB\u2191 ', props.totalSpeed, '/s\u30FB', props.totalETA ); } var ThrottledProgressDetails = throttle(progressDetails, 500, { leading: true, trailing: true }); var STATE_ERROR = 'error'; var STATE_WAITING = 'waiting'; var STATE_PREPROCESSING = 'preprocessing'; var STATE_UPLOADING = 'uploading'; var STATE_POSTPROCESSING = 'postprocessing'; var STATE_COMPLETE = 'complete'; function getUploadingState(props, files) { if (props.isAllErrored) { return STATE_ERROR; } // If ALL files have been completed, show the completed state. if (props.isAllComplete) { return STATE_COMPLETE; } var state = STATE_WAITING; var fileIDs = Object.keys(files); for (var i = 0; i < fileIDs.length; i++) { var progress = files[fileIDs[i]].progress; // If ANY files are being uploaded right now, show the uploading state. if (progress.uploadStarted && !progress.uploadComplete) { return STATE_UPLOADING; } // If files are being preprocessed AND postprocessed at this time, we show the // preprocess state. If any files are being uploaded we show uploading. if (progress.preprocess && state !== STATE_UPLOADING) { state = STATE_PREPROCESSING; } // If NO files are being preprocessed or uploaded right now, but some files are // being postprocessed, show the postprocess state. if (progress.postprocess && state !== STATE_UPLOADING && state !== STATE_PREPROCESSING) { state = STATE_POSTPROCESSING; } } return state; } function calculateProcessingProgress(files) { // Collect pre or postprocessing progress states. var progresses = []; Object.keys(files).forEach(function (fileID) { var progress = files[fileID].progress; if (progress.preprocess) { progresses.push(progress.preprocess); } if (progress.postprocess) { progresses.push(progress.postprocess); } }); // In the future we should probably do this differently. For now we'll take the // mode and message from the first file… var _progresses$ = progresses[0], mode = _progresses$.mode, message = _progresses$.message; var value = progresses.filter(isDeterminate).reduce(function (total, progress, index, all) { return total + progress.value / all.length; }, 0); function isDeterminate(progress) { return progress.mode === 'determinate'; } return { mode: mode, message: message, value: value }; } function togglePauseResume(props) { if (props.isAllComplete) return; if (!props.resumableUploads) { return props.cancelAll(); } if (props.isAllPaused) { return props.resumeAll(); } return props.pauseAll(); } module.exports = function (props) { props = props || {}; var uploadState = getUploadingState(props, props.files || {}); var progressValue = props.totalProgress; var progressMode = void 0; var progressBarContent = void 0; if (uploadState === STATE_PREPROCESSING || uploadState === STATE_POSTPROCESSING) { var progress = calculateProcessingProgress(props.files); progressMode = progress.mode; if (progressMode === 'determinate') { progressValue = progress.value * 100; } progressBarContent = ProgressBarProcessing(progress); } else if (uploadState === STATE_COMPLETE) { progressBarContent = ProgressBarComplete(props); } else if (uploadState === STATE_UPLOADING) { progressBarContent = ProgressBarUploading(props); } else if (uploadState === STATE_ERROR) { progressValue = undefined; progressBarContent = ProgressBarError(props); } var width = typeof progressValue === 'number' ? progressValue : 100; var isHidden = uploadState === STATE_WAITING && props.hideUploadButton || uploadState === STATE_WAITING && !props.newFiles > 0 || uploadState === STATE_COMPLETE && props.hideAfterFinish; var progressClasses = 'uppy-StatusBar-progress\n ' + (progressMode ? 'is-' + progressMode : ''); return h( 'div', { 'class': 'uppy uppy-StatusBar is-' + uploadState, 'aria-hidden': isHidden }, h('div', { 'class': progressClasses, style: { width: width + '%' }, role: 'progressbar', 'aria-valuemin': '0', 'aria-valuemax': '100', 'aria-valuenow': progressValue }), progressBarContent, h( 'div', { 'class': 'uppy-StatusBar-actions' }, props.newFiles && !props.hideUploadButton ? h(UploadBtn, props) : null, props.error ? h(RetryBtn, props) : null ) ); }; var UploadBtn = function UploadBtn(props) { return h( 'button', { type: 'button', 'class': 'uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--upload', 'aria-label': props.i18n('uploadXFiles', { smart_count: props.newFiles }), onclick: props.startUpload }, props.inProgress ? props.i18n('uploadXNewFiles', { smart_count: props.newFiles }) : props.i18n('uploadXFiles', { smart_count: props.newFiles }) ); }; var RetryBtn = function RetryBtn(props) { return h( 'button', { type: 'button', 'class': 'uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--retry', 'aria-label': props.i18n('retryUpload'), onclick: props.retryAll }, props.i18n('retry') ); }; var ProgressBarProcessing = function ProgressBarProcessing(props) { var value = Math.round(props.value * 100); return h( 'div', { 'class': 'uppy-StatusBar-content' }, props.mode === 'determinate' ? value + '%\u30FB' : '', props.message ); }; var ProgressBarUploading = function ProgressBarUploading(props) { var i18n = props.i18n; return h( 'div', { 'class': 'uppy-StatusBar-content' }, props.isUploadStarted && !props.isAllComplete ? !props.isAllPaused ? h( 'div', { title: 'Uploading' }, h(PauseResumeButtons, props), ' ', i18n('uploading'), ' ', h(ThrottledProgressDetails, props) ) : h( 'div', { title: 'Paused' }, h(PauseResumeButtons, props), ' ', i18n('paused'), '\u30FB', props.totalProgress, '%' ) : null ); }; var ProgressBarComplete = function ProgressBarComplete(_ref) { var totalProgress = _ref.totalProgress, i18n = _ref.i18n; return h( 'div', { 'class': 'uppy-StatusBar-content', role: 'status' }, h( 'span', { title: 'Complete' }, h( 'svg', { 'aria-hidden': 'true', 'class': 'uppy-StatusBar-statusIndicator UppyIcon', width: '18', height: '17', viewBox: '0 0 23 17' }, h('path', { d: 'M8.944 17L0 7.865l2.555-2.61 6.39 6.525L20.41 0 23 2.645z' }) ), i18n('uploadComplete'), '\u30FB', totalProgress, '%' ) ); }; var ProgressBarError = function ProgressBarError(_ref2) { var error = _ref2.error, retryAll = _ref2.retryAll, i18n = _ref2.i18n; return h( 'div', { 'class': 'uppy-StatusBar-content', role: 'alert' }, h( 'strong', null, i18n('uploadFailed'), '.' ), ' ', h( 'span', null, i18n('pleasePressRetry') ), h( 'span', { 'class': 'uppy-StatusBar-details', 'aria-label': error, 'data-microtip-position': 'top', 'data-microtip-size': 'large', role: 'tooltip' }, '?' ) ); }; var PauseResumeButtons = function PauseResumeButtons(props) { var resumableUploads = props.resumableUploads, isAllPaused = props.isAllPaused, i18n = props.i18n; var title = resumableUploads ? isAllPaused ? i18n('resumeUpload') : i18n('pauseUpload') : i18n('cancelUpload'); return h( 'button', { title: title, 'class': 'uppy-StatusBar-statusIndicator', type: 'button', onclick: function onclick() { return togglePauseResume(props); } }, resumableUploads ? isAllPaused ? h( 'svg', { 'aria-hidden': 'true', 'class': 'UppyIcon', width: '15', height: '17', viewBox: '0 0 11 13' }, h('path', { d: 'M1.26 12.534a.67.67 0 0 1-.674.012.67.67 0 0 1-.336-.583v-11C.25.724.38.5.586.382a.658.658 0 0 1 .673.012l9.165 5.5a.66.66 0 0 1 .325.57.66.66 0 0 1-.325.573l-9.166 5.5z' }) ) : h( 'svg', { 'aria-hidden': 'true', 'class': 'UppyIcon', width: '16', height: '17', viewBox: '0 0 12 13' }, h('path', { d: 'M4.888.81v11.38c0 .446-.324.81-.722.81H2.722C2.324 13 2 12.636 2 12.19V.81c0-.446.324-.81.722-.81h1.444c.398 0 .722.364.722.81zM9.888.81v11.38c0 .446-.324.81-.722.81H7.722C7.324 13 7 12.636 7 12.19V.81c0-.446.324-.81.722-.81h1.444c.398 0 .722.364.722.81z' }) ) : h( 'svg', { 'aria-hidden': 'true', 'class': 'UppyIcon', width: '16px', height: '16px', viewBox: '0 0 19 19' }, h('path', { d: 'M17.318 17.232L9.94 9.854 9.586 9.5l-.354.354-7.378 7.378h.707l-.62-.62v.706L9.318 9.94l.354-.354-.354-.354L1.94 1.854v.707l.62-.62h-.706l7.378 7.378.354.354.354-.354 7.378-7.378h-.707l.622.62v-.706L9.854 9.232l-.354.354.354.354 7.378 7.378.708-.707-7.38-7.378v.708l7.38-7.38.353-.353-.353-.353-.622-.622-.353-.353-.354.352-7.378 7.38h.708L2.56 1.23 2.208.88l-.353.353-.622.62-.353.355.352.353 7.38 7.38v-.708l-7.38 7.38-.353.353.352.353.622.622.353.353.354-.353 7.38-7.38h-.708l7.38 7.38z' }) ) ); }; //# sourceMappingURL=StatusBar.js.map