/* CopyLeft 2022-2023 Pascal Engélibert (why copyleft? -> https://txmn.tk/blog/why-copyleft/) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, version 3 of the License. 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/. */ var webcomments = {}; const MODE_TOPIC = 1;// param: {topic:str} const ORDER_BY_DATE_ASC = 1; const ORDER_BY_DATE_DESC = 2; const DEFAULT_CONFIG = { default_order: ORDER_BY_DATE_ASC, /*template_comment: `

{{comment.author}} {{comment.post_time}}

{{comment.text}}

`,*/ template_pending_comment: `

{{comment.post_time}} Remove

`, template_approved_comment: `

{{comment.post_time}} Remove

`, template_widget: `
New comment


`, }; class Webcomment { constructor(root_id, api, mode, mode_param, config) { this.root_id = root_id; this.api = api; this.mode = mode; this.mode_param = mode_param; this.config = config; this.root = document.getElementById(root_id); this.root.innerHTML = config.template_widget.replaceAll("{{root.id}}", this.root_id);; this.elem_comments = this.root.getElementsByClassName("comments")[0]; this.comments = []; switch(mode) { case MODE_TOPIC: var this_ = this; this.query_comments_by_topic(mode_param.topic, function(resp) { this_.append_comments(resp.approved_comments); }); break; default: console.log("Webcomment: invalid mode"); } } query_comments_by_topic(topic, success) { if("admin_psw" in this) { $.ajax({ method: "POST", url: this.api+"/api/admin/comments_by_topic", data: JSON.stringify({ admin_psw: this.admin_psw, topic: topic, }), success: success, dataType: "json", contentType: "application/json; charset=utf-8", }); } else { $.ajax({ method: "POST", url: this.api+"/api/comments_by_topic", data: JSON.stringify({ mutation_token: "", topic: topic, }), success: success, dataType: "json", contentType: "application/json; charset=utf-8", }); } } query_new_comment(topic, author, email, text, success) { $.ajax({ method: "POST", url: this.api+"/api/new_comment", data: JSON.stringify({ author: author, email: email, text: text, topic: topic, }), success: success, dataType: "json", contentType: "application/json; charset=utf-8", }); } post_new_comment() { var elem_author = $("#comments .comment-new-form [name=author]")[0]; var elem_email = $("#comments .comment-new-form [name=email]")[0]; var elem_text = $("#comments .comment-new-form [name=text]")[0]; switch(this.mode) { case MODE_TOPIC: var comment = { topic: this.mode_param.topic, author: elem_author.value, email: elem_email.value, text: elem_text.value, }; var this_ = this; this.query_new_comment(comment.topic, comment.author, comment.email, comment.text, function(resp) { if(resp.id) { comment.id = resp.id; comment.post_time = resp.post_time; this_.append_comments([], [comment]); elem_text.value = ""; } }); break; default: console.log("Webcomment: invalid mode"); } } append_comments(approved_comments, pending_comments=[]) { var this_ = this; for(var i in pending_comments) { var comment = pending_comments[i]; this.comments[comment.id] = comment; var post_time = new Date(comment.post_time*1000); var comment_html = this.config.template_pending_comment; comment_html = comment_html.replaceAll("{{root.id}}", this.root_id); comment_html = comment_html.replaceAll("{{comment.id}}", comment.id); //comment_html = comment_html.replaceAll("{{comment.author}}", comment.author); comment_html = comment_html.replaceAll("{{comment.post_time}}", post_time.toLocaleDateString()+" "+post_time.toLocaleTimeString()); //comment_html = comment_html.replaceAll("{{comment.text}}", comment.text); $(this.elem_comments).append(comment_html); var elem = document.getElementById(this.root_id+"-pending-"+comment.id); elem.getElementsByClassName("comment-author")[0].innerHTML = comment.author; elem.getElementsByClassName("comment-text")[0].innerHTML = comment.text; if("email" in comment) elem.getElementsByClassName("comment-email")[0].innerHTML = comment.email; else elem.getElementsByClassName("comment-email")[0].remove(); if("addr" in comment) elem.getElementsByClassName("comment-addr")[0].innerHTML = comment.addr; else elem.getElementsByClassName("comment-addr")[0].remove(); if(comment.editable) { var edition_remove_elems = elem.getElementsByClassName("comment-edition-remove"); console.log(edition_remove_elems); for(var j = 0; j < edition_remove_elems.length; j ++) { edition_remove_elems[j].onclick = function() { this_.remove_comment(comment.id); }; } } else { var edition_elems = elem.getElementsByClassName("comment-edition"); for(var j = 0; j < edition_elems.length; j ++) { edition_elems[j].remove(); } } } for(var i in approved_comments) { var comment = approved_comments[i]; this.comments[comment.id] = comment; var post_time = new Date(comment.post_time*1000); var comment_html = this.config.template_approved_comment; comment_html = comment_html.replaceAll("{{root.id}}", this.root_id); comment_html = comment_html.replaceAll("{{comment.id}}", comment.id); //comment_html = comment_html.replaceAll("{{comment.author}}", comment.author); comment_html = comment_html.replaceAll("{{comment.post_time}}", post_time.toLocaleDateString()+" "+post_time.toLocaleTimeString()); //comment_html = comment_html.replaceAll("{{comment.text}}", comment.text); $(this.elem_comments).append(comment_html); var elem = document.getElementById(this.root_id+"-"+comment.id); elem.getElementsByClassName("comment-author")[0].innerHTML = comment.author; elem.getElementsByClassName("comment-text")[0].innerHTML = comment.text; if("email" in comment) elem.getElementsByClassName("comment-email")[0].innerHTML = comment.email; else elem.getElementsByClassName("comment-email")[0].remove(); } } remove_comment(comment_id) { var this_ = this; if(this.admin_psw) { $.ajax({ method: "POST", url: this.api+"/api/admin/remove_comment", data: JSON.stringify({ admin_psw: this.admin_psw, comment_id: comment_id, }), success: function(resp) { console.log(resp); // TODO check resp var comment_elems = this_.elem_comments.getElementsByClassName("comment-"+comment_id); for(var j = 0; j < comment_elems.length; j ++) { comment_elems[j].remove(); } var comment_elems = this_.elem_comments.getElementsByClassName("comment-pending-"+comment_id); for(var j = 0; j < comment_elems.length; j ++) { comment_elems[j].remove(); } this_.comments[comment_id] }, dataType: "json", contentType: "application/json; charset=utf-8", }); } } prompt_admin_psw() { this.admin_psw = prompt("Admin password"); if(this.admin_psw == null) return; switch(this.mode) { case MODE_TOPIC: var this_ = this; this.query_comments_by_topic(this.mode_param.topic, function(resp) { this_.elem_comments.innerHTML = ""; this_.append_comments(resp.approved_comments, resp.pending_comments); }); break; default: console.log("Webcomment: invalid mode"); } } } function webcomment_topic(root_id, api, topic, config=DEFAULT_CONFIG) { webcomments[root_id] = (new Webcomment(root_id, api, MODE_TOPIC, {topic: topic}, config)); } function post_new_comment(root_id) { webcomments[root_id].post_new_comment(); }