feat: Implement infinite scroll for the tags page by adding a paginated API endpoint and client-side loading logic.
This commit is contained in:
@@ -1,11 +1,53 @@
|
||||
import db from "../../inc/sql.mjs";
|
||||
import cfg from "../../inc/config.mjs";
|
||||
|
||||
const TAGS_PER_PAGE = 50;
|
||||
|
||||
export default (router, tpl) => {
|
||||
// API endpoint for lazy loading tags
|
||||
router.get(/^\/api\/tags$/, async (req, res) => {
|
||||
const page = Math.max(1, +(req.url.qs?.page ?? 1));
|
||||
const offset = (page - 1) * TAGS_PER_PAGE;
|
||||
const isLoggedIn = !!req.session;
|
||||
|
||||
const nsfp = cfg.nsfp.map(n => `${n}`);
|
||||
|
||||
let tags;
|
||||
if (isLoggedIn) {
|
||||
tags = await db`
|
||||
SELECT t.id, t.tag, COUNT(DISTINCT ta.item_id) AS total_items
|
||||
FROM tags t
|
||||
LEFT JOIN tags_assign ta ON t.id = ta.tag_id
|
||||
GROUP BY t.id, t.tag
|
||||
HAVING COUNT(DISTINCT ta.item_id) >= 1
|
||||
ORDER BY total_items DESC
|
||||
OFFSET ${offset}
|
||||
LIMIT ${TAGS_PER_PAGE}
|
||||
`;
|
||||
} else {
|
||||
tags = await db`
|
||||
SELECT t.id, t.tag, COUNT(DISTINCT ta.item_id) AS total_items
|
||||
FROM tags t
|
||||
LEFT JOIN tags_assign ta ON t.id = ta.tag_id
|
||||
WHERE t.id not in (${db.unsafe(nsfp)})
|
||||
GROUP BY t.id, t.tag
|
||||
HAVING COUNT(DISTINCT ta.item_id) >= 1
|
||||
ORDER BY total_items DESC
|
||||
OFFSET ${offset}
|
||||
LIMIT ${TAGS_PER_PAGE}
|
||||
`;
|
||||
}
|
||||
|
||||
res.json({
|
||||
tags,
|
||||
page,
|
||||
hasMore: tags.length === TAGS_PER_PAGE
|
||||
});
|
||||
});
|
||||
|
||||
// Main tags page - only load first page
|
||||
router.get(/^\/tags$/, async (req, res) => {
|
||||
|
||||
const phrase = cfg.websrv.phrases[~~(Math.random() * cfg.websrv.phrases.length)];
|
||||
|
||||
const nsfp = cfg.nsfp.map(n => `${n}`);
|
||||
|
||||
const toptags = await db`
|
||||
@@ -16,7 +58,7 @@ export default (router, tpl) => {
|
||||
GROUP BY t.id, t.tag
|
||||
HAVING COUNT(DISTINCT ta.item_id) >= 1
|
||||
ORDER BY total_items DESC
|
||||
;
|
||||
LIMIT ${TAGS_PER_PAGE}
|
||||
`;
|
||||
|
||||
const toptags_regged = await db`
|
||||
@@ -26,7 +68,7 @@ export default (router, tpl) => {
|
||||
GROUP BY t.id, t.tag
|
||||
HAVING COUNT(DISTINCT ta.item_id) >= 1
|
||||
ORDER BY total_items DESC
|
||||
;
|
||||
LIMIT ${TAGS_PER_PAGE}
|
||||
`;
|
||||
|
||||
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate');
|
||||
@@ -43,5 +85,6 @@ export default (router, tpl) => {
|
||||
}, req)
|
||||
});
|
||||
});
|
||||
|
||||
return router;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user