Changeset 5f7dba2 in Klonkt


Ignore:
Timestamp:
06/19/2026 12:02:20 PM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
cbfbf88
Parents:
408afc1
Message:

fix(editor): action bar correctly above keyboard (no mid-screen bug)

  • viewport: interactive-widget=resizes-content → layout shrinks when keyboard opens (Android), so sticky bottom sits naturally above the keyboard.
  • .pe-actions stays sticky; bottom offset = max(keyboard part the layout doesn't cover, audio-player height). Replaces the wrong position:fixed+top calculation that placed the bar in the middle of the screen (Android counted it twice).

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

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG.md

    r408afc1 r5f7dba2  
    1515
    1616### Opgelost
    17 - Post-editor op mobiel: de Opslaan/Annuleren-balk viel achter het toetsenbord
    18   (sticky-bottom). De balk zweeft nu mee bóven het toetsenbord (positie via de
    19   visual viewport), dus de knoppen blijven bereikbaar tijdens het typen.
     17- Post-editor op mobiel: de Opslaan/Annuleren-balk blijft nu net bóven het
     18  toetsenbord (sticky met dynamische bottom-offset = max van toetsenbord- en
     19  audiospeler-hoogte), i.p.v. erachter te vallen of midden in beeld te zweven.
     20  Viewport schaalt mee met het toetsenbord (`interactive-widget=resizes-content`).
    2021- Mobiel toetsenbord vs. layout (site-breed): zodra het toetsenbord opent tijdens
    2122  het typen, verbergen de vaste onderbalken (bottom-tab + mini-speler) zich, zodat
  • src/views/pages/post-edit.ejs

    r408afc1 r5f7dba2  
    874874   tabbalk, anders zou die zweven boven de actiebalk. */
    875875body:has(.post-edit-page) .audio-player { bottom: 0; }
    876 
    877 /* Toetsenbord open op mobiel: de Opslaan/Annuleren-balk zweeft mee boven het
    878    toetsenbord (top wordt via JS o.b.v. de visual viewport gezet). Sticky bottom
    879    valt anders achter het toetsenbord → knoppen uit beeld. */
    880 body.kb-open .pe-actions {
    881   position: fixed;
    882   left: 0; right: 0;
    883   margin: 0;
    884   z-index: 1001;
    885 }
    886876</style>
    887877
     
    15771567
    15781568(function () {
    1579   // De Opslaan/Annuleren-balk goed positioneren in twee situaties:
    1580   //  1) Toetsenbord open (body.kb-open): balk FIXED pinnen aan de onderkant van de
    1581   //     ZICHTBARE viewport (boven het toetsenbord) — anders valt de sticky-bottom
    1582   //     balk achter het toetsenbord en zijn Opslaan/Annuleren uit beeld.
    1583   //  2) Audiospeler speelt: balk net boven de fixed speler houden (z-index 1000).
     1569  // De Opslaan/Annuleren-balk (position: sticky; bottom:0) net boven twee mogelijke
     1570  // obstakels houden door een dynamische bottom-offset te zetten = het grootste van:
     1571  //  1) de hoogte van het toetsenbord-deel dat de layout-viewport NIET dekt
     1572  //     (op iOS verschuift de visual viewport; op Android verkleint de layout-
     1573  //     viewport door interactive-widget=resizes-content → offset ≈ 0);
     1574  //  2) de hoogte van de spelende audiospeler (fixed, z-index 1000).
     1575  // We blijven bij sticky (geen fixed/top-gegoochel → geen balk midden in beeld).
    15841576  var bar = document.querySelector('.pe-actions');
    15851577  if (!bar) return;
    15861578  var vv = window.visualViewport;
    1587   function fitAudio() {
     1579  function position() {
    15881580    var ap = document.querySelector('.audio-player');
    15891581    var playing = document.body.classList.contains('has-audio-player') &&
    15901582                  ap && getComputedStyle(ap).display !== 'none';
    1591     bar.style.bottom = playing ? Math.round(ap.getBoundingClientRect().height) + 'px' : '';
    1592   }
    1593   function position() {
    1594     if (document.body.classList.contains('kb-open') && vv) {
    1595       bar.style.bottom = '';
    1596       bar.style.top = Math.round(vv.offsetTop + vv.height - bar.offsetHeight) + 'px';
    1597     } else {
    1598       bar.style.top = '';
    1599       fitAudio();
    1600     }
     1583    var audioOffset = playing ? Math.round(ap.getBoundingClientRect().height) : 0;
     1584    var kbCovered = vv ? Math.max(0, Math.round(window.innerHeight - vv.height - vv.offsetTop)) : 0;
     1585    var offset = Math.max(audioOffset, kbCovered);
     1586    bar.style.bottom = offset ? offset + 'px' : '';
    16011587  }
    16021588  position();
    16031589  window.addEventListener('resize', position);
    16041590  if (vv) { vv.addEventListener('resize', position); vv.addEventListener('scroll', position); }
    1605   // kb-open + has-audio-player wisselen via een body-class → daarop reageren.
     1591  // has-audio-player wisselt via een body-class → daarop reageren.
    16061592  try { new MutationObserver(position).observe(document.body, { attributes: true, attributeFilter: ['class'] }); } catch (_) {}
    16071593})();
  • src/views/shell.ejs

    r408afc1 r5f7dba2  
    9898<head>
    9999<meta charset="utf-8">
    100 <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
     100<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover,interactive-widget=resizes-content">
    101101<meta name="color-scheme" content="dark light">
    102102
Note: See TracChangeset for help on using the changeset viewer.