|
@@ -0,0 +1,141 @@
|
|
|
|
+const Plugin = require('../Plugin')
|
|
|
|
+const StatusBar = require('./StatusBar')
|
|
|
|
+const { getSpeed } = require('../../core/Utils')
|
|
|
|
+const { getBytesRemaining } = require('../../core/Utils')
|
|
|
|
+const { prettyETA } = require('../../core/Utils')
|
|
|
|
+const prettyBytes = require('prettier-bytes')
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * A status bar.
|
|
|
|
+ */
|
|
|
|
+module.exports = class StatusBarUI extends Plugin {
|
|
|
|
+ constructor (core, opts) {
|
|
|
|
+ super(core, opts)
|
|
|
|
+ this.id = 'StatusBarUI'
|
|
|
|
+ this.title = 'StatusBar UI'
|
|
|
|
+ this.type = 'progressindicator'
|
|
|
|
+
|
|
|
|
+ // set default options
|
|
|
|
+ const defaultOptions = {
|
|
|
|
+ target: 'body',
|
|
|
|
+ showProgressDetails: false
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // merge default options with the ones set by user
|
|
|
|
+ this.opts = Object.assign({}, defaultOptions, opts)
|
|
|
|
+
|
|
|
|
+ this.pauseAll = this.pauseAll.bind(this)
|
|
|
|
+ this.resumeAll = this.resumeAll.bind(this)
|
|
|
|
+ this.cancelAll = this.cancelAll.bind(this)
|
|
|
|
+ this.render = this.render.bind(this)
|
|
|
|
+ this.install = this.install.bind(this)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cancelAll () {
|
|
|
|
+ this.core.bus.emit('core:cancel-all')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pauseAll () {
|
|
|
|
+ this.core.bus.emit('core:pause-all')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ resumeAll () {
|
|
|
|
+ this.core.bus.emit('core:resume-all')
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getTotalSpeed (files) {
|
|
|
|
+ let totalSpeed = 0
|
|
|
|
+ files.forEach((file) => {
|
|
|
|
+ totalSpeed = totalSpeed + getSpeed(file.progress)
|
|
|
|
+ })
|
|
|
|
+ return totalSpeed
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getTotalETA (files) {
|
|
|
|
+ const totalSpeed = this.getTotalSpeed(files)
|
|
|
|
+ if (totalSpeed === 0) {
|
|
|
|
+ return 0
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const totalBytesRemaining = files.reduce((total, file) => {
|
|
|
|
+ return total + getBytesRemaining(file.progress)
|
|
|
|
+ }, 0)
|
|
|
|
+
|
|
|
|
+ return Math.round(totalBytesRemaining / totalSpeed * 10) / 10
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ render (state) {
|
|
|
|
+ const files = state.files
|
|
|
|
+
|
|
|
|
+ const uploadStartedFiles = Object.keys(files).filter((file) => {
|
|
|
|
+ return files[file].progress.uploadStarted
|
|
|
|
+ })
|
|
|
|
+ const completeFiles = Object.keys(files).filter((file) => {
|
|
|
|
+ return files[file].progress.uploadComplete
|
|
|
|
+ })
|
|
|
|
+ const inProgressFiles = Object.keys(files).filter((file) => {
|
|
|
|
+ return !files[file].progress.uploadComplete &&
|
|
|
|
+ files[file].progress.uploadStarted &&
|
|
|
|
+ !files[file].isPaused
|
|
|
|
+ })
|
|
|
|
+ const processingFiles = Object.keys(files).filter((file) => {
|
|
|
|
+ return files[file].progress.preprocess || files[file].progress.postprocess
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ let inProgressFilesArray = []
|
|
|
|
+ inProgressFiles.forEach((file) => {
|
|
|
|
+ inProgressFilesArray.push(files[file])
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ const totalSpeed = prettyBytes(this.getTotalSpeed(inProgressFilesArray))
|
|
|
|
+ const totalETA = prettyETA(this.getTotalETA(inProgressFilesArray))
|
|
|
|
+
|
|
|
|
+ // total size and uploaded size
|
|
|
|
+ let totalSize = 0
|
|
|
|
+ let totalUploadedSize = 0
|
|
|
|
+ inProgressFilesArray.forEach((file) => {
|
|
|
|
+ totalSize = totalSize + (file.progress.bytesTotal || 0)
|
|
|
|
+ totalUploadedSize = totalUploadedSize + (file.progress.bytesUploaded || 0)
|
|
|
|
+ })
|
|
|
|
+ totalSize = prettyBytes(totalSize)
|
|
|
|
+ totalUploadedSize = prettyBytes(totalUploadedSize)
|
|
|
|
+
|
|
|
|
+ const isAllComplete = state.totalProgress === 100 &&
|
|
|
|
+ completeFiles.length === Object.keys(files).length &&
|
|
|
|
+ processingFiles.length === 0
|
|
|
|
+ const isAllPaused = inProgressFiles.length === 0 && !isAllComplete && uploadStartedFiles.length > 0
|
|
|
|
+ const isUploadStarted = uploadStartedFiles.length > 0
|
|
|
|
+
|
|
|
|
+ const resumableUploads = this.core.getState().capabilities.resumableUploads || false
|
|
|
|
+
|
|
|
|
+ return StatusBar({
|
|
|
|
+ error: state.error,
|
|
|
|
+ totalProgress: state.totalProgress,
|
|
|
|
+ totalSize: totalSize,
|
|
|
|
+ totalUploadedSize: totalUploadedSize,
|
|
|
|
+ uploadStartedFiles: uploadStartedFiles,
|
|
|
|
+ isAllComplete: isAllComplete,
|
|
|
|
+ isAllPaused: isAllPaused,
|
|
|
|
+ isUploadStarted: isUploadStarted,
|
|
|
|
+ pauseAll: this.pauseAll,
|
|
|
|
+ resumeAll: this.resumeAll,
|
|
|
|
+ cancelAll: this.cancelAll,
|
|
|
|
+ complete: completeFiles.length,
|
|
|
|
+ inProgress: uploadStartedFiles.length,
|
|
|
|
+ totalSpeed: totalSpeed,
|
|
|
|
+ totalETA: totalETA,
|
|
|
|
+ files: state.files,
|
|
|
|
+ resumableUploads: resumableUploads
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ install () {
|
|
|
|
+ const target = this.opts.target
|
|
|
|
+ const plugin = this
|
|
|
|
+ this.target = this.mount(target, plugin)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ uninstall () {
|
|
|
|
+ this.unmount()
|
|
|
|
+ }
|
|
|
|
+}
|