diff --git a/src/App.vue b/src/App.vue index 671da4c..6726fac 100644 --- a/src/App.vue +++ b/src/App.vue @@ -315,6 +315,7 @@ export default { mounted() { this.setupConfig(); // localSettings persisted settings this.setupIdleDetection(); + this.setupDropZone(); // file upload drag/drop this.webcam.elem = document.querySelector("#localVideo"); this.historyScrollbox = document.querySelector("#chatHistory"); @@ -2793,8 +2794,48 @@ export default { * Image sharing in chat */ - // The image upload button handler. - uploadFile() { + // Set up the HTML5 drag/drop handlers. + setupDropZone() { + let $dropArea = document.querySelector("#drop-modal"); + let $body = document.querySelector("body"); + + // Set up drag/drop file upload events. + $body.addEventListener("dragenter", (e) => { + e.preventDefault(); + e.stopPropagation(); + $dropArea.classList.add("is-active"); + }); + $body.addEventListener("dragover", (e) => { + e.preventDefault(); + e.stopPropagation(); + $dropArea.classList.add("is-active"); + }); + $body.addEventListener("dragleave", (e) => { + e.preventDefault(); + e.stopPropagation(); + $dropArea.classList.remove("is-active"); + }); + $body.addEventListener("drop", (e) => { + e.preventDefault(); + e.stopPropagation(); + $dropArea.classList.remove("is-active"); + + // Grab the file. + let dt = e.dataTransfer; + let file = dt.files[0]; + + this.onFileUpload(file); + }); + }, + + // Common file selection handler for drag/drop or manual upload. + onFileUpload(file) { + // Validate they can upload it here. + if (!this.canUploadFile) { + this.ChatClient("Photo sharing in DMs is not available."); + return; + } + // Prepare the message now so the channel name will be correct, // in case they upload a fat file and switch to a wrong channel // before the data is ready to send. @@ -2803,39 +2844,44 @@ export default { channel: this.channel, }; + if (file.size > FileUploadMaxSize) { + this.ChatClient(`Please share an image smaller than ${FileUploadMaxSize / 1024 / 1024} MB in size!`); + return; + } + + this.ChatClient(`Uploading file to chat: ${file.name} - ${file.size} bytes, ${file.type} format.`); + + // Get image file data. + let reader = new FileReader(); + let rawData = new ArrayBuffer(); + reader.onload = e => { + rawData = e.target.result; + + let fileByteArray = [], + u8array = new Uint8Array(rawData); + for (let i = 0; i < u8array.length; i++) { + fileByteArray.push(u8array[i]); + } + + // Attach the file to the message. + msg.message = file.name; + msg.bytes = fileByteArray; + + // Send it to the chat server. + this.client.send(msg); + }; + + reader.readAsArrayBuffer(file); + }, + + // The image upload button handler. + uploadFile() { let input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; input.onchange = e => { let file = e.target.files[0]; - if (file.size > FileUploadMaxSize) { - this.ChatClient(`Please share an image smaller than ${FileUploadMaxSize / 1024 / 1024} MB in size!`); - return; - } - - this.ChatClient(`Uploading file to chat: ${file.name} - ${file.size} bytes, ${file.type} format.`); - - // Get image file data. - let reader = new FileReader(); - let rawData = new ArrayBuffer(); - reader.onload = e => { - rawData = e.target.result; - - let fileByteArray = [], - u8array = new Uint8Array(rawData); - for (let i = 0; i < u8array.length; i++) { - fileByteArray.push(u8array[i]); - } - - // Attach the file to the message. - msg.message = file.name; - msg.bytes = fileByteArray; - - // Send it to the chat server. - this.client.send(msg); - }; - - reader.readAsArrayBuffer(file); + this.onFileUpload(file); }; input.click(); }, @@ -3056,6 +3102,16 @@ export default { + + +