diag+fix(mobile): capture keyboard-open composer position; replay open slide transition

- Debug now reports curKb/compBottom/kbTop/coveredBy on keyboard events so I can see WHY the composer is
  covered (lift coming out 0) from the server log.
- Transition: force the bzConvoIn slide to replay on every chat open (CSS animation only auto-plays on a
  class change, so chat->chat looked instant). Restart via reflow + inline animation.
Build marker -> 2026-07-18-batch111.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 16:23:22 +05:30
parent bf8df593a1
commit 9f7561bf8b
+10 -2
View File
@@ -1117,7 +1117,7 @@
</head>
<body>
<script src="/icons.js?v=6"></script>
<script>window.__BUILD='2026-07-18-batch110';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
<script>window.__BUILD='2026-07-18-batch111';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
@@ -1174,7 +1174,11 @@ function twemojify(_el){ /* native emoji: nothing to do */ }</script>
};
window.__bzFindOverflow=findOverflow;
window.addEventListener('load', function(){ setTimeout(function(){ bzDbg('load',{overflow:findOverflow()}); }, 900); });
if(window.visualViewport){ var t; window.visualViewport.addEventListener('resize', function(){ clearTimeout(t); t=setTimeout(function(){ bzDbg('kb',{overflow:findOverflow()}); }, 300); }); }
if(window.visualViewport){ var t; window.visualViewport.addEventListener('resize', function(){ clearTimeout(t); t=setTimeout(function(){
var vv=window.visualViewport; var comp=document.querySelector('.composer'); var cr=comp?comp.getBoundingClientRect():null;
var kbTop=Math.round(vv.height+vv.offsetTop); // bottom of the visible area = top of the keyboard
bzDbg('kb',{ curKb:getComputedStyle(document.documentElement).getPropertyValue('--kb').trim(), kbOpen:document.body.classList.contains('kb-open'), compBottom:cr?Math.round(cr.bottom):-1, kbTop:kbTop, coveredBy:cr?Math.round(cr.bottom-kbTop):null });
}, 250); }); }
})();
</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>
@@ -2730,6 +2734,10 @@ async function openConvo(kind,id){
convoIsGroup=(kind==='group');
const el=document.getElementById('chatPanel'); el.classList.remove('center');
el.innerHTML=convoShellHTML(it);
// Smooth page transition: replay the slide-in every time a chat opens on mobile — even chat→chat where
// body.chat-open already exists (a CSS animation only auto-plays on a class change, so it looked instant
// after the first open). Force a restart via reflow, then set the animation inline.
if(window.matchMedia('(max-width:760px)').matches){ el.style.animation='none'; void el.offsetWidth; el.style.animation='bzConvoIn .26s cubic-bezier(.2,.7,.3,1)'; }
// #1: drag-and-drop a file/video/image anywhere on the conversation to send it.
el.ondragover=(e)=>{ if(e.dataTransfer&&Array.from(e.dataTransfer.types||[]).includes('Files')){ e.preventDefault(); el.classList.add('drag-over'); } };
el.ondragleave=(e)=>{ if(e.relatedTarget===null||!el.contains(e.relatedTarget)) el.classList.remove('drag-over'); };