diff --git a/mobile/capacitor.config.json b/mobile/capacitor.config.json index cb11352..afd4b3d 100644 --- a/mobile/capacitor.config.json +++ b/mobile/capacitor.config.json @@ -17,7 +17,7 @@ "offsetForKeyboardInsetBug": false }, "Keyboard": { - "resize": "native" + "resize": "none" }, "SplashScreen": { "launchShowDuration": 900, diff --git a/server/public/home.html b/server/public/home.html index a6e21c8..89e0f61 100644 --- a/server/public/home.html +++ b/server/public/home.html @@ -1117,7 +1117,7 @@ - // juggling here — we only tag so CSS can make small native-only tweaks if needed. (function(){ try{ var C=window.Capacitor; if(!C||!C.isNativePlatform||!C.isNativePlatform()) return; var p=(C.getPlatform&&C.getPlatform())||''; var r=document.documentElement; r.classList.add('native-app'); if(p) r.classList.add('native-'+p); - // Keyboard — DEVICE-INDEPENDENT. The exact amount to lift the composer so it sits on the keyboard is - // the difference between the layout viewport and the VISIBLE viewport: clientHeight - visualViewport. - // This is self-adapting: with resize:native the WebView already shrank so the difference is the small - // prediction-bar residual; with resize:none the difference is the full keyboard. We read it LIVE from - // VisualViewport (never on a timer, which would sample a mid-animation, inconsistent state — that was - // the bug that left a gap). See bzKeyboardLift() in the unit test for the pure logic. - if(window.visualViewport){ - var vv=window.visualViewport; - var applyKb=function(){ - var kb=Math.max(0, Math.round(document.documentElement.clientHeight - vv.height - vv.offsetTop)); - r.style.setProperty('--kb', kb+'px'); - document.body.classList.toggle('kb-open', kb>4); - var b=document.getElementById('msgs'); if(b) b.scrollTop=b.scrollHeight; - }; - vv.addEventListener('resize', applyKb); vv.addEventListener('scroll', applyKb); + // Keyboard. The device log proved that on our build (resize:none) the WebView does NOT resize and + // VisualViewport does NOT reflect the keyboard (clientHeight & vvHeight both stay full) — so the ONLY + // reliable signal is the Capacitor Keyboard plugin's reported height. Now that the iOS auto-zoom is + // gone (inputs are 16px), that height is clean, so we lift the composer by exactly it. keyboardWillShow + // fires at the START of the animation, so the CSS bottom-transition slides the composer up WITH the + // keyboard (smooth). raw>innerHeight guards the rare device-pixel unit. + function setKb(px){ px=Math.max(0,Math.round(px)); r.style.setProperty('--kb',px+'px'); document.body.classList.toggle('kb-open',px>4); var b=document.getElementById('msgs'); if(b) b.scrollTop=b.scrollHeight; } + var KB=C.Plugins&&C.Plugins.Keyboard; + if(KB && KB.addListener){ + KB.addListener('keyboardWillShow', function(info){ var raw=(info&&info.keyboardHeight)||0; var kb = raw>window.innerHeight ? raw/(window.devicePixelRatio||1) : raw; setKb(kb); if(window.bzDbg) bzDbg('kbShow',{raw:raw, applied:Math.round(kb)}); }); + KB.addListener('keyboardWillHide', function(){ setKb(0); }); } }catch(_){} })();