diff --git a/assets/src/components/files/Listing.vue b/assets/src/components/files/Listing.vue index af688012..b1c07ac3 100644 --- a/assets/src/components/files/Listing.vue +++ b/assets/src/components/files/Listing.vue @@ -318,18 +318,36 @@ export default { handleFiles (files, base, overwrite = false) { buttons.loading('upload') let promises = [] + let progress = new Array(files.length).fill(0) - for (let file of files) { - promises.push(api.post(this.$route.path + base + file.name, file, overwrite)) + let onupload = (id) => (event) => { + progress[id] = (event.loaded / event.total) * 100 + + let sum = 0 + for (let i = 0; i < progress.length; i++) { + sum += progress[i] + } + + this.$store.commit('setProgress', Math.ceil(sum / progress.length)) + } + + for (let i = 0; i < files.length; i++) { + let file = files[i] + promises.push(api.post(this.$route.path + base + file.name, file, overwrite, onupload(i))) + } + + let finish = () => { + buttons.success('upload') + this.$store.commit('setProgress', 0) } Promise.all(promises) .then(() => { - buttons.success('upload') + finish() this.$store.commit('setReload', true) }) .catch(error => { - buttons.done('upload') + finish() this.$store.commit('showError', error) }) diff --git a/assets/src/css/base.css b/assets/src/css/base.css index 0bc872b4..f5582857 100644 --- a/assets/src/css/base.css +++ b/assets/src/css/base.css @@ -145,3 +145,19 @@ main { #breadcrumbs span a { padding: .2em; } + +#progress { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 3px; + z-index: 9999999999; +} + +#progress div { + height: 100%; + background-color: #40c4ff; + width: 0; + transition: .2s ease width; +} diff --git a/assets/src/store/index.js b/assets/src/store/index.js index a9a41e03..cdecc09b 100644 --- a/assets/src/store/index.js +++ b/assets/src/store/index.js @@ -15,6 +15,7 @@ const state = { staticGen: document.querySelector('meta[name="staticgen"]').getAttribute('content'), baseURL: document.querySelector('meta[name="base"]').getAttribute('content'), jwt: '', + progress: 0, schedule: '', loading: false, reload: false, diff --git a/assets/src/store/mutations.js b/assets/src/store/mutations.js index 965bebef..6caa26ee 100644 --- a/assets/src/store/mutations.js +++ b/assets/src/store/mutations.js @@ -61,6 +61,9 @@ const mutations = { }, setSchedule: (state, value) => { state.schedule = value + }, + setProgress: (state, value) => { + state.progress = value } } diff --git a/assets/src/utils/api.js b/assets/src/utils/api.js index dc2029fa..087165cf 100644 --- a/assets/src/utils/api.js +++ b/assets/src/utils/api.js @@ -56,7 +56,7 @@ export function remove (url) { }) } -export function post (url, content = '', overwrite = false) { +export function post (url, content = '', overwrite = false, onupload) { url = removePrefix(url) return new Promise((resolve, reject) => { @@ -64,6 +64,10 @@ export function post (url, content = '', overwrite = false) { request.open('POST', `${store.state.baseURL}/api/resource${url}`, true) request.setRequestHeader('Authorization', `Bearer ${store.state.jwt}`) + if (typeof onupload === 'function') { + request.upload.onprogress = onupload + } + if (overwrite) { request.setRequestHeader('Action', `override`) } diff --git a/assets/src/views/Layout.vue b/assets/src/views/Layout.vue index dc0af7a6..6120fe56 100644 --- a/assets/src/views/Layout.vue +++ b/assets/src/views/Layout.vue @@ -1,5 +1,8 @@