Add a feedback when uploading a file

This commit is contained in:
Pierre HUBERT 2021-03-09 17:06:35 +01:00
parent b614f649e3
commit b8be70f6dc
5 changed files with 70 additions and 9 deletions

View File

@ -30,9 +30,10 @@ const APIClient = {
}, },
/** /**
* @param {(number) => void} progressCallback Use this function to monitor upload
* @returns {Promise} * @returns {Promise}
*/ */
execFormData: function(uri, data, withLogin) { execFormData: function(uri, data, withLogin, progressCallback) {
if (!data) if (!data)
data = new FormData(); data = new FormData();
@ -43,7 +44,7 @@ const APIClient = {
else else
res(result); res(result);
}) }, progressCallback)
}); });
}, },
@ -108,8 +109,9 @@ const APIClient = {
* @param {FormData} data The form data object * @param {FormData} data The form data object
* @param {Boolean} requireLoginTokens Specify if login tokens are required or not * @param {Boolean} requireLoginTokens Specify if login tokens are required or not
* @param {Function} nextAction What to do next * @param {Function} nextAction What to do next
* @param {(number) => void} progressCallback Use this function to monitor upload
*/ */
makeFormDatarequest: function(apiURI, data, requireLoginTokens, nextAction){ makeFormDatarequest: function(apiURI, data, requireLoginTokens, nextAction, progressCallback){
//Prepare the request URL //Prepare the request URL
var requestURL = ComunicWeb.__config.apiURL + apiURI; var requestURL = ComunicWeb.__config.apiURL + apiURI;
@ -134,6 +136,12 @@ const APIClient = {
ComunicWeb.common.api._on_state_change(requestURL, apiXHR, nextAction); ComunicWeb.common.api._on_state_change(requestURL, apiXHR, nextAction);
} }
// Monitor upload progress, if required
if (progressCallback)
apiXHR.upload.addEventListener("progress", e => {
progressCallback(e.loaded/e.total);
});
//Submit request //Submit request
apiXHR.send(data); apiXHR.send(data);
}, },

View File

@ -0,0 +1,50 @@
/**
* Conversation file upload progress
*
* Show a progress bar letting the user know when
* is file is sent.
*
* @author Pierre Hubert
*/
class FileUploadProgress {
/**
* Initialise a new progress bar
*
* @param {HTMLElement} target
*/
constructor(target) {
const progressContainerElem = createElem2({
appendTo: target,
type: "div",
class: "progress progress-xs progress-striped active"
});
progressContainerElem.style.marginBottom = "0px"
this.progresselem = createElem2({
appendTo: progressContainerElem,
type: "div",
class: "progress-bar progress-bar-success",
})
this.setProgress(0)
}
/**
* Apply a new progress
*
* @param {number} progress Between 0 and 1
*/
setProgress(progress) {
this.progresselem.style.width = Math.floor(progress*100) + "%"
}
/**
* Remove the progress element
* from the page
*/
remove() {
this.progresselem.parentNode.remove()
}
}

View File

@ -237,8 +237,9 @@ const ConversationsInterface = {
* @param {number} convID The ID of the conversation * @param {number} convID The ID of the conversation
* @param {string} message The message to send (if not a file) * @param {string} message The message to send (if not a file)
* @param {HTMLInputElement} file The file to send (if any) * @param {HTMLInputElement} file The file to send (if any)
* @param {(number) => void} progress Optional progress callback (if a file is sent)
*/ */
sendMessage: async function(convID, message, file){ sendMessage: async function(convID, message, file, progress){
//Perform an API request //Perform an API request
var apiURI = "conversations/sendMessage"; var apiURI = "conversations/sendMessage";
@ -264,7 +265,7 @@ const ConversationsInterface = {
fd.append("file", file.files[0], file.files[0].name); fd.append("file", file.files[0], file.files[0].name);
//Perform an API request //Perform an API request
await APIClient.execFormData(apiURI, fd, true); await APIClient.execFormData(apiURI, fd, true, progress);
} }
}, },

View File

@ -228,7 +228,7 @@ const ConversationsUtils = {
* @param {HTMLInputElement} input * @param {HTMLInputElement} input
* @param {HTMLElement} target * @param {HTMLElement} target
*/ */
registerInputToSendFile: function(convID, fileInput, splashScreenTarget){ registerInputToSendFile: function(convID, fileInput, progressTarget){
fileInput.addEventListener("change", async (e) => { fileInput.addEventListener("change", async (e) => {
e.preventDefault(); e.preventDefault();
@ -252,9 +252,10 @@ const ConversationsUtils = {
return; return;
} }
el = Page.showTransparentWaitSplashScreen(splashScreenTarget); el = new FileUploadProgress(progressTarget);
await ConversationsInterface.sendMessage(convID, null, fileInput);
await ConversationsInterface.sendMessage(convID, null, fileInput, (progress) => el.setProgress(progress));
} }
catch(e) { catch(e) {
@ -262,7 +263,7 @@ const ConversationsUtils = {
notify(tr("Failed to send file!"), "danger"); notify(tr("Failed to send file!"), "danger");
} }
el.remove(); el.remove()
}); });
}, },

View File

@ -407,6 +407,7 @@ class Dev {
"js/components/conversations/unreadDropdown.js", "js/components/conversations/unreadDropdown.js",
"js/components/conversations/messageEditor.js", "js/components/conversations/messageEditor.js",
"js/components/conversations/writingNotifier.js", "js/components/conversations/writingNotifier.js",
"js/components/conversations/fileUploadProgress.js",
//User selector //User selector
"js/components/userSelect/userSelect.js", "js/components/userSelect/userSelect.js",