SkateSpots/src/main.tsx
shakespeare.diy 8c25110f44 debug: add visible error overlay in APK to diagnose white screen crash
Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
2026-06-18 21:41:32 +07:00

77 lines
3.1 KiB
TypeScript

import { createRoot } from 'react-dom/client';
// Import polyfills first
import './lib/polyfills.ts';
import { ErrorBoundary } from '@/components/ErrorBoundary';
import App from './App.tsx';
import './index.css';
// Hide Capacitor splash screen once JS is ready
// Uses the global Capacitor object to avoid a hard dependency on the package
if (typeof window !== 'undefined') {
const cap = (window as unknown as { Capacitor?: { Plugins?: { SplashScreen?: { hide: () => Promise<void> } } } }).Capacitor;
if (cap?.Plugins?.SplashScreen) {
cap.Plugins.SplashScreen.hide().catch(() => {});
}
}
// Outfit font for body text
import '@fontsource-variable/outfit';
// Bebas Neue — bold condensed display font for headlines
import '@fontsource/bebas-neue';
// Barlow Condensed — tight condensed font for subheadings and UI labels
import '@fontsource/barlow-condensed/400.css';
import '@fontsource/barlow-condensed/600.css';
import '@fontsource/barlow-condensed/700.css';
// Leaflet CSS is loaded via CDN in index.html
/**
* AMBER CALLBACK PRE-CHECK
*
* PWAs can sometimes lose URL parameters during React hydration.
* This runs BEFORE React renders to capture Amber callback data.
* We store it in sessionStorage so the AmberCallbackHandler can retrieve it.
*/
(function captureAmberCallback() {
const params = new URLSearchParams(window.location.search);
const event = params.get('event');
if (event) {
console.log('[Amber Pre-Check] Detected Amber callback in URL');
console.log('[Amber Pre-Check] Full URL:', window.location.href);
console.log('[Amber Pre-Check] Event param:', event);
// Store the callback data immediately before React can interfere
try {
sessionStorage.setItem('amber_callback_event', event);
sessionStorage.setItem('amber_callback_url', window.location.href);
sessionStorage.setItem('amber_callback_timestamp', Date.now().toString());
console.log('[Amber Pre-Check] Stored callback data in sessionStorage');
} catch (e) {
console.error('[Amber Pre-Check] Failed to store callback:', e);
}
}
})();
// Global error trap — shows error on screen in the APK so we can debug
// without needing USB/adb. Remove once white screen is fixed.
window.onerror = (msg, src, line, col, err) => {
const div = document.createElement('div');
div.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:#000;color:#ff0040;padding:16px;font:14px monospace;z-index:99999;overflow:auto;white-space:pre-wrap;word-break:break-all;';
div.textContent = `ERROR:\n${msg}\n\n${src}:${line}:${col}\n\n${err?.stack || ''}`;
document.body.appendChild(div);
};
window.onunhandledrejection = (e) => {
const div = document.createElement('div');
div.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:#000;color:#ff6600;padding:16px;font:14px monospace;z-index:99999;overflow:auto;white-space:pre-wrap;word-break:break-all;';
div.textContent = `UNHANDLED REJECTION:\n${e.reason?.stack || e.reason || 'unknown'}`;
document.body.appendChild(div);
};
createRoot(document.getElementById("root")!).render(
<ErrorBoundary>
<App />
</ErrorBoundary>
);