From 951c89e255bf1f8cfa7cd787e9703c7992b45cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Fri, 13 Jan 2023 11:42:48 +0100 Subject: [PATCH] upload progress --- app/assets/javascripts/vue.js | 1 + .../vue/direct-upload-controller.js | 52 +++++++++++++++++++ .../admin/communication/blocks/edit.html.erb | 39 +++++++++----- 3 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 app/assets/javascripts/vue/direct-upload-controller.js diff --git a/app/assets/javascripts/vue.js b/app/assets/javascripts/vue.js index f812291c6..503079155 100644 --- a/app/assets/javascripts/vue.js +++ b/app/assets/javascripts/vue.js @@ -1,2 +1,3 @@ //= require vue/dist/vue.global.prod.js //= require vue-draggable-next/dist/vue-draggable-next.global.js +//= require vue/direct-upload-controller \ No newline at end of file diff --git a/app/assets/javascripts/vue/direct-upload-controller.js b/app/assets/javascripts/vue/direct-upload-controller.js new file mode 100644 index 000000000..b16af85fb --- /dev/null +++ b/app/assets/javascripts/vue/direct-upload-controller.js @@ -0,0 +1,52 @@ +/*global Vue */ +Vue.DirectUploadController = function DirectUploadController (input, file, url) { + 'use strict'; + this.input = input; + this.file = file; + this.url = url; + this.directUpload = new ActiveStorage.DirectUpload(this.file, this.url, this) + this.dispatch("initialize"); +} + +Vue.DirectUploadController.prototype.start = function (callback) { + 'use strict'; + this.directUpload.create(function (error, blob) { + this.dispatch("end"); + if (error) { + console.log(error); + } else { + callback(blob); + } + }.bind(this)); +} + +Vue.DirectUploadController.prototype.uploadRequestDidProgress = function (event) { + 'use strict'; + var progress = event.loaded / event.total * 100 + if (progress) { + this.dispatch("progress", { "progress": progress }); + } +} + +Vue.DirectUploadController.prototype.dispatch = function (name, detail) { + var event = document.createEvent("Event"), + disabled = this.input.disabled; + detail = detail || {}; + detail.file = this.file; + detail.id = this.directUpload.id; + event.initEvent(`direct-upload:${name}`, true, true); + event.detail = detail; + + this.input.disabled = false; + this.input.dispatchEvent(event); + this.input.disabled = disabled; + + return event; +} + +// DirectUpload delegate + +Vue.DirectUploadController.prototype.directUploadWillStoreFileWithXHR = function (xhr) { + 'use strict'; + xhr.upload.addEventListener("progress", this.uploadRequestDidProgress.bind(this)); +} \ No newline at end of file diff --git a/app/views/admin/communication/blocks/edit.html.erb b/app/views/admin/communication/blocks/edit.html.erb index 8dfdb9fb7..ff00edca2 100644 --- a/app/views/admin/communication/blocks/edit.html.erb +++ b/app/views/admin/communication/blocks/edit.html.erb @@ -65,27 +65,22 @@ var files = event.target.files || event.dataTransfer.files; if (!files.length) return; - this.uploadFile(files[0], object, key); + this.uploadFile(event.target, files[0], object, key); }, - uploadFile(file, object, key) { - var url = this.directUpload.url, - size = Math.round(file.size / 1024 / 1024); + uploadFile(input, file, object, key) { + var size = Math.round(file.size / 1024 / 1024); + var controller = new Vue.DirectUploadController(input, file, this.directUpload.url) if (file.size > <%= Communication::Block::IMAGE_MAX_SIZE %>) { alert("<%= t('admin.communication.blocks.alerts.image_is_too_big').html_safe %> (" + size + " Mo > <%= number_to_human_size Communication::Block::IMAGE_MAX_SIZE %>)"); return; } - var upload = new ActiveStorage.DirectUpload(file, url); - upload.create(function (error, blob) { - if (error) { - console.log(error); - } else { - object[key] = { + controller.start(function (blob) { + object[key] = { id: blob.id, signed_id: blob.signed_id, filename: blob.filename - }; - } - }.bind(this)); + }; + }); }, getFileUrl(signed_id, filename) { return this.directUpload.blobUrlTemplate @@ -123,6 +118,24 @@ } }); + window.addEventListener('direct-upload:initialize', function (event) { + event.target.insertAdjacentHTML('afterend', `<progress value="0" max="100" style="width: 100%;"></progress>`) + }); + + window.addEventListener('direct-upload:progress', function (event) { + var progressBar = event.target.parentNode.querySelector('progress'); + if (progressBar) { + progressBar.value = event.detail.progress; + } + }); + + window.addEventListener('direct-upload:end', function (event) { + var progressBar = event.target.parentNode.querySelector('progress'); + if (progressBar) { + progressBar.parentNode.removeChild(progressBar); + } + }); + window.addEventListener('load', function(){ setTimeout(function() { app.mount('#app'); -- GitLab