Implement client sorting and pinning

This commit is contained in:
Dominic Ferrando
2025-04-24 20:31:43 -04:00
parent 91e8538c3c
commit f9aad52dc5
3 changed files with 38 additions and 4 deletions
+1
View File
@@ -430,6 +430,7 @@ func main() {
IpCount: len(uniqueIpHashes), IpCount: len(uniqueIpHashes),
Pinned: thread.Pinned, Pinned: thread.Pinned,
Locked: thread.Locked, Locked: thread.Locked,
BumpedAt: thread.BumpedAt,
}) })
} }
+20 -1
View File
@@ -71,7 +71,7 @@ function highlightPost(postId, e, status = true) {
} }
function resizeCatalogPreviewImgs() { function resizeCatalogPreviewImgs() {
const value = $("selectSortBy").value; const value = $("selectResize").value;
const postsImages = Array.from(document.querySelectorAll(".catalog-preview img")); const postsImages = Array.from(document.querySelectorAll(".catalog-preview img"));
for (const postImage of postsImages) { for (const postImage of postsImages) {
switch (value) { switch (value) {
@@ -105,6 +105,25 @@ function applyCatalogSearch() {
} }
} }
function applyCatalogSort(desc = true) {
const sortBy = $("selectSortBy").value;
const catalog = document.getElementById('catalog');
const previews = Array.from(catalog.children);
previews.sort((a, b) => {
const pinDiff = (+b.dataset.pinned) - (+a.dataset.pinned);
if (pinDiff !== 0) return pinDiff;
const bumpDiff = (+a.dataset[sortBy]) - (+b.dataset[sortBy]);
return desc ? -bumpDiff : bumpDiff;
});
const frag = document.createDocumentFragment();
previews.forEach(el => frag.appendChild(el));
catalog.appendChild(frag);
}
function currentBoardSlug() { function currentBoardSlug() {
return window.location.pathname.split("/")[1] || ""; return window.location.pathname.split("/")[1] || "";
} }
+17 -3
View File
@@ -6,6 +6,7 @@ import (
"github.com/dominicf2001/comfychan/internal/util" "github.com/dominicf2001/comfychan/internal/util"
"github.com/dominicf2001/comfychan/web/views/shared" "github.com/dominicf2001/comfychan/web/views/shared"
"strconv" "strconv"
"time"
) )
templ BoardHeader(board database.Board) { templ BoardHeader(board database.Board) {
@@ -32,10 +33,15 @@ templ Board(board database.Board, isAdmin bool) {
<hr/> <hr/>
<div id="boardActionBar"> <div id="boardActionBar">
<span>Image size: </span> <span>Image size: </span>
<select onchange="resizeCatalogPreviewImgs()" id="selectSortBy"> <select onchange="resizeCatalogPreviewImgs()" id="selectResize">
<option selected value="small">Small</option> <option selected value="small">Small</option>
<option value="large">Large</option> <option value="large">Large</option>
</select> </select>
<span>Sort by: </span>
<select onchange="applyCatalogSort()" id="selectSortBy">
<option selected value="bumpedat">Bump order</option>
<option value="replycount">Reply count</option>
</select>
<input style="margin-left: 10px;" oninput="applyCatalogSearch()" id="catalogSearch" placeholder="Search"/> <input style="margin-left: 10px;" oninput="applyCatalogSearch()" id="catalogSearch" placeholder="Search"/>
<a style _="on click trigger refreshPosts on body" class="link-button">[Refresh]</a> <a style _="on click trigger refreshPosts on body" class="link-button">[Refresh]</a>
</div> </div>
@@ -45,7 +51,8 @@ templ Board(board database.Board, isAdmin bool) {
hx-trigger="load, refreshPosts from:body" hx-trigger="load, refreshPosts from:body"
_="on htmx:afterRequest _="on htmx:afterRequest
call resizeCatalogPreviewImgs() call resizeCatalogPreviewImgs()
then call applyCatalogSearch()" then call applyCatalogSearch()
then call applyCatalogSort()"
></div> ></div>
} }
} }
@@ -60,6 +67,7 @@ type CatalogThreadPreview struct {
IpCount int IpCount int
Pinned bool Pinned bool
Locked bool Locked bool
BumpedAt time.Time
} }
type CatalogContext struct { type CatalogContext struct {
@@ -73,7 +81,13 @@ templ ThreadsCatalog(previews []CatalogThreadPreview, catalogContext CatalogCont
{{ replyCount := strconv.FormatInt(int64(preview.ReplyCount), 10) }} {{ replyCount := strconv.FormatInt(int64(preview.ReplyCount), 10) }}
{{ ipCount := strconv.FormatInt(int64(preview.IpCount), 10) }} {{ ipCount := strconv.FormatInt(int64(preview.IpCount), 10) }}
{{ elThreadId := fmt.Sprintf("thread-%d", preview.ThreadId) }} {{ elThreadId := fmt.Sprintf("thread-%d", preview.ThreadId) }}
<div id={ elThreadId } class="catalog-preview"> {{
pinnedInt := 0
if preview.Pinned {
pinnedInt = 1
}
}}
<div data-pinned={ strconv.Itoa(pinnedInt) } data-replycount={ strconv.Itoa(preview.ReplyCount) } data-bumpedat={ strconv.FormatInt(preview.BumpedAt.UnixMilli(), 10) } id={ elThreadId } class="catalog-preview">
<a href={ templ.URL(preview.ThreadURL) }> <a href={ templ.URL(preview.ThreadURL) }>
<img <img
loading="lazy" loading="lazy"