Implement replies in post header
This commit is contained in:
+29
-20
@@ -8,28 +8,37 @@ import (
|
|||||||
|
|
||||||
func EnrichPost(body string) string {
|
func EnrichPost(body string) string {
|
||||||
var b strings.Builder
|
var b strings.Builder
|
||||||
for _, raw := range strings.Split(body, "\n") {
|
for _, rawLine := range strings.Split(body, "\n") {
|
||||||
var out string
|
var outLine string
|
||||||
switch {
|
|
||||||
case strings.HasPrefix(raw, ">>"):
|
for i, rawWord := range strings.Split(rawLine, " ") {
|
||||||
postId := strings.TrimPrefix(raw, ">>")
|
var outWord string
|
||||||
esc := template.HTMLEscapeString(raw)
|
if strings.HasPrefix(rawWord, ">>") {
|
||||||
out = fmt.Sprintf(
|
postId := strings.TrimPrefix(rawWord, ">>")
|
||||||
`<a onclick="onReplyLinkClick(event)"
|
esc := template.HTMLEscapeString(rawWord)
|
||||||
onmouseover="highlightPost(%[1]s, event)" `+
|
outWord = fmt.Sprintf(
|
||||||
`onmouseleave="highlightPost(%[1]s, event, false)" `+
|
`<a onclick="onReplyLinkClick(event)"
|
||||||
`href="#post-%[1]s" class="reply-link">%s</a>`,
|
onmouseover="highlightPost(%[1]s, event)" `+
|
||||||
postId, esc,
|
`onmouseleave="highlightPost(%[1]s, event, false)" `+
|
||||||
)
|
`href="#post-%[1]s" class="reply-link">%s</a>`,
|
||||||
case strings.HasPrefix(raw, ">"):
|
postId, esc,
|
||||||
esc := template.HTMLEscapeString(raw)
|
)
|
||||||
out = `<span class="greentext">` + esc + `</span>`
|
} else {
|
||||||
default:
|
outWord = template.HTMLEscapeString(rawWord)
|
||||||
out = template.HTMLEscapeString(raw)
|
}
|
||||||
|
|
||||||
|
if i != 0 {
|
||||||
|
outLine += " "
|
||||||
|
}
|
||||||
|
outLine += outWord
|
||||||
}
|
}
|
||||||
|
|
||||||
b.WriteString(out)
|
if strings.HasPrefix(rawLine, ">") && !strings.HasPrefix(rawLine, ">>") {
|
||||||
b.WriteString("<br />")
|
outLine = `<span class="greentext">` + outLine + `</span>`
|
||||||
|
}
|
||||||
|
|
||||||
|
b.WriteString(outLine)
|
||||||
|
b.WriteString("<br/>")
|
||||||
}
|
}
|
||||||
return b.String()
|
return b.String()
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -146,12 +146,13 @@ body {
|
|||||||
|
|
||||||
.thread-subject {
|
.thread-subject {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #b294bb;
|
color: #0F0C5D;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-op {
|
.post-op {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post {
|
.post {
|
||||||
@@ -159,8 +160,9 @@ body {
|
|||||||
margin: 5x;
|
margin: 5x;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #D6DAF0;
|
background-color: #D6DAF0;
|
||||||
border: 1px solid #282a2e;
|
border: 1px solid #B7C5D9;
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-highlighted {
|
.post-highlighted {
|
||||||
@@ -211,6 +213,17 @@ body {
|
|||||||
cursor: pointer;
|
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 */
|
/* GENERAL LAYOUT */
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ templ Layout() {
|
|||||||
<title>Comfychan</title>
|
<title>Comfychan</title>
|
||||||
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
<script src="https://unpkg.com/htmx.org@2.0.4"></script>
|
||||||
<script src="https://unpkg.com/hyperscript.org@0.9.14"></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/reset.css"/>
|
||||||
<link rel="stylesheet" href="/static/index.css"/>
|
<link rel="stylesheet" href="/static/index.css"/>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ templ ThreadPost(post database.Post, thread *database.Thread) {
|
|||||||
_={ fmt.Sprintf("on click set #newPostBody.value to #newPostBody.value + '>>%d\n'", post.Id) }
|
_={ fmt.Sprintf("on click set #newPostBody.value to #newPostBody.value + '>>%d\n'", post.Id) }
|
||||||
class=" post-num"
|
class=" post-num"
|
||||||
>
|
>
|
||||||
No. { strconv.Itoa(post.Id) }
|
No.{ strconv.Itoa(post.Id) }
|
||||||
</span>
|
</span>
|
||||||
|
<div class="post-replies"></div>
|
||||||
</header>
|
</header>
|
||||||
<p>
|
<p>
|
||||||
@templ.Raw(util.EnrichPost(post.Body))
|
@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) {
|
templ Thread(board database.Board, thread database.Thread, posts []database.Post) {
|
||||||
@shared.Layout() {
|
@shared.Layout() {
|
||||||
|
<script src="/static/thread.js" defer></script>
|
||||||
@BoardHeader(board)
|
@BoardHeader(board)
|
||||||
<div class="new-post-container">
|
<div class="new-post-container">
|
||||||
<form
|
<form
|
||||||
|
|||||||
Reference in New Issue
Block a user