Changeset cb01666 in Klonkt


Ignore:
Timestamp:
06/23/2026 02:54:36 PM (3 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
9b851e7
Parents:
8f2f97c
Message:

feat: lite mode (KLONKT_AUDIO=off) — audio disabled, single codebase

Boot flag that skips the entire audio feature: no audio/playlist/download/
embed routes (no ffmpeg calls), no tracks loaded, own-audio shortcodes
(track/album/playlist) stripped, audio buttons in admin/profile
hidden. Hub and Circles keep working; external embeds (YouTube/SoundCloud/
Spotify) keep working too. Default = on (full version unchanged).
This lets Klonkt run as a lightweight blog/photo/EPK site on an environment
without ffmpeg.

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

Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • .env.example

    r8f2f97c rcb01666  
    3535SMTP_PASS=
    3636SMTP_FROM=
     37
     38# ── Lite-modus (optioneel) ─────────────────────────────────────────
     39# Zet op "off" om de hele audio-feature uit te schakelen (geen eigen muziek-
     40# hosting/speler, geen ffmpeg nodig). Klonkt draait dan als lichte blog/foto/
     41# EPK-site, ook op een omgeving zonder ffmpeg. Hub en Cirkels blijven werken.
     42# Externe embeds (YouTube/SoundCloud/Spotify) blijven ook werken.
     43KLONKT_AUDIO=on
  • src/middleware/render.js

    r8f2f97c rcb01666  
    2020import { isPremium as isPremiumInstance, premiumEnabled, premiumUnlocked } from '../services/PatreonService.js';
    2121import { unreadCount as notifUnreadCount } from '../services/NotificationService.js';
     22import { audioEnabled as audioFeatureEnabled } from '../config/features.js';
    2223import { PLATFORMS as PLATFORMS_CATALOG } from '../services/PlatformIcons.js';
    2324import { t as i18nT, resolveLang, SUPPORTED as LANGS, LANG_NAMES } from '../services/i18n.js';
     
    111112    siteOwnerAvatar,
    112113    site: _site,
     114    audioEnabled: audioFeatureEnabled(),
    113115    audioTracks: data.audioTracks || res.locals.audioTracks || [],
    114116    siteUrlBase: res.locals.siteUrlBase || '',
  • src/middleware/site.js

    r8f2f97c rcb01666  
    1212import { getTenancy } from '../services/SettingsService.js';
    1313import { audioUrl } from '../services/AudioStreamService.js';
     14import { audioEnabled } from '../config/features.js';
    1415
    1516/**
     
    7071 */
    7172export function loadAudioTracks(req, res, next) {
     73  if (!audioEnabled()) { res.locals.audioTracks = []; return next(); }   // lite-modus
    7274  const site = res.locals.site;
    7375  if (!site || site.enable_audio_player === 0) {
  • src/routes/posts.js

    r8f2f97c rcb01666  
    1616import AudioEmbedService from '../services/AudioEmbedService.js';
    1717import PlaylistService from '../services/PlaylistService.js';
     18import { audioEnabled } from '../config/features.js';
    1819import { audioUrl } from '../services/AudioStreamService.js';
    1920import { toWebp } from '../services/ImageWebpService.js';
     
    538539  //   stored HTML → autoembed → [[track]]/[[album]]/[[playlist]] → response
    539540  let html = post.content || '';
     541  if (audioEnabled()) {
    540542  if (site.enable_audio_player !== 0) {
    541543    html = AudioEmbedService.autoembed(html);
     
    622624    }
    623625  }
     626  } else {
     627    // LITE-modus (KLONKT_AUDIO=off): geen eigen audio (geen ffmpeg/stream-route).
     628    // Externe embeds (YouTube/SoundCloud/Spotify) blijven wel; de eigen-audio-
     629    // shortcodes ([[track]]/[[album]]/[[playlist]]) verwijderen we netjes.
     630    html = AudioEmbedService.autoembed(html);
     631    html = AudioEmbedService.embedMediaShortcodes(html);
     632    html = AudioEmbedService.embedExternalLinkShortcodes(html);
     633    html = html.replace(/\[\[(track|album|playlist):[^\]]+\]\]/gi, '');
     634  }
    624635  post.content_html = html;
    625636
  • src/server.js

    r8f2f97c rcb01666  
    2222import { isViewer } from './middleware/auth.js';
    2323import { renderPage } from './middleware/render.js';
     24import { audioEnabled } from './config/features.js';
    2425import authRoutes from './routes/auth.js';
    2526import accountRoutes from './routes/account.js';
     
    251252app.use('/account', accountRoutes);
    252253app.use('/notifications', notificationsRoutes);
    253 app.use('/admin/audio', adminAudioRoutes);
    254 app.use('/admin/playlists', adminPlaylistsRoutes);
     254if (audioEnabled()) {
     255  app.use('/admin/audio', adminAudioRoutes);
     256  app.use('/admin/playlists', adminPlaylistsRoutes);
     257}
    255258app.use('/admin/sites', adminSitesRoutes);
    256259app.use('/admin/users', adminUsersRoutes);
     
    266269app.use('/admin/epk', adminEpkRoutes);
    267270app.use('/admin', adminRoutes);
    268 app.use('/audio', audioRoutes);
     271if (audioEnabled()) app.use('/audio', audioRoutes);
    269272app.use('/search', searchRoutes);
    270273app.use('/comments', commentsRoutes);
     
    280283app.use('/', epkRoutes); // /pers perskit (premium; niet-premium: next() -> 404)
    281284app.use('/', newsletterRoutes); // /nieuwsbrief in/uitschrijven (premium; niet-premium: next())
    282 app.use('/', downloadRoutes); // /downloads + /download/:id download-voor-email (premium)
     285if (audioEnabled()) app.use('/', downloadRoutes); // /downloads + /download/:id (audio; lite: uit)
    283286app.use('/', linkbioRoutes); // /links link-in-bio + klikstats (premium)
    284 app.use('/', embedRoutes); // /embed inbedbare audiospeler (premium)
     287if (audioEnabled()) app.use('/', embedRoutes); // /embed inbedbare audiospeler (audio; lite: uit)
    285288app.use('/', showsRoutes); // /shows agenda + notify-me (premium)
    286289app.use('/', changelogRoutes); // /changelog publieke release-/wijzigingen-pagina
  • src/views/pages/admin-site-edit.ejs

    r8f2f97c rcb01666  
    159159        </select>
    160160      </label>
     161      <% if (typeof audioEnabled === 'undefined' || audioEnabled) { %>
    161162      <label class="cb">
    162163        <input type="checkbox" name="enable_audio_player" value="1" <%= site.enable_audio_player ? 'checked' : '' %>>
    163164        <span><%= t('asite.enable_audio') %></span>
    164165      </label>
     166      <% } %>
    165167    </fieldset>
    166168
  • src/views/pages/admin.ejs

    r8f2f97c rcb01666  
    1111      <a href="/admin/sites" class="btn"><%= t('admin.b_sites') %></a>
    1212      <a href="/admin/users" class="btn"><%= t('admin.b_users') %></a>
     13      <% if (typeof audioEnabled === 'undefined' || audioEnabled) { %>
    1314      <a href="/admin/audio" class="btn"><%= t('admin.b_audio') %></a>
    1415      <a href="/admin/playlists" class="btn"><%= t('admin.b_playlists') %></a>
     16      <% } %>
    1517      <a href="/admin/comments" class="btn"><%= t('admin.b_comments') %></a>
    1618      <% if (primarySite) { %><a href="/admin/seo" class="btn"><%= t('admin.b_seo') %></a><% } %>
     
    1820    <% } else { %>
    1921      <a href="/posts/new" class="btn"><%= t('admin.b_newpost') %></a>
     22      <% if (typeof audioEnabled === 'undefined' || audioEnabled) { %>
    2023      <a href="/admin/audio" class="btn"><%= t('admin.b_audio') %></a>
     24      <% } %>
    2125      <a href="/admin/comments" class="btn"><%= t('admin.b_comments') %></a>
    2226      <% if (primarySite) { %>
  • src/views/partials/profile-header.ejs

    r8f2f97c rcb01666  
    4141      <% } else if (typeof siteOwnerAvatar !== 'undefined' && siteOwnerAvatar) { %>
    4242        <img src="<%= siteOwnerAvatar %>" alt="">
    43       <% } else if (site.enable_audio_player) { %>
     43      <% } else if (site.enable_audio_player && (typeof audioEnabled === 'undefined' || audioEnabled)) { %>
    4444        <span class="profile-photo-fallback profile-photo-fallback--music" aria-hidden="true">
    4545          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
Note: See TracChangeset for help on using the changeset viewer.