Changeset 89d6536 in Klonkt
- Timestamp:
- 06/14/2026 04:20:02 AM (3 months ago)
- Branches:
- main
- Children:
- c80e78b
- Parents:
- 2b52bfb
- Location:
- src
- Files:
-
- 2 edited
-
assets/js/audio-player.js (modified) (2 diffs)
-
views/shell.ejs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/audio-player.js
r2b52bfb r89d6536 13 13 * - body.has-audio-player adds bottom padding when player visible 14 14 * - body.audio-sheet-locked prevents body scroll when sheet open 15 * - Survives HTMX swaps via htmx:afterSettle re-attach15 * - Survives HTMX swaps + history-restores via event delegation on document.body 16 16 * 17 17 * Singleton — guards against double-init. … … 593 593 // wrapper. For the other three the data is on the button itself. The 594 594 // handler reads from button-first, falls back to wrapper. 595 function attachListeners() { 596 const playBtns = document.querySelectorAll( 597 '.post-audio-track .pat-play, ' + 598 '.post-album-tracks .pat-row, ' + 599 '.post-album-cover-btn, ' + 600 '.post-album-playall' 601 ); 602 if (playBtns.length) console.log('[pcms-audio] attaching to', playBtns.length, 'play buttons'); 603 604 playBtns.forEach((btn) => { 605 if (btn.dataset.pcmsAttached) return; 606 btn.dataset.pcmsAttached = '1'; 607 608 btn.addEventListener('click', (e) => { 609 e.preventDefault(); 610 e.stopPropagation(); 611 // Resolve metadata: button-first, then closest .post-audio-track wrapper 612 // (only inline single-track widgets put the data on the wrapper). 613 const wrapper = btn.closest('.post-audio-track'); 614 const albumId = btn.dataset.pcmsAlbumId || (wrapper && wrapper.dataset.pcmsAlbumId); 615 const trackData = btn.dataset.pcmsTrack || (wrapper && wrapper.dataset.pcmsTrack); 616 const trackUrl = btn.dataset.pcmsTrackUrl || (wrapper && wrapper.dataset.pcmsTrackUrl); 617 console.log('[pcms-audio] click', { btn: btn.className, albumId, trackUrl, hasTrackData: !!trackData }); 618 619 if (albumId) { 620 const album = document.getElementById(albumId); 621 if (!album) { console.error('[pcms-audio] album not found:', albumId); return; } 622 try { 623 const tracks = JSON.parse(album.dataset.pcmsAlbum); 624 // Start at the clicked track if we know its URL, else start at 0 625 // (cover-btn and playall both want to start from the beginning). 626 const startIdx = trackUrl ? tracks.findIndex(t => t.url === trackUrl) : 0; 627 setQueue(tracks, startIdx >= 0 ? startIdx : 0, { albumName: album.dataset.pcmsAlbumTitle || '' }); 628 } catch(err) { console.error('[pcms-audio] bad album JSON', err, album.dataset.pcmsAlbum); } 629 } else if (trackData) { 630 try { 631 const t = JSON.parse(trackData); 632 setQueue([t], 0); 633 } catch(err) { console.error('[pcms-audio] bad track JSON', err, trackData); } 634 } else if (trackUrl) { 635 // Fallback: at minimum we have the signed URL 636 setQueue([{ url: trackUrl, title: 'Track', artist: '', cover: '' }], 0); 637 } else { 638 console.error('[pcms-audio] no track data or url on button or wrapper', btn); 639 } 640 }); 641 }); 642 } 643 644 attachListeners(); 645 document.body.addEventListener('htmx:afterSettle', attachListeners); 595 // Event-delegation op document.body i.p.v. per-knop listeners. Dit overleeft 596 // HTMX history-restores: de mobiele terug-knop (popstate) laat HTMX #pcms-main 597 // terugzetten uit z'n snapshot; een per-element `data-pcms-attached`-vlag zou 598 // dan dode knoppen geven (vlag ingebakken in de snapshot, listener weg). Eén 599 // gedelegeerde listener werkt ongeacht hoe vaak de DOM ge(her)swapt wordt. 600 const PLAY_SELECTOR = 601 '.post-audio-track .pat-play, .post-album-tracks .pat-row, .post-album-cover-btn, .post-album-playall'; 602 document.body.addEventListener('click', (e) => { 603 const btn = e.target.closest(PLAY_SELECTOR); 604 if (!btn) return; 605 e.preventDefault(); 606 e.stopPropagation(); 607 // Resolve metadata: button-first, then closest .post-audio-track wrapper 608 // (only inline single-track widgets put the data on the wrapper). 609 const wrapper = btn.closest('.post-audio-track'); 610 const albumId = btn.dataset.pcmsAlbumId || (wrapper && wrapper.dataset.pcmsAlbumId); 611 const trackData = btn.dataset.pcmsTrack || (wrapper && wrapper.dataset.pcmsTrack); 612 const trackUrl = btn.dataset.pcmsTrackUrl || (wrapper && wrapper.dataset.pcmsTrackUrl); 613 console.log('[pcms-audio] click', { btn: btn.className, albumId, trackUrl, hasTrackData: !!trackData }); 614 615 if (albumId) { 616 const album = document.getElementById(albumId); 617 if (!album) { console.error('[pcms-audio] album not found:', albumId); return; } 618 try { 619 const tracks = JSON.parse(album.dataset.pcmsAlbum); 620 // Start at the clicked track if we know its URL, else start at 0 621 // (cover-btn and playall both want to start from the beginning). 622 const startIdx = trackUrl ? tracks.findIndex(t => t.url === trackUrl) : 0; 623 setQueue(tracks, startIdx >= 0 ? startIdx : 0, { albumName: album.dataset.pcmsAlbumTitle || '' }); 624 } catch(err) { console.error('[pcms-audio] bad album JSON', err, album.dataset.pcmsAlbum); } 625 } else if (trackData) { 626 try { 627 const t = JSON.parse(trackData); 628 setQueue([t], 0); 629 } catch(err) { console.error('[pcms-audio] bad track JSON', err, trackData); } 630 } else if (trackUrl) { 631 // Fallback: at minimum we have the signed URL 632 setQueue([{ url: trackUrl, title: 'Track', artist: '', cover: '' }], 0); 633 } else { 634 console.error('[pcms-audio] no track data or url on button or wrapper', btn); 635 } 636 }); 646 637 647 638 // ============================================================ -
src/views/shell.ejs
r2b52bfb r89d6536 277 277 ?v=N — cache-buster: bump bij elke audio-player.js wijziging zodat 278 278 Cloudflare (max-age=1y) niet de oude versie blijft serveren. --> 279 <script src="/assets/js/audio-player.js?v= 8"></script>279 <script src="/assets/js/audio-player.js?v=9"></script> 280 280 <% if (site && site.enable_audio_player && audioTracks && audioTracks.length > 0) { %> 281 281 <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)