fix(mobile): lift composer by Capacitor Keyboard plugin height (resize:none, vv doesn't reflect kbd)

Device log (post-zoom-fix): keyboard open leaves clientHeight AND visualViewport at 926 -> vv gives 0 ->
composer covered. On resize:none the plugin's keyboardHeight is the only signal; now that zoom is gone
it's clean, so --kb = keyboardHeight lifts the composer flush, and keyboardWillShow at animation start +
the CSS bottom-transition makes it slide up WITH the keyboard (smooth). Config pinned to resize:none.
Build marker -> 2026-07-18-batch112.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 16:46:00 +05:30
parent 9f7561bf8b
commit 2cadf90bc8
2 changed files with 13 additions and 17 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
"offsetForKeyboardInsetBug": false
},
"Keyboard": {
"resize": "native"
"resize": "none"
},
"SplashScreen": {
"launchShowDuration": 900,
+12 -16
View File
@@ -1117,7 +1117,7 @@
</head>
<body>
<script src="/icons.js?v=6"></script>
<script>window.__BUILD='2026-07-18-batch111';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
<script>window.__BUILD='2026-07-18-batch112';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
// Emoji are rendered with the OS's own (colour) emoji font — instant, zero network.
//
// We used to run Twemoji over every emoji, which swapped each one for an <img> pulled INDIVIDUALLY from
@@ -1132,21 +1132,17 @@ function twemojify(_el){ /* native emoji: nothing to do */ }</script>
// juggling here — we only tag <html> 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(_){} })();
</script>