Changeset 73b41eb in Klonkt
- Timestamp:
- 06/20/2026 03:42:00 AM (3 months ago)
- Branches:
- main
- Children:
- 9e6b54f
- Parents:
- 389aa99
- Location:
- src
- Files:
-
- 5 edited
-
assets/css/embed.css (modified) (1 diff)
-
assets/js/embed-player.js (modified) (3 diffs)
-
services/AudioEmbedService.js (modified) (3 diffs)
-
views/pages/post-edit.ejs (modified) (1 diff)
-
views/shell.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/css/embed.css
r389aa99 r73b41eb 119 119 width: 320px; 120 120 height: 60px; 121 opacity: 0; 122 pointer-events: none; 123 } 124 /* Audio-only YouTube: de YT-speler draait verborgen (off-screen) maar moet een 125 * echte grootte houden, anders pauzeert de browser 'm. Alleen het geluid telt. */ 126 .pcms-embed-card--youtube.pcms-embed-audio-mode .pcms-embed-mount { 127 position: absolute; 128 left: -99999px; 129 top: 0; 130 width: 320px; 131 height: 180px; 121 132 opacity: 0; 122 133 pointer-events: none; -
src/assets/js/embed-player.js
r389aa99 r73b41eb 183 183 184 184 // --- UI ophangen (verschilt per provider-type) --- 185 const isVideo = provider === 'youtube'; 185 // Audio-only YouTube (data-embed-mode="audio"): render als audio-kaart met 186 // onze controls; de YT-speler draait verborgen (off-screen) en levert alleen 187 // het geluid. Video blijft de default. 188 const audioOnly = provider === 'youtube' && el.dataset.embedMode === 'audio'; 189 if (audioOnly) el.classList.add('pcms-embed-audio-mode'); 190 const isVideo = provider === 'youtube' && !audioOnly; 186 191 const custom = provider === 'youtube' || provider === 'soundcloud'; // eigen controls 187 192 const poster = provider === 'youtube' … … 222 227 let vol = 100; // huidige volume 0-100 (wordt op de adapter toegepast) 223 228 let preMuteVol = 100; 229 // Audio-only YouTube: zet de thumbnail als albumhoes op de audio-kaart. 230 if (audioOnly && poster) { 231 const art0 = el.querySelector('.pcms-embed-art'); 232 if (art0) { art0.style.backgroundImage = `url('${poster}')`; art0.classList.add('has-art'); } 233 } 224 234 225 235 function setPlayingUI(on) { … … 369 379 events: { 370 380 onReady() { 371 let d = 0; try { d = player.getDuration() || 0; } catch (e) {} 372 hooks.onReady({ duration: d }); 381 let d = 0; const meta = {}; 382 try { d = player.getDuration() || 0; } catch (e) {} 383 try { const vd = player.getVideoData(); if (vd && vd.title) meta.title = vd.title; } catch (e) {} 384 meta.duration = d; 385 hooks.onReady(meta); 373 386 resolve({ 374 387 play() { try { player.playVideo(); } catch (e) {} }, -
src/services/AudioEmbedService.js
r389aa99 r73b41eb 67 67 case 'youtube': 68 68 return this.embedPlaceholder('youtube', config.id, 'video', 69 config.url || `https://youtu.be/${config.id}` );69 config.url || `https://youtu.be/${config.id}`, config.mode); 70 70 case 'soundcloud': 71 71 return this.embedPlaceholder('soundcloud', config.url, 'track', config.url); … … 91 91 * ALLE waarden via escape() — post.content_html wordt ongeescaped uitgevoerd. 92 92 */ 93 static embedPlaceholder(provider, ref, type, url ) {93 static embedPlaceholder(provider, ref, type, url, mode) { 94 94 const attrs = [ 95 95 `data-embed-provider="${this.escape(provider)}"`, 96 96 `data-embed-ref="${this.escape(ref)}"`, 97 97 type ? `data-embed-type="${this.escape(type)}"` : '', 98 mode ? `data-embed-mode="${this.escape(mode)}"` : '', 98 99 `data-embed-url="${this.escape(url)}"`, 99 100 ].filter(Boolean).join(' '); … … 227 228 static embedMediaShortcodes(html) { 228 229 if (!html) return html; 229 return html.replace(/\[\[embed:([^\]]+)\]\]/gi, (match, rawUrl) => { 230 const url = rawUrl.trim().replace(/&/g, '&'); 230 return html.replace(/\[\[embed:([^\]]+)\]\]/gi, (match, rawSpec) => { 231 // Optionele modus-prefix: [[embed:audio:URL]] = alleen-audio speler, 232 // [[embed:video:URL]] / [[embed:URL]] = normaal (video waar van toepassing). 233 let spec = rawSpec.trim(); 234 let mode = null; 235 const mm = spec.match(/^(audio|video):(.+)$/i); 236 if (mm) { mode = mm[1].toLowerCase(); spec = mm[2].trim(); } 237 const url = spec.replace(/&/g, '&'); 231 238 const detected = this.detectProvider(url); 232 239 if (!detected) { 233 240 return `<div class="post-embed-missing"><em>Embed: niet-ondersteunde of ongeldige URL.</em></div>`; 234 241 } 235 return this.generateIframe(detected.provider, detected) || match;242 return this.generateIframe(detected.provider, { ...detected, mode }) || match; 236 243 }); 237 244 } -
src/views/pages/post-edit.ejs
r389aa99 r73b41eb 1463 1463 const url = raw.trim(); 1464 1464 if (!/^https?:\/\//i.test(url)) { alert('Geef een volledige URL (https://…).'); return; } 1465 insertChip('embed', url); 1465 // YouTube: keuze audio-only (alleen geluid) of video. 1466 let val = url; 1467 if (/(youtube\.com|youtu\.be)/i.test(url)) { 1468 const audioOnly = window.confirm('YouTube — alleen audio afspelen?\n\nOK = audio-only speler (geen video)\nAnnuleren = video'); 1469 if (audioOnly) val = 'audio:' + url; 1470 } 1471 insertChip('embed', val); 1466 1472 }); 1467 1473 } -
src/views/shell.ejs
r389aa99 r73b41eb 170 170 <link rel="stylesheet" href="/assets/css/audio.css?v=6"> 171 171 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) in huisstijl. --> 172 <link rel="stylesheet" href="/assets/css/embed.css?v= 4">172 <link rel="stylesheet" href="/assets/css/embed.css?v=5"> 173 173 174 174 <%- include('partials/shared-styles') %> … … 303 303 <!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) via de echte 304 304 player-API's + gedeelde mutual-exclusion registry met de site-speler. --> 305 <script src="/assets/js/embed-player.js?v= 7" defer></script>305 <script src="/assets/js/embed-player.js?v=8" defer></script> 306 306 <% if (site && site.enable_audio_player && audioTracks && audioTracks.length > 0) { %> 307 307 <script>window.PCMS_SITE_TRACKS = <%- JSON.stringify(audioTracks) %>;</script>
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)