fix(ios/mobile): safe-area insets, no keyboard auto-open, no h-scroll, swipe-back, hide desktop-download

Reported on the iOS TestFlight build:
- #1/#5 notch/home-indicator: apply top safe-area inset per surface (chat list column +
  content panels) instead of on the whole shell, so headers sit below the Dynamic Island
  and nothing is cut off top/bottom.
- #2: opening a chat no longer auto-focuses the composer (was popping the phone keyboard
  and shoving the layout up); tapping the box still focuses normally.
- #3: overflow-x:hidden + max-width:100vw guards so pages can't pan left/right.
- #4: left-edge swipe-right now triggers the existing bzcBack() (close popup/search/open
  chat) — a native-feeling back gesture with no native code.
- #6: hide the 'Download app' (Windows) button when running inside the Capacitor app.
Build marker -> 2026-07-17-batch90.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 16:44:12 +05:30
parent 2e4e0210b0
commit 95e13a707e
2 changed files with 32 additions and 10 deletions
+5 -4
View File
@@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Biz Connect</title>
<meta name="theme-color" content="#1F3B73">
<link rel="icon" href="/favicon.ico?v=3" sizes="any">
@@ -14,7 +14,7 @@
:root{ --brand:#FFC708; --brand-d:#E0AC00; --blue:#1F3B73; --blue-d:#16294f; --blue-soft:#EAF0FB; --ink:#1f2430; --muted:#6b7280; --bg:#f6f8fb; --line:#e6e9ef; }
*{box-sizing:border-box;}
body{font-family:'Segoe UI',system-ui,sans-serif;background:var(--bg);color:var(--ink);margin:0;min-height:100vh;display:flex;flex-direction:column;}
header{background:var(--blue);padding:.85rem 1.5rem;display:flex;justify-content:space-between;align-items:center;}
header{background:var(--blue);padding:calc(.85rem + env(safe-area-inset-top,0px)) 1.5rem .85rem;display:flex;justify-content:space-between;align-items:center;}
.brandrow{display:flex;align-items:center;gap:.7rem;}
.hdr-right{display:flex;align-items:center;gap:.9rem;}
.dl-btn{display:inline-flex;align-items:center;gap:.4rem;background:#fff;color:var(--blue);padding:.45rem .85rem;border-radius:9px;font-size:.85rem;font-weight:700;text-decoration:none;white-space:nowrap;box-shadow:0 2px 8px rgba(0,0,0,.12);}
@@ -88,8 +88,9 @@ function profileHTML(name){return '<div class="profile"><button class="pbtn" id=
function wireProfile(){const btn=document.getElementById('pbtn'),menu=document.getElementById('pmenu');if(!btn)return;btn.onclick=(e)=>{e.stopPropagation();menu.classList.toggle('open');};document.addEventListener('click',()=>menu.classList.remove('open'));const lo=document.getElementById('plogout');if(lo)lo.onclick=async()=>{try{await fetch('/api/logout',{method:'POST'});}catch(_){}location.href='/';};}
function makeBrandClickable(){document.querySelectorAll('.brandrow,.wordmark').forEach(el=>{el.style.cursor='pointer';el.addEventListener('click',()=>{location.href='/';});});}
makeBrandClickable();
// No "download" link when we're already inside the desktop app.
if(window.__NATIVE__){var _dl=document.getElementById('dlWin');if(_dl)_dl.style.display='none';}
// No "download the desktop app" link when we're already inside a native shell — the Electron desktop
// app (window.__NATIVE__) OR the iOS/Android Capacitor app (window.Capacitor.isNativePlatform()).
if(window.__NATIVE__ || (window.Capacitor && window.Capacitor.isNativePlatform && window.Capacitor.isNativePlatform())){var _dl=document.getElementById('dlWin');if(_dl)_dl.style.display='none';}
// Already signed in -> skip this landing entirely and go straight to the app (no redundant
// "Open Biz Connect" page). This landing only shows when logged out.
(async function(){try{const r=await fetch('/api/me');if(r.ok){ location.replace('/home'); return; }}catch(_){}})();