Changes in src/routes/posts.js [fb9a8ad:72ec6a4] in Klonkt
- File:
-
- 1 edited
-
src/routes/posts.js (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/posts.js
rfb9a8ad r72ec6a4 256 256 257 257 renderPage(req, res, 'pages/post-edit', { 258 // post-edit neemt de playlist-editor op.259 pageJs: 'post-edit playlist-editor',260 258 post: { 261 259 id: uuid(), … … 797 795 } 798 796 renderPage(req, res, 'pages/authorize-interaction', { 799 pageJs: 'authorize-interaction',800 797 pageTitleKey: 'fedi.remote_interact', // i18n: was hardcoded Dutch on non-NL sites 801 798 bodyClass: 'on-special', … … 809 806 liked: !!req.query.liked, 810 807 boosted: !!req.query.boosted, 811 reacted: (site && uri) ? ActivityPubService.get Reaction(site.slug, uri) : { liked: false, boosted: false },808 reacted: (site && uri) ? ActivityPubService.getMyReactions(site.slug, uri) : { liked: false, boosted: false }, 812 809 siteTitle: site ? site.title : '', 813 810 }); … … 842 839 let on = false; 843 840 if (site && uri) { 844 on = !ActivityPubService.get Reaction(site.slug, uri).liked;841 on = !ActivityPubService.getMyReactions(site.slug, uri).liked; 845 842 ActivityPubService.resolveRemoteNote(uri) 846 843 .then((note) => note && ActivityPubService.sendInteraction(site, on ? 'like' : 'unlike', note.object_uri || uri, note.actor_uri)) 847 844 .catch((e) => console.warn('[AP] remote like failed:', e.message)); 848 // Eén schrijfpad (shaer-9e9): tussentabel + afgeleide vlag. 849 ActivityPubService.setReaction(site.slug, uri, 'like', on); 845 ActivityPubService.setMyReaction(site.slug, uri, 'like', on); 850 846 } 851 847 if (req.get('X-Requested-With') === 'fetch') return res.json({ ok: true, on }); … … 860 856 let on = false; 861 857 if (site && uri) { 862 on = !ActivityPubService.get Reaction(site.slug, uri).boosted;858 on = !ActivityPubService.getMyReactions(site.slug, uri).boosted; 863 859 ActivityPubService.resolveRemoteNote(uri) 864 860 .then((note) => { … … 866 862 const id = note.object_uri || uri; 867 863 return Promise.resolve(ActivityPubService.sendInteraction(site, on ? 'boost' : 'unboost', id, note.actor_uri)) 868 // De note gaat mee: een boost zet niet alleen een vlag maar trekt de 869 // post je tijdlijn in, ook als je de auteur niet volgt, zodat hij in 870 // de Cirkel verschijnt. 871 .then(() => ActivityPubService.setReaction(site.slug, uri, 'boost', on, { flagUri: id, note: on ? note : null })); 864 // Boost → store the post in the timeline (even if you don't follow the author) so it 865 // surfaces in the Cirkel; unboost → just clear the flag. 866 .then(() => on ? ActivityPubService.upsertBoostedNote(site.slug, note) : ActivityPubService.unmarkBoosted(site.slug, id)); 872 867 }) 873 868 .catch((e) => console.warn('[AP] remote boost failed:', e.message)); 874 // Meteen zetten, zodat de knop klopt voordat de resolve terug is. Via 875 // setReaction en niet via setMyReaction: ook dit korte moment mag geen 876 // halve schrijfactie zijn. De resolve hierboven werkt hem daarna bij met de 877 // note, zodat de post ook in je tijdlijn belandt. 878 ActivityPubService.setReaction(site.slug, uri, 'boost', on); 869 ActivityPubService.setMyReaction(site.slug, uri, 'boost', on); 879 870 } 880 871 if (req.get('X-Requested-With') === 'fetch') return res.json({ ok: true, on }); … … 939 930 : []).filter((o) => o['shaer:ward'] === gMe && o['shaer:needsMyAccept']); 940 931 renderPage(req, res, 'pages/messages', { 941 pageTitleKey: 'msg.title', bodyClass: 'on-special', pageJs: 'messages',items, seenAt,932 pageTitleKey: 'msg.title', bodyClass: 'on-special', items, seenAt, 942 933 hasMore, nextOffset: offset + FEED_PAGE, moreBase, guardianOffers, 943 934 success: req.query.success || null, error: req.query.error || null, … … 974 965 } catch { /* fall through */ } 975 966 res.redirect(back + '?error=quickreply'); 976 });977 978 // Antwoorden vanuit een gesprek in Berichten. Twee paden, en welke het wordt979 // bepaalt de draad zelf (zie groupConversations → replyTo):980 // - hangt de draad aan een post van jou, dan is dit een gewone reply op het981 // nieuwste ontvangen bericht erin: deliverReply, publiek zoals de thread;982 // - hangt hij aan een persoon, dan is het een direct bericht terug.983 // Rijk in beide gevallen: `content` is de HTML uit de reply-editor, `text` de984 // platte versie die de editor er altijd bij levert (en die het no-JS-formulier985 // als enige stuurt).986 router.post('/messages/reply', requireSiteManager, async (req, res) => {987 const site = res.locals.site;988 const back = `${res.locals.siteUrlBase || ''}/messages`;989 if (!site) return res.status(404).send('Site required');990 const text = String(req.body.text || '');991 const html = String(req.body.content || '');992 let attachments = [];993 try { attachments = JSON.parse(req.body.attachments || '[]'); } catch { /* geen media */ }994 let mentions;995 try { if (req.body.mentions !== undefined) mentions = JSON.parse(req.body.mentions || '[]'); } catch { mentions = undefined; }996 const language = String(req.body.language || '');997 // Leeg is leeg: een bericht zonder tekst EN zonder media is geen bericht.998 if (!text.trim() && !html.trim() && !attachments.length) return res.redirect(back + '?error=reply_empty');999 1000 const interactionId = parseInt(req.body.interaction_id, 10) || 0;1001 const postSlug = String(req.body.post_slug || '');1002 const toActor = String(req.body.to || '');1003 try {1004 if (interactionId && postSlug) {1005 const post = db.prepare('SELECT id, slug FROM posts WHERE site_id = ? AND slug = ?').get(site.id, postSlug);1006 const parent = ActivityPubService.getInteractionById(interactionId);1007 // De parent MOET bij deze post horen: anders zou een gemanipuleerd1008 // formulier een antwoord onder andermans draad kunnen hangen.1009 if (!post || !parent || parent.post_id !== post.id) return res.redirect(back + '?error=reply_target');1010 await ActivityPubService.deliverReply(site, {1011 postId: post.id, postSlug: post.slug, parent, text, html, attachments, mentions, language,1012 });1013 } else if (/^https?:\/\//i.test(toActor)) {1014 const r = await Guardianship.deliverDirectNote(site, { recipients: [toActor], text, html, language, attachments });1015 if (!r) return res.redirect(back + '?error=reply_failed');1016 } else {1017 return res.redirect(back + '?error=reply_target');1018 }1019 } catch (e) {1020 console.warn('[AP] reply from Berichten failed:', e.message);1021 return res.redirect(back + '?error=reply_failed');1022 }1023 res.redirect(back + '?success=reply_sent');1024 967 }); 1025 968 … … 1196 1139 } 1197 1140 renderPage(req, res, 'pages/news', { 1198 pageJs: 'news',1199 1141 pageTitle: 'News', bodyClass: 'on-special', 1200 1142 timeline, hasMore, nextOffset: offset + FEED_PAGE, moreBase, … … 1287 1229 let on = false; 1288 1230 if (site && note) { 1289 on = !ActivityPubService.get Reaction(site.slug, note).liked;1231 on = !ActivityPubService.getTimelineReaction(site.slug, note).liked; 1290 1232 try { await ActivityPubService.sendInteraction(site, on ? 'like' : 'unlike', note, (req.body.author || '').toString()); } catch (e) { /* ignore */ } 1291 ActivityPubService.setReaction(site.slug, note, 'like', on);1233 if (on) ActivityPubService.markLiked(site.slug, note); else ActivityPubService.unmarkLiked(site.slug, note); 1292 1234 } 1293 1235 if (req.get('X-Requested-With') === 'fetch') return res.json({ ok: true, on }); … … 1301 1243 let on = false; 1302 1244 if (site && note) { 1303 on = !ActivityPubService.get Reaction(site.slug, note).boosted;1245 on = !ActivityPubService.getTimelineReaction(site.slug, note).boosted; 1304 1246 try { await ActivityPubService.sendInteraction(site, on ? 'boost' : 'unboost', note, (req.body.author || '').toString()); } catch (e) { /* ignore */ } 1305 ActivityPubService.setReaction(site.slug, note, 'boost', on); // instant UI state1306 1247 if (on) { 1248 ActivityPubService.markBoosted(site.slug, note); // instant UI state 1307 1249 // Fire-and-forget: re-resolve the note so the cached row is refreshed 1308 1250 // (cover/content) — boosting again heals a stale copy from EVERY boost 1309 1251 // path, not just the interact page. 1310 1252 ActivityPubService.resolveRemoteNote(note) 1311 .then((n) => { if (n) ActivityPubService. setReaction(site.slug, note, 'boost', true, { note: n }); })1253 .then((n) => { if (n) ActivityPubService.upsertBoostedNote(site.slug, n); }) 1312 1254 .catch(() => { /* best-effort */ }); 1255 } else { 1256 ActivityPubService.unmarkBoosted(site.slug, note); 1313 1257 } 1314 1258 } … … 1394 1338 const { newerPost, olderPost } = postNeighbors(site, post); 1395 1339 return renderPage(req, res, 'pages/paid-gate', { 1396 pageJs: 'paid-gate',1397 1340 pageTitle: post.title || 'Voor supporters', 1398 1341 bodyClass: 'on-special', … … 1511 1454 1512 1455 renderPage(req, res, 'pages/post', { 1513 pageJs: 'post',1514 1456 post, 1515 1457 poll: ActivityPubService.ownPollView(post), … … 1563 1505 const kind = req.body.kind === 'boost' ? 'boost' : 'like'; 1564 1506 if (parent && parent.post_id === post.id && parent.object_uri) { 1565 // Toggle: react, or retract it (Undo Announce / Undo Like) if already on. 1566 // De stand komt uit dezelfde bron als de knop die je zag; leest de toggle uit 1567 // de kolom en de knop uit de tussentabel, dan draait een divergentie de 1568 // richting om en stuur je een Undo voor iets dat nooit is verstuurd. 1569 const ik = ActivityPubService.getReaction(site.slug, parent.object_uri); 1570 const on = kind === 'boost' ? !ik.boosted : !ik.liked; 1571 ActivityPubService.sendInteraction(site, on ? kind : `un${kind}`, parent.object_uri, parent.actor_uri) 1572 .catch((e) => console.warn('[AP] reaction failed:', e.message)); 1573 // De tussentabel is de waarheid (shaer-ipb), gesleuteld op object_uri -- net 1574 // als de Like die hierboven de fediverse in gaat. acted_* blijft voorlopig 1575 // als afgeleide meelopen, hetzelfde vangnet dat ap_timeline.liked na 1576 // shaer-9e9 is: pas weghalen als deze migratie een release heeft ingelopen. 1577 ActivityPubService.setReaction(site.slug, parent.object_uri, kind, on); 1578 if (kind === 'boost') ActivityPubService.setInteractionBoosted(parent.id, on); 1579 else ActivityPubService.setInteractionLiked(parent.id, on); 1507 if (kind === 'boost') { 1508 // Toggle: boost an unboosted comment, or retract it (Undo Announce) if already boosted. 1509 const on = !parent.acted_boost; 1510 ActivityPubService.sendInteraction(site, on ? 'boost' : 'unboost', parent.object_uri, parent.actor_uri) 1511 .catch((e) => console.warn('[AP] reaction failed:', e.message)); 1512 ActivityPubService.setInteractionBoosted(parent.id, on); 1513 } else { 1514 // Toggle: like an unliked comment, or un-favourite (Undo Like) if already liked. 1515 const on = !parent.acted_like; 1516 ActivityPubService.sendInteraction(site, on ? 'like' : 'unlike', parent.object_uri, parent.actor_uri) 1517 .catch((e) => console.warn('[AP] reaction failed:', e.message)); 1518 ActivityPubService.setInteractionLiked(parent.id, on); 1519 } 1580 1520 } 1581 1521 res.redirect(`${res.locals.siteUrlBase || ''}/${post.slug}#fediverse`);
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)