Changeset e0a1ec1 in Klonkt for src/routes/posts.js


Ignore:
Timestamp:
06/30/2026 02:27:57 AM (2 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
d3b9f68
Parents:
084d1c0
Message:

feat(editor): per-post "share audio on the fediverse" toggle

Adds a per-post checkbox in the post editor that sets fedi_open on the post's hosted tracks
on save — so opening audio + federating it happens in one step, instead of toggling per track
in Beheer -> Audio and then re-saving the post. The underlying flag stays per track.

  • src/routes/posts.js — setAudioFediOpen()/postAudioFediOpen() helpers; create + save set fedi_open on the post's track/album/playlist tracks before federating; the edit form computes the checkbox's initial state
  • src/views/pages/post-edit.ejs — the fedi_open_audio checkbox next to NSFW/noindex
  • src/services/i18n.js — pedit.fedi_audio_label (nl/en/de)

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r084d1c0 re0a1ec1  
    169169
    170170// ==================== CREATE POST ====================
     171// ── Per-post audio federation ──────────────────────────────────────────────
     172// "Share audio on the fediverse" is a per-post choice in the editor, but the underlying
     173// flag is per track (audio_tracks.fedi_open — it gates the file + drives the AS2 Audio
     174// attachment). NB: the file gate is per file, so opening a track in one post makes its file
     175// fetchable for every post that reuses it.
     176function setAudioFediOpen(siteId, content, open) {
     177  const val = open ? 1 : 0;
     178  const c = content || '';
     179  try {
     180    for (const m of c.matchAll(/\[\[track:([A-Za-z0-9_-]+)\]\]/g)) db.prepare('UPDATE audio_tracks SET fedi_open = ? WHERE id = ? AND site_id = ?').run(val, m[1], siteId);
     181    for (const m of c.matchAll(/\[\[album:([^\]]+)\]\]/g)) db.prepare('UPDATE audio_tracks SET fedi_open = ? WHERE site_id = ? AND album = ?').run(val, siteId, m[1].trim());
     182    for (const m of c.matchAll(/\[\[playlist:([A-Za-z0-9_-]+)\]\]/g)) db.prepare('UPDATE audio_tracks SET fedi_open = ? WHERE id IN (SELECT track_id FROM playlist_tracks WHERE playlist_id = ?)').run(val, m[1]);
     183  } catch { /* non-fatal */ }
     184}
     185// True when the post references hosted audio AND all of it is currently fedi_open (drives the
     186// editor checkbox's initial state).
     187function postAudioFediOpen(siteId, content) {
     188  const c = content || '';
     189  if (!/\[\[(track|album|playlist):/i.test(c)) return false;
     190  let total = 0, open = 0;
     191  const tally = (r) => { if (r && r.media_id) { total++; if (r.fedi_open) open++; } };
     192  try {
     193    for (const m of c.matchAll(/\[\[track:([A-Za-z0-9_-]+)\]\]/g)) tally(db.prepare('SELECT fedi_open, media_id FROM audio_tracks WHERE id = ? AND site_id = ?').get(m[1], siteId));
     194    for (const m of c.matchAll(/\[\[album:([^\]]+)\]\]/g)) for (const r of db.prepare('SELECT fedi_open, media_id FROM audio_tracks WHERE site_id = ? AND album = ? AND media_id IS NOT NULL').all(siteId, m[1].trim())) tally(r);
     195    for (const m of c.matchAll(/\[\[playlist:([A-Za-z0-9_-]+)\]\]/g)) for (const r of db.prepare('SELECT t.fedi_open, t.media_id FROM playlist_tracks pt JOIN audio_tracks t ON t.id = pt.track_id WHERE pt.playlist_id = ? AND t.media_id IS NOT NULL').all(m[1])) tally(r);
     196  } catch { /* non-fatal */ }
     197  return total > 0 && open === total;
     198}
     199
    171200router.post('/posts/create', requireAuth, (req, res) => {
    172201  const site = res.locals.site;
     
    228257  );
    229258
     259  // Per-post "share audio on the fediverse" → set fedi_open on this post's hosted tracks
     260  // BEFORE federating, so the Create note carries the right Audio attachments.
     261  setAudioFediOpen(site.id, cleanContent, req.body.fedi_open_audio);
     262
    230263  if (finalStatus === 'published') {
    231264    try {
     
    278311    post,
    279312    isNew: false,
     313    fediOpenAudio: postAudioFediOpen(site.id, post.content),
    280314    pageTitle: 'Edit: ' + (post.title || 'Untitled'),
    281315    bodyClass: 'on-special',
     
    349383    finalSlug, publishedAt, now, post.id
    350384  );
     385
     386  // Per-post "share audio on the fediverse" → set fedi_open on this post's hosted tracks
     387  // BEFORE federating, so the Update/Create note carries the right Audio attachments.
     388  setAudioFediOpen(site.id, cleanContent, req.body.fedi_open_audio);
    351389
    352390  // Update FTS
Note: See TracChangeset for help on using the changeset viewer.