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, sizes: [], progress: [], queue: [], uploads: {}, speedMbyte: 0, eta: 0, }; const mutations = { setProgress(state, { id, loaded }) { Vue.set(state.progress, id, loaded); }, reset: (state) => { state.id = 0; state.sizes = []; state.progress = []; }, addJob: (state, item) => { state.queue.push(item); state.sizes[state.id] = 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) { Vue.delete(state.uploads, id); delete state.uploads[id]; }, }; const beforeUnload = (event) => { event.preventDefault(); event.returnValue = ""; }; 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) { window.addEventListener("beforeunload", beforeUnload); 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) { window.removeEventListener("beforeunload", beforeUnload); 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, actions, namespaced: true };