Skip to content

Commit

Permalink
feat: upload queue
Browse files Browse the repository at this point in the history
  • Loading branch information
ramiresviana committed Jul 10, 2020
1 parent c9cc0d3 commit 6ec6a23
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 65 deletions.
93 changes: 77 additions & 16 deletions frontend/src/store/modules/upload.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,95 @@
import Vue from 'vue'
import { files as api } from '@/api'
import throttle from 'lodash.throttle'
import buttons from '@/utils/buttons'

const UPLOADS_LIMIT = 5;

const state = {
id: 0,
count: 0,
size: 0,
progress: []
progress: [],
queue: [],
uploads: {}
}

const mutations = {
incrementId: (state) => {
state.id = state.id + 1
},
incrementSize: (state, value) => {
state.size = state.size + value
},
incrementCount: (state) => {
state.count = state.count + 1
},
decreaseCount: (state) => {
state.count = state.count - 1
},
setProgress(state, { id, loaded }) {
Vue.set(state.progress, id, loaded)
},
reset: (state) => {
state.id = 0
state.size = 0
state.count = 0
state.progress = []
},
addJob: (state, item) => {
state.queue.push(item)
state.size += item.file.size
state.id++
},
moveJob(state) {
const item = state.queue[0]
state.queue.shift()
Vue.set(state.uploads, item.id, item)
},
removeJob(state, id) {
delete state.uploads[id]
}
}

const actions = {
upload: (context, item) => {
let uploadsCount = Object.keys(context.state.uploads).length;

let isQueueEmpty = context.state.queue.length == 0
let isUploadsEmpty = uploadsCount == 0

if (isQueueEmpty && isUploadsEmpty) {
buttons.loading('upload')
}

context.commit('addJob', item)
context.dispatch('processUploads')
},
finishUpload: (context, item) => {
context.commit('setProgress', { id: item.id, loaded: item.file.size })
context.commit('removeJob', item.id)
context.dispatch('processUploads')
},
processUploads: async (context) => {
let uploadsCount = Object.keys(context.state.uploads).length;

let isBellowLimit = uploadsCount < UPLOADS_LIMIT
let isQueueEmpty = context.state.queue.length == 0
let isUploadsEmpty = uploadsCount == 0

let isFinished = isQueueEmpty && isUploadsEmpty
let canProcess = isBellowLimit && !isQueueEmpty

if (isFinished) {
buttons.success('upload')
context.commit('reset')
context.commit('setReload', true, { root: true })
}

if (canProcess) {
const item = context.state.queue[0];
context.commit('moveJob')

if (item.file.isDir) {
await api.post(item.path).catch(Vue.prototype.$showError)
} else {
let onUpload = throttle(
(event) => context.commit('setProgress', { id: item.id, loaded: event.loaded }),
100, { leading: true, trailing: false }
)

await api.post(item.path, item.file, item.overwrite, onUpload).catch(Vue.prototype.$showError)
}

context.dispatch('finishUpload', item)
}
}
}

export default { state, mutations, namespaced: true }
export default { state, mutations, actions, namespaced: true }
63 changes: 14 additions & 49 deletions frontend/src/utils/upload.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import store from '@/store'
import { files as api } from '@/api'
import throttle from 'lodash.throttle'
import buttons from '@/utils/buttons'
import url from '@/utils/url'

export function checkConflict(files, items) {
Expand Down Expand Up @@ -71,6 +68,7 @@ export function scanFiles(dt) {
} else if (entry.isDirectory) {
const dir = {
isDir: true,
size: 0,
path: `${directory}${entry.name}`
}

Expand Down Expand Up @@ -102,67 +100,34 @@ export function scanFiles(dt) {
}

export function handleFiles(files, path, overwrite = false) {
if (store.state.upload.count == 0) {
buttons.loading('upload')
}

let promises = []

let onupload = (id) => (event) => {
store.commit('upload/setProgress', { id, loaded: event.loaded })
}

for (let i = 0; i < files.length; i++) {
let file = files[i]

if (!file.isDir) {
let filename = (file.fullPath !== undefined) ? file.fullPath : file.name
let filenameEncoded = url.encodeRFC5987ValueChars(filename)

let id = store.state.upload.id
let filename = (file.fullPath !== undefined) ? file.fullPath : file.name
let filenameEncoded = url.encodeRFC5987ValueChars(filename)

store.commit('upload/incrementSize', file.size)
store.commit('upload/incrementId')
store.commit('upload/incrementCount')
let id = store.state.upload.id

let promise = api.post(path + filenameEncoded, file, overwrite, throttle(onupload(id), 100)).finally(() => {
store.commit('upload/decreaseCount')
})
let itemPath = path + filenameEncoded

promises.push(promise)
} else {
let uri = path
if (file.isDir) {
itemPath = path
let folders = file.path.split("/")

for (let i = 0; i < folders.length; i++) {
let folder = folders[i]
let folderEncoded = encodeURIComponent(folder)
uri += folderEncoded + "/"
itemPath += folderEncoded + "/"
}

api.post(uri)
}
}

let finish = () => {
if (store.state.upload.count > 0) {
return
const item = {
id,
path: itemPath,
file,
overwrite
}

buttons.success('upload')

store.commit('setReload', true)
store.commit('upload/reset')
store.dispatch('upload/upload', item);
}

Promise.all(promises)
.then(() => {
finish()
})
.catch(error => {
finish()
this.$showError(error)
})

return false
}

0 comments on commit 6ec6a23

Please sign in to comment.