|
@@ -1,46 +1,8 @@
|
|
const throttle = require('lodash.throttle')
|
|
const throttle = require('lodash.throttle')
|
|
const classNames = require('classnames')
|
|
const classNames = require('classnames')
|
|
|
|
+const statusBarStates = require('./StatusBarStates')
|
|
const { h } = require('preact')
|
|
const { h } = require('preact')
|
|
|
|
|
|
-const STATE_ERROR = 'error'
|
|
|
|
-const STATE_WAITING = 'waiting'
|
|
|
|
-const STATE_PREPROCESSING = 'preprocessing'
|
|
|
|
-const STATE_UPLOADING = 'uploading'
|
|
|
|
-const STATE_POSTPROCESSING = 'postprocessing'
|
|
|
|
-const 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
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let state = STATE_WAITING
|
|
|
|
- const fileIDs = Object.keys(files)
|
|
|
|
- for (let i = 0; i < fileIDs.length; i++) {
|
|
|
|
- const 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) {
|
|
function calculateProcessingProgress (files) {
|
|
// Collect pre or postprocessing progress states.
|
|
// Collect pre or postprocessing progress states.
|
|
const progresses = []
|
|
const progresses = []
|
|
@@ -88,13 +50,13 @@ function togglePauseResume (props) {
|
|
module.exports = (props) => {
|
|
module.exports = (props) => {
|
|
props = props || {}
|
|
props = props || {}
|
|
|
|
|
|
- const uploadState = getUploadingState(props, props.files || {})
|
|
|
|
|
|
+ const uploadState = props.uploadState
|
|
|
|
|
|
let progressValue = props.totalProgress
|
|
let progressValue = props.totalProgress
|
|
let progressMode
|
|
let progressMode
|
|
let progressBarContent
|
|
let progressBarContent
|
|
- // let progressBarContentDetails
|
|
|
|
- if (uploadState === STATE_PREPROCESSING || uploadState === STATE_POSTPROCESSING) {
|
|
|
|
|
|
+
|
|
|
|
+ if (uploadState === statusBarStates.STATE_PREPROCESSING || uploadState === statusBarStates.STATE_POSTPROCESSING) {
|
|
const progress = calculateProcessingProgress(props.files)
|
|
const progress = calculateProcessingProgress(props.files)
|
|
progressMode = progress.mode
|
|
progressMode = progress.mode
|
|
if (progressMode === 'determinate') {
|
|
if (progressMode === 'determinate') {
|
|
@@ -102,19 +64,19 @@ module.exports = (props) => {
|
|
}
|
|
}
|
|
|
|
|
|
progressBarContent = ProgressBarProcessing(progress)
|
|
progressBarContent = ProgressBarProcessing(progress)
|
|
- } else if (uploadState === STATE_COMPLETE) {
|
|
|
|
|
|
+ } else if (uploadState === statusBarStates.STATE_COMPLETE) {
|
|
progressBarContent = ProgressBarComplete(props)
|
|
progressBarContent = ProgressBarComplete(props)
|
|
- } else if (uploadState === STATE_UPLOADING) {
|
|
|
|
|
|
+ } else if (uploadState === statusBarStates.STATE_UPLOADING) {
|
|
progressBarContent = ProgressBarUploading(props)
|
|
progressBarContent = ProgressBarUploading(props)
|
|
- } else if (uploadState === STATE_ERROR) {
|
|
|
|
|
|
+ } else if (uploadState === statusBarStates.STATE_ERROR) {
|
|
progressValue = undefined
|
|
progressValue = undefined
|
|
progressBarContent = ProgressBarError(props)
|
|
progressBarContent = ProgressBarError(props)
|
|
}
|
|
}
|
|
|
|
|
|
const width = typeof progressValue === 'number' ? progressValue : 100
|
|
const width = typeof progressValue === 'number' ? progressValue : 100
|
|
- const isHidden = (uploadState === STATE_WAITING && props.hideUploadButton) ||
|
|
|
|
- (uploadState === STATE_WAITING && !props.newFiles > 0) ||
|
|
|
|
- (uploadState === STATE_COMPLETE && props.hideAfterFinish)
|
|
|
|
|
|
+ const isHidden = (uploadState === statusBarStates.STATE_WAITING && props.hideUploadButton) ||
|
|
|
|
+ (uploadState === statusBarStates.STATE_WAITING && !props.newFiles > 0) ||
|
|
|
|
+ (uploadState === statusBarStates.STATE_COMPLETE && props.hideAfterFinish)
|
|
|
|
|
|
const progressClassNames = `uppy-StatusBar-progress
|
|
const progressClassNames = `uppy-StatusBar-progress
|
|
${progressMode ? 'is-' + progressMode : ''}`
|
|
${progressMode ? 'is-' + progressMode : ''}`
|
|
@@ -136,19 +98,30 @@ module.exports = (props) => {
|
|
aria-valuenow={progressValue} />
|
|
aria-valuenow={progressValue} />
|
|
{progressBarContent}
|
|
{progressBarContent}
|
|
<div class="uppy-StatusBar-actions">
|
|
<div class="uppy-StatusBar-actions">
|
|
- { props.newFiles && !props.hideUploadButton ? <UploadBtn {...props} /> : null }
|
|
|
|
|
|
+ { props.newFiles && !props.hideUploadButton ? <UploadBtn {...props} uploadState={uploadState} /> : null }
|
|
{ props.error ? <RetryBtn {...props} /> : null }
|
|
{ props.error ? <RetryBtn {...props} /> : null }
|
|
|
|
+ { uploadState !== statusBarStates.STATE_WAITING && uploadState !== statusBarStates.STATE_COMPLETE
|
|
|
|
+ ? <CancelBtn {...props} />
|
|
|
|
+ : null
|
|
|
|
+ }
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|
|
}
|
|
}
|
|
|
|
|
|
const UploadBtn = (props) => {
|
|
const UploadBtn = (props) => {
|
|
|
|
+ const uploadBtnClassNames = classNames(
|
|
|
|
+ 'uppy-u-reset',
|
|
|
|
+ 'uppy-c-btn',
|
|
|
|
+ { 'uppy-c-btn-primary': props.uploadState === statusBarStates.STATE_WAITING },
|
|
|
|
+ { 'uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--upload': props.uploadState !== statusBarStates.STATE_WAITING }
|
|
|
|
+ )
|
|
|
|
+
|
|
return <button type="button"
|
|
return <button type="button"
|
|
- class="uppy-u-reset uppy-c-buttonLarge uppy-c-buttonLarge--blue uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--upload"
|
|
|
|
|
|
+ class={uploadBtnClassNames}
|
|
aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
|
|
aria-label={props.i18n('uploadXFiles', { smart_count: props.newFiles })}
|
|
onclick={props.startUpload}>
|
|
onclick={props.startUpload}>
|
|
- {props.inProgress
|
|
|
|
|
|
+ {props.newFiles && props.uploadStarted
|
|
? props.i18n('uploadXNewFiles', { smart_count: props.newFiles })
|
|
? props.i18n('uploadXNewFiles', { smart_count: props.newFiles })
|
|
: props.i18n('uploadXFiles', { smart_count: props.newFiles })
|
|
: props.i18n('uploadXFiles', { smart_count: props.newFiles })
|
|
}
|
|
}
|
|
@@ -157,11 +130,42 @@ const UploadBtn = (props) => {
|
|
|
|
|
|
const RetryBtn = (props) => {
|
|
const RetryBtn = (props) => {
|
|
return <button type="button"
|
|
return <button type="button"
|
|
- class="uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--retry"
|
|
|
|
|
|
+ class="uppy-u-reset uppy-c-btn uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--retry"
|
|
aria-label={props.i18n('retryUpload')}
|
|
aria-label={props.i18n('retryUpload')}
|
|
onclick={props.retryAll}>{props.i18n('retry')}</button>
|
|
onclick={props.retryAll}>{props.i18n('retry')}</button>
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const CancelBtn = (props) => {
|
|
|
|
+ return <button type="button"
|
|
|
|
+ class="uppy-u-reset uppy-c-btn uppy-StatusBar-actionBtn uppy-StatusBar-actionBtn--cancel"
|
|
|
|
+ aria-label={props.i18n('cancel')}
|
|
|
|
+ onclick={props.cancelAll}>Cancel{props.i18n('cancel')}</button>
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+const PauseResumeButtons = (props) => {
|
|
|
|
+ const { resumableUploads, isAllPaused, i18n } = props
|
|
|
|
+ const title = resumableUploads
|
|
|
|
+ ? isAllPaused
|
|
|
|
+ ? i18n('resumeUpload')
|
|
|
|
+ : i18n('pauseUpload')
|
|
|
|
+ : i18n('cancelUpload')
|
|
|
|
+
|
|
|
|
+ return <button title={title} class="uppy-u-reset uppy-StatusBar-statusIndicator" type="button" onclick={() => togglePauseResume(props)}>
|
|
|
|
+ {resumableUploads
|
|
|
|
+ ? isAllPaused
|
|
|
|
+ ? <svg aria-hidden="true" class="UppyIcon" width="15" height="17" viewBox="0 0 11 13">
|
|
|
|
+ <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" />
|
|
|
|
+ </svg>
|
|
|
|
+ : <svg aria-hidden="true" class="UppyIcon" width="16" height="17" viewBox="0 0 12 13">
|
|
|
|
+ <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" />
|
|
|
|
+ </svg>
|
|
|
|
+ : <svg aria-hidden="true" class="UppyIcon" width="16px" height="16px" viewBox="0 0 19 19">
|
|
|
|
+ <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" />
|
|
|
|
+ </svg>
|
|
|
|
+ }
|
|
|
|
+ </button>
|
|
|
|
+}
|
|
|
|
+
|
|
const ProgressBarProcessing = (props) => {
|
|
const ProgressBarProcessing = (props) => {
|
|
const value = Math.round(props.value * 100)
|
|
const value = Math.round(props.value * 100)
|
|
|
|
|
|
@@ -200,11 +204,11 @@ const ProgressBarUploading = (props) => {
|
|
|
|
|
|
const ProgressBarComplete = ({ totalProgress, i18n }) => {
|
|
const ProgressBarComplete = ({ totalProgress, i18n }) => {
|
|
return (
|
|
return (
|
|
- <div class="uppy-StatusBar-content" role="status" title="Complete">
|
|
|
|
|
|
+ <div class="uppy-StatusBar-content" role="status" title={i18n('complete')}>
|
|
<svg aria-hidden="true" class="uppy-StatusBar-statusIndicator UppyIcon" width="18" height="17" viewBox="0 0 23 17">
|
|
<svg aria-hidden="true" class="uppy-StatusBar-statusIndicator UppyIcon" width="18" height="17" viewBox="0 0 23 17">
|
|
<path d="M8.944 17L0 7.865l2.555-2.61 6.39 6.525L20.41 0 23 2.645z" />
|
|
<path d="M8.944 17L0 7.865l2.555-2.61 6.39 6.525L20.41 0 23 2.645z" />
|
|
</svg>
|
|
</svg>
|
|
- {i18n('uploadComplete')}
|
|
|
|
|
|
+ {i18n('complete')}
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|
|
}
|
|
}
|
|
@@ -212,7 +216,8 @@ const ProgressBarComplete = ({ totalProgress, i18n }) => {
|
|
const ProgressBarError = ({ error, retryAll, i18n }) => {
|
|
const ProgressBarError = ({ error, retryAll, i18n }) => {
|
|
return (
|
|
return (
|
|
<div class="uppy-StatusBar-content" role="alert">
|
|
<div class="uppy-StatusBar-content" role="alert">
|
|
- <strong>{i18n('uploadFailed')}.</strong> <span>{i18n('pleasePressRetry')}</span>
|
|
|
|
|
|
+ <strong>{i18n('uploadFailed')}.</strong>
|
|
|
|
+ <span>{i18n('pleasePressRetry')}</span>
|
|
<span class="uppy-StatusBar-details"
|
|
<span class="uppy-StatusBar-details"
|
|
aria-label={error}
|
|
aria-label={error}
|
|
data-microtip-position="top"
|
|
data-microtip-position="top"
|
|
@@ -221,27 +226,3 @@ const ProgressBarError = ({ error, retryAll, i18n }) => {
|
|
</div>
|
|
</div>
|
|
)
|
|
)
|
|
}
|
|
}
|
|
-
|
|
|
|
-const PauseResumeButtons = (props) => {
|
|
|
|
- const { resumableUploads, isAllPaused, i18n } = props
|
|
|
|
- const title = resumableUploads
|
|
|
|
- ? isAllPaused
|
|
|
|
- ? i18n('resumeUpload')
|
|
|
|
- : i18n('pauseUpload')
|
|
|
|
- : i18n('cancelUpload')
|
|
|
|
-
|
|
|
|
- return <button title={title} class="uppy-StatusBar-statusIndicator" type="button" onclick={() => togglePauseResume(props)}>
|
|
|
|
- {resumableUploads
|
|
|
|
- ? isAllPaused
|
|
|
|
- ? <svg aria-hidden="true" class="UppyIcon" width="15" height="17" viewBox="0 0 11 13">
|
|
|
|
- <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" />
|
|
|
|
- </svg>
|
|
|
|
- : <svg aria-hidden="true" class="UppyIcon" width="16" height="17" viewBox="0 0 12 13">
|
|
|
|
- <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" />
|
|
|
|
- </svg>
|
|
|
|
- : <svg aria-hidden="true" class="UppyIcon" width="16px" height="16px" viewBox="0 0 19 19">
|
|
|
|
- <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" />
|
|
|
|
- </svg>
|
|
|
|
- }
|
|
|
|
- </button>
|
|
|
|
-}
|
|
|