upload.js: moved these functions into own file.
authorArt Cancro <ajc@citadel.org>
Sat, 30 Sep 2023 04:47:08 +0000 (00:47 -0400)
committerArt Cancro <ajc@citadel.org>
Sat, 30 Sep 2023 04:47:08 +0000 (00:47 -0400)
Good clean separation of functions.
This should allow us to handle uploads in lots of different places
in the system.

webcit-ng/static/css/webcit.css
webcit-ng/static/index.html
webcit-ng/static/js/upload.js [new file with mode: 0644]
webcit-ng/static/js/view_mail.js

index 359b79013178701a8bee0b2c8c1e6c60561b4605..503cf67d5c3a59247da3f1f1108f5e57be740bca 100644 (file)
@@ -651,7 +651,7 @@ blockquote pre {
 }
 
 .ctdl-upload.highlight {
-       border-color: purple;
+       border-color: Blue;
 }
 
 .ctdl-compose-attachments-title {
@@ -665,7 +665,8 @@ blockquote pre {
        align-content: start
 }
 
-.my-form {
+.ctdl-upload-form {
+       text-align: center;
        margin-bottom: 10px;
 }
 
index b6f270668da74656acb169997bacac0526cf4def..9fa702b25033dd926b725f2ba0e39c9357d71009 100644 (file)
@@ -75,6 +75,7 @@
 <script type="text/javascript" src="js/mail_folder_list.js"></script>
 <script type="text/javascript" src="js/roomlist.js"></script>
 <script type="text/javascript" src="js/user_profile.js"></script>
+<script type="text/javascript" src="js/upload.js"></script>
 <script>
 
 // Get the Sidebar
diff --git a/webcit-ng/static/js/upload.js b/webcit-ng/static/js/upload.js
new file mode 100644 (file)
index 0000000..b19d1bb
--- /dev/null
@@ -0,0 +1,148 @@
+// Handle any tasks which require uploading files to the server (such as attachments)
+// h/t https://www.smashingmagazine.com/2018/01/drag-drop-file-uploader-vanilla-js/ which inspired the design of this module
+//
+// Copyright (c) 2016-2023 by the citadel.org team
+//
+// This program is open source software.  Use, duplication, or
+// disclosure are subject to the GNU General Public License v3.
+
+var uploads_in_progress = 0;
+var uploads = [] ;                                                             // everything the user has uploaded
+
+
+// Turn the specified div into a place where we can upload.  (Note: permanently changes the drag-and-drop behavior of that div.)
+function activate_uploads(parent_div) {
+               document.getElementById(parent_div).innerHTML += `
+                       <div class="ctdl-upload" id="ctdl-upload">
+                               <div id="ctdl_attachments_title" class="ctdl-compose-attachments-title">
+                                       <div><h1><i class="fa fa-paperclip" style="color:grey"></i>` + _("Attachments:") + ` <span id="num_attachments">` + uploads.length + `</span></h1></div>
+                                       <div><h1><i class="fas fa-window-close" style="color:red" onClick="show_or_hide_upload_window()"></i></h1></div>
+                               </div>
+                               <br>
+                               <ul id="ctdl-upload_list">
+                               </ul>
+                               <br>
+                               <div id="drop-area" class="ctdl-upload-drop-area">
+                                       <form class="ctdl-upload-form">
+                                               <p>${_("Drop files here to upload")}</p>
+                                               <input type="file" id="fileElem" multiple accept="*/*" onChange="handle_upload_files(this.files)">
+                                       </form>
+                               </div>
+                       </div>
+               `;
+
+               // activate drag and drop
+               let dropArea = document.getElementById(parent_div);
+               ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
+                       dropArea.addEventListener(eventName, upload_prevent_defaults, false)
+               })
+               ;["dragenter", "dragover"].forEach(eventName => {
+                       dropArea.addEventListener(eventName, upload_highlight, false)
+               })
+               ;['dragleave', 'drop'].forEach(eventName => {
+                       dropArea.addEventListener(eventName, upload_unhighlight, false)
+               })
+               dropArea.addEventListener('drop', upload_handle_drop, false);
+}
+
+
+// prevent drag and drop events from propagating up through the DOM
+function upload_prevent_defaults(e) {
+       e.preventDefault();
+       e.stopPropagation();
+}
+
+
+function upload_handle_drop(e) {
+       let dt = e.dataTransfer;
+       let files = dt.files;
+       handle_upload_files(files);
+}
+
+
+function handle_upload_files(files) {
+       ([...files]).forEach(upload_file)
+}
+
+
+function upload_file(file) {
+       var url = '/ctdl/a/upload';
+       var xhr = new XMLHttpRequest();
+       var formData = new FormData();
+       xhr.open('POST', url, true);
+      
+       xhr.addEventListener('readystatechange', function(e) {
+               if (xhr.readyState == 4 && xhr.status == 200) {
+                       // remove the "uploading in progress" message
+                       let li = document.getElementById("ctdl_uploading_" + uploads_in_progress.toString());
+                       li.parentNode.removeChild(li);
+                       uploads_in_progress -= 1;
+
+                       // The response body will be a JSON array of completed uploads.
+                       var j_response = JSON.parse(xhr.response);
+
+                       // Add these uploads to the displayed list
+                       j_response.forEach((item) => {
+                               let new_upl = document.createElement("li");
+                               new_upl.innerHTML = item["tempfilename"] + " " + item["uploadfilename"] + " " + item["contenttype"] + " " + item["contentlength"];
+                               document.getElementById("ctdl-upload_list").appendChild(new_upl);
+                       });
+
+                       // append it to the global list of uploads
+                       uploads.push(j_response);
+                       document.getElementById("num_attachments").innerHTML = uploads.length;
+               }
+               else if (xhr.readyState == 4 && xhr.status != 200) {
+                       // remove the "uploading in progress" message (there was an error, so just let it disappear)
+                       let li = document.getElementById("ctdl_uploading_" + uploads_in_progress.toString());
+                       li.parentNode.removeChild(li);
+                       uploads_in_progress -= 1;
+               }
+       })
+       formData.append('file', file);
+       xhr.send(formData);
+       uploads_in_progress += 1;
+
+       // Make an "uploading in progress" message appear in the uploads list!
+       progress = document.createElement("li");
+       progress.setAttribute("id", "ctdl_uploading_" + uploads_in_progress.toString());
+       progress.innerHTML = `<img src="/ctdl/s/images/throbber.gif" /> ` + _("Processing dropped files...");
+       document.getElementById("ctdl-upload_list").appendChild(progress);
+}
+
+
+// called when the user drags a file into the upload area
+function upload_highlight(e) {
+       let dropArea = document.getElementById("ctdl-upload");
+       dropArea.classList.add('highlight')
+
+       document.getElementById("ctdl-upload").style.display = "block";         /* also make it appear */
+}
+
+
+// called when the user is no longer dragging a file into the upload area
+function upload_unhighlight(e) {
+       let dropArea = document.getElementById("ctdl-upload");
+       dropArea.classList.remove('highlight')
+}
+
+
+// Show or hide the attachments window in the composer
+function show_or_hide_upload_window() {
+
+       if (document.getElementById("ctdl-upload").style.display == "block") {
+               document.getElementById("ctdl-upload").style.display = "none";          /* turn it off */
+       }
+       else {
+               document.getElementById("ctdl-upload").style.display = "block";         /* turn it on */
+       }
+}
+
+
+// Flush all uploaded files and close the window
+function flush_uploads() {
+        document.getElementById('ctdl-upload').style.display='none';
+        // FIXME tell the server to delete the files
+        uploads=[];
+}
\ No newline at end of file
index 6db894d130d40c5cd8e0b5da81dbc144a6327287..8e31a18cf5c67cfaf7f928b1be175e64305b4a03 100644 (file)
@@ -13,8 +13,6 @@ var newmail_notify = {
         NO  : 0,                                                               // do not perform new mail notifications
         YES : 1                                                                        // yes, perform new mail notifications
 };
-var uploads_in_progress = 0;
-var uploads = [] ;                                                             // everything the user has uploaded
 
 
 // This is the async back end for mail_delete_selected()
@@ -514,9 +512,9 @@ function mail_compose(is_quoted, references, quoted_msgnum, m_to, m_cc, m_subjec
                <div class="ctdl-compose-toolbar">
                <span class="ctdl-msg-button" onclick="mail_send_message()"><i class="fa fa-paper-plane" style="color:green"></i> ${_("Send message")} </span>
                <span class="ctdl-msg-button"> ${_("Save to Drafts")} </span>
-               <span class="ctdl-msg-button" onClick="show_or_hide_attachments()"><i class="fa fa-paperclip" style="color:grey"></i> ${_("Attachments:")} <span id="ctdl_num_attachments"> ${uploads.length} </span></span>
+               <span class="ctdl-msg-button" onClick="show_or_hide_upload_window()"><i class="fa fa-paperclip" style="color:grey"></i> ${_("Attachments:")} <span id="ctdl_num_attachments"> ${uploads.length} </span></span>
                <span class="ctdl-msg-button">  ${_("Contacts")} </span>
-               <span class="ctdl-msg-button" onClick="document.getElementById('ctdl-upload').style.display='none';uploads=[];gotoroom(current_room)"><i class="fa fa-trash" style="color:red"></i> ${_("Cancel")} </span>
+               <span class="ctdl-msg-button" onClick="flush_uploads();gotoroom(current_room)"><i class="fa fa-trash" style="color:red"></i> ${_("Cancel")} </span>
                </div>`
        ;
 
@@ -530,134 +528,6 @@ function mail_compose(is_quoted, references, quoted_msgnum, m_to, m_cc, m_subjec
        activate_uploads("ctdl-editor-body");
 }
 
-
-// Turn the specified div into a place where we can upload.  (Note: permanently changes the drag-and-drop behavior of that div.)
-function activate_uploads(parent_div) {
-               document.getElementById(parent_div).innerHTML += `
-                       <div class="ctdl-upload" id="ctdl-upload">
-                               <div id="ctdl_attachments_title" class="ctdl-compose-attachments-title">
-                                       <div><h1><i class="fa fa-paperclip" style="color:grey"></i>` + _("Attachments:") + ` <span id="num_attachments">` + uploads.length + `</span></h1></div>
-                                       <div><h1><i class="fas fa-window-close" style="color:red" onClick="show_or_hide_attachments()"></i></h1></div>
-                               </div>
-                               <br>
-                               <ul id="ctdl-upload_list">
-                               </ul>
-                               <br>
-                               <div id="drop-area" class="ctdl-upload-drop-area">
-                                       <form class="my-form">
-                                               <p>${_("Drop files here to upload")}</p>
-                                               <input type="file" id="fileElem" multiple accept="*/*" onChange="handle_upload_files(this.files)">
-                                       </form>
-                               </div>
-                       </div>
-               `;
-
-               // activate drag and drop (shamelessly swiped from https://www.smashingmagazine.com/2018/01/drag-drop-file-uploader-vanilla-js/ )
-               let dropArea = document.getElementById(parent_div);
-               ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
-                       dropArea.addEventListener(eventName, upload_prevent_defaults, false)
-               })
-               ;["dragenter", "dragover"].forEach(eventName => {
-                       dropArea.addEventListener(eventName, upload_highlight, false)
-               })
-               ;['dragleave', 'drop'].forEach(eventName => {
-                       dropArea.addEventListener(eventName, upload_unhighlight, false)
-               })
-               dropArea.addEventListener('drop', upload_handle_drop, false);
-}
-
-
-// prevent drag and drop events from propagating up through the DOM
-function upload_prevent_defaults(e) {
-       e.preventDefault();
-       e.stopPropagation();
-}
-
-
-function upload_handle_drop(e) {
-       let dt = e.dataTransfer;
-       let files = dt.files;
-       handle_upload_files(files);
-}
-
-
-function handle_upload_files(files) {
-       ([...files]).forEach(upload_file)
-}
-
-
-function upload_file(file) {
-       var url = '/ctdl/a/upload';
-       var xhr = new XMLHttpRequest();
-       var formData = new FormData();
-       xhr.open('POST', url, true);
-      
-       xhr.addEventListener('readystatechange', function(e) {
-               if (xhr.readyState == 4 && xhr.status == 200) {
-                       // remove the "uploading in progress" message
-                       let li = document.getElementById("ctdl_uploading_" + uploads_in_progress.toString());
-                       li.parentNode.removeChild(li);
-                       uploads_in_progress -= 1;
-
-                       // The response body will be a JSON array of completed uploads.
-                       var j_response = JSON.parse(xhr.response);
-
-                       // Add these uploads to the displayed list
-                       j_response.forEach((item) => {
-                               let new_upl = document.createElement("li");
-                               new_upl.innerHTML = item["tempfilename"] + " " + item["uploadfilename"] + " " + item["contenttype"] + " " + item["contentlength"];
-                               document.getElementById("ctdl-upload_list").appendChild(new_upl);
-                       });
-
-                       // append it to the global list of uploads
-                       uploads.push(j_response);
-                       document.getElementById("num_attachments").innerHTML = uploads.length;
-               }
-               else if (xhr.readyState == 4 && xhr.status != 200) {
-                       // remove the "uploading in progress" message (there was an error, so just let it disappear)
-                       let li = document.getElementById("ctdl_uploading_" + uploads_in_progress.toString());
-                       li.parentNode.removeChild(li);
-                       uploads_in_progress -= 1;
-               }
-       })
-       formData.append('file', file);
-       xhr.send(formData);
-       uploads_in_progress += 1;
-
-       // Make an "uploading in progress" message appear in the uploads list!
-       progress = document.createElement("li");
-       progress.setAttribute("id", "ctdl_uploading_" + uploads_in_progress.toString());
-       progress.innerHTML = `<img src="/ctdl/s/images/throbber.gif" /> ` + _("Processing dropped files...");
-       document.getElementById("ctdl-upload_list").appendChild(progress);
-}
-
-
-function upload_highlight(e) {
-       let dropArea = document.getElementById("ctdl-upload");
-       dropArea.classList.add('highlight')
-
-       document.getElementById("ctdl-upload").style.display = "block";         /* also make it appear */
-}
-      
-function upload_unhighlight(e) {
-       let dropArea = document.getElementById("ctdl-upload");
-       dropArea.classList.remove('highlight')
-}
-
-
-// Show or hide the attachments window in the composer
-function show_or_hide_attachments() {
-
-       if (document.getElementById("ctdl-upload").style.display == "block") {
-               document.getElementById("ctdl-upload").style.display = "none";          /* turn it off */
-       }
-       else {
-               document.getElementById("ctdl-upload").style.display = "block";         /* turn it on */
-       }
-}
-
-
 // Called when the user clicks the button to make the hidden "CC" and "BCC" lines appear.
 // It is also called automatically during a Reply when CC is pre-populated.
 function make_cc_bcc_visible() {