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
JavaScript
'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