Changeset 21ef238 in Klonkt for src/services/ActivityPubService.js
- Timestamp:
- 08/10/2026 04:53:05 PM (4 weeks ago)
- Branches:
- main
- Children:
- e215090
- Parents:
- 41de7cb
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r41de7cb r21ef238 3238 3238 return await c2sCreatePost(base, site, user, object); 3239 3239 } 3240 // ── Gelezen tot hier (shaer-frontend-3tx) ─────────────────── 3241 // 3242 // AS2 kent Read: 'the actor has read the object'. Geen shaer:seen 3243 // verzinnen, en geen zetbare stand: dit is een GEBEURTENIS, dus twee 3244 // toestellen kunnen elkaar niet terugzetten. Blijft lokaal -- een 3245 // leesbevestiging heeft in de fediverse niets te zoeken. 3246 case 'Read': { 3247 const targetUri = c2sIdOf(object); 3248 if (!targetUri) return { status: 400, error: 'missing_object' }; 3249 const uit = markRead(site.slug, targetUri); 3250 // Kennen we die note niet, dan is er niets gelezen om te onthouden. 3251 // Geen fout: een client mag best een oud bericht aanwijzen. 3252 return { status: uit ? 200 : 202 }; 3253 } 3240 3254 case 'Like': 3241 3255 case 'Announce': { … … 4348 4362 } 4349 4363 4364 /** 4365 * Tot waar deze lezer elk gesprek gelezen heeft (shaer-frontend-3tx). 4366 * 4367 * De markering komt uit AS2 `Read`-activiteiten, en die zijn OPTELLEND: het 4368 * lezen van bericht N maakt niets anders ongelezen. Daarom is achteruit gaan 4369 * geen regel die iemand moet onthouden maar een eigenschap van het model -- 4370 * markRead neemt het maximum. Een 'zet mijn markering op X' zou een toestel 4371 * dat een week uit stond je gelezen berichten weer op ongelezen laten zetten. 4372 */ 4373 export function readMarkers(slug) { 4374 try { 4375 return new Map(db.prepare('SELECT other, cursor FROM ap_read_markers WHERE slug = ?') 4376 .all(slug).map((r) => [r.other, r.cursor])); 4377 } catch { return new Map(); } 4378 } 4379 4380 /** 4381 * Markeer een gesprek als gelezen tot en met dit bericht. 4382 * 4383 * Het object van de Read is een berichturi; welk gesprek dat is en waar het in 4384 * de tijd staat weet de server zelf, dus de client hoeft niets uit te rekenen 4385 * en kan er ook niet naast zitten. 4386 */ 4387 export function markRead(slug, objectUri) { 4388 try { 4389 const rij = db.prepare(`SELECT other, stamp, ref FROM (${CONVERSATION_UNION}) 4390 WHERE ref = @ref ORDER BY stamp DESC LIMIT 1`) 4391 .get({ slug, ref: String(objectUri || '') }); 4392 if (!rij) return null; 4393 const cursor = `${rij.stamp}|${rij.ref}`; 4394 db.prepare(`INSERT INTO ap_read_markers (slug, other, cursor) VALUES (?,?,?) 4395 ON CONFLICT(slug, other) DO UPDATE SET cursor = MAX(cursor, excluded.cursor), at = CURRENT_TIMESTAMP`) 4396 .run(slug, rij.other, cursor); 4397 return { other: rij.other, cursor }; 4398 } catch { return null; } 4399 } 4400 4401 /** 4402 * Hoeveel er per gesprek nog ongelezen is, en of daar een zwaai bij zit. 4403 * 4404 * Een COUNT en geen bijgehouden getal (Barts besluit): niets om op te hogen 4405 * bij bezorging, niets om te verlagen bij lezen, en bij een verwijdering klopt 4406 * het vanzelf weer. 4407 * 4408 * Een zwaai telt apart, want dat is geen gesprek maar een zetje van een 4409 * guardian -- die hoort een eigen teken te krijgen en niet opgeteld te worden. 4410 * Eigen berichten tellen nooit mee: je hebt jezelf gelezen. 4411 */ 4412 export function unreadPerConversation(slug) { 4413 try { 4414 const rijen = db.prepare(` 4415 SELECT u.other AS other, 4416 COUNT(*) AS n, 4417 MAX(CASE WHEN m.wave = 1 THEN 1 ELSE 0 END) AS wave 4418 FROM (${CONVERSATION_UNION}) u 4419 LEFT JOIN ap_read_markers r ON r.slug = @slug AND r.other = u.other 4420 LEFT JOIN ap_mentions m ON m.slug = @slug AND m.object_uri = u.ref 4421 WHERE u.direction = 'in' 4422 AND (r.cursor IS NULL OR (u.stamp || '|' || u.ref) > r.cursor) 4423 GROUP BY u.other`).all({ slug }); 4424 return new Map(rijen.map((r) => [r.other, { n: r.n, wave: !!r.wave }])); 4425 } catch { return new Map(); } 4426 } 4427 4350 4428 export function getDirectMessages(slug, limit) { 4351 4429 try { … … 6441 6519 getInteractions, getInteractionById, setInteractionBoosted, setInteractionLiked, buildReplyNote, getOutboxNote, getSentNotes, deliverReply, resolveRemoteNote, noteAudience, mayReadNote, 6442 6520 listOutbox, deliverOutboxDelete, deliverOutboxUpdate, deliverDirectNote, 6443 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, moveAccount, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, timelineRowsByIds, getDirectMessages, messageRowsByUri, replyRowsByUri, conversationHeads, conversationHistory, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll,6521 webfingerResolve, followActor, resolveRemoteActor, unfollowActor, handleMoveInbox, moveAccount, listFollowing, setAutoBoost, backfillFromOutbox, getTimeline, timelineRowsByIds, getDirectMessages, readMarkers, markRead, unreadPerConversation, messageRowsByUri, replyRowsByUri, conversationHeads, conversationHistory, isoStamp, timelineAttachments, timelineEmojis, timelineObjectLinks, timelineQuote, timelineEmbed, applyQuoteProps, deliverToActor, sendInteraction, voteOnPoll, voteOnRemotePoll, 6444 6522 acceptGatedFollow, rejectGatedFollow, isWardGuardian, outboxAudience, sendFollowDecision, 6445 6523 gateOutgoingFollow, performApprovedFollow, recordGuardianEvent, listGuardianEvents, GUARDIAN_EVENT_KEEP,
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)