Changeset 4c9c60b in Klonkt
- Timestamp:
- 06/25/2026 05:27:29 AM (3 months ago)
- Branches:
- main
- Children:
- ca25f360
- Parents:
- e951b7c
- Location:
- src
- Files:
-
- 2 edited
-
routes/embed.js (modified) (2 diffs)
-
views/shell.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/embed.js
re951b7c r4c9c60b 12 12 13 13 import express from 'express'; 14 import db from '../config/database.js'; 14 15 import { premiumUnlocked } from '../services/PatreonService.js'; 15 16 … … 28 29 ); 29 30 30 const tracks = (res.locals.audioTracks || []).map((t) => ({31 let tracks = (res.locals.audioTracks || []).map((t) => ({ 31 32 id: t.id, title: t.title, artist: t.artist, duration: t.duration, url: t.media_url, 32 33 })).filter((t) => t.url); 34 35 // ?post=<slug> → scope the player to that post's tracks (for the fediverse 36 // player card). Resolve [[track]]/[[album]]/[[playlist]] shortcodes → track ids. 37 const postSlug = (req.query.post || '').toString(); 38 if (postSlug) { 39 try { 40 const post = db.prepare("SELECT content FROM posts WHERE site_id = ? AND slug = ? AND status = 'published'").get(site.id, postSlug); 41 if (post && post.content) { 42 const ids = []; const seen = new Set(); 43 const add = (id) => { if (id && !seen.has(id)) { seen.add(id); ids.push(id); } }; 44 for (const m of post.content.matchAll(/\[\[track:([A-Za-z0-9_-]+)\]\]/g)) add(m[1]); 45 for (const m of post.content.matchAll(/\[\[album:([^\]]+)\]\]/g)) for (const r of db.prepare('SELECT id FROM audio_tracks WHERE site_id = ? AND album = ? ORDER BY position').all(site.id, m[1].trim())) add(r.id); 46 for (const m of post.content.matchAll(/\[\[playlist:([A-Za-z0-9_-]+)\]\]/g)) for (const r of db.prepare('SELECT track_id FROM playlist_tracks WHERE playlist_id = ? ORDER BY position').all(m[1])) add(r.track_id); 47 if (ids.length) { 48 const byId = new Map(tracks.map((t) => [t.id, t])); 49 const scoped = ids.map((id) => byId.get(id)).filter(Boolean); 50 if (scoped.length) tracks = scoped; 51 } 52 } 53 } catch { /* fall back to the full site player */ } 54 } 33 55 34 56 res.render('pages/embed-player', { -
src/views/shell.ejs
re951b7c r4c9c60b 153 153 <% } %> 154 154 <% if (_canonical) { %><meta property="og:url" content="<%= _e(_canonical) %>"><% } %> 155 <% 156 // Fediverse/social PLAYER card for posts with audio: instead of shipping the raw 157 // mp3, point at our embeddable player (/embed?post=slug) so Mastodon shows an 158 // inline player that streams via the gated /audio/stream (no downloadable file). 159 const _postAudio = !!(typeof post !== 'undefined' && post 160 && /\[\[(track|album|playlist):/i.test(post.content || post.content_html || '') 161 && typeof premiumUnlocked !== 'undefined' && premiumUnlocked); 162 const _embedUrl = _postAudio 163 ? ((typeof ogOrigin !== 'undefined' && ogOrigin ? ogOrigin : '') + safeUrlBase + '/embed?post=' + encodeURIComponent(post.slug)) 164 : ''; 165 %> 166 <% if (_postAudio) { %> 167 <meta property="og:video" content="<%= _e(_embedUrl) %>"> 168 <meta property="og:video:secure_url" content="<%= _e(_embedUrl) %>"> 169 <meta property="og:video:type" content="text/html"> 170 <meta property="og:video:width" content="480"> 171 <meta property="og:video:height" content="160"> 172 <% } %> 155 173 <% if (typeof post !== 'undefined' && post && post.published_at) { %> 156 174 <meta property="article:published_time" content="<%= _e(post.published_at) %>"> … … 160 178 161 179 <!-- Twitter Cards --> 162 <meta name="twitter:card" content="<%= _socialImage ? 'summary_large_image' : 'summary' %>"> 180 <meta name="twitter:card" content="<%= _postAudio ? 'player' : (_socialImage ? 'summary_large_image' : 'summary') %>"> 181 <% if (_postAudio) { %> 182 <meta name="twitter:player" content="<%= _e(_embedUrl) %>"> 183 <meta name="twitter:player:width" content="480"> 184 <meta name="twitter:player:height" content="160"> 185 <% } %> 163 186 <meta name="twitter:title" content="<%= _e(_socialTitle) %>"> 164 187 <meta name="twitter:description" content="<%= _e(_socialDescr) %>">
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)