summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
Diffstat (limited to 'static')
-rw-r--r--static/js/controllers/base_controller.js40
-rw-r--r--static/js/controllers/comments_controller.js39
-rw-r--r--static/js/controllers/pagination_controller.js52
-rw-r--r--static/js/controllers/replies_controller.js82
-rw-r--r--static/js/paginator.js15
5 files changed, 133 insertions, 95 deletions
diff --git a/static/js/controllers/base_controller.js b/static/js/controllers/base_controller.js
index 2ef359c..40a16ca 100644
--- a/static/js/controllers/base_controller.js
+++ b/static/js/controllers/base_controller.js
@@ -1,5 +1,5 @@
export class BaseController {
- constructor() {
+ constructor() {
this.comments_server_url = document.getElementById('comments-client').src;
this.origin = window.location.origin;
this.protocol = this.getProtocol();
@@ -7,39 +7,39 @@ export class BaseController {
this.post = window.location.pathname;
this.comments_server_host = `${this.protocol}//${this.domain}`;
this.parser = new DOMParser();
- }
+ }
- async submit(event, route, form = new FormData(event.target)) {
+ async submit(event, route, form = new FormData(event.target)) {
event.preventDefault();
try {
- const response = await fetch(route, { method: "POST", body: form });
+ const response = await fetch(route, { method: "POST", body: form });
- response.text().then((response_document) => {
+ response.text().then((response_document) => {
this.renderSubmitResponse(response_document);
- });
- } catch(error) {}
- }
+ });
+ } catch (error) { }
+ }
- getDomain() {
+ getDomain() {
return this.comments_server_url.split('/')[2];
- }
+ }
- getProtocol() {
+ getProtocol() {
return this.comments_server_url.split('/')[0];
- }
+ }
- htmlFromResponse(body) {
+ htmlFromResponse(body) {
return this.parser.parseFromString(body, "text/html");
- }
+ }
- async get(route) {
+ async get(route) {
try {
- const response = await fetch(`${this.comments_server_host}${route}`);
+ const response = await fetch(`${this.comments_server_host}${route}`);
- return response.text().then(this.htmlFromResponse.bind(this));
- } catch(error) {
- return null;
+ return response.text().then(this.htmlFromResponse.bind(this));
+ } catch (error) {
+ return null;
}
- }
+ }
}
diff --git a/static/js/controllers/comments_controller.js b/static/js/controllers/comments_controller.js
index 683f5ca..86abfe6 100644
--- a/static/js/controllers/comments_controller.js
+++ b/static/js/controllers/comments_controller.js
@@ -1,51 +1,52 @@
import { BaseController } from "./base_controller.js";
-import { Paginator } from "../paginator.js";
+import { PaginationController } from "./pagination_controller.js";
export class CommentsController extends BaseController {
- constructor(replies_controller) {
+ constructor(replies_controller) {
super();
this.replies_controller = replies_controller;
this.comments_node = document.getElementById("comments-thread");
- this.paginator = new Paginator(this.comments_server_host, "/api/comments", this.post);
+ this.paginator = new PaginationController(this.comments_server_host, "/api/comments", this.post,
+ this.replies_controller);
this.renderForm();
this.renderComments();
- }
+ }
- renderForm() {
+ renderForm() {
this.get("/api/comments/new").then((value) => {
- const form = value?.getElementById("comment-form");
+ const form = value?.getElementById("comment-form");
- if(form != null) {
+ if (form != null) {
this.comments_node.appendChild(form);
this.form_element = document.getElementById("comment-form");
this.form_element.addEventListener("submit", this.submit.bind(this));
- }
+ }
});
- }
+ }
- renderComments() {
+ renderComments() {
this.get(`/api/comments?path=${this.post}`).then((value) => {
- const comments = value?.getElementById("comment-section");
+ const comments = value?.getElementById("comment-section");
- if(comments != null) {
+ if (comments != null) {
this.comments_node.appendChild(comments);
this.replies_controller.init();
this.paginator.populatePageAnchors();
- }
+ }
});
- }
+ }
- renderSubmitResponse(response_document) {
+ 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) {
+ async submit(event) {
var form = new FormData(event.target);
form.append("domain", `${window.location.protocol}//${window.location.host}`);
super.submit(event, `${this.comments_server_host}/api/comments?path=${this.post}`, form);
- }
- }
+ }
+}
diff --git a/static/js/controllers/pagination_controller.js b/static/js/controllers/pagination_controller.js
new file mode 100644
index 0000000..bfb1a48
--- /dev/null
+++ b/static/js/controllers/pagination_controller.js
@@ -0,0 +1,52 @@
+import { BaseController } from "./base_controller.js";
+
+export class PaginationController extends BaseController {
+ constructor(host, context, path, replies_controller) {
+ super();
+ this.replies_controller = replies_controller;
+ this.endpoint = `${host}${context}?path=${path}`;
+ this.comments_node = document.getElementById("comments-thread");
+ }
+
+ populatePageAnchors() {
+ const pagination_widget = document.querySelector(".pagination");
+ var anchors = pagination_widget.querySelectorAll('a');
+
+ for (let anchor of anchors) {
+ var page = /\d/.exec(anchor.id)[0];
+ anchor.setAttribute("href", `${this.endpoint}&page=${page}`);
+ }
+
+ this.listenForPageChange(anchors);
+ }
+
+ listenForPageChange(page_selectors) {
+ for (let anchor of page_selectors) {
+ anchor.addEventListener("click", this.changeCommentsPage.bind(this))
+ }
+ }
+
+ changeCommentsPage(event) {
+ event.preventDefault();
+
+ fetch(event.target.getAttribute("href"))
+ .then((response) => {
+ return response.text();
+ })
+ .then((data) => {
+ this.loadComments(this.htmlFromResponse(data));
+ });
+ }
+
+ loadComments(body) {
+ const previous_comments = document.getElementById("comment-section");
+ const comments = body?.getElementById("comment-section");
+
+ if(comments) {
+ previous_comments.remove();
+ this.comments_node.appendChild(comments);
+ this.replies_controller.init();
+ this.populatePageAnchors();
+ }
+ }
+} \ No newline at end of file
diff --git a/static/js/controllers/replies_controller.js b/static/js/controllers/replies_controller.js
index c383e57..dfcafb2 100644
--- a/static/js/controllers/replies_controller.js
+++ b/static/js/controllers/replies_controller.js
@@ -1,70 +1,70 @@
import { BaseController } from "./base_controller.js";
export class RepliesController extends BaseController {
- constructor() {
+ constructor() {
super();
- }
+ }
- async init() {
+ 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) {
+ async submit(event) {
await super.submit(event, `${this.comments_server_host}/api/comments/${this.comment_id}/replies`);
- }
+ }
- listenButtons(class_name, func) {
+ listenButtons(class_name, func) {
const buttons = document.getElementsByClassName(class_name);
- if(buttons) {
- for(let button of buttons)
+ if (buttons) {
+ for (let button of buttons)
button.addEventListener("click", func);
}
- }
+ }
- showReplyForm(event) {
+ showReplyForm(event) {
const replies_section = event.target.parentElement.parentElement.childNodes[3];
const form = replies_section.querySelector(".reply-form");
- if(form == null) {
- replies_section.appendChild(this.reply_form);
- this.setCommentId(replies_section);
- this.reply_form.addEventListener("submit", this.submit.bind(this));
+ 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();
- }
+ form.remove();
+ }
- 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 present_replies = comment_replies_section.querySelector(".replies-section");
- this.setCommentId(comment_replies_section);
+ 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 present_replies = comment_replies_section.querySelector(".replies-section");
+ this.setCommentId(comment_replies_section);
- if(present_replies != null) {
- present_replies.remove();
+ if (present_replies != null) {
+ present_replies.remove();
- return;
- }
+ return;
+ }
+
+ this.get(`/api/comments/${this.comment_id}/replies`).then((value) => {
+ const replies = value?.getElementById(`replies-section-${this.comment_id}`);
- 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);
- });
- }
+ if (replies != null)
+ comment_replies_section.appendChild(replies);
+ });
+ }
- setCommentId(replies_section) {
- 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");
+ async getReplyForm() {
+ var form = await this.get("/api/replies/new");
- return form.getElementsByClassName("reply-form")[0];
- }
+ return form.getElementsByClassName("reply-form")[0];
+ }
}
diff --git a/static/js/paginator.js b/static/js/paginator.js
deleted file mode 100644
index 9a7ed65..0000000
--- a/static/js/paginator.js
+++ /dev/null
@@ -1,15 +0,0 @@
-export class Paginator {
- constructor(host, context, path) {
- this.endpoint = `${host}${context}?path=${path}`;
- }
-
- populatePageAnchors() {
- const pagination_widget = document.querySelector(".pagination");
- var anchors = pagination_widget.querySelectorAll('a');
-
- for(let anchor of anchors) {
- var page = /\d/.exec(anchor.id)[0];
- anchor.setAttribute("href", `${this.endpoint}&page=${page}`);
- }
- }
-} \ No newline at end of file