Implement client sorting and pinning
This commit is contained in:
@@ -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
@@ -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
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user