Implement replies in post header

This commit is contained in:
Dominic Ferrando
2025-04-19 16:40:43 -04:00
parent 656595e47e
commit 34d3ec5366
5 changed files with 82 additions and 24 deletions
+22 -13
View File
@@ -8,27 +8,36 @@ import (
func EnrichPost(body string) string {
var b strings.Builder
for _, raw := range strings.Split(body, "\n") {
var out string
switch {
case strings.HasPrefix(raw, ">>"):
postId := strings.TrimPrefix(raw, ">>")
esc := template.HTMLEscapeString(raw)
out = fmt.Sprintf(
for _, rawLine := range strings.Split(body, "\n") {
var outLine string
for i, rawWord := range strings.Split(rawLine, " ") {
var outWord string
if strings.HasPrefix(rawWord, ">>") {
postId := strings.TrimPrefix(rawWord, ">>")
esc := template.HTMLEscapeString(rawWord)
outWord = fmt.Sprintf(
`<a onclick="onReplyLinkClick(event)"
onmouseover="highlightPost(%[1]s, event)" `+
`onmouseleave="highlightPost(%[1]s, event, false)" `+
`href="#post-%[1]s" class="reply-link">%s</a>`,
postId, esc,
)
case strings.HasPrefix(raw, ">"):
esc := template.HTMLEscapeString(raw)
out = `<span class="greentext">` + esc + `</span>`
default:
out = template.HTMLEscapeString(raw)
} else {
outWord = template.HTMLEscapeString(rawWord)
}
b.WriteString(out)
if i != 0 {
outLine += " "
}
outLine += outWord
}
if strings.HasPrefix(rawLine, ">") && !strings.HasPrefix(rawLine, ">>") {
outLine = `<span class="greentext">` + outLine + `</span>`
}
b.WriteString(outLine)
b.WriteString("<br/>")
}
return b.String()
+15 -2
View File
@@ -146,12 +146,13 @@ body {
.thread-subject {
font-weight: bold;
color: #b294bb;
color: #0F0C5D;
margin-right: 5px;
}
.post-op {
margin-bottom: 10px;
font-size: 14px;
}
.post {
@@ -159,8 +160,9 @@ body {
margin: 5x;
padding: 10px;
background-color: #D6DAF0;
border: 1px solid #282a2e;
border: 1px solid #B7C5D9;
margin-bottom: 10px;
font-size: 14px;
}
.post-highlighted {
@@ -211,6 +213,17 @@ body {
cursor: pointer;
}
.reply-link-header {
color: rgb(52, 52, 92);
text-decoration: underline;
cursor: pointer;
margin-left: 8px;
}
.reply-link-header:hover {
color: #D00;
}
/* GENERAL LAYOUT */
.container {
+34
View File
@@ -0,0 +1,34 @@
const posts = Array.from(document.querySelectorAll("article"));
const replies = {};
for (const post of posts) {
const postId = +post.id.split("-")[1];
const postBody = post.querySelector("p").textContent;
const replyLinkIds = [...postBody.matchAll(/(?:^|\s)>>(\d+)\b/g)].map(m => parseInt(m[1]));
for (const replyLinkId of replyLinkIds) {
replies[replyLinkId] = replies[replyLinkId] ?
replies[replyLinkId].add(postId) :
replies[replyLinkId] = new Set([postId]);
}
}
for (const postId in replies) {
const post = $(`post-${postId}`);
const postRepliesContainer = post.querySelector(".post-replies");
const replyIds = Array.from(replies[postId]);
for (const replyId of replyIds) {
const replyLink = document.createElement("a");
replyLink.textContent = `>>${replyId}`;
replyLink.classList.add("reply-link-header");
replyLink.setAttribute("href", `#post-${replyId}`);
replyLink.onmouseover = (e) => highlightPost(+replyId, e);
replyLink.onmouseleave = (e) => highlightPost(+replyId, e, false);
replyLink.onclick = onReplyLinkClick;
postRepliesContainer.append(replyLink);
}
}
+1 -1
View File
@@ -8,7 +8,7 @@ templ Layout() {
<title>Comfychan</title>
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
<script src="https://unpkg.com/hyperscript.org@0.9.14"></script>
<script src="/static/index.js" defer></script>
<script src="/static/index.js"></script>
<link rel="stylesheet" href="/static/reset.css"/>
<link rel="stylesheet" href="/static/index.css"/>
</head>
+2
View File
@@ -36,6 +36,7 @@ templ ThreadPost(post database.Post, thread *database.Thread) {
>
No.{ strconv.Itoa(post.Id) }
</span>
<div class="post-replies"></div>
</header>
<p>
@templ.Raw(util.EnrichPost(post.Body))
@@ -52,6 +53,7 @@ templ ThreadPosts(posts []database.Post) {
templ Thread(board database.Board, thread database.Thread, posts []database.Post) {
@shared.Layout() {
<script src="/static/thread.js" defer></script>
@BoardHeader(board)
<div class="new-post-container">
<form