浏览代码

Refactor StatusBar, add Cancel button

Artur Paikin 7 年之前
父节点
当前提交
3257f7dd00
共有 3 个文件被更改,包括 110 次插入88 次删除
  1. 60 79
      src/plugins/StatusBar/StatusBar.js
  2. 8 0
      src/plugins/StatusBar/StatusBarStates.js
  3. 42 9
      src/plugins/StatusBar/index.js

+ 60 - 79
src/plugins/StatusBar/StatusBar.js

@@ -1,46 +1,8 @@
 const throttle = require('lodash.throttle')
 const classNames = require('classnames')
+const statusBarStates = require('./StatusBarStates')
 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) {
   // Collect pre or postprocessing progress states.
   const progresses = []
@@ -88,13 +50,13 @@ function togglePauseResume (props) {
 module.exports = (props) => {
   props = props || {}
 
-  const uploadState = getUploadingState(props, props.files || {})
+  const uploadState = props.uploadState
 
   let progressValue = props.totalProgress
   let progressMode
   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)
     progressMode = progress.mode
     if (progressMode === 'determinate') {
@@ -102,19 +64,19 @@ module.exports = (props) => {
     }
 
     progressBarContent = ProgressBarProcessing(progress)
-  } else if (uploadState === STATE_COMPLETE) {
+  } else if (uploadState === statusBarStates.STATE_COMPLETE) {
     progressBarContent = ProgressBarComplete(props)
-  } else if (uploadState === STATE_UPLOADING) {
+  } else if (uploadState === statusBarStates.STATE_UPLOADING) {
     progressBarContent = ProgressBarUploading(props)
-  } else if (uploadState === STATE_ERROR) {
+  } else if (uploadState === statusBarStates.STATE_ERROR) {
     progressValue = undefined
     progressBarContent = ProgressBarError(props)
   }
 
   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
                            ${progressMode ? 'is-' + progressMode : ''}`
@@ -136,19 +98,30 @@ module.exports = (props) => {
         aria-valuenow={progressValue} />
       {progressBarContent}
       <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 }
+        { uploadState !== statusBarStates.STATE_WAITING && uploadState !== statusBarStates.STATE_COMPLETE
+          ? <CancelBtn {...props} />
+          : null
+        }
       </div>
     </div>
   )
 }
 
 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"
-    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 })}
     onclick={props.startUpload}>
-    {props.inProgress
+    {props.newFiles && props.uploadStarted
       ? props.i18n('uploadXNewFiles', { smart_count: props.newFiles })
       : props.i18n('uploadXFiles', { smart_count: props.newFiles })
     }
@@ -157,11 +130,42 @@ const UploadBtn = (props) => {
 
 const RetryBtn = (props) => {
   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')}
     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 value = Math.round(props.value * 100)
 
@@ -200,11 +204,11 @@ const ProgressBarUploading = (props) => {
 
 const ProgressBarComplete = ({ totalProgress, i18n }) => {
   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">
         <path d="M8.944 17L0 7.865l2.555-2.61 6.39 6.525L20.41 0 23 2.645z" />
       </svg>
-      {i18n('uploadComplete')}
+      {i18n('complete')}
     </div>
   )
 }
@@ -212,7 +216,8 @@ const ProgressBarComplete = ({ totalProgress, i18n }) => {
 const ProgressBarError = ({ error, retryAll, i18n }) => {
   return (
     <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"
         aria-label={error}
         data-microtip-position="top"
@@ -221,27 +226,3 @@ const ProgressBarError = ({ error, retryAll, i18n }) => {
     </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>
-}

+ 8 - 0
src/plugins/StatusBar/StatusBarStates.js

@@ -0,0 +1,8 @@
+module.exports = {
+  'STATE_ERROR': 'error',
+  'STATE_WAITING': 'waiting',
+  'STATE_PREPROCESSING': 'preprocessing',
+  'STATE_UPLOADING': 'uploading',
+  'STATE_POSTPROCESSING': 'postprocessing',
+  'STATE_COMPLETE': 'complete'
+}

+ 42 - 9
src/plugins/StatusBar/index.js

@@ -1,6 +1,7 @@
 const Plugin = require('../../core/Plugin')
 const Translator = require('../../core/Translator')
 const StatusBarUI = require('./StatusBar')
+const statusBarStates = require('./StatusBarStates')
 const { getSpeed } = require('../../core/Utils')
 const { getBytesRemaining } = require('../../core/Utils')
 const { prettyETA } = require('../../core/Utils')
@@ -19,7 +20,7 @@ module.exports = class StatusBar extends Plugin {
     const defaultLocale = {
       strings: {
         uploading: 'Uploading',
-        uploadComplete: 'Upload complete',
+        complete: 'Complete',
         uploadFailed: 'Upload failed',
         pleasePressRetry: 'Please press Retry to upload again',
         paused: 'Paused',
@@ -97,6 +98,37 @@ module.exports = class StatusBar extends Plugin {
     })
   }
 
+  getUploadingState (isAllErrored, isAllComplete, files) {
+    if (isAllErrored) {
+      return statusBarStates.STATE_ERROR
+    }
+
+    if (isAllComplete) {
+      return statusBarStates.STATE_COMPLETE
+    }
+
+    let state = statusBarStates.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 statusBarStates.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 !== statusBarStates.STATE_UPLOADING) {
+        state = statusBarStates.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 !== statusBarStates.STATE_UPLOADING && state !== statusBarStates.STATE_PREPROCESSING) {
+        state = statusBarStates.STATE_POSTPROCESSING
+      }
+    }
+    return state
+  }
+
   render (state) {
     const files = state.files
 
@@ -154,30 +186,31 @@ module.exports = class StatusBar extends Plugin {
       !isAllErrored &&
       uploadStartedFiles.length > 0
 
-    const resumableUploads = this.uppy.getState().capabilities.resumableUploads || false
+    const resumableUploads = state.capabilities.resumableUploads || false
 
     return StatusBarUI({
       error: state.error,
+      uploadState: this.getUploadingState(isAllErrored, isAllComplete, state.files || {}),
       totalProgress: state.totalProgress,
       totalSize: totalSize,
       totalUploadedSize: totalUploadedSize,
-      uploadStartedFiles: uploadStartedFiles,
+      uploadStarted: uploadStartedFiles.length,
       isAllComplete: isAllComplete,
       isAllPaused: isAllPaused,
       isAllErrored: isAllErrored,
       isUploadStarted: isUploadStarted,
+      complete: completeFiles.length,
+      newFiles: newFiles.length,
+      inProgress: inProgressFiles.length,
+      totalSpeed: totalSpeed,
+      totalETA: totalETA,
+      files: state.files,
       i18n: this.i18n,
       pauseAll: this.uppy.pauseAll,
       resumeAll: this.uppy.resumeAll,
       retryAll: this.uppy.retryAll,
       cancelAll: this.uppy.cancelAll,
       startUpload: this.startUpload,
-      complete: completeFiles.length,
-      newFiles: newFiles.length,
-      inProgress: uploadStartedFiles.length,
-      totalSpeed: totalSpeed,
-      totalETA: totalETA,
-      files: state.files,
       resumableUploads: resumableUploads,
       showProgressDetails: this.opts.showProgressDetails,
       hideUploadButton: this.opts.hideUploadButton,