Changeset 78b6d8a in Klonkt


Ignore:
Timestamp:
06/26/2026 12:16:33 PM (2 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
4c47eff
Parents:
3384e95
Message:

feat(tijdlijn): unboost button — retract a boost (Undo Announce) from posts

The 🔁 on a timeline post is now a toggle: not boosted -> boost (Announce + mark
locally); boosted -> unboost (highlighted) which sends Undo(Announce) so followers'
servers remove the reblog, and clears the local flag. sendInteraction handles
'unboost' (Undo wrapping Announce, matched on actor+object — no record of the
original Announce needed). All operator-driven: your click sends it, nothing
automatic touches the fediverse.

Co-Authored-By: Claude <noreply@…>

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r3384e95 r78b6d8a  
    633633  }
    634634  res.redirect('/tijdlijn?success=' + encodeURIComponent('Geboost 🔁'));
     635});
     636
     637// Unboost (retract): send Undo(Announce) + clear the local flag.
     638router.post('/tijdlijn/unboost', requireSiteManager, async (req, res) => {
     639  const site = res.locals.site;
     640  const note = (req.body.note || '').toString();
     641  if (site && note) {
     642    try { await ActivityPubService.sendInteraction(site, 'unboost', note, (req.body.author || '').toString()); } catch (e) { /* ignore */ }
     643    ActivityPubService.unmarkBoosted(site.slug, note);
     644  }
     645  res.redirect('/tijdlijn?success=' + encodeURIComponent('Boost ingetrokken'));
    635646});
    636647
  • src/services/ActivityPubService.js

    r3384e95 r78b6d8a  
    10731073}
    10741074// Mark a timeline post as boosted so it shows in the Cirkel (mixed by date).
    1075 let _markBoost, _boostedCount;
     1075let _markBoost, _unmarkBoost, _boostedCount;
    10761076export function markBoosted(slug, noteId) {
    10771077  try { if (!_markBoost) _markBoost = db.prepare('UPDATE ap_timeline SET boosted = 1 WHERE slug = ? AND id = ?'); _markBoost.run(slug, noteId); } catch { /* ignore */ }
     1078}
     1079export function unmarkBoosted(slug, noteId) {
     1080  try { if (!_unmarkBoost) _unmarkBoost = db.prepare('UPDATE ap_timeline SET boosted = 0 WHERE slug = ? AND id = ?'); _unmarkBoost.run(slug, noteId); } catch { /* ignore */ }
    10781081}
    10791082export function boostedCount(slug) {
     
    12261229  const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
    12271230  if (!base || !site || !site.slug || !targetNoteId) return { error: 'config' };
    1228   const type = kind === 'boost' ? 'Announce' : 'Like';
    12291231  const me = actorId(base, site.slug);
    12301232  const keys = getOrCreateKeys(site.slug);
    1231   const act = {
    1232     '@context': 'https://www.w3.org/ns/activitystreams',
    1233     id: `${me}#${type.toLowerCase()}-${Date.now()}-${rid()}`,
    1234     type, actor: me, object: targetNoteId,
    1235   };
    1236   if (type === 'Announce') { act.to = [PUBLIC]; act.cc = [`${me}/followers`]; }
     1233  // 'unboost' = Undo(Announce): retracts a boost so followers' servers remove the
     1234  // reblog (matched on actor+object — no record of the original Announce needed).
     1235  const fanout = (kind === 'boost' || kind === 'unboost'); // also goes to our followers
     1236  let act;
     1237  if (kind === 'unboost') {
     1238    act = {
     1239      '@context': 'https://www.w3.org/ns/activitystreams',
     1240      id: `${me}#undo-${Date.now()}-${rid()}`, type: 'Undo', actor: me,
     1241      to: [PUBLIC], cc: [`${me}/followers`],
     1242      object: { id: `${me}#announce-${Date.now()}-${rid()}`, type: 'Announce', actor: me, object: targetNoteId },
     1243    };
     1244  } else {
     1245    const type = kind === 'boost' ? 'Announce' : 'Like';
     1246    act = {
     1247      '@context': 'https://www.w3.org/ns/activitystreams',
     1248      id: `${me}#${type.toLowerCase()}-${Date.now()}-${rid()}`,
     1249      type, actor: me, object: targetNoteId,
     1250    };
     1251    if (type === 'Announce') { act.to = [PUBLIC]; act.cc = [`${me}/followers`]; }
     1252  }
    12371253  const inboxes = new Set();
    12381254  if (authorUri) { const a = await fetchActor(authorUri).catch(() => null); if (a) inboxes.add((a.endpoints && a.endpoints.sharedInbox) || a.inbox); }
    1239   // A boost is public → also deliver to our own followers so it shows for them.
    1240   if (type === 'Announce') { for (const f of fStmts().list.all(site.slug)) inboxes.add(f.shared_inbox || f.inbox); }
     1255  if (fanout) { for (const f of fStmts().list.all(site.slug)) inboxes.add(f.shared_inbox || f.inbox); }
    12411256  let delivered = 0;
    12421257  for (const inbox of [...inboxes].filter(Boolean)) { try { const st = await deliver(inbox, act, `${me}#main-key`, keys.private_pem); if (st >= 200 && st < 300) delivered++; } catch { /* best-effort */ } }
    1243   console.log('[AP]', type, site.slug, '→', targetNoteId, 'delivered', delivered);
     1258  console.log('[AP]', kind, site.slug, '→', targetNoteId, 'delivered', delivered);
    12441259  return { ok: true, delivered };
    12451260}
     
    13561371  listOutbox, deliverOutboxDelete,
    13571372  webfingerResolve, followActor, resolveRemoteActor, unfollowActor, listFollowing, setAutoBoost, getTimeline, sendInteraction,
    1358   autoBoostCount, boostedCount, markBoosted, getCirkelPosts, getCirkelMembers, autoMigrateCircles, selfHealTimeline, boostLatestN,
     1373  autoBoostCount, boostedCount, markBoosted, unmarkBoosted, getCirkelPosts, getCirkelMembers, autoMigrateCircles, selfHealTimeline, boostLatestN,
    13591374  getNotifications, listBlocks, isBlockedAny, blockTarget, unblock,
    13601375  deliverWithRetry, enqueueDelivery, processDeliveryQueue, startDeliveryWorker,
  • src/services/i18n.js

    r3384e95 r78b6d8a  
    109109    'fedi.heading': 'Vanuit de fediverse', 'fedi.likes': 'sterren', 'fedi.boosts': 'boosts', 'fedi.replies': 'Reacties uit de fediverse',
    110110    'fedi.reply': 'Reageer', 'fedi.reply_ph': 'Je antwoord aan de fediverse…', 'fedi.send': 'Versturen', 'fedi.you': 'Jij',
    111     'fedi.remote_title': 'Reageer via de fediverse', 'fedi.follow_heading': 'Volgen via de fediverse', 'fedi.profile_follow': 'Volg via de fediverse', 'fedi.follow_intro': 'Je staat op het punt te volgen:', 'fedi.follow_btn': 'Volgen', 'fedi.followed_title': 'Volgverzoek verstuurd ✅', 'fedi.followed_done': 'Je volgverzoek is onderweg. Zodra de andere kant het accepteert, verschijnen hun berichten in je tijdlijn.', 'fedi.view_profile': 'Bekijk profiel →', 'fedi.remote_reply': 'Reageer via de fediverse', 'fedi.remote_prompt': 'Je fediverse-adres (bv. @jij@mastodon.social):', 'fedi.remote_notfound': 'Kon die post niet ophalen. Plak de volledige post-URL:', 'fedi.remote_load': 'Ophalen', 'fedi.remote_replying_to': 'Je reageert op', 'fedi.remote_as': 'Wordt verzonden als {site}.', 'fedi.remote_view_original': 'Bekijk de hele post + reacties op de bron →', 'fedi.remote_reply_short': 'via de fediverse', 'fedi.like_short': 'Like', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is verstuurd. Hij verschijnt zo bij de originele post op de fediverse, niet op deze pagina. Bekijk hem daar:', 'fedi.reply_where': 'Je reactie verschijnt bij de originele post op de fediverse, niet op deze pagina. Via de link hierboven zie je hem daar.', 'fedi.remote_back': '← Terug naar je site', 'fedi.like_btn': 'Like deze post', 'fedi.or_reply': 'of reageer:', 'fedi.liked_title': 'Geliket', 'fedi.liked_done': 'Je like is onderweg naar de fediverse.', 'fedi.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'tl.title': 'Tijdlijn', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.autoboost': 'Uitgelicht', 'tl.autoboost_follow': 'uitlichten in cirkel', 'tl.autoboost_hint': 'Hun posts verschijnen in jouw Cirkel (lokaal, geen fediverse-boost).', 'tl.boost5_follow': 'laatste 5 boosten', 'tl.boost5_hint': 'Eenmalig hun 5 nieuwste posts naar je fediverse-volgers boosten (optioneel).', 'tl.pending': 'in afwachting', 'tl.feed': 'Berichten', 'tl.tab_feed': 'Tijdlijn', 'tl.tab_following': 'Volgend', 'tl.empty_following': 'Je volgt nog niemand.', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →',
     111    'fedi.remote_title': 'Reageer via de fediverse', 'fedi.follow_heading': 'Volgen via de fediverse', 'fedi.profile_follow': 'Volg via de fediverse', 'fedi.follow_intro': 'Je staat op het punt te volgen:', 'fedi.follow_btn': 'Volgen', 'fedi.followed_title': 'Volgverzoek verstuurd ✅', 'fedi.followed_done': 'Je volgverzoek is onderweg. Zodra de andere kant het accepteert, verschijnen hun berichten in je tijdlijn.', 'fedi.view_profile': 'Bekijk profiel →', 'fedi.remote_reply': 'Reageer via de fediverse', 'fedi.remote_prompt': 'Je fediverse-adres (bv. @jij@mastodon.social):', 'fedi.remote_notfound': 'Kon die post niet ophalen. Plak de volledige post-URL:', 'fedi.remote_load': 'Ophalen', 'fedi.remote_replying_to': 'Je reageert op', 'fedi.remote_as': 'Wordt verzonden als {site}.', 'fedi.remote_view_original': 'Bekijk de hele post + reacties op de bron →', 'fedi.remote_reply_short': 'via de fediverse', 'fedi.like_short': 'Like', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'jouw server', 'fedi.remote_sent_title': 'Verzonden ✅', 'fedi.remote_sent': 'Je reactie is verstuurd. Hij verschijnt zo bij de originele post op de fediverse, niet op deze pagina. Bekijk hem daar:', 'fedi.reply_where': 'Je reactie verschijnt bij de originele post op de fediverse, niet op deze pagina. Via de link hierboven zie je hem daar.', 'fedi.remote_back': '← Terug naar je site', 'fedi.like_btn': 'Like deze post', 'fedi.or_reply': 'of reageer:', 'fedi.liked_title': 'Geliket', 'fedi.liked_done': 'Je like is onderweg naar de fediverse.', 'fedi.delete_confirm': 'Deze reactie verwijderen?', 'fedi.manage_title': 'Mijn fediverse-reacties', 'fedi.manage_empty': 'Je hebt nog geen reacties verstuurd.', 'tl.title': 'Tijdlijn', 'tl.lead': 'Volg accounts in de fediverse en zie hun berichten hier.', 'tl.follow_btn': 'Volgen', 'tl.following': 'Je volgt', 'tl.unfollow': 'Ontvolgen', 'tl.autoboost': 'Uitgelicht', 'tl.autoboost_follow': 'uitlichten in cirkel', 'tl.autoboost_hint': 'Hun posts verschijnen in jouw Cirkel (lokaal, geen fediverse-boost).', 'tl.boost5_follow': 'laatste 5 boosten', 'tl.boost5_hint': 'Eenmalig hun 5 nieuwste posts naar je fediverse-volgers boosten (optioneel).', 'tl.pending': 'in afwachting', 'tl.unboost': 'Boost intrekken', 'tl.feed': 'Berichten', 'tl.tab_feed': 'Tijdlijn', 'tl.tab_following': 'Volgend', 'tl.empty_following': 'Je volgt nog niemand.', 'tl.empty': 'Nog niks — volg iemand om hun berichten hier te zien.', 'tl.view_original': 'Bekijk origineel →',
    112112    'comments.to_start': 'om de conversatie te starten.',
    113113    'comments.reply': 'Reageer', 'comments.delete': 'Verwijder', 'comments.cancel': 'Annuleren',
     
    11211121    'fedi.heading': 'From the fediverse', 'fedi.likes': 'favourites', 'fedi.boosts': 'boosts', 'fedi.replies': 'Replies from the fediverse',
    11221122    'fedi.reply': 'Reply', 'fedi.reply_ph': 'Your reply to the fediverse…', 'fedi.send': 'Send', 'fedi.you': 'You',
    1123     'fedi.remote_title': 'Reply via the fediverse', 'fedi.follow_heading': 'Follow via the fediverse', 'fedi.profile_follow': 'Follow via the fediverse', 'fedi.follow_intro': 'You are about to follow:', 'fedi.follow_btn': 'Follow', 'fedi.followed_title': 'Follow request sent ✅', 'fedi.followed_done': 'Your follow request is on its way. Once accepted, their posts show up in your timeline.', 'fedi.view_profile': 'View profile →', 'fedi.remote_reply': 'Reply via the fediverse', 'fedi.remote_prompt': 'Your fediverse address (e.g. @you@mastodon.social):', 'fedi.remote_notfound': 'Could not fetch that post. Paste the full post URL:', 'fedi.remote_load': 'Fetch', 'fedi.remote_replying_to': 'Replying to', 'fedi.remote_as': 'Sent as {site}.', 'fedi.remote_view_original': 'View the full post + comments on the source →', 'fedi.remote_reply_short': 'via the fediverse', 'fedi.like_short': 'Like', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply has been sent. It will show up on the original post on the fediverse, not on this page. See it there:', 'fedi.reply_where': 'Your reply appears on the original post on the fediverse, not on this page. Use the link above to see it there.', 'fedi.remote_back': '← Back to your site', 'fedi.like_btn': 'Like this post', 'fedi.or_reply': 'or reply:', 'fedi.liked_title': 'Liked', 'fedi.liked_done': 'Your like is on its way to the fediverse.', 'fedi.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'tl.title': 'Timeline', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.autoboost': 'Featured', 'tl.autoboost_follow': 'feature in circle', 'tl.autoboost_hint': 'Their posts show in your Circle (local, no fediverse boost).', 'tl.boost5_follow': 'boost latest 5', 'tl.boost5_hint': 'One-time: boost their 5 newest posts to your fediverse followers (optional).', 'tl.pending': 'pending', 'tl.feed': 'Posts', 'tl.tab_feed': 'Timeline', 'tl.tab_following': 'Following', 'tl.empty_following': 'You do not follow anyone yet.', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →',
     1123    'fedi.remote_title': 'Reply via the fediverse', 'fedi.follow_heading': 'Follow via the fediverse', 'fedi.profile_follow': 'Follow via the fediverse', 'fedi.follow_intro': 'You are about to follow:', 'fedi.follow_btn': 'Follow', 'fedi.followed_title': 'Follow request sent ✅', 'fedi.followed_done': 'Your follow request is on its way. Once accepted, their posts show up in your timeline.', 'fedi.view_profile': 'View profile →', 'fedi.remote_reply': 'Reply via the fediverse', 'fedi.remote_prompt': 'Your fediverse address (e.g. @you@mastodon.social):', 'fedi.remote_notfound': 'Could not fetch that post. Paste the full post URL:', 'fedi.remote_load': 'Fetch', 'fedi.remote_replying_to': 'Replying to', 'fedi.remote_as': 'Sent as {site}.', 'fedi.remote_view_original': 'View the full post + comments on the source →', 'fedi.remote_reply_short': 'via the fediverse', 'fedi.like_short': 'Like', 'fedi.boost_short': 'Boost', 'fedi.remote_ph': 'your server', 'fedi.remote_sent_title': 'Sent ✅', 'fedi.remote_sent': 'Your reply has been sent. It will show up on the original post on the fediverse, not on this page. See it there:', 'fedi.reply_where': 'Your reply appears on the original post on the fediverse, not on this page. Use the link above to see it there.', 'fedi.remote_back': '← Back to your site', 'fedi.like_btn': 'Like this post', 'fedi.or_reply': 'or reply:', 'fedi.liked_title': 'Liked', 'fedi.liked_done': 'Your like is on its way to the fediverse.', 'fedi.delete_confirm': 'Delete this reply?', 'fedi.manage_title': 'My fediverse replies', 'fedi.manage_empty': 'You have not sent any replies yet.', 'tl.title': 'Timeline', 'tl.lead': 'Follow accounts on the fediverse and see their posts here.', 'tl.follow_btn': 'Follow', 'tl.following': 'Following', 'tl.unfollow': 'Unfollow', 'tl.autoboost': 'Featured', 'tl.autoboost_follow': 'feature in circle', 'tl.autoboost_hint': 'Their posts show in your Circle (local, no fediverse boost).', 'tl.boost5_follow': 'boost latest 5', 'tl.boost5_hint': 'One-time: boost their 5 newest posts to your fediverse followers (optional).', 'tl.pending': 'pending', 'tl.unboost': 'Unboost', 'tl.feed': 'Posts', 'tl.tab_feed': 'Timeline', 'tl.tab_following': 'Following', 'tl.empty_following': 'You do not follow anyone yet.', 'tl.empty': 'Nothing yet — follow someone to see their posts here.', 'tl.view_original': 'View original →',
    11241124    'comments.to_start': 'to start the conversation.',
    11251125    'comments.reply': 'Reply', 'comments.delete': 'Delete', 'comments.cancel': 'Cancel',
     
    21312131    'fedi.heading': 'Aus dem Fediverse', 'fedi.likes': 'Favoriten', 'fedi.boosts': 'Boosts', 'fedi.replies': 'Antworten aus dem Fediverse',
    21322132    'fedi.reply': 'Antworten', 'fedi.reply_ph': 'Deine Antwort an das Fediverse…', 'fedi.send': 'Senden', 'fedi.you': 'Du',
    2133     'fedi.remote_title': 'Über das Fediverse antworten', 'fedi.follow_heading': 'Über das Fediverse folgen', 'fedi.profile_follow': 'Über das Fediverse folgen', 'fedi.follow_intro': 'Du folgst gleich:', 'fedi.follow_btn': 'Folgen', 'fedi.followed_title': 'Folge-Anfrage gesendet ✅', 'fedi.followed_done': 'Deine Folge-Anfrage ist unterwegs. Sobald sie akzeptiert wird, erscheinen ihre Beiträge in deiner Timeline.', 'fedi.view_profile': 'Profil ansehen →', 'fedi.remote_reply': 'Über das Fediverse antworten', 'fedi.remote_prompt': 'Deine Fediverse-Adresse (z.B. @du@mastodon.social):', 'fedi.remote_notfound': 'Beitrag konnte nicht geladen werden. Füge die vollständige Beitrags-URL ein:', 'fedi.remote_load': 'Laden', 'fedi.remote_replying_to': 'Antwort an', 'fedi.remote_as': 'Wird als {site} gesendet.', 'fedi.remote_view_original': 'Ganzen Beitrag + Kommentare an der Quelle ansehen →', 'fedi.remote_reply_short': 'übers Fediverse', 'fedi.like_short': 'Liken', 'fedi.boost_short': 'Boosten', 'fedi.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort wurde gesendet. Sie erscheint gleich beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Sieh sie dir dort an:', 'fedi.reply_where': 'Deine Antwort erscheint beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Über den Link oben siehst du sie dort.', 'fedi.remote_back': '← Zurück zu deiner Seite', 'fedi.like_btn': 'Diesen Beitrag liken', 'fedi.or_reply': 'oder antworten:', 'fedi.liked_title': 'Geliked', 'fedi.liked_done': 'Dein Like ist unterwegs ins Fediverse.', 'fedi.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'tl.title': 'Timeline', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.autoboost': 'Hervorgehoben', 'tl.autoboost_follow': 'im Zirkel hervorheben', 'tl.autoboost_hint': 'Ihre Beiträge erscheinen in deinem Zirkel (lokal, kein Fediverse-Boost).', 'tl.boost5_follow': 'neueste 5 boosten', 'tl.boost5_hint': 'Einmalig ihre 5 neuesten Beiträge an deine Fediverse-Follower boosten (optional).', 'tl.pending': 'ausstehend', 'tl.feed': 'Beiträge', 'tl.tab_feed': 'Timeline', 'tl.tab_following': 'Folge ich', 'tl.empty_following': 'Du folgst noch niemandem.', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →',
     2133    'fedi.remote_title': 'Über das Fediverse antworten', 'fedi.follow_heading': 'Über das Fediverse folgen', 'fedi.profile_follow': 'Über das Fediverse folgen', 'fedi.follow_intro': 'Du folgst gleich:', 'fedi.follow_btn': 'Folgen', 'fedi.followed_title': 'Folge-Anfrage gesendet ✅', 'fedi.followed_done': 'Deine Folge-Anfrage ist unterwegs. Sobald sie akzeptiert wird, erscheinen ihre Beiträge in deiner Timeline.', 'fedi.view_profile': 'Profil ansehen →', 'fedi.remote_reply': 'Über das Fediverse antworten', 'fedi.remote_prompt': 'Deine Fediverse-Adresse (z.B. @du@mastodon.social):', 'fedi.remote_notfound': 'Beitrag konnte nicht geladen werden. Füge die vollständige Beitrags-URL ein:', 'fedi.remote_load': 'Laden', 'fedi.remote_replying_to': 'Antwort an', 'fedi.remote_as': 'Wird als {site} gesendet.', 'fedi.remote_view_original': 'Ganzen Beitrag + Kommentare an der Quelle ansehen →', 'fedi.remote_reply_short': 'übers Fediverse', 'fedi.like_short': 'Liken', 'fedi.boost_short': 'Boosten', 'fedi.remote_ph': 'dein Server', 'fedi.remote_sent_title': 'Gesendet ✅', 'fedi.remote_sent': 'Deine Antwort wurde gesendet. Sie erscheint gleich beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Sieh sie dir dort an:', 'fedi.reply_where': 'Deine Antwort erscheint beim Originalbeitrag im Fediverse, nicht auf dieser Seite. Über den Link oben siehst du sie dort.', 'fedi.remote_back': '← Zurück zu deiner Seite', 'fedi.like_btn': 'Diesen Beitrag liken', 'fedi.or_reply': 'oder antworten:', 'fedi.liked_title': 'Geliked', 'fedi.liked_done': 'Dein Like ist unterwegs ins Fediverse.', 'fedi.delete_confirm': 'Diese Antwort löschen?', 'fedi.manage_title': 'Meine Fediverse-Antworten', 'fedi.manage_empty': 'Du hast noch keine Antworten gesendet.', 'tl.title': 'Timeline', 'tl.lead': 'Folge Konten im Fediverse und sieh ihre Beiträge hier.', 'tl.follow_btn': 'Folgen', 'tl.following': 'Du folgst', 'tl.unfollow': 'Entfolgen', 'tl.autoboost': 'Hervorgehoben', 'tl.autoboost_follow': 'im Zirkel hervorheben', 'tl.autoboost_hint': 'Ihre Beiträge erscheinen in deinem Zirkel (lokal, kein Fediverse-Boost).', 'tl.boost5_follow': 'neueste 5 boosten', 'tl.boost5_hint': 'Einmalig ihre 5 neuesten Beiträge an deine Fediverse-Follower boosten (optional).', 'tl.pending': 'ausstehend', 'tl.unboost': 'Boost zurücknehmen', 'tl.feed': 'Beiträge', 'tl.tab_feed': 'Timeline', 'tl.tab_following': 'Folge ich', 'tl.empty_following': 'Du folgst noch niemandem.', 'tl.empty': 'Noch nichts — folge jemandem, um Beiträge hier zu sehen.', 'tl.view_original': 'Original ansehen →',
    21342134    'comments.to_start': 'um das Gespräch zu starten.',
    21352135    'comments.reply': 'Antworten', 'comments.delete': 'Löschen', 'comments.cancel': 'Abbrechen',
  • src/views/pages/timeline.ejs

    r3384e95 r78b6d8a  
    2525            <div class="tl-actions">
    2626              <form method="post" action="/tijdlijn/like" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act" title="<%= t('fedi.likes') %>">⭐</button></form>
     27              <% if (p.boosted) { %>
     28              <form method="post" action="/tijdlijn/unboost" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act tl-act-on" title="<%= t('tl.unboost') %>">🔁</button></form>
     29              <% } else { %>
    2730              <form method="post" action="/tijdlijn/boost" class="tl-act-form"><input type="hidden" name="note" value="<%= p.id %>"><input type="hidden" name="author" value="<%= p.author_uri %>"><button type="submit" class="tl-act" title="<%= t('fedi.boosts') %>">🔁</button></form>
     31              <% } %>
    2832              <button type="button" class="tl-act fedi-remote-reply-btn" data-fedi-uri="<%= p.id %>" data-fedi-ph="<%= t('fedi.remote_ph') %>" title="<%= t('fedi.remote_reply') %>">↩</button>
    2933              <form method="post" action="/blokkeren/add" class="tl-act-form" onsubmit="return confirm('<%= t('tl.block') %>?');"><input type="hidden" name="target" value="<%= p.author_uri %>"><button type="submit" class="tl-act" title="<%= t('tl.block') %>">🚫</button></form>
     
    7074  .tl-act { background: none; border: 1px solid color-mix(in srgb, var(--ink, #000) 14%, transparent); border-radius: 999px; padding: .2rem .6rem; cursor: pointer; font-size: .9rem; color: var(--ink-soft, #888); }
    7175  .tl-act:hover { color: var(--ink, #000); border-color: color-mix(in srgb, var(--accent, #888) 50%, transparent); }
     76  .tl-act-on { color: var(--accent, #06c); border-color: color-mix(in srgb, var(--accent, #888) 60%, transparent); background: color-mix(in srgb, var(--accent, #888) 14%, transparent); }
    7277</style>
    7378
Note: See TracChangeset for help on using the changeset viewer.