Changeset 6117035 in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
06/15/2026 04:02:17 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
11a6871
Parents:
33886fb
Message:

fix: post navigation over ALL posts incl. pinned (no more pinned-only stack)

A pinned post showed only the pinned-stack navigation at the bottom. Now
Newer/Older runs through all posts in canonical feed order: solo = pinned
first by rank, then by date (same as the homepage); hub = globally by date.
Pinned posts simply sit in the continuous sequence. Neighbours determined
by index in that ordered list. The separate pinned-stack navigation
(PREVIOUS PINNED / TOP / BOTTOM) has been removed.

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r33886fb r6117035  
    507507  const urlBaseFor = (p) => (isHub && p && p.site_slug) ? `/user/${p.site_slug}` : '';
    508508
    509   const prevPost = isHub
     509  // Newer/Older over ALLE posts, in de canonieke feed-volgorde — niet alleen de
     510  // pinned-stack. Solo: binnen de site, pinned eerst op rank, dan op datum
     511  // (zelfde volgorde als de homepage-feed). Hub: globaal op datum over alle
     512  // sites. De vorige positie in de lijst = "Newer" (← omhoog), de volgende =
     513  // "Older" (→ omlaag). Pinned posts zitten zo gewoon in de doorlopende reeks.
     514  const ordered = isHub
    510515    ? db.prepare(`
    511         SELECT p.slug, p.title, s.slug AS site_slug
     516        SELECT p.id, p.slug, p.title, s.slug AS site_slug
    512517        FROM posts p JOIN sites s ON s.id = p.site_id
    513         WHERE p.status = 'published' AND p.published_at < ? AND p.id != ?
    514         ORDER BY p.published_at DESC LIMIT 1
    515       `).get(post.published_at, post.id)
     518        WHERE p.status = 'published'
     519        ORDER BY p.published_at DESC
     520      `).all()
    516521    : db.prepare(`
    517         SELECT slug, title FROM posts
    518         WHERE site_id = ? AND status = 'published' AND published_at < ? AND id != ?
    519         ORDER BY published_at DESC LIMIT 1
    520       `).get(site.id, post.published_at, post.id);
    521 
    522   const nextPost = isHub
    523     ? db.prepare(`
    524         SELECT p.slug, p.title, s.slug AS site_slug
    525         FROM posts p JOIN sites s ON s.id = p.site_id
    526         WHERE p.status = 'published' AND p.published_at > ? AND p.id != ?
    527         ORDER BY p.published_at ASC LIMIT 1
    528       `).get(post.published_at, post.id)
    529     : db.prepare(`
    530         SELECT slug, title FROM posts
    531         WHERE site_id = ? AND status = 'published' AND published_at > ? AND id != ?
    532         ORDER BY published_at ASC LIMIT 1
    533       `).get(site.id, post.published_at, post.id);
    534   if (prevPost) prevPost._urlBase = urlBaseFor(prevPost);
    535   if (nextPost) nextPost._urlBase = urlBaseFor(nextPost);
     522        SELECT id, slug, title FROM posts
     523        WHERE site_id = ? AND status = 'published'
     524        ORDER BY (pinned = 0) ASC, pinned ASC, published_at DESC
     525      `).all(site.id);
     526  const _idx = ordered.findIndex((p) => p.id === post.id);
     527  const newerPost = _idx > 0 ? ordered[_idx - 1] : null;
     528  const olderPost = (_idx >= 0 && _idx < ordered.length - 1) ? ordered[_idx + 1] : null;
     529  if (newerPost) newerPost._urlBase = urlBaseFor(newerPost);
     530  if (olderPost) olderPost._urlBase = urlBaseFor(olderPost);
    536531
    537532  // ── Related posts: same-tag matching with recency fallback ─────
     
    588583  relatedPosts = relatedPosts.map(({ _overlap, tags, ...rest }) => ({ ...rest, _urlBase: urlBaseFor(rest) }));
    589584
    590   // ── Pinned navigation: prev/next pinned post ───────────────────
    591   // Only meaningful if the current post is pinned. We order by
    592   // published_at DESC (newest pinned first) — same as the homepage feed.
    593   // Pinned navigation: prev/next pinned post by RANK (not by date).
    594   // - prev (← back to) = post with smaller rank, i.e. higher in stack
    595   // - next (→ forward) = post with larger rank, i.e. lower in stack
    596   // BOVENAAN appears when current is rank 1 (no rank 0 above);
    597   // ONDERAAN appears when current is the highest rank (no further down).
    598   let prevPinnedPost = null;
    599   let nextPinnedPost = null;
    600   let pinnedTopOfStack = false;
    601   let pinnedBottomOfStack = false;
    602   if (post.pinned > 0) {
    603     // The rank one step UP the stack (towards #1)
    604     prevPinnedPost = db.prepare(`
    605       SELECT slug, title FROM posts
    606       WHERE site_id = ? AND status = 'published' AND pinned > 0
    607         AND pinned < ? AND id != ?
    608       ORDER BY pinned DESC LIMIT 1
    609     `).get(site.id, post.pinned, post.id) || null;
    610 
    611     // The rank one step DOWN the stack (away from #1)
    612     nextPinnedPost = db.prepare(`
    613       SELECT slug, title FROM posts
    614       WHERE site_id = ? AND status = 'published' AND pinned > 0
    615         AND pinned > ? AND id != ?
    616       ORDER BY pinned ASC LIMIT 1
    617     `).get(site.id, post.pinned, post.id) || null;
    618 
    619     pinnedTopOfStack    = !prevPinnedPost;  // already rank #1 (or nothing higher)
    620     pinnedBottomOfStack = !nextPinnedPost;  // nothing further down the stack
    621   }
    622 
    623585  renderPage(req, res, 'pages/post', {
    624586    post,
    625     prevPost,
    626     nextPost,
     587    newerPost,
     588    olderPost,
    627589    relatedPosts,
    628     prevPinnedPost,
    629     nextPinnedPost,
    630     pinnedTopOfStack,
    631     pinnedBottomOfStack,
    632590    comments: topLevel,
    633591    totalComments,
Note: See TracChangeset for help on using the changeset viewer.