Skip to content

Commit b7d3797

Browse files
Fix Android layout safe area top inset for AdMob and Next.js SSR hydration flash when running natively
1 parent a8878eb commit b7d3797

4 files changed

Lines changed: 16 additions & 9 deletions

File tree

Skypulse/src/app/globals.css

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ body {
3939
background: hsl(var(--background));
4040
color: hsl(var(--foreground));
4141
scroll-behavior: smooth;
42-
height: calc(100vh - var(--ad-banner-height));
43-
margin-top: var(--ad-banner-height);
4442
overflow: hidden;
43+
height: 100%;
4544
}
4645

4746
/* Custom attribution component replaces built-in controls */

Skypulse/src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ export default function RootLayout({
155155
<script
156156
dangerouslySetInnerHTML={{
157157
__html: `
158-
if (window.Capacitor && (window.location.pathname === '/' || window.location.pathname === '/index.html')) {
158+
if ((window.Capacitor || navigator.userAgent.includes('Capacitor')) && (window.location.pathname === '/' || window.location.pathname === '/index.html')) {
159159
document.documentElement.style.display = 'none';
160160
window.location.replace('/map.html');
161161
}

Skypulse/src/app/page.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,27 @@ export default function LandingPage() {
1414
const router = useRouter();
1515
const [isNative, setIsNative] = useState(() => {
1616
if (typeof window !== "undefined") {
17-
return Capacitor.isNativePlatform();
17+
return (window as any).Capacitor !== undefined || navigator.userAgent.includes("Capacitor");
1818
}
19-
return false;
19+
return true; // Default to true during SSR to prevent flash, then adjust
2020
});
2121

22+
// We need a second state to confirm Web so we don't accidentally show a black screen forever on Desktop SSR
23+
const [isWebConfirmed, setIsWebConfirmed] = useState(false);
24+
2225
useEffect(() => {
23-
if (isNative) {
26+
if (Capacitor.isNativePlatform() || navigator.userAgent.includes("Capacitor")) {
27+
setIsNative(true);
2428
router.replace("/map");
29+
} else {
30+
setIsNative(false);
31+
setIsWebConfirmed(true);
2532
}
26-
}, [isNative, router]);
33+
}, [router]);
2734

2835
// Unconditionally block rendering the heavy marketing site if we know we're on mobile
29-
if (isNative) {
36+
// Or if we haven't confirmed it's Web yet (to prevent SSR flash on mobile)
37+
if (isNative || !isWebConfirmed) {
3038
return (
3139
<div className="fixed inset-0 z-[9999] bg-[#050505] flex items-center justify-center">
3240
{/* Optional subtle loading indicator if jumping to /map takes a split second */}

Skypulse/src/components/flight-tracker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ function FlightTrackerInner() {
915915
<div
916916
data-map-theme={mapStyle.dark ? "dark" : "light"}
917917
className="pointer-events-none absolute inset-x-0 bottom-0 z-10"
918-
style={{ top: "var(--ad-banner-height, 0px)" }}
918+
style={{ top: "calc(env(safe-area-inset-top, 0px) + var(--ad-banner-height, 0px))" }}
919919
>
920920
{!fpvIcao24 && (
921921
<div className="pointer-events-auto absolute left-3 top-3 flex items-center gap-3 sm:left-4 sm:top-4">

0 commit comments

Comments
 (0)