fix(mobile): pad Android app below the status bar on Android 15
Android 15 enforces edge-to-edge and ignores the StatusBar overlay:false inset the app relied on, while every --oc-safe-area-* CSS definition was gated behind iOS-only conditions. Read the Capacitor-injected --safe-area-inset-* vars (with env() fallback) on the Android native shell so the header, top toasts, and connect screen clear the status bar; both sources report 0 where the native inset still applies.
This commit is contained in:
@@ -242,9 +242,10 @@ const useNativeMobileChrome = (): void => {
|
||||
const platform = (window as typeof window & { Capacitor?: { getPlatform?: () => string } }).Capacitor?.getPlatform?.();
|
||||
const applyStatusBar = async () => {
|
||||
if (platform === 'android') {
|
||||
// Android doesn't feed env(safe-area-inset-top) to CSS, so overlaying the status bar
|
||||
// makes content render under it. Inset the WebView below the bar instead and paint the
|
||||
// bar with the resolved theme background (the splash colours the theme system persists).
|
||||
// Inset the WebView below the bar and paint it with the resolved theme background
|
||||
// (the splash colours the theme system persists). On Android 15+ edge-to-edge is
|
||||
// enforced and both calls are no-ops — there the app pads itself via the
|
||||
// Capacitor-injected --safe-area-inset-* CSS vars (see mobile.css, oc-platform-android).
|
||||
const isDark = document.documentElement.classList.contains('dark');
|
||||
const themeBg =
|
||||
(isDark ? localStorage.getItem('splashBgDark') : localStorage.getItem('splashBgLight')) ||
|
||||
@@ -763,7 +764,7 @@ const MobileConnectionWelcome: React.FC<{ onConnected: () => void }> = ({ onConn
|
||||
}, [conn]);
|
||||
|
||||
return (
|
||||
<main className="oc-keyboard-fill-screen flex min-h-dvh flex-col overflow-y-auto bg-background px-6 pb-[calc(env(safe-area-inset-bottom)+28px)] pt-[calc(env(safe-area-inset-top)+28px)] text-foreground">
|
||||
<main className="oc-keyboard-fill-screen flex min-h-dvh flex-col overflow-y-auto bg-background px-6 pb-[calc(var(--safe-area-inset-bottom,env(safe-area-inset-bottom,0px))+28px)] pt-[calc(var(--safe-area-inset-top,env(safe-area-inset-top,0px))+28px)] text-foreground">
|
||||
<div className="m-auto flex w-full max-w-[360px] shrink-0 flex-col items-center gap-9 py-8">
|
||||
<div className="flex flex-col items-center gap-5 text-center">
|
||||
<OpenChamberLogo width={72} height={72} className="size-[72px]" />
|
||||
|
||||
@@ -519,7 +519,32 @@
|
||||
not match — so nothing reserves bottom room in the native app. Expose it as a token
|
||||
so any native surface can consume it; the chat shell does so below. */
|
||||
:root.oc-capacitor-app {
|
||||
--oc-app-bottom-safe: max(16px, calc(env(safe-area-inset-bottom, 0px) * 0.5));
|
||||
--oc-app-bottom-safe: max(16px, calc(var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px)) * 0.5));
|
||||
}
|
||||
|
||||
/* Android native safe areas. Every --oc-safe-area-* definition above is gated
|
||||
behind -webkit-touch-callout (iOS) or display-mode: standalone, neither of
|
||||
which matches the Capacitor Android WebView — so the Android app used to rely
|
||||
entirely on StatusBar overlay:false insetting the WebView natively. Android 15
|
||||
enforces edge-to-edge and ignores that call, leaving content under the status
|
||||
bar. Capacitor injects the real insets as --safe-area-inset-* inline vars on
|
||||
<html> (env() still reads 0 on WebViews without the safe-area passthrough
|
||||
fix), so read those first and fall back to env(). On devices where the native
|
||||
inset still applies, both sources report 0 — no double padding. */
|
||||
:root.oc-capacitor-app.oc-platform-android {
|
||||
--oc-safe-area-top: var(--safe-area-inset-top, env(safe-area-inset-top, 0px));
|
||||
--oc-safe-area-right: var(--safe-area-inset-right, env(safe-area-inset-right, 0px));
|
||||
--oc-safe-area-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px));
|
||||
--oc-safe-area-bottom-visual: clamp(0px, calc(var(--oc-safe-area-bottom) * 0.05), 4px);
|
||||
--oc-safe-area-left: var(--safe-area-inset-left, env(safe-area-inset-left, 0px));
|
||||
}
|
||||
|
||||
:root.oc-capacitor-app.oc-platform-android .header-safe-area {
|
||||
padding-top: var(--oc-safe-area-top);
|
||||
}
|
||||
|
||||
:root.oc-capacitor-app.oc-platform-android [data-sonner-toaster][data-y-position='top'] {
|
||||
top: calc(var(--oc-safe-area-top) + 16px) !important;
|
||||
}
|
||||
|
||||
/* Paint the document canvas with the theme background in the native app — the same
|
||||
|
||||
Reference in New Issue
Block a user