summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze <zerodaysfordays@sdf.org>2026-02-16 12:50:24 -0500
committerJakob L. Kreuze <zerodaysfordays@sdf.org>2026-02-16 12:50:24 -0500
commit06bc7adb5e5daa152497efa2fec07334a0126398 (patch)
tree4131e7dc1d5b7e26b9308bb7f71563dfd2335fca
parentc00ace03d64001c6fb49d7ba7e25d75386eb6ae9 (diff)
Fix comment replies
-rw-r--r--jakob/utils/comments.scm31
-rw-r--r--static/css/style.css43
-rw-r--r--static/js/dynamic-comment-form.js51
3 files changed, 114 insertions, 11 deletions
diff --git a/jakob/utils/comments.scm b/jakob/utils/comments.scm
index f9228bd..15824b1 100644
--- a/jakob/utils/comments.scm
+++ b/jakob/utils/comments.scm
@@ -114,17 +114,25 @@
(if (webmention? comment)
'()
(internal-comment-reactions comment)))
+ (define (comment-subject comment)
+ (if (webmention? comment)
+ #f
+ (internal-comment-subject comment)))
`(article (@ ,@(if (not (webmention? comment))
`((id ,(format #f "comment-~a" (internal-comment-id comment))))
'())
- (class "comment-block"))
+ ,(if reply?
+ '(class "comment-block reply")
+ '(class "comment-block")))
(header (@ (class "comment-meta"))
(img (@ (class "comment-avatar")
(src ,(comment-photo comment))
(alt "User Icon")))
(div (@ (class "comment-info"))
(strong ,(comment-name comment))
- ;; (span (@ (class "subject")))
+ ,@(if (comment-subject comment)
+ `((span (@ (class "subject")) ,(comment-subject comment)(span (@ (class "subject")))))
+ '())
(br)
,@(if (and (comment-url comment)
(not (string= "" (comment-url comment)))
@@ -139,11 +147,20 @@
,(date->string (comment-publish-time comment) "~B ~e, ~Y at ~H:~M"))))
(div (@ (class "comment-body"))
,@(comment-content comment))
- (footer (@ (class "comment-reactions"))
- ,@(map (match-lambda
- ((emote . count)
- `(span (@ (class "reaction")) ,(format #f "~a ~a" emote count))))
- (comment-reactions comment)))
+ ,@(if (not (webmention? comment))
+ `((footer (@ (class "comment-reactions"))
+ (button (@ (class "reply-button") (hidden #t)
+ (aria-label "Reply to comment")
+ (data-target ,(format #f "comment-~a" (internal-comment-id comment)))
+ (data-reply-to-id ,(internal-comment-id comment)))
+ "Reply")
+ ,@(map (match-lambda
+ ((emote . count)
+ `(span (@ (class "reaction")) ,(format #f "~a ~a" emote count))))
+ (comment-reactions comment))
+ (button (@ (class "add-reaction") (hidden #t)
+ (aria-label "Add reaction")) "+")))
+ '())
,@(if (and (not reply?)
(internal-comment? comment)
(positive? (length (internal-comment-replies comment))))
diff --git a/static/css/style.css b/static/css/style.css
index 442af67..2fee7bf 100644
--- a/static/css/style.css
+++ b/static/css/style.css
@@ -368,6 +368,25 @@ hr {
font-size: 8px
}
+.reply-button {
+ background: #eee;
+ border: 1px solid #ccc;
+ color: #666;
+ cursor: pointer;
+ font-size: 8px;
+ padding: 2px 6px;
+ border-radius: 3px;
+ text-transform: uppercase;
+ font-family: inherit;
+ margin-right: 5px
+}
+
+.reply-button:hover {
+ background: #e0e0e0;
+ color: #333;
+ border-color: #999
+}
+
.reaction {
background: #eee;
border: 1px solid #ccc;
@@ -468,6 +487,30 @@ hr {
color: #999
}
+#reply-preview-area {
+ padding: 10px;
+ background: #fcfcfc;
+ border: 1px dashed #ccc;
+ margin-bottom: 15px;
+}
+
+#reply-preview-area .comment-block {
+ margin-bottom: 0;
+ border-right: 1px solid #eee; /* Visual hint it's a preview */
+}
+
+#cancel-reply {
+ background: #333;
+ color: #fff;
+ border: none;
+ padding: 2px 5px;
+ text-transform: uppercase;
+}
+
+#cancel-reply:hover {
+ background: #cc0000;
+}
+
.legacy-warning {
background: linear-gradient(to bottom,#fff3e0 0,#ffe0b2 100%);
border: 1px dotted #fb8c00;
diff --git a/static/js/dynamic-comment-form.js b/static/js/dynamic-comment-form.js
index 809a755..75e2fb6 100644
--- a/static/js/dynamic-comment-form.js
+++ b/static/js/dynamic-comment-form.js
@@ -81,12 +81,55 @@ window.addEventListener("load", () => {
});
window.addEventListener("load", () => {
- // Unhide additional comment actions if Javascript is enabled.
- let additionalActionsRows = document.querySelectorAll(".comment-additional-actions");
- for (let row of additionalActionsRows) {
- row.removeAttribute("hidden");
+ const replyToField = document.getElementById("reply-to");
+ const commentFormModule = document.querySelector('.comment-form-module');
+
+ // Create a "Replying To" preview container dynamically
+ const previewContainer = document.createElement('div');
+ previewContainer.id = 'reply-preview-area';
+ previewContainer.style.display = 'none';
+ commentFormModule.prepend(previewContainer);
+
+ const replyButtons = document.querySelectorAll(".reply-button");
+ for (const button of replyButtons) {
+ button.removeAttribute("hidden");
+ button.addEventListener('click', (e) => {
+ replyTo.value = button.getAttribute("data-reply-to-id");
+ const targetId = button.getAttribute('data-target');
+ const originalComment = document.getElementById(targetId);
+
+ if (originalComment) {
+ const clone = originalComment.cloneNode(true);
+ const nestedReplies = clone.querySelectorAll('.reply');
+ nestedReplies.forEach(reply => reply.remove());
+ const actionButtons = clone.querySelector('.comment-reactions');
+ if (actionButtons) actionButtons.remove();
+ previewContainer.innerHTML = `
+<div>
+ <strong>You are replying to this comment:</strong>
+ <button id="cancel-reply" style="margin-left: auto; cursor: pointer; font-size: 8px;">Cancel Reply</button>
+</div>
+<div class="reply-preview-content" style="opacity: 0.8; scale: 0.95; origin: top left;">
+ ${clone.outerHTML}
+</div>
+`;
+ previewContainer.style.display = 'block';
+ commentFormModule.scrollIntoView({ behavior: 'smooth', block: 'center' });
+ document.getElementById('cancel-reply').addEventListener('click', () => {
+ replyTo.value = "";
+ previewContainer.style.display = 'none';
+ previewContainer.innerHTML = '';
+ });
+ }
+ })
}
+ document.addEventListener('click', (e) => {
+ if (e.target.classList.contains('reply-button')) {
+
+ }
+ });
+
let header = document.getElementById("comment-form-header");
let replyTo = document.getElementById("reply-to");
let buttons = document.querySelectorAll(".comment-reply-button");