fix(ios): status-bar inset via StatusBar plugin, hide nav in open chat, bulletproof h-scroll
Root cause from device screenshots: the iOS Capacitor WebView reports env(safe-area-inset-*)=0, so CSS padding did nothing and content slid under the Dynamic Island (every page: home/share/ connect/login) and the bottom nav was clipped. - Use the already-installed StatusBar plugin: setOverlaysWebView(false) pushes content below the status bar natively (no rebuild). Applied on all entry pages via a small native-chrome snippet. - Hard-code the bottom home-indicator inset (--sab:34px on html.native-ios) since env() can't give it. - #2 keyboard: hide the bottom tab bar inside an open conversation so the composer sits directly on the keyboard (was sandwiched between composer and keyboard). - #3 h-scroll: clip every scroll surface + overflow-wrap:anywhere so long content can't widen the page. Build marker -> 2026-07-17-batch91. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,16 @@
|
||||
<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 — Agent Console</title>
|
||||
<script>
|
||||
// Native shell: push content below the status bar/notch (the Capacitor WebView reports safe-area insets
|
||||
// as 0, so the back button/header would otherwise slide under the Dynamic Island).
|
||||
(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 SB=C.Plugins&&C.Plugins.StatusBar; if(SB){ try{ SB.setOverlaysWebView({overlay:false}); }catch(_){}; try{ SB.setStyle({style:'DARK'}); }catch(_){}; try{ SB.setBackgroundColor({color:'#ffffff'}); }catch(_){} }
|
||||
}catch(_){} })();
|
||||
</script>
|
||||
<meta name="theme-color" content="#1F3B73">
|
||||
<link rel="icon" href="/favicon.ico?v=3" sizes="any">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=3">
|
||||
|
||||
+33
-9
@@ -23,6 +23,11 @@
|
||||
bottom rail (the "gap"). overscroll-behavior:none pins the page; the rail's own height already
|
||||
includes the home-indicator inset. */
|
||||
html,body{height:100%;overscroll-behavior:none;}
|
||||
/* Safe-area insets. The iOS Capacitor WebView reports env(safe-area-inset-*)=0, so on the native app
|
||||
we (a) push content below the status bar/notch with StatusBar.setOverlaysWebView(false) — see the
|
||||
native-chrome script — and (b) hard-code the bottom home-indicator inset here (env() can't give it). */
|
||||
:root{--sat:env(safe-area-inset-top,0px);--sab:env(safe-area-inset-bottom,0px);}
|
||||
html.native-ios{--sab:34px;}
|
||||
body{font-family:'Segoe UI',system-ui,sans-serif;background:var(--bg);color:var(--ink);margin:0;display:flex;flex-direction:column;height:100vh;height:100dvh;overflow:hidden;position:fixed;inset:0;width:100%;}
|
||||
|
||||
/* ---- Top bar ---- */
|
||||
@@ -1020,10 +1025,11 @@
|
||||
relocated into the chat-list header (see placeHdrRight). The shell is pushed below the
|
||||
device status bar so no view overlaps it. */
|
||||
header{display:none;}
|
||||
/* #3: kill any horizontal drift on phones (long content, 100vw children, safe-area math) — the page
|
||||
should never pan left/right. */
|
||||
html,body{overflow-x:hidden;max-width:100vw;}
|
||||
.shell,.content,.chatcol,.panel,.convo,.convo-msgs,.chatlist{overflow-x:hidden;max-width:100%;}
|
||||
/* #3: kill any horizontal drift on phones (long content, over-wide children, safe-area math) — the
|
||||
page must never pan left/right. Clip every scroll surface and let long words/URLs wrap. */
|
||||
html,body{overflow-x:hidden;}
|
||||
.shell,.content,.chatcol,.panel,.convo,.convo-msgs,.chatlist,.side-head,.side-search-row,.chat-row{overflow-x:hidden;max-width:100%;min-width:0;}
|
||||
.chat-main,.msg,.msg-body,.bubble{min-width:0;max-width:100%;overflow-wrap:anywhere;}
|
||||
/* #1/#5: the top safe-area inset (notch / Dynamic Island) is applied PER SURFACE — the chat-list
|
||||
column and each content panel — rather than on the whole shell, so nothing hides under the island
|
||||
and there's no double-padding. Bottom inset is handled by the fixed nav + panel bottom below. */
|
||||
@@ -1037,8 +1043,8 @@
|
||||
indicator and drifted with the URL bar. Use border-box + a height that INCLUDES the inset, pin it
|
||||
with a promoted layer, and use px-unit env() fallbacks (unitless 0 breaks calc() on Safari). */
|
||||
.rail{position:fixed;left:0;right:0;bottom:0;top:auto;width:auto;box-sizing:border-box;
|
||||
height:calc(60px + env(safe-area-inset-bottom,0px));
|
||||
padding:0 .3rem env(safe-area-inset-bottom,0px) .3rem;
|
||||
height:calc(60px + var(--sab));
|
||||
padding:0 .3rem var(--sab) .3rem;
|
||||
flex-direction:row;justify-content:space-around;align-items:center;gap:0;
|
||||
border-right:none;border-top:1px solid var(--line);box-shadow:0 -3px 14px rgba(20,30,60,.08);
|
||||
transform:translateZ(0)!important;-webkit-transform:translateZ(0)!important;z-index:1200;background:var(--card);}
|
||||
@@ -1052,12 +1058,17 @@
|
||||
/* Meeting room code: always fully visible, full-width, easy to read */
|
||||
.meet-bar .code{flex:1 1 100%;font-size:.9rem;white-space:normal;word-break:break-word;text-align:center;background:var(--blue-soft);border-radius:8px;padding:.35rem .5rem;}
|
||||
/* Chat: one pane at a time (list, then the open conversation) */
|
||||
.chatcol{width:100%;flex:1 1 100%;padding-top:env(safe-area-inset-top,0px);padding-bottom:calc(60px + env(safe-area-inset-bottom,0px));}
|
||||
.chatcol{width:100%;flex:1 1 100%;padding-top:var(--sat);padding-bottom:calc(60px + var(--sab));}
|
||||
body.chat-open .chatcol{display:none;}
|
||||
.content{display:none;}
|
||||
body.chat-open .content, .shell:not(.is-chat) .content{display:block;}
|
||||
.shell:not(.is-chat) .chatcol{display:none;}
|
||||
.content .panel{top:env(safe-area-inset-top,0px);bottom:calc(60px + env(safe-area-inset-bottom,0px));} /* below the notch; clear the bottom nav + home indicator */
|
||||
.content .panel{top:var(--sat);bottom:calc(60px + var(--sab));} /* below the notch; clear the bottom nav + home indicator */
|
||||
/* #2 (mobile keyboard): inside an open conversation, hide the bottom tab bar so the composer sits
|
||||
directly above the keyboard (no nav sandwiched between the text box and the keyboard). The panel
|
||||
then only needs to clear the home indicator. */
|
||||
body.chat-open .rail{display:none;}
|
||||
body.chat-open .content .panel{bottom:var(--sab);}
|
||||
/* Bigger touch targets */
|
||||
.chat-row{padding:.7rem .85rem;}
|
||||
.convo-head{padding:.7rem .85rem;}
|
||||
@@ -1084,7 +1095,7 @@
|
||||
</head>
|
||||
<body>
|
||||
<script src="/icons.js?v=6"></script>
|
||||
<script>window.__BUILD='2026-07-17-batch90';console.log('%cBiz Connect','color:#1F3B73;font-weight:bold','build '+window.__BUILD);
|
||||
<script>window.__BUILD='2026-07-17-batch91';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
|
||||
@@ -1093,6 +1104,19 @@
|
||||
// ship full-colour emoji, so the native glyphs look right and cost nothing. Kept as a no-op so the
|
||||
// existing call sites don't have to change.
|
||||
function twemojify(_el){ /* native emoji: nothing to do */ }</script>
|
||||
<script>
|
||||
// Native shell chrome (iOS/Android). The Capacitor WebView reports env(safe-area-inset-*)=0, so content
|
||||
// slides under the Dynamic Island / notch. We tag <html> (CSS then hard-codes the bottom home-indicator
|
||||
// inset) and ask the StatusBar plugin to NOT overlay the WebView, which pushes the top of our content
|
||||
// below the status bar. Runs on every entry page (home/share/connect/index) that includes this snippet.
|
||||
(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 SB=C.Plugins&&C.Plugins.StatusBar;
|
||||
if(SB){ try{ SB.setOverlaysWebView({overlay:false}); }catch(_){}; try{ SB.setStyle({style:'DARK'}); }catch(_){}; try{ SB.setBackgroundColor({color:'#ffffff'}); }catch(_){} }
|
||||
}catch(_){} })();
|
||||
</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>
|
||||
|
||||
<header>
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<title>Biz Connect</title>
|
||||
<script>
|
||||
// Native shell: push content below the status bar/notch (the Capacitor WebView reports safe-area insets
|
||||
// as 0). Runs before render so headers never sit under the Dynamic Island.
|
||||
(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 SB=C.Plugins&&C.Plugins.StatusBar; if(SB){ try{ SB.setOverlaysWebView({overlay:false}); }catch(_){}; try{ SB.setStyle({style:'DARK'}); }catch(_){}; try{ SB.setBackgroundColor({color:'#ffffff'}); }catch(_){} }
|
||||
}catch(_){} })();
|
||||
</script>
|
||||
<meta name="theme-color" content="#1F3B73">
|
||||
<link rel="icon" href="/favicon.ico?v=3" sizes="any">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=3">
|
||||
|
||||
@@ -2,8 +2,16 @@
|
||||
<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 — Share your screen</title>
|
||||
<script>
|
||||
// Native shell: push content below the status bar/notch (the Capacitor WebView reports safe-area insets
|
||||
// as 0, so the back button/header would otherwise slide under the Dynamic Island).
|
||||
(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 SB=C.Plugins&&C.Plugins.StatusBar; if(SB){ try{ SB.setOverlaysWebView({overlay:false}); }catch(_){}; try{ SB.setStyle({style:'DARK'}); }catch(_){}; try{ SB.setBackgroundColor({color:'#ffffff'}); }catch(_){} }
|
||||
}catch(_){} })();
|
||||
</script>
|
||||
<meta name="theme-color" content="#1F3B73">
|
||||
<link rel="icon" href="/favicon.ico?v=3" sizes="any">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png?v=3">
|
||||
|
||||
Reference in New Issue
Block a user