Changeset 97bacf2 in Klonkt
- Timestamp:
- 07/25/2026 11:32:44 PM (6 weeks ago)
- Branches:
- main
- Children:
- 8f8b40f
- Parents:
- f1c50f9
- Files:
-
- 1 added
- 3 edited
-
src/config/database.js (modified) (1 diff)
-
src/routes/activitypub.js (modified) (1 diff)
-
src/services/ActivityPubService.js (modified) (4 diffs)
-
test/custom-emojis.test.js (added)
Legend:
- Unmodified
- Added
- Removed
-
src/config/database.js
rf1c50f9 r97bacf2 547 547 ensureColumn('ap_timeline', 'nsfw', 'INTEGER DEFAULT 0'); // remote sensitive post → blur in the Cirkel 548 548 ensureColumn('ap_timeline', 'cw', 'TEXT'); // remote content-warning text 549 ensureColumn('ap_timeline', 'emoji_json', 'TEXT'); // FEP-9098 custom emoji Emoji tags from the inbound note, served back as `tag` 549 550 ensureColumn('ap_timeline', 'reblog_name', 'TEXT'); // a followed account boosted this → "X boosted" 550 551 ensureColumn('ap_timeline', 'reblog_handle', 'TEXT'); // the booster's @handle -
src/routes/activitypub.js
rf1c50f9 r97bacf2 162 162 // client renders their images/audio like own outbox posts. 163 163 attachment: AP.timelineAttachments(t.media_json), 164 // FEP-9098 custom emojis: the note's Emoji tags, so the client can 165 // render :shortcode: as an image instead of literal text. 166 tag: AP.timelineEmojis(t.emoji_json), 164 167 }, 165 168 })); -
src/services/ActivityPubService.js
rf1c50f9 r97bacf2 1537 1537 // FEP-633c §2.2: register the ward hint on the stored object (no action yet). 1538 1538 if (Guardianship.objectHasGuardians(o)) { try { db.prepare('UPDATE ap_timeline SET has_guardians = 1 WHERE id = ? AND slug = ?').run(o.id, s.slug); } catch { /* ignore */ } } 1539 // FEP-9098: keep the note's custom-emoji tags so the C2S inbox read can serve them. 1540 { const ej = extractEmojiTags(o.tag); if (ej) { try { db.prepare('UPDATE ap_timeline SET emoji_json = ? WHERE id = ? AND slug = ?').run(ej, o.id, s.slug); } catch { /* ignore */ } } } 1539 1541 if (poll) { try { db.prepare('UPDATE ap_timeline SET poll_json = ? WHERE id = ? AND slug = ?').run(JSON.stringify(poll), o.id, s.slug); } catch { /* ignore */ } } 1540 1542 } … … 2565 2567 } 2566 2568 2569 // FEP-9098 custom emojis. Inbound: keep the note's Emoji tags (as JSON) so we 2570 // can serve them back. `extractEmojiTags` returns the JSON to store (or null); 2571 // `timelineEmojis` turns the stored JSON back into an AS2 `tag` array for the 2572 // C2S inbox read, so a client (Shaer) can render :shortcode: as an image. 2573 export function extractEmojiTags(tag) { 2574 const arr = Array.isArray(tag) ? tag : (tag ? [tag] : []); 2575 const emojis = arr.filter((t) => t && (Array.isArray(t.type) ? t.type[0] : t.type) === 'Emoji' 2576 && typeof t.name === 'string' && t.icon); 2577 return emojis.length ? JSON.stringify(emojis) : null; 2578 } 2579 export function timelineEmojis(emojiJson) { 2580 try { const arr = emojiJson ? JSON.parse(emojiJson) : null; return (Array.isArray(arr) && arr.length) ? arr : undefined; } 2581 catch { return undefined; } 2582 } 2583 2567 2584 // ── Cirkel = posts from the accounts you auto-boost ("feature an artist") ── 2568 2585 let _abCount, _cirkelPosts, _cirkelMembers; … … 2720 2737 const r = tlStmts().ins.run(o.id, slug, actorUri, ai.name, ai.handle, ai.icon, ai.url, html, o.url || null, o.published || null, mediaFromNote(o), o.sensitive ? 1 : 0, o.summary || null); 2721 2738 if (r && r.changes > 0) added++; 2739 // FEP-9098: keep custom-emoji tags from backfilled posts too. 2740 { const ej = extractEmojiTags(o.tag); if (ej) { try { db.prepare('UPDATE ap_timeline SET emoji_json = ? WHERE id = ? AND slug = ?').run(ej, o.id, slug); } catch { /* ignore */ } } } 2722 2741 // Set poll_json if this is a poll and we don't already have it (COALESCE preserves a vote). 2723 2742 if (poll) { try { db.prepare('UPDATE ap_timeline SET poll_json = COALESCE(poll_json, ?) WHERE id = ? AND slug = ?').run(JSON.stringify(poll), o.id, slug); } catch { /* ignore */ } } … … 3357 3376 getInteractions, getInteractionById, setInteractionBoosted, setInteractionLiked, setMyReaction, getMyReactions, buildReplyNote, getOutboxNote, deliverReply, resolveRemoteNote, 3358 3377 listOutbox, deliverOutboxDelete, deliverOutboxUpdate, deliverDirectNote, 3359 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, timelineAttachments, sendInteraction, voteOnPoll, voteOnRemotePoll,3378 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, timelineAttachments, timelineEmojis, sendInteraction, voteOnPoll, voteOnRemotePoll, 3360 3379 acceptGatedFollow, rejectGatedFollow, isWardGuardian, sendFollowDecision, 3361 3380 parseOwnPoll, pollTally, ownPollView, deliverPollUpdate, maybeCrawlThread, sendReport, localMentionSlugs,
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)