From a0ff547c4bd4361f60baf2d82d511a291b5996ff Mon Sep 17 00:00:00 2001 From: HombreLaser Date: Sat, 24 Feb 2024 17:12:34 -0600 Subject: Improve comments rendering --- .vscode/launch.json | 26 +++++++++ .vscode/simple-comments.code-workspace | 39 +++++++++++++ src/controllers/replies_controller.py | 6 +- src/lib/blacklist_matcher.py | 3 + static/js/controllers/base_controller.js | 66 +++++++++++----------- static/js/controllers/comments_controller.js | 72 ++++++++++++------------ static/js/controllers/replies_controller.js | 84 ++++++++++++++++------------ templates/replies/form.jinja | 16 +++--- templates/replies/index.jinja | 4 +- 9 files changed, 199 insertions(+), 117 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/simple-comments.code-workspace diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..90ecc77 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "Python Debugger: Flask", + "type": "debugpy", + "request": "launch", + "module": "flask", + "env": { + "FLASK_APP": "main.py", + "FLASK_DEBUG": "1" + }, + "args": [ + "run", + "--debug", + "--no-debugger", + "--no-reload" + ], + "jinja": true + } + ] +} \ No newline at end of file diff --git a/.vscode/simple-comments.code-workspace b/.vscode/simple-comments.code-workspace new file mode 100644 index 0000000..db16e41 --- /dev/null +++ b/.vscode/simple-comments.code-workspace @@ -0,0 +1,39 @@ +{ + "folders": [ + { + "path": ".." + }, + { + "path": "../../../../Jekyll Pages/russian-lessons" + } + ], + "settings": {}, + "launch": { + "version": "0.2.0", + "configurations": [ + { + "type": "firefox", + "request": "launch", + "reAttach": true, + "name": "Launch localhost", + "url": "http://127.0.0.1:4000", + "webRoot": "${workspaceFolder:russian-lessons}/_site", + "pathMappings": [ + { "url": "http://127.0.0.1:5000/static/js", "path": "${workspaceFolder:simple-comments}/static/js" } + ] + }, + { + "name": "Attach", + "type": "firefox", + "request": "attach" + }, + { + "name": "Launch WebExtension", + "type": "firefox", + "request": "launch", + "reAttach": true, + "addonPath": "${workspaceFolder:russian-lessons}/_site" + } + ] + } +} \ No newline at end of file diff --git a/src/controllers/replies_controller.py b/src/controllers/replies_controller.py index bd47a44..6713e26 100644 --- a/src/controllers/replies_controller.py +++ b/src/controllers/replies_controller.py @@ -12,7 +12,9 @@ comments_query = CommentsQuery() @replies_blueprint.get('/api/comments//replies') def index(comment_id): - return render_template('replies/index.jinja', page=comments_query.replies_of(comment_id)) + comment = db.get_or_404(Comment, comment_id) + + return render_template('replies/index.jinja', page=comments_query.replies_of(comment.id), comment=comment) @replies_blueprint.get('/api/replies/new') @@ -28,4 +30,4 @@ def create(comment_id): if status_code != 200: abort(status_code) - return render_template('comments/index.jinja') + return render_template('comments/index.jinja', page=comments_query.replies_of(comment_id)) diff --git a/src/lib/blacklist_matcher.py b/src/lib/blacklist_matcher.py index 0f28953..4618792 100644 --- a/src/lib/blacklist_matcher.py +++ b/src/lib/blacklist_matcher.py @@ -6,6 +6,9 @@ from config import user_config def contains_forbidden_term(comment): matcher = build_matcher() + if comment is None: + return False + return matcher.search(comment) is not None diff --git a/static/js/controllers/base_controller.js b/static/js/controllers/base_controller.js index fc05e29..6caa9dd 100644 --- a/static/js/controllers/base_controller.js +++ b/static/js/controllers/base_controller.js @@ -1,46 +1,46 @@ export class BaseController { - constructor() { - this.comments_server_url = document.getElementById('comments-client').src; - this.origin = window.location.origin; - this.protocol = this.getProtocol(); - this.domain = this.getDomain(); - this.post = window.location.pathname; - this.comments_server_host = `${this.protocol}//${this.domain}`; - this.parser = new DOMParser(); - } - - async submit(event, route) { - event.preventDefault(); - const form = new FormData(event.target); - - try { + constructor() { + this.comments_server_url = document.getElementById('comments-client').src; + this.origin = window.location.origin; + this.protocol = this.getProtocol(); + this.domain = this.getDomain(); + this.post = window.location.pathname; + this.comments_server_host = `${this.protocol}//${this.domain}`; + this.parser = new DOMParser(); + } + + async submit(event, route) { + event.preventDefault(); + const form = new FormData(event.target); + + try { const response = await fetch(route, { method: "POST", body: form }); response.text().then((response_document) => { - this.renderSubmitResponse(response_document); + this.renderSubmitResponse(response_document); }); - } catch(error) {} - } + } catch(error) {} + } - getDomain() { - return this.comments_server_url.split('/')[2]; - } + getDomain() { + return this.comments_server_url.split('/')[2]; + } - getProtocol() { - return this.comments_server_url.split('/')[0]; - } + getProtocol() { + return this.comments_server_url.split('/')[0]; + } - htmlFromResponse(body) { - return this.parser.parseFromString(body, "text/html"); - } + htmlFromResponse(body) { + return this.parser.parseFromString(body, "text/html"); + } - async get(route) { - try { + async get(route) { + try { const response = await fetch(`${this.comments_server_host}${route}`); return response.text().then(this.htmlFromResponse.bind(this)); - } catch(error) { - return null; - } - } + } catch(error) { + return null; + } + } } diff --git a/static/js/controllers/comments_controller.js b/static/js/controllers/comments_controller.js index 8989c5a..a21bd05 100644 --- a/static/js/controllers/comments_controller.js +++ b/static/js/controllers/comments_controller.js @@ -1,45 +1,45 @@ import { BaseController } from "./base_controller.js"; export class CommentsController extends BaseController { - constructor(replies_controller) { - super(); - this.replies_controller = replies_controller; - this.comments_node = document.getElementById("comments-thread"); - this.renderForm(); - this.renderComments(); - } - - renderForm() { - this.get("/api/comments/new").then((value) => { + constructor(replies_controller) { + super(); + this.replies_controller = replies_controller; + this.comments_node = document.getElementById("comments-thread"); + this.renderForm(); + this.renderComments(); + } + + renderForm() { + this.get("/api/comments/new").then((value) => { const form = value?.getElementById("comment-form"); if(form != null) { - this.comments_node.appendChild(form); - this.form_element = document.getElementById("comment-form"); - this.form_element.addEventListener("submit", this.submit.bind(this)); + this.comments_node.appendChild(form); + this.form_element = document.getElementById("comment-form"); + this.form_element.addEventListener("submit", this.submit.bind(this)); } - }); - } - - renderComments() { - this.get(`/api/comments?path=${this.post}`).then((value) => { - const comments = value?.getElementById("comment-section"); - - if(comments != null) { - this.comments_node.appendChild(comments); - this.replies_controller.init(); - } - }); - } - - renderSubmitResponse(response_document) { - const new_comments = this.htmlFromResponse(response_document).getElementById("comment-section"); - const comments = document.getElementById("comment-section"); - comments.replaceWith(new_comments); - } - - async submit(event) { - super.submit(event, `${this.comments_server_host}/api/comments?path=${this.post}`); - } + }); + } + + renderComments() { + this.get(`/api/comments?path=${this.post}`).then((value) => { + const comments = value?.getElementById("comment-section"); + + if(comments != null) { + this.comments_node.appendChild(comments); + this.replies_controller.init(); + } + }); + } + + renderSubmitResponse(response_document) { + const new_comments = this.htmlFromResponse(response_document).getElementById("comment-section"); + const comments = document.getElementById("comment-section"); + comments.replaceWith(new_comments); + } + + async submit(event) { + super.submit(event, `${this.comments_server_host}/api/comments?path=${this.post}`); + } } diff --git a/static/js/controllers/replies_controller.js b/static/js/controllers/replies_controller.js index 5d638a5..5f767be 100644 --- a/static/js/controllers/replies_controller.js +++ b/static/js/controllers/replies_controller.js @@ -1,58 +1,70 @@ import { BaseController } from "./base_controller.js"; export class RepliesController extends BaseController { - constructor() { - super(); - } + constructor() { + super(); + } - async init() { - this.comment_id = 0; - this.reply_form = await this.getReplyForm(); - this.listenButtons("replies-button", this.showReplies.bind(this)); - this.listenButtons("new-reply-button", this.showReplyForm.bind(this)); - } + async init() { + this.comment_id = 0; + this.reply_form = await this.getReplyForm(); + this.listenButtons("replies-button", this.renderReplies.bind(this)); + this.listenButtons("new-reply-button", this.showReplyForm.bind(this)); + } - async submit(event) { - await super.submit(event, `${this.comments_server_host}/api/comments/${this.comment_id}/replies`); - } + async submit(event) { + await super.submit(event, `${this.comments_server_host}/api/comments/${this.comment_id}/replies`); + } - listenButtons(class_name, func) { - const buttons = document.getElementsByClassName(class_name); + listenButtons(class_name, func) { + const buttons = document.getElementsByClassName(class_name); - if(buttons) { + if(buttons) { for(let button of buttons) - button.addEventListener("click", func); - } - } + button.addEventListener("click", func); + } + } - showReplyForm(event) { - const replies_section = event.target.parentElement.parentElement.childNodes[3]; - const form = replies_section.querySelector(".reply-form"); + showReplyForm(event) { + const replies_section = event.target.parentElement.parentElement.childNodes[3]; + const form = replies_section.querySelector(".reply-form"); - if(form == null) { + if(form == null) { replies_section.appendChild(this.reply_form); this.setCommentId(replies_section); this.reply_form.addEventListener("submit", this.submit.bind(this)); - } else - form.remove(); - } + } else + form.remove(); + } - showReplies(event) { - /* The div to contain the comment's replies. From the element id - we can get the comment's id. */ - this.setCommentId(event.target); - console.log("You're in showReplies()"); - } + renderReplies(event) { + /* The div to contain the comment's replies. From the element id + we can get the comment's id. */ + const comment_replies_section = event.target.parentElement.parentElement.parentElement; + const replies = comment_replies_section.querySelector(".replies-section"); + this.setCommentId(comment_replies_section); + + if( replies != null) { + replies.remove(); - setCommentId(parent) { - const replies_section = parent.parentElement.parentElement.childNodes[3]; + return; + } + + this.get(`/api/comments/${this.comment_id}/replies`).then((value) => { + const replies = value?.getElementById(`replies-section-${this.comment_id}`); + + if(replies != null) + comment_replies_section.appendChild(replies); + }); + } - this.comment_id = /\d/.exec(replies_section.id)[0]; + setCommentId(replies_section) { + this.comment_id = /\d/.exec(replies_section.id)[0]; } async getReplyForm() { - var form = await this.get("/api/replies/new"); + var form = await this.get("/api/replies/new"); - return form.getElementsByClassName("reply-form")[0]; + return form.getElementsByClassName("reply-form")[0]; } } diff --git a/templates/replies/form.jinja b/templates/replies/form.jinja index f585d4e..e65e244 100644 --- a/templates/replies/form.jinja +++ b/templates/replies/form.jinja @@ -1,17 +1,17 @@ -
+
- - + +
- - + +
- +
- +
diff --git a/templates/replies/index.jinja b/templates/replies/index.jinja index df0705a..c1fc6ea 100644 --- a/templates/replies/index.jinja +++ b/templates/replies/index.jinja @@ -1,4 +1,4 @@ -
+
{% for reply in page.items %}
@@ -6,7 +6,7 @@ {% if reply.author is eq('') %} Anonymous said: {% else %} - {{ reply.author }} said: + {{ reply.author }} replied: {% endif %}
-- cgit v1.2.3