Changeset 2d6a9c3 in Klonkt
- Timestamp:
- 07/16/2026 12:20:51 PM (8 weeks ago)
- Branches:
- main
- Children:
- af21002
- Parents:
- 8878814
- git-author:
- Robin <roboburr@…> (07/13/2026 05:21:50 AM)
- git-committer:
- Robin <roboburr@…> (07/16/2026 12:20:51 PM)
- Location:
- src
- Files:
-
- 3 edited
-
config/database.js (modified) (1 diff)
-
routes/posts.js (modified) (5 diffs)
-
services/ActivityPubService.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/config/database.js
r8878814 r2d6a9c3 387 387 ensureColumn('ap_followers', 'last_delivery_at', 'DATETIME'); // last SUCCESSFUL delivery to this follower's inbox 388 388 ensureColumn('ap_followers', 'last_error_at', 'DATETIME'); // last time a delivery to it gave up (max retries) 389 390 // ActivityPub `source` model: content_rendered = baked display HTML (#hashtags / URLs / 391 // @mentions linkified once at save). `content` stays the raw source used for editing and 392 // re-rendering. NULL on old posts → the render route bakes on the fly as a fallback. 393 ensureColumn('posts', 'content_rendered', 'TEXT'); 389 394 } 390 395 -
src/routes/posts.js
r8878814 r2d6a9c3 238 238 } 239 239 240 // Bake + cache a post's display HTML (ActivityPub `source` model): `content` stays the raw 241 // source (used by the editor + re-rendering), content_rendered holds the linkified render the 242 // page serves. Called after every create/edit. Non-fatal: the render route falls back to 243 // baking on the fly if this ever fails. 244 function cacheRenderedContent(postId, rawContent) { 245 try { 246 db.prepare('UPDATE posts SET content_rendered = ? WHERE id = ?') 247 .run(ActivityPubService.bakePostContent(rawContent || ''), postId); 248 } catch (e) { /* fallback bake in the render route keeps display correct */ } 249 } 250 240 251 router.post('/posts/create', requireAuth, (req, res) => { 241 252 const site = res.locals.site; … … 299 310 now, now, publishedAt 300 311 ); 312 cacheRenderedContent(postId, cleanContent); // bake display HTML (ActivityPub `source` model) 301 313 302 314 // Per-post "share audio on the fediverse" → set fedi_open on this post's hosted tracks … … 439 451 finalSlug, publishedAt, now, post.id 440 452 ); 453 cacheRenderedContent(post.id, cleanContent); // re-bake display HTML on edit (ActivityPub `source` model) 441 454 442 455 // Per-post "share audio on the fediverse" → set fedi_open on this post's hosted tracks … … 994 1007 if (post.status === 'published') recordPostView(post, req); 995 1008 996 // Render content. Content is now user-authored HTML (already sanitized on 997 // save). The pipeline still adds autoembed iframes and shortcode embeds: 998 // stored HTML → autoembed → [[track]]/[[album]]/[[playlist]] → response 999 let html = post.content || ''; 1009 // Render content. Base = the pre-rendered ("baked") display HTML: #hashtags/URLs (and, later, 1010 // @mentions) linkified once at SAVE and cached in content_rendered — the ActivityPub `source` 1011 // model (content = raw source, kept for editing). Old posts with no baked copy fall back to 1012 // baking on the fly (cheap, no network). The dynamic layer (autoembed + [[track/album/ 1013 // playlist]] + signed audio URLs) stays per-render on top, since it can't be cached. 1014 let html = (post.content_rendered != null && post.content_rendered !== '') 1015 ? post.content_rendered 1016 : ActivityPubService.bakePostContent(post.content || ''); 1000 1017 if (audioEnabled()) { 1001 1018 if (site.enable_audio_player !== 0) { … … 1092 1109 html = html.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, ''); 1093 1110 } 1094 // Linkify inline #hashtags and bare URLs for on-site display — same rules as the 1095 // federated copy (buildNote). Was: only the Mastodon copy got links; the website 1096 // showed raw "#tag"/URL text. Idempotent, so editor links + embeds are untouched. 1097 html = ActivityPubService.linkifyBody('', html); 1111 // (linkify is baked into content_rendered at save now, not re-run here.) 1098 1112 post.content_html = html; 1099 1113 -
src/services/ActivityPubService.js
r8878814 r2d6a9c3 1464 1464 } 1465 1465 1466 // Bake a post's raw source into its display HTML (the ActivityPub `source` model): done ONCE 1467 // at save and cached in posts.content_rendered, so page views serve it statically instead of 1468 // re-linkifying every render. Step 1 = #hashtags + bare URLs (cheap, no network). Step 2 will 1469 // resolve @mentions here too (webfinger once at save instead of per page view). 1470 export function bakePostContent(source) { 1471 return linkifyBody('', source || ''); 1472 } 1473 1466 1474 // Extract the AP Hashtag tag objects from already-linked reply content. 1467 1475 function hashtagTags(base, content) { … … 2463 2471 deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker, 2464 2472 getReplyUris, markNotificationsSeen, countUnseenNotifications, hasPlayableAudio, 2465 linkifyBody, listFollowers, removeFollower,2473 linkifyBody, bakePostContent, listFollowers, removeFollower, 2466 2474 };
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)