d88c5f09c72549eb65f8477115092d089927b152
[citadel.git] / webcit-ng / static / js / mail_folder_list.js
1 // Display the mail folder list
2 //
3 // Copyright (c) 2016-2023 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, or
6 // disclosure are subject to the GNU General Public License v3.
7
8
9 // Display the mail folder list in the specified div
10 function display_mail_folder_list(target_div) {
11
12         display_mail_folder_list_async = async(target_div) => {
13                 let rendered_list = "";
14
15                 // load the room list from the Citadel Server
16                 response = await fetch("/ctdl/r/", { method: "GET" } );
17                 if (response.ok) {
18                         roomlist = await response.json();
19                         rendered_list = render_mail_folder_list(roomlist);
20                 }
21                 else {
22                         rendered_list = "❌ " + response.status;
23                 }
24
25                 document.getElementById(target_div).innerHTML = rendered_list;
26         }
27
28         document.getElementById(target_div).innerHTML = "<img src=\"/ctdl/s/images/throbber.gif\" />";  // show throbber
29         document.getElementById(target_div).style.display = "block";
30         display_mail_folder_list_async(target_div);
31 }
32
33
34 // Given a JSON object containing the output of the `/ctdl/r` API call, return a rendered mail folder list.
35 function render_mail_folder_list(roomlist_json) {
36
37         // Sort first by floor then by room order
38         roomlist_json.sort(function(a, b) {
39                 if (a.floor > b.floor) return 1;
40                 if (a.floor < b.floor) return -1;
41                 if (a.name == "Mail") return -1;
42                 if (b.name == "Mail") return 1;
43                 if (a.rorder > b.rorder) return 1;
44                 if (a.rorder < b.rorder) return -1;
45                 return 0;
46         });
47
48         // Turn it into displayable markup
49         let rendered_list = "<ul class=\"ctdl_mail_folders\" id=\"ctdl_mail_folders\">\n";
50         for (let i=0; i<roomlist_json.length; ++i) {
51                 if (roomlist_json[i].current_view == views.VIEW_MAILBOX) {
52                         rendered_list += "<li "
53                                         + "id=\"" + randomString() + "\" "
54                                         + "onclick=\"gotoroom('" + roomlist_json[i].name + "')\" "
55                                         + "ondragover=\"mail_folder_dragover(event)\" "
56                                         + "ondragleave=\"mail_folder_dragleave(event)\" "
57                                         + "ondrop=\"mail_folder_drop(event, '" + escapeJS(roomlist_json[i].name) + "')\" "
58                                         + ">"
59                                         + ((roomlist_json[i].name == "Mail") ? _("INBOX") : escapeHTML(roomlist_json[i].name))
60                                         + "</li>\n"
61                         ;
62                 }
63         }
64         rendered_list += "</ul>";
65         return rendered_list;
66 }
67
68
69 // There MUST be a dragover handler, otherwise drop doesn't work.
70 // This also seems to be more reliable than a dragStart handler.
71 function mail_folder_dragover(event) {
72         event.preventDefault();
73         event.target.classList.toggle("ctdl_mail_folder_droppable", true);
74 }
75
76
77 // The user is no longer hovering over this folder.
78 function mail_folder_dragleave(event) {
79         event.preventDefault();
80         event.target.classList.toggle("ctdl_mail_folder_droppable", false);
81 }
82
83
84 // Something has been dropped onto a folder.
85 function mail_folder_drop(event, destination_room) {
86         event.preventDefault();
87         event.target.classList.toggle("ctdl_mail_folder_droppable", false);
88         var msgs = event.dataTransfer.getData("text").split(",");
89         for (var i=0; i<msgs.length; ++i) {
90                 mail_move(msgs[i], destination_room);
91         }
92 }
93
94
95 // mail_folder_drop() calls this function for each message being moved
96 mail_move = async(msgdivid, destination_room) => {
97         let msgdiv = document.getElementById(msgdivid);
98         let m = parseInt(msgdivid.substring(12));                               // derive msgnum from row id
99         let source = "/ctdl/r/" + escapeHTMLURI(current_room) + "/" + m;
100         let destination = "/ctdl/r/" + escapeHTMLURI(destination_room);
101
102         let response = await fetch(
103                 source, {
104                         method: "MOVE",
105                         headers: {
106                                 "Destination" : destination
107                         }
108                 }
109         );
110
111         // If the server accepted the MOVE operation, delete the row from our screen.
112         if (response.ok) {
113                 var table = document.getElementById("ctdl-onscreen-mailbox");
114                 for (var i = 0, row; row = table.rows[i]; i++) {
115                         if (row.id == msgdivid) {
116                                 table.deleteRow(i);
117                         }
118                 }
119         }
120 }