Changeset 837fc9c in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
06/27/2026 07:51:44 AM (2 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
92f6976
Parents:
aa45208
Message:

feat(posts): NSFW / sensitive content

Mark a post NSFW (checkbox in the editor, available to all). On-site the cover blurs in
feed/grid and the whole post blurs behind a 'Gevoelige inhoud' banner until clicked. In the
fediverse the Note gets sensitive:true + a content-warning summary (Mastodon CW). i18n NL/EN/DE.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    raa45208 r837fc9c  
    176176  const { title, slug, content, excerpt, status, pinned, cover_image_url, tags, noindex, type } = req.body;
    177177  const fanOnly = req.body.fan_only ? 1 : 0;
     178  const nsfw = req.body.nsfw ? 1 : 0;
    178179
    179180  // Content arrives as user-authored HTML from the WYSIWYG editor — sanitize
     
    213214    INSERT INTO posts (
    214215      id, site_id, slug, author_id, title, content, excerpt,
    215       status, cover_image_url, pinned, tags, type, noindex, fan_only, publish_at,
     216      status, cover_image_url, pinned, tags, type, noindex, fan_only, nsfw, publish_at,
    216217      created_at, updated_at, published_at
    217     ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
     218    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    218219  `).run(
    219220    postId, site.id, finalSlug, req.session.user.id,
     
    221222    finalStatus, cover_image_url || null, parsePinnedRank(pinned),
    222223    JSON.stringify((tags || '').split(',').map(t => t.trim()).filter(Boolean)),
    223     finalType, noindex ? 1 : 0, fanOnly, publishAt,
     224    finalType, noindex ? 1 : 0, fanOnly, nsfw, publishAt,
    224225    now, now, publishedAt
    225226  );
     
    238239        id: postId, slug: finalSlug, title: title || finalSlug,
    239240        content: cleanContent, cover_image_url: cover_image_url || null,
    240         published_at: publishedAt, created_at: now, fan_only: fanOnly,
     241        published_at: publishedAt, created_at: now, fan_only: fanOnly, nsfw,
    241242      }).catch(() => { /* best-effort */ });
    242243    }
     
    296297  const { title, content, excerpt, status, pinned, cover_image_url, tags, noindex, type } = req.body;
    297298  const fanOnly = req.body.fan_only ? 1 : 0;
     299  const nsfw = req.body.nsfw ? 1 : 0;
    298300  const newSlug = req.body.slug;
    299301  const action = req.body.action || 'save';
     
    334336      title = ?, content = ?, excerpt = ?, status = ?,
    335337      cover_image_url = ?, pinned = ?, tags = ?,
    336       type = ?, noindex = ?, fan_only = ?, publish_at = ?,
     338      type = ?, noindex = ?, fan_only = ?, nsfw = ?, publish_at = ?,
    337339      slug = ?, published_at = ?, updated_at = ?
    338340    WHERE id = ?
     
    341343    cover_image_url || null, parsePinnedRank(pinned),
    342344    JSON.stringify((tags || '').split(',').map(t => t.trim()).filter(Boolean)),
    343     finalType, noindex ? 1 : 0, fanOnly, publishAt,
     345    finalType, noindex ? 1 : 0, fanOnly, nsfw, publishAt,
    344346    finalSlug, publishedAt, now, post.id
    345347  );
     
    362364      id: post.id, slug: finalSlug, title: title || finalSlug,
    363365      content: cleanContent, cover_image_url: cover_image_url || null,
    364       published_at: publishedAt, created_at: post.created_at, fan_only: fanOnly,
     366      published_at: publishedAt, created_at: post.created_at, fan_only: fanOnly, nsfw,
    365367    };
    366368    if (post.status !== 'published') ActivityPubService.deliverCreate(site, apPost).catch(() => { /* best-effort */ });
Note: See TracChangeset for help on using the changeset viewer.