Ignore:
Timestamp:
06/27/2026 08:10:43 AM (2 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
c21197a
Parents:
92f6976
Message:

feat(nsfw): custom content-warning text + blur in the Cirkel

  • Per-post content-warning text (like Mastodon): editor field; used as the on-site veil/banner label and the fediverse Note summary (falls back to 'Gevoelige inhoud').
  • Cirkel feed now blurs remote sensitive posts: ap_timeline gets nsfw+cw (captured from the incoming Note's sensitive/summary), getCirkelPosts returns them, circle.js maps them so post-card/tile show the veil.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    r92f6976 rb7d4458  
    250250    sensitive: !!post.nsfw,
    251251  };
    252   if (post.nsfw) note.summary = 'Gevoelige inhoud';
     252  if (post.nsfw) note.summary = post.content_warning || 'Gevoelige inhoud';
    253253  if (attachment.length) note.attachment = attachment;
    254254  // Playable-audio posts suppress the cover attachment (player card). Still expose
     
    708708        // the timeline).
    709709        for (const s of subs) {
    710           tlStmts().ins.run(o.id, s.slug, actorUri, ai.name, ai.handle, ai.icon, ai.url, html, o.url || null, o.published || null, media);
     710          tlStmts().ins.run(o.id, s.slug, actorUri, ai.name, ai.handle, ai.icon, ai.url, html, o.url || null, o.published || null, media, o.sensitive ? 1 : 0, o.summary || null);
    711711        }
    712712        console.log('[AP] timeline +', actorUri, 'x' + subs.length);
     
    775775  if (!site) return;
    776776  const recent = db.prepare(
    777     `SELECT id, slug, title, content, cover_image_url, nsfw, published_at, created_at
     777    `SELECT id, slug, title, content, cover_image_url, nsfw, content_warning, published_at, created_at
    778778     FROM posts WHERE site_id = ? AND status = 'published' AND (fan_only IS NULL OR fan_only = 0)
    779779     ORDER BY COALESCE(published_at, created_at) DESC LIMIT 20`
     
    10111011    url: note.url || url,
    10121012    content: HtmlSanitizerService.sanitize(rawHtml),       // full, sanitized
     1013    sensitive: !!note.sensitive,                            // remote CW → blur in the Cirkel
     1014    cw: note.summary || '',
    10131015    images,
    10141016    threadInboxes,                                          // every ancestor author's inbox
     
    10831085function tlStmts() {
    10841086  if (!_insTl) {
    1085     _insTl = db.prepare('INSERT OR IGNORE INTO ap_timeline (id, slug, author_uri, author_name, author_handle, author_icon, author_url, content, url, published, media_json, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)');
     1087    _insTl = db.prepare('INSERT OR IGNORE INTO ap_timeline (id, slug, author_uri, author_name, author_handle, author_icon, author_url, content, url, published, media_json, nsfw, cw, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP)');
    10861088    _listTl = db.prepare('SELECT * FROM ap_timeline WHERE slug = ? ORDER BY COALESCE(published, created_at) DESC LIMIT ?');
    10871089    _delTl = db.prepare('DELETE FROM ap_timeline WHERE id = ?');
     
    11021104    if (!_cirkelPosts) _cirkelPosts = db.prepare(`
    11031105      SELECT t.id, t.author_uri, t.author_name, t.author_handle, t.author_icon, t.author_url,
    1104              t.content, t.url, t.published, t.media_json, t.boosted
     1106             t.content, t.url, t.published, t.media_json, t.boosted, t.nsfw, t.cw
    11051107      FROM ap_timeline t
    11061108      LEFT JOIN ap_following f ON f.slug = t.slug AND f.actor_uri = t.author_uri
     
    11421144    tlStmts().ins.run(id, slug, note.actor_uri || '', note.actor_name || '', note.actor_handle || '',
    11431145      note.actor_icon || '', note.actor_url || '', note.content || '', note.url || null,
    1144       new Date().toISOString(), media);
     1146      new Date().toISOString(), media, note.sensitive ? 1 : 0, note.cw || null);
    11451147  } catch { /* ignore */ }
    11461148  markBoosted(slug, id);
Note: See TracChangeset for help on using the changeset viewer.