Changeset 230e446 in Klonkt


Ignore:
Timestamp:
06/20/2026 01:38:16 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
fa08981
Parents:
d188736
Message:

feat(player): mini-player jumps to post AND scrolls to the track (desktop)

Track embed gets id="track-<id>" (anchor) + id in the track JSON. goToPost
now carries the track id: after the htmx swap to the post it scrolls to the
track embed (block:center, smooth) with a brief highlight, instead of
scrolling to the top. Busters: audio-player.js?v=17, style.css?v=16.

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

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/assets/css/style.css

    rd188736 r230e446  
    28192819    border-color: var(--accent, #c2410c);
    28202820    background: color-mix(in srgb, var(--accent, #c2410c) 5%, var(--paper-2, transparent));
     2821}
     2822/* Korte highlight wanneer je via de mini-speler naar deze track springt. */
     2823.post-audio-track.pat-flash {
     2824    animation: patFlash 1.6s ease-out;
     2825}
     2826@keyframes patFlash {
     2827    0%, 30% { border-color: var(--accent, #c2410c); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, #c2410c) 35%, transparent); }
     2828    100% { box-shadow: 0 0 0 0 transparent; }
    28212829}
    28222830.post-audio-track .pat-play {
  • src/assets/js/audio-player.js

    rd188736 r230e446  
    566566  //    via htmx zodat de audio blijft spelen. Geen post bekend → val terug op de sheet.
    567567  //  - MOBIEL: altijd de uitgebreide speler-sheet openen (huidig gedrag).
    568   function goToPost(url) {
     568  function scrollToTrack(trackId) {
     569    if (!trackId) { window.scrollTo(0, 0); return; }
     570    const el = document.getElementById('track-' + trackId);
     571    if (!el) { window.scrollTo(0, 0); return; }
     572    el.scrollIntoView({ block: 'center', behavior: 'smooth' });
     573    el.classList.add('pat-flash');
     574    setTimeout(() => el.classList.remove('pat-flash'), 1600);
     575  }
     576  function goToPost(url, trackId) {
     577    const hash = trackId ? ('#track-' + trackId) : '';
    569578    if (window.htmx && url.charAt(0) === '/') {
    570579      try {
    571         window.htmx.ajax('GET', url, { target: '#pcms-main', swap: 'innerHTML' });
    572         history.pushState({}, '', url);
    573         window.scrollTo(0, 0);
     580        const p = window.htmx.ajax('GET', url, { target: '#pcms-main', swap: 'innerHTML' });
     581        history.pushState({}, '', url + hash);
     582        // Na de swap naar de track scrollen (klein uitstel zodat de globale
     583        // afterSwap-top-scroll eerst is geweest); val terug op top als niet gevonden.
     584        const go = () => setTimeout(() => scrollToTrack(trackId), 60);
     585        if (p && typeof p.then === 'function') p.then(go); else setTimeout(go, 150);
    574586        return;
    575587      } catch (e) { /* val terug op volledige navigatie */ }
    576588    }
    577     location.href = url;
     589    location.href = url + hash;
    578590  }
    579591  expandTrigger.addEventListener('click', () => {
    580592    const t = queue[currentIndex];
    581593    const isDesktop = window.matchMedia && window.matchMedia('(min-width: 768px)').matches;
    582     if (isDesktop && t && t.postUrl) { goToPost(t.postUrl); return; }
     594    if (isDesktop && t && t.postUrl) { goToPost(t.postUrl, t.id); return; }
    583595    openSheet();
    584596  });
  • src/services/AudioEmbedService.js

    rd188736 r230e446  
    248248      if (!t || !t.url) return match;
    249249      const trackJson = JSON.stringify({
     250        id,
    250251        url: t.url,
    251252        title: t.title || 'Untitled',
     
    258259      const dataAttr = trackJson
    259260        .replace(/&/g, '&amp;').replace(/'/g, '&#39;').replace(/</g, '&lt;');
    260       return `<div class="post-audio-track" data-pcms-track-url="${urlH}" data-pcms-track='${dataAttr}'>
     261      // id="track-<id>" = anker zodat de mini-speler hierheen kan scrollen.
     262      return `<div class="post-audio-track" id="track-${id}" data-pcms-track-id="${id}" data-pcms-track-url="${urlH}" data-pcms-track='${dataAttr}'>
    261263  <button type="button" class="pat-play" aria-label="Play ${titleH}">
    262264    <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M8 4l12 8-12 8z"/></svg>
  • src/views/shell.ejs

    rd188736 r230e446  
    163163
    164164<!-- v9 stylesheet (full palette system) -->
    165 <link rel="stylesheet" href="/assets/css/style.css?v=15">
     165<link rel="stylesheet" href="/assets/css/style.css?v=16">
    166166
    167167<!-- Audio player styles: loaded on every page so the mini-player works
     
    300300     ?v=N — cache-buster: bump bij elke audio-player.js wijziging zodat
    301301     Cloudflare (max-age=1y) niet de oude versie blijft serveren. -->
    302 <script src="/assets/js/audio-player.js?v=16"></script>
     302<script src="/assets/js/audio-player.js?v=17"></script>
    303303<!-- Eigen custom media-embeds (YouTube/SoundCloud/Spotify) via de echte
    304304     player-API's + gedeelde mutual-exclusion registry met de site-speler. -->
Note: See TracChangeset for help on using the changeset viewer.