fix(mobile): keyboard resize:none + web-tunable JS lift (deterministic, no plugin fight)

resize:native gave contradictory results (covered vs header) because the safe-area plugin fights it.
Set resize:none so the native layer does nothing, and lift the composer purely in JS by keyboardHeight
* KB_LIFT. Once resize:none is built, the lift is web-tunable with zero further builds.
Build marker -> 2026-07-18-batch100.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 00:55:17 +05:30
parent 9bee2c635c
commit 357f0168ba
2 changed files with 16 additions and 9 deletions
+1 -1
View File
@@ -17,7 +17,7 @@
"offsetForKeyboardInsetBug": false "offsetForKeyboardInsetBug": false
}, },
"Keyboard": { "Keyboard": {
"resize": "native" "resize": "none"
}, },
"SplashScreen": { "SplashScreen": {
"launchShowDuration": 900, "launchShowDuration": 900,
+15 -8
View File
@@ -1069,9 +1069,11 @@
directly above the keyboard (no nav sandwiched between the text box and the keyboard). The panel directly above the keyboard (no nav sandwiched between the text box and the keyboard). The panel
then only needs to clear the home indicator. */ then only needs to clear the home indicator. */
body.chat-open .rail{display:none;} body.chat-open .rail{display:none;}
/* Composer clears the home indicator; @capacitor/keyboard resize:native shrinks the WebView when the /* Composer clears the home indicator; with keyboard resize:none we raise it by --kb (the reported
keyboard opens so this bottom edge lands right on top of the keyboard (no JS lift — that overshot). */ keyboard height, set by the Keyboard listener) so it sits on the keyboard. No home indicator while
body.chat-open .content .panel{bottom:var(--sab);} the keyboard is up, so --sab collapses to 0. */
body.chat-open .content .panel{bottom:calc(var(--sab) + var(--kb));transition:bottom .18s ease;}
body.kb-open{--sab:0px;}
/* Native-style push/pop: the conversation slides in from the right when opened and slides back out /* Native-style push/pop: the conversation slides in from the right when opened and slides back out
when you go back, so navigation has a clear direction (like Teams/WhatsApp). */ when you go back, so navigation has a clear direction (like Teams/WhatsApp). */
@keyframes bzConvoIn{from{transform:translateX(100%);}to{transform:translateX(0);}} @keyframes bzConvoIn{from{transform:translateX(100%);}to{transform:translateX(0);}}
@@ -1110,7 +1112,7 @@
</head> </head>
<body> <body>
<script src="/icons.js?v=6"></script> <script src="/icons.js?v=6"></script>
<script>window.__BUILD='2026-07-18-batch99';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD); <script>window.__BUILD='2026-07-18-batch100';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. // 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 // We used to run Twemoji over every emoji, which swapped each one for an <img> pulled INDIVIDUALLY from
@@ -1125,11 +1127,16 @@ 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. // 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; (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); var p=(C.getPlatform&&C.getPlatform())||''; var r=document.documentElement; r.classList.add('native-app'); if(p) r.classList.add('native-'+p);
// Keyboard: @capacitor/keyboard resize:native already lifts the composer to sit on the keyboard, so we // Keyboard: with resize:none the native layer does NOTHING, so we lift the composer ourselves by the
// do NOT add any JS lift (that double-lifted it up to the header). We only keep the thread pinned to the // reported keyboard height (× a tunable factor). This is fully web-controllable now — if the lift is a
// newest message when the keyboard appears. // touch high/low we adjust KB_LIFT here and redeploy, no rebuild.
var KB_LIFT=1.0; // fraction of keyboardHeight to raise the composer by (calibrate via web if needed)
var KB=C.Plugins&&C.Plugins.Keyboard; var KB=C.Plugins&&C.Plugins.Keyboard;
if(KB && KB.addListener){ KB.addListener('keyboardDidShow', function(){ var b=document.getElementById('msgs'); if(b) b.scrollTop=b.scrollHeight; }); } if(KB && KB.addListener){
KB.addListener('keyboardWillShow', function(info){ var h=Math.round(((info&&info.keyboardHeight)||0)*KB_LIFT); r.style.setProperty('--kb', h+'px'); document.body.classList.add('kb-open'); });
KB.addListener('keyboardDidShow', function(){ var b=document.getElementById('msgs'); if(b) b.scrollTop=b.scrollHeight; });
KB.addListener('keyboardWillHide', function(){ r.style.setProperty('--kb','0px'); document.body.classList.remove('kb-open'); });
}
}catch(_){} })(); }catch(_){} })();
</script> </script>
<div class="loading" id="loading"><div class="ld-inner"><img src="/loaders/loader-orbit-dark.svg" alt="" width="72" height="72"><div class="ld-wm">Biz <b>Connect</b></div><span class="ld-sub">Loading…</span></div></div> <div class="loading" id="loading"><div class="ld-inner"><img src="/loaders/loader-orbit-dark.svg" alt="" width="72" height="72"><div class="ld-wm">Biz <b>Connect</b></div><span class="ld-sub">Loading…</span></div></div>