Changeset f5cf299 in Klonkt for src/routes/posts.js
- Timestamp:
- 08/18/2026 06:47:58 PM (3 weeks ago)
- Branches:
- main
- Children:
- 9622f20
- Parents:
- 8b65e67
- git-author:
- Bart <bart@…> (08/17/2026 07:42:53 PM)
- git-committer:
- Bart <bart@…> (08/18/2026 06:47:58 PM)
- File:
-
- 1 edited
-
src/routes/posts.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/posts.js
r8b65e67 rf5cf299 24 24 import { defaultMinCents as paidDefaultMinCents, patreonUrl as paidPatronUrl } from '../services/PaidPatreonService.js'; 25 25 import { verifyBlob } from '../services/CryptoBox.js'; 26 import { postEntry } from '../services/PostAccessService.js'; 26 27 import MusicMeta from '../services/MusicMeta.js'; 27 28 import { mediaDir } from '../config/paths.js'; … … 148 149 'authorize_interaction', 'fediverse', 'news', 'following', 'notifications', 'blocking', 149 150 'paid', 'push', 'guardian', 151 // De meeslepende tijdlijn (Barts idee, naar bartoverkamp.nl). Gereserveerd 152 // omdat een bericht met deze slug de route anders zou overschaduwen. 153 'lees', 150 154 ]); 151 155 … … 246 250 bodyClass: 'on-home', 247 251 }); 252 }); 253 254 // ==================== LEES (meeslepende tijdlijn) ==================== 255 // 256 // Eén bericht vult het scherm, de chrome schuift weg, en je scrollt voorbij de 257 // rand naar het vorige of volgende. Naar bartoverkamp.nl, waar prev/next 258 // schildwachten boven en onder het artikel staan en het overscrollen zelf de 259 // navigatie is. 260 // 261 // De buren komen uit postNeighbors(), dezelfde die de gewone postpagina al 262 // gebruikt -- dus "vorige" en "volgende" betekenen hier precies hetzelfde als 263 // daar, ook voor gepinde berichten. 264 // 265 // ?partial=1 levert alleen het artikel, want dat is wat de schildwacht inruilt. 266 router.get('/lees/:slug?', (req, res, next) => { 267 const site = res.locals.site; 268 if (!site) return next(); 269 270 // Zonder slug: het nieuwste bericht, zodat /lees een ingang is en niet een 271 // fout. Gepind eerst, net als op de voorpagina. 272 const post = req.params.slug 273 ? db.prepare(`SELECT p.*, u.username as author_username FROM posts p JOIN users u ON p.author_id = u.id 274 WHERE p.site_id = ? AND p.slug = ?`).get(site.id, req.params.slug) 275 : db.prepare(`SELECT p.*, u.username as author_username FROM posts p JOIN users u ON p.author_id = u.id 276 WHERE p.site_id = ? AND p.status = 'published' 277 ORDER BY (p.pinned = 0) ASC, p.pinned ASC, p.published_at DESC LIMIT 1`).get(site.id); 278 if (!post) return next(); 279 280 // Het besluit en het lijf komen uit één plek (PostAccessService). Een dichte 281 // poort levert hier GEEN tekst op: die wordt niet eens gerenderd. 282 const _u = req.query.u ? verifyBlob(String(req.query.u)) : null; 283 const unlockedSlug = (_u && _u.purpose === 'unlocked' && _u.siteId === site.id) ? String(_u.post) : null; 284 const entry = postEntry(post, { user: req.session?.user || null, site, unlockedSlug }, 285 { renderBody: (p) => renderPostBodyHtml(site, p, req) }); 286 287 if (entry.access === 'forbidden') return next(); 288 289 const { newerPost, olderPost } = postNeighbors(site, post); 290 const model = { 291 post, entry, newerPost, olderPost, 292 pageTitle: post.title || site.title, 293 // on-lees zet de chrome weg; de mini-topnav blijft (chrome.ejs, _headerless). 294 bodyClass: 'on-lees on-special', 295 }; 296 if (req.query.partial === '1' || req.headers['hx-request'] === 'true') { 297 return renderPage(req, res, 'partials/lees-article', model); 298 } 299 recordPageview(site.id, req); 300 return renderPage(req, res, 'pages/lees', model); 248 301 }); 249 302
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)