fix(mobile): revert app-breaking interactive edge-back (iOS touchcancel left UI stuck)
The finger-follow edge gesture starting at the very left edge collided with iOS's own edge-swipe, which fires touchcancel instead of touchend, so cleanup never ran and .content stayed transformed + chat-dragging stuck on top -> bottom nav hidden and all clicks blocked. Back to the safe release-based swipe (still gets showWelcome's parallax slide). Keyboard --kb inset, #7 no-dance, #8 image swipe kept. Build marker -> 2026-07-17-batch96. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+12
-30
@@ -1112,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-17-batch95';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
|
<script>window.__BUILD='2026-07-17-batch96';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
|
||||||
@@ -4696,39 +4696,21 @@ function bzcBack(){
|
|||||||
}
|
}
|
||||||
try{ history.pushState(null,'',location.href); }catch(_){}
|
try{ history.pushState(null,'',location.href); }catch(_){}
|
||||||
window.addEventListener('popstate', ()=>{ if(bzcBack()){ try{ history.pushState(null,'',location.href); }catch(_){} } });
|
window.addEventListener('popstate', ()=>{ if(bzcBack()){ try{ history.pushState(null,'',location.href); }catch(_){} } });
|
||||||
// #4: iOS/Android have no on-screen back button in a full-screen webview, so give the app a native-feeling
|
// #4: iOS/Android have no on-screen back button in a full-screen webview, so give the app a left-edge
|
||||||
// left-edge back gesture. When a conversation is the top layer, the drag is INTERACTIVE — the whole
|
// SWIPE-back: a drag that begins at the very left edge and moves clearly rightward closes the topmost
|
||||||
// conversation follows the finger and the chat list is revealed underneath (like Teams); releasing past a
|
// layer (popup → in-conversation search → open chat) via bzcBack() — which runs showWelcome()'s parallax
|
||||||
// third of the width commits the back, otherwise it springs shut. For other layers (popup / in-conversation
|
// slide. This is RELEASE-triggered on purpose: an interactive finger-follow drag conflicts with iOS's own
|
||||||
// search) it falls back to a release-triggered bzcBack().
|
// edge gesture (it fires touchcancel), which left the UI stuck; release-based never leaves that state.
|
||||||
(function(){
|
(function(){
|
||||||
let sx=0, sy=0, mode='', content=null, w=0, decided=false;
|
let sx=0, sy=0, edge=false;
|
||||||
const convoIsTop=()=> window.matchMedia('(max-width:760px)').matches
|
|
||||||
&& document.body.classList.contains('chat-open')
|
|
||||||
&& !document.querySelector('.modal-ov') && !document.getElementById('lightbox')
|
|
||||||
&& !(function(){ const sh=document.getElementById('convoSearchHead'); return sh && sh.style.display!=='none'; })();
|
|
||||||
window.addEventListener('touchstart',(e)=>{
|
window.addEventListener('touchstart',(e)=>{
|
||||||
mode='';
|
if(e.touches.length!==1){ edge=false; return; }
|
||||||
if(e.touches.length!==1) return;
|
const t=e.touches[0]; edge = t.clientX<=24; sx=t.clientX; sy=t.clientY; // only arm when starting at the left edge
|
||||||
const t=e.touches[0]; if(t.clientX>28) return; // only from the very left edge
|
|
||||||
sx=t.clientX; sy=t.clientY; decided=false; w=window.innerWidth||360;
|
|
||||||
if(convoIsTop()){ mode='convo'; content=document.querySelector('.shell > .content'); renderChats(searchVal()); } // list ready underneath
|
|
||||||
else mode='back';
|
|
||||||
}, {passive:true});
|
|
||||||
window.addEventListener('touchmove',(e)=>{
|
|
||||||
if(mode!=='convo'||!content) return;
|
|
||||||
const t=e.touches[0], dx=t.clientX-sx, dy=t.clientY-sy;
|
|
||||||
if(!decided){ if(Math.abs(dx)>10||Math.abs(dy)>10){ decided=true; if(Math.abs(dy)>Math.abs(dx)){ mode=''; return; } document.body.classList.add('chat-dragging'); } }
|
|
||||||
if(decided && dx>=0){ content.style.transition='none'; content.style.transform='translateX('+dx+'px)'; }
|
|
||||||
}, {passive:true});
|
}, {passive:true});
|
||||||
window.addEventListener('touchend',(e)=>{
|
window.addEventListener('touchend',(e)=>{
|
||||||
const t=e.changedTouches&&e.changedTouches[0]; const dx=t?(t.clientX-sx):0, dy=t?(t.clientY-sy):0;
|
if(!edge) return; edge=false;
|
||||||
if(mode==='convo' && content){
|
const t=e.changedTouches&&e.changedTouches[0]; if(!t) return;
|
||||||
content.style.transition='transform .17s ease-out';
|
if((t.clientX-sx)>60 && Math.abs(t.clientY-sy)<50) bzcBack(); // rightward, mostly-horizontal swipe = back
|
||||||
if(dx > w*0.32){ content.style.transform='translateX(100%)'; setTimeout(()=>{ content.style.transition=''; content.style.transform=''; document.body.classList.remove('chat-dragging'); selected=null; document.body.classList.remove('chat-open'); renderChats(searchVal()); renderChatPanel(); updateRailUnread(); }, 165); }
|
|
||||||
else { content.style.transform='translateX(0)'; setTimeout(()=>{ content.style.transition=''; content.style.transform=''; document.body.classList.remove('chat-dragging'); }, 165); }
|
|
||||||
} else if(mode==='back'){ if(dx>60 && Math.abs(dy)<50) bzcBack(); }
|
|
||||||
mode=''; content=null;
|
|
||||||
}, {passive:true});
|
}, {passive:true});
|
||||||
})();
|
})();
|
||||||
// #9: swipe a message bubble to the right to reply to it (mobile), like WhatsApp/Teams. The bubble
|
// #9: swipe a message bubble to the right to reply to it (mobile), like WhatsApp/Teams. The bubble
|
||||||
|
|||||||
Reference in New Issue
Block a user