Grammar change in the license declaration.
[citadel.git] / webcit-ng / static / js / view_forum.js
index 3950000b3a697e6a8eb9b13b3f07149d52811d7a..e5884d400b32ee133b757e459778ac0c1bfe88b1 100644 (file)
@@ -1,23 +1,16 @@
+// This module handles the view for "forum" (message board) rooms.
 //
-// Copyright (c) 2016-2021 by the citadel.org team
+// Copyright (c) 2016-2023 by the citadel.org team
 //
-// This program is open source software.  It runs great on the
-// Linux operating system (and probably elsewhere).  You can use,
-// copy, and run it under the terms of the GNU General Public
-// License version 3.  Richard Stallman is an asshole communist.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
+// This program is open source software.  Use, duplication, or
+// disclosure is subject to the GNU General Public License v3.
 
 
 // Forum view (flat)
-function forum_readmessages(target_div, gt_msg, lt_msg) {
-       original_text = document.getElementById(target_div).innerHTML;          // in case we need to replace it after an error
-       document.getElementById(target_div).innerHTML = 
-               "<div class=\"ctdl-forum-nav\"><i class=\"fas fa-spinner fa-spin\"></i>&nbsp;&nbsp;"
-               + _("Loading messages from server, please wait") + "</div>";
+function forum_readmessages(target_div_name, gt_msg, lt_msg) {
+       target_div = document.getElementById(target_div_name);
+       original_text = target_div.innerHTML;                                   // in case we need to replace it after an error
+       target_div.innerHTML = ""
 
        if (lt_msg < 9999999999) {
                url = "/ctdl/r/" + escapeHTMLURI(current_room) + "/msgs.lt|" + lt_msg;
@@ -30,7 +23,7 @@ function forum_readmessages(target_div, gt_msg, lt_msg) {
                response = await fetch(url);
                msgs = await(response.json());
                if (response.ok) {
-                       document.getElementById(target_div).innerHTML = "" ;
+                       target_div.innerHTML = "" ;
 
                        // If we were given an explicit starting point, by all means start there.
                        // Note that we don't have to remove them from the array because we did a 'msgs gt|xxx' command to Citadel.
@@ -43,45 +36,40 @@ function forum_readmessages(target_div, gt_msg, lt_msg) {
                                if (msgs.length > messages_per_page) {
                                        msgs = msgs.slice(msgs.length - messages_per_page);
                                }
-                               new_old_div_name = randomString(5);
+                               new_old_div_name = randomString();
                                if (msgs.length < 1) {
                                        newlt = lt_msg;
                                }
                                else {
                                        newlt = msgs[0];
                                }
-                               document.getElementById(target_div).innerHTML +=
+                               target_div.innerHTML +=
                                        "<div id=\"" + new_old_div_name + "\">" +
-                                       "<div class=\"ctdl-forum-nav\">" +
-                                       "<a href=\"javascript:forum_readmessages('" + new_old_div_name + "', 0, " + newlt + ");\">" +
+                                       "<div class=\"ctdl-forum-nav\" " +
+                                       "onclick=\"javascript:forum_readmessages('" + new_old_div_name + "', 0, " + newlt + ");\">" +
                                        "<i class=\"fa fa-arrow-circle-up\"></i>&nbsp;&nbsp;" +
-                                       _("Older posts") + "&nbsp;&nbsp;<i class=\"fa fa-arrow-circle-up\"></a></div></div></a></div></div>" ;
+                                       _("Older posts") + "&nbsp;&nbsp;<i class=\"fa fa-arrow-circle-up\"></div></div></a></div></div>" ;
                        }
 
-                       // Render an empty div for each message.  We will fill them in later.
-                       //for (var i in msgs) {
-                               //document.getElementById(target_div).innerHTML += "<div id=\"ctdl_msg_" + msgs[i] + "\"> </div>" ;
-                       //}
-
                        // The messages will go here.
-                       let msgs_div_name = "ctdl_msgs_" + randomString(5);
-                       document.getElementById(target_div).innerHTML += "<div id=\"" + msgs_div_name + "\"> </div>" ;
-
+                       let msgs_div_name = randomString();
+                       target_div.innerHTML += "<div id=\"" + msgs_div_name + "\"> </div>" ;
 
                        if (lt_msg == 9999999999) {
-                               new_new_div_name = randomString(5);
+                               new_new_div_name = randomString();
                                if (msgs.length <= 0) {
                                        newgt = gt_msg;
                                }
                                else {
                                        newgt = msgs[msgs.length-1];
                                }
-                               document.getElementById(target_div).innerHTML +=
+                               target_div.innerHTML +=
                                        "<div id=\"" + new_new_div_name + "\">" +
-                                       "<div class=\"ctdl-forum-nav\">" +
-                                       "<a href=\"javascript:forum_readmessages('" + new_new_div_name + "', " + newgt + ", 9999999999);\">" +
+                                       "<div id=\"ctdl-newmsg-here\"></div>" +
+                                       "<div class=\"ctdl-forum-nav\" " +
+                                       "onClick=\"javascript:forum_readmessages('" + new_new_div_name + "', " + newgt + ", 9999999999);\">" +
                                        "<i class=\"fa fa-arrow-circle-down\"></i>&nbsp;&nbsp;" +
-                                       _("Newer posts") + "&nbsp;&nbsp;<i class=\"fa fa-arrow-circle-down\"></a></div></div>" ;
+                                       _("Newer posts") + "&nbsp;&nbsp;<i class=\"fa fa-arrow-circle-down\"></div></div>" ;
                        }
 
                        // Now figure out where to scroll to after rendering.
@@ -103,14 +91,25 @@ function forum_readmessages(target_div, gt_msg, lt_msg) {
                }
                else {
                        // if xhr fails, this will make the link reappear so the user can try again
-                       document.getElementById(target_div).innerHTML = original_text;
+                       target_div.innerHTML = original_text;
                }
        }
        fetch_msg_list();
+
+       // make the nav buttons appear (post a new message, skip this room, goto next room)
+
+       document.getElementById("ctdl-newmsg-button").innerHTML = `<i class="fa fa-edit"></i>&nbsp;` + _("Post message");
+       document.getElementById("ctdl-newmsg-button").style.display = "block";
+
+       document.getElementById("ctdl-skip-button").innerHTML = _("Skip this room") + `&nbsp;<i class="fa fa-arrow-alt-circle-right"></i>`;
+       document.getElementById("ctdl-skip-button").style.display = "block";
+
+       document.getElementById("ctdl-goto-button").innerHTML = _("Goto next room") + `&nbsp;<i class="fa fa-arrow-circle-right"></i>`;
+       document.getElementById("ctdl-goto-button").style.display = "block";
 }
 
 
-// Render a range of messages into the specified prefix
+// Render a range of messages into the specified target div
 function forum_render_messages(message_numbers, msgs_div_name, scroll_to) {
 
        // Build an array of Promises and then wait for them all to resolve.
@@ -118,89 +117,117 @@ function forum_render_messages(message_numbers, msgs_div_name, scroll_to) {
        let msg_promises = Array.apply(null, Array(num_msgs));
        for (i=0; i<num_msgs; ++i) {
                msg_promises[i] = fetch("/ctdl/r/" + escapeHTMLURI(current_room) + "/" + message_numbers[i] + "/json")
-                       .then((response) => response.json());
+                       .then(response => response.json())
+                       .catch((error) => {
+                               response => null;
+                       })
+               ;
        }
 
        // Here is the async function that waits for all the messages to be loaded, and then renders them.
        fetch_msg_list = async() => {
                document.body.style.cursor = "wait";
+               activate_loading_modal();
                await Promise.all(msg_promises);
+               deactivate_loading_modal();
                document.body.style.cursor = "default";
                
                // At this point all of the Promises are resolved and we can render.
                // Note: "let" keeps "i" in scope even through the .then scope
+               let scroll_to_div = null;
                for (let i=0; i<num_msgs; ++i) {
                        msg_promises[i].then((one_message) => {
-                               document.getElementById(msgs_div_name).innerHTML +=
-                                       forum_render_one(message_numbers[i], one_message);
+                               let new_msg_div = forum_render_one(one_message, null);
+                               document.getElementById(msgs_div_name).append(new_msg_div);
+                               if (message_numbers[i] == scroll_to) {
+                                       scroll_to_div = new_msg_div;
+                               }
+                               if (i == num_msgs - 1) {
+                                       scroll_to_div.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
+                               }
                        });
-                       //if (msgnum == scroll_to) {
-                               //document.getElementById(prefix+msgnum).scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"});
-                       //}
                }
        }
 
        fetch_msg_list();
-}
-
-
-// We have to put each XHR for forum_render_messages() into its own stack frame, otherwise it jumbles them together.  I don't know why.
-function forum_render_one(msgnum, msg) {
-
-       mdiv = randomString(10);                                        // div name for this message
-
-       outmsg =
-         "<div id=\"" + mdiv + "\">"                                   // begin message div
-       + "<div class=\"ctdl-msg-wrapper\">"                            // begin message wrapper
-       + "<div class=\"ctdl-avatar\">"                                 // begin avatar
-       + "<img src=\"/ctdl/u/" + msg.from + "/userpic\" width=\"32\" "
-       + "onerror=\"this.parentNode.innerHTML='&lt;i class=&quot;fa fa-user-circle fa-2x&quot;&gt;&lt;/i&gt; '\">"
-       + "</div>"                                                      // end avatar
-       + "<div class=\"ctdl-msg-content\">"                            // begin content
-       + "<div class=\"ctdl-msg-header\">"                             // begin header
-       + "<span class=\"ctdl-msg-header-info\">"                       // begin header info on left side
-       + "<span class=\"ctdl-username\"><a href=\"#\">"                // FIXME link to user profile
-       + msg.from
-       + "</a></span>"                                                 // end username
-       + "<span class=\"ctdl-msgdate\">"
-       + msg.time
-       + "</span>"                                                     // end msgdate
-       + "</span>"                                                     // end header info on left side
-       + "<span class=\"ctdl-msg-header-buttons\">"                    // begin buttons on right side
 
-       + "<span class=\"ctdl-msg-button\">"                            // Reply
-       + "<a href=\"javascript:open_reply_box('"+mdiv+"',false,'"+msg.wefw+"','"+msg.msgn+"');\">"
-       + "<i class=\"fa fa-reply\"></i> " 
-       + _("Reply")
-       + "</a></span>"
+       // Make a note of the highest message number we saw, so we can mark it when we "Goto next room"
+       // (Compared to the text client, this is actually more like <A>bandon than <G>oto)
+       if ((num_msgs > 0) && (message_numbers[num_msgs-1] > last_seen)) {
+               last_seen = message_numbers[num_msgs-1];
+       }
+}
 
-       + "<span class=\"ctdl-msg-button\">"                            // ReplyQuoted
-       + "<a href=\"javascript:open_reply_box('"+mdiv+"',true,'"+msg.wefw+"','"+msg.msgn+"');\">"
-       + "<i class=\"fa fa-comment\"></i> " 
-       + _("ReplyQuoted")
-       + "</a></span>"
 
-       + "<span class=\"ctdl-msg-button\"><a href=\"#\">"              // Delete , show only with permission FIXME
-       + "<i class=\"fa fa-trash\"></i> " 
-       + _("Delete")
-       + "</a></span>"
+// Render a message.  Returns a div object.
+function forum_render_one(msg, existing_div) {
+       let div = null;
+       if (existing_div != null) {                                             // If an existing div was supplied, render into it
+               div = existing_div;
+       }
+       else {                                                                  // Otherwise, create a new one
+               div = document.createElement("div");
+       }
 
-       + "</span>";                                                    // end buttons on right side
-       if (msg.subj) {
+       mdiv = randomString();                                                  // Give the div a new name
+       div.id = mdiv;
+
+       try {
+               outmsg =
+                 "<div class=\"ctdl-fmsg-wrapper\">"                           // begin message wrapper
+               + render_userpic(msg.from)                                      // user avatar
+               + "<div class=\"ctdl-fmsg-content\">"                           // begin content
+               + "<div class=\"ctdl-msg-header\">"                             // begin header
+               + "<span class=\"ctdl-msg-header-info\">"                       // begin header info on left side
+               + render_msg_author(msg, views.VIEW_BBS)                        // author
+               + "<span class=\"ctdl-msgdate\">"
+               + string_timestamp(msg.time,0)
+               + "</span>"                                                     // end msgdate
+               + "</span>"                                                     // end header info on left side
+               + "<span class=\"ctdl-msg-header-buttons\">"                    // begin buttons on right side
+       
+               + "<span class=\"ctdl-msg-button\">"                            // Reply
+               + "<a href=\"javascript:open_reply_box('"+mdiv+"',false,'"+msg.wefw+"','"+msg.msgn+"');\">"
+               + "<i class=\"fa fa-reply\"></i> " 
+               + _("Reply")
+               + "</a></span>"
+       
+               + "<span class=\"ctdl-msg-button\">"                            // ReplyQuoted
+               + "<a href=\"javascript:open_reply_box('"+mdiv+"',true,'"+msg.wefw+"','"+msg.msgn+"');\">"
+               + "<i class=\"fa fa-comment\"></i> " 
+               + _("ReplyQuoted")
+               + "</a></span>";
+       
+               if (can_delete_messages) {
+                       outmsg +=
+                       "<span class=\"ctdl-msg-button\">"
+                       + "<a href=\"javascript:forum_delete_message('"+mdiv+"','"+msg.msgnum+"');\">"
+                       + "<i class=\"fa fa-trash\"></i> " 
+                       + _("Delete")
+                       + "</a></span>";
+               }
+       
+               outmsg +=
+                 "</span>";                                                    // end buttons on right side
+               if (msg.subj) {
+                       outmsg +=
+                       "<br><span class=\"ctdl-msgsubject\">" + msg.subj + "</span>";
+               }
                outmsg +=
-               "<br><span class=\"ctdl-msgsubject\">" + msg.subj + "</span>";
+                 "</div>"                                                      // end header
+               + "<div class=\"ctdl-msg-body\" id=\"" + mdiv + "_body\">"      // begin body
+               + msg.text
+               + "</div>"                                                      // end body
+               + "</div>"                                                      // end content
+               + "</div>"                                                      // end wrapper
+               ;
+       }
+       catch(err) {
+               outmsg = "<div class=\"ctdl-fmsg-wrapper\">" + err.message + "</div>";
        }
-       outmsg +=
-         "</div><br>"                                                  // end header
-       + "<div class=\"ctdl-msg-body\">"                               // begin body
-       + msg.text
-       + "</div>"                                                      // end body
-       + "</div>"                                                      // end content
-       + "</div>"                                                      // end wrapper
-       + "</div>"                                                      // end message div
-       ;
 
-       return(outmsg);
+       div.innerHTML = outmsg;
+       return(div);
 }
 
 
@@ -223,30 +250,48 @@ function compose_references(references, msgid) {
        return refs;
 }
 
+// Delete a message.
+// We don't bother checking for permission because the button only appears if we have permission,
+// and even if someone hacks the client, the server will deny any unauthorized deletes.
+function forum_delete_message(message_div, message_number) {
+       if (confirm(_("Delete this message?")) == true) {
+               async_forum_delete_message = async() => {
+                       response = await fetch(
+                               "/ctdl/r/" + escapeHTMLURI(current_room) + "/" + message_number,
+                               { method: "DELETE" }
+                       );
+                       if (response.ok) {              // If the server accepted the delete, blank out the message div.
+                               document.getElementById(message_div).outerHTML = "";
+                       }
+               }
+               async_forum_delete_message();
+       }
+}
+
 
 // Open a reply box directly below a specific message
 function open_reply_box(parent_div, is_quoted, references, msgid) {
        let new_div = document.createElement("div");
-       let new_div_name = randomString(10);
+       let new_div_name = randomString();
        new_div.id = new_div_name;
 
        document.getElementById(parent_div).append(new_div);
 
        replybox =
-         "<div class=\"ctdl-msg-wrapper ctdl-msg-reply\">"             // begin message wrapper
+         "<div class=\"ctdl-fmsg-wrapper ctdl-msg-reply\">"            // begin message wrapper
        + "<div class=\"ctdl-avatar\">"                                 // begin avatar
-       + "<img src=\"/ctdl/u/" + "FIXME my name" + "/userpic\" width=\"32\" "
+       + "<img src=\"/ctdl/u/" + current_user + "/userpic\" width=\"32\" "
        + "onerror=\"this.parentNode.innerHTML='&lt;i class=&quot;fa fa-user-circle fa-2x&quot;&gt;&lt;/i&gt; '\">"
        + "</div>"                                                      // end avatar
-       + "<div class=\"ctdl-msg-content\">"                            // begin content
+       + "<div class=\"ctdl-fmsg-content\">"                           // begin content
        + "<div class=\"ctdl-msg-header\">"                             // begin header
        + "<span class=\"ctdl-msg-header-info\">"                       // begin header info on left side
-       + "<span class=\"ctdl-username\"><a href=\"#\">"                // FIXME link to user profile
-       + "FIXME my name"
-       + "</a></span>"                                                 // end username
+       + "<span class=\"ctdl-username\">"
+       + current_user                                                  // user = me !
+       + "</span>"
        + "<span class=\"ctdl-msgdate\">"
-       + "FIXME now time"
-       + "</span>"                                                     // end msgdate
+       + string_timestamp((Date.now() / 1000),0)                       // the current date/time (temporary for display)
+       + "</span>"
        + "</span>"                                                     // end header info on left side
        + "<span class=\"ctdl-msg-header-buttons\">"                    // begin buttons on right side
 
@@ -284,13 +329,21 @@ function open_reply_box(parent_div, is_quoted, references, msgid) {
        + "<span id=\"ctdl-replyreferences\" style=\"display:none\">"   // hidden field for references
        + compose_references(references,msgid) + "</span>"
                                                                        // begin body
-       + "<div class=\"ctdl-msg-body\" id=\"ctdl-editor-body\" style=\"padding:5px;\" contenteditable=\"true\">"
-       + "\n"                                                          // empty initial content
-       + "</div>"                                                      // end body
+       + "<div class=\"ctdl-msg-body ctdl-forum-editor-body\" id=\"ctdl-editor-body\" contenteditable=\"true\">"
+       + "\n";                                                         // empty initial content
+
+       if (is_quoted) {
+               replybox += "<br><blockquote>"
+                       + document.getElementById(parent_div+"_body").innerHTML
+                       + "</blockquote>";
+       }
+
+       replybox +=
+         "</div>"                                                      // end body
 
        + "<div class=\"ctdl-msg-header\">"                             // begin footer
        + "<span class=\"ctdl-msg-header-info\">"                       // begin footer info on left side
-       + "x"
+       + "&nbsp;"                                                      // (nothing here for now)
        + "</span>"                                                     // end footer info on left side
        + "<span class=\"ctdl-msg-header-buttons\">"                    // begin buttons on right side
 
@@ -311,25 +364,22 @@ function open_reply_box(parent_div, is_quoted, references, msgid) {
        + "</div>"                                                      // end content
        + "</div>"                                                      // end wrapper
 
-       + "<div id=\"forum_url_entry_box\" class=\"w3-modal\">"         // begin URL entry modal
-       + "     <div class=\"w3-modal-content w3-animate-top w3-card-4\">"
-       + "             <header class=\"w3-container w3-blue\"> "
-       + "                     <p><span>URL:</span></p>"
-       + "             </header>"
-       + "             <div class=\"w3-container w3-blue\">"
-       + "                     <input id=\"forum_txtFormatUrl\" placeholder=\"http://\" style=\"width:100%\">"
-       + "             </div>"
-       + "             <footer class=\"w3-container w3-blue\">"
-       + "                     <p><span class=\"ctdl-msg-button\"><a href=\"javascript:forum_close_urlbox(true);\">"
-       + "                             <i class=\"fa fa-check\" style=\"color:green\"></i> "
-       +                               _("Save")
-       +                       "</a></span>"
-       + "                     <span class=\"ctdl-msg-button\"><a href=\"javascript:forum_close_urlbox(false);\">"
-       + "                             <i class=\"fa fa-trash\" style=\"color:red\"></i> "
-       +                               _("Cancel")
-       +                       "</a></span></p>"
-       + "             </footer>"
-       + "             </div>"
+       + "<div id=\"forum_url_entry_box\" class=\"ctdl-modal ctdl-forum-urlmodal\">"           // begin URL entry modal
+       + "     <div class=\"ctdl-modal-header\">" 
+       + "             <p>URL:</p>"
+       + "     </div>"
+       + "     <div class=\"ctdl-modal-main\">"
+       + "             <input id=\"ctdl-forum-urlbox\" placeholder=\"http://\" style=\"width:100%\">"
+       + "     </div>"
+       + "     <div class=\"ctdl-modal-footer\">"
+       + "             <p><span class=\"ctdl-msg-button\"><a href=\"javascript:forum_close_urlbox(true);\">"
+       + "                     <i class=\"fa fa-check\" style=\"color:green\"></i> "
+       +                       _("Save")
+       +               "</a></span>"
+       + "             <span class=\"ctdl-msg-button\"><a href=\"javascript:forum_close_urlbox(false);\">"
+       + "                     <i class=\"fa fa-trash\" style=\"color:red\"></i> "
+       +                       _("Cancel")
+       +               "</a></span></p>"
        + "     </div>"
        + "     <input id=\"forum_selection_start\" style=\"display:none\"></input>"    // hidden fields
        + "     <input id=\"forum_selection_end\" style=\"display:none\"></input>"      // to store selection range
@@ -365,21 +415,11 @@ function forum_save_message(editor_div_name) {
                + "/dummy_name_for_new_message"
                + "?wefw=" + wefw
                + "&subj=" + subj
-       boundary = randomString(20);
-       body_text =
-               "--" + boundary + "\r\n"
-               + "Content-type: text/html\r\n"
-               + "Content-transfer-encoding: quoted-printable\r\n"
-               + "\r\n"
-               + quoted_printable_encode(
-                       "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>"
-               ) + "\r\n"
-               + "--" + boundary + "--\r\n"
-       ;
+       body_text = "<html><body>" + document.getElementById("ctdl-editor-body").innerHTML + "</body></html>\r\n";
 
        var request = new XMLHttpRequest();
        request.open("PUT", url, true);
-       request.setRequestHeader("Content-type", "multipart/mixed; boundary=\"" + boundary + "\"");
+       request.setRequestHeader("Content-type", "text/html");
        request.onreadystatechange = function() {
                if (request.readyState == 4) {
                        document.body.style.cursor = "default";
@@ -391,8 +431,16 @@ function forum_save_message(editor_div_name) {
                                        }
                                }
 
-                               // change the name of the editor div to make it look like a regular message...
-                               document.getElementById(editor_div_name).innerHTML = "fixme render message " + new_msg_num;
+                               // After saving the message, load it back from the server and replace the editor div with it.
+                               replace_editor_with_final_message = async() => {
+                                       response = await fetch("/ctdl/r/" + escapeHTMLURI(current_room) + "/" + new_msg_num + "/json");
+                                       if (response.ok) {
+                                               newly_posted_message = await(response.json());
+                                               forum_render_one(newly_posted_message, document.getElementById(editor_div_name));
+                                       }
+                               }
+                               replace_editor_with_final_message();
+
                        }
                        else {
                                error_message = request.responseText;
@@ -429,12 +477,25 @@ function forum_close_urlbox(do_save) {
                var start_replace = document.getElementById("forum_selection_start").value;     // use saved selection range
                var end_replace = document.getElementById("forum_selection_end").value;
                new_text = tag.innerHTML.substring(0, start_replace)
-                       + "<a href=\"" + document.getElementById("forum_txtFormatUrl").value + "\">"
+                       + "<a href=\"" + document.getElementById("ctdl-forum-urlbox").value + "\">"
                        + tag.innerHTML.substring(start_replace, end_replace)
                        + "</a>"
                        + tag.innerHTML.substring(end_replace);
                tag.innerHTML = new_text;
        }
-       document.getElementById("forum_txtFormatUrl").value = "";                               // clear url box for next time
+       document.getElementById("ctdl-forum-urlbox").value = "";                                // clear url box for next time
        document.getElementById("forum_url_entry_box").style.display = "none";
 }
+
+
+// User has clicked the "Post message" button.  This is roughly the same as "reply" except there is no parent message.
+function forum_entmsg() {
+       open_reply_box("ctdl-newmsg-here", false, "", "");
+}
+
+
+// RENDERER FOR THIS VIEW
+function view_render_forums() {
+       document.getElementById("ctdl-main").innerHTML = `<div id="ctdl-mrp" class="ctdl-forum-reading-pane"></div>`;
+       forum_readmessages("ctdl-mrp", 0, 9999999999);
+}