import { StrictMode, useEffect } from 'react'; import { createRoot } from 'react-dom/client'; import { App } from './App.tsx'; import { useAppLifecycle } from './hooks/useAppLifecycle'; // Prevent iOS from refreshing the app too aggressively if ('serviceWorker' in navigator) { // Increase cache size for better persistence navigator.serviceWorker.addEventListener('message', event => { if (event.data && event.data.type === 'CACHE_UPDATED') { console.log('Cache updated, app should persist better'); } }); } // PWA Initialization Component const PWAInitializer = () => { const { saveAppState, loadAppState } = useAppLifecycle(); useEffect(() => { // Register service worker for PWA if ('serviceWorker' in navigator && process.env.NODE_ENV === 'production') { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { console.log('ServiceWorker registration successful with scope: ', registration.scope); }) .catch(error => { console.log('ServiceWorker registration failed: ', error); }); }); } // Add iOS specific meta tags const metaThemeColor = document.createElement('meta'); metaThemeColor.name = 'theme-color'; metaThemeColor.content = '#00A4DC'; document.head.appendChild(metaThemeColor); const appleMobileWebAppCapable = document.createElement('meta'); appleMobileWebAppCapable.name = 'apple-mobile-web-app-capable'; appleMobileWebAppCapable.content = 'yes'; document.head.appendChild(appleMobileWebAppCapable); const appleMobileWebAppStatusBarStyle = document.createElement('meta'); appleMobileWebAppStatusBarStyle.name = 'apple-mobile-web-app-status-bar-style'; appleMobileWebAppStatusBarStyle.content = 'black-translucent'; document.head.appendChild(appleMobileWebAppStatusBarStyle); // Add viewport meta for better iOS handling const viewport = document.querySelector('meta[name="viewport"]'); if (viewport) { viewport.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover'); } // Prevent iOS from killing the app by keeping it active const keepAlive = () => { // Small periodic activity to prevent iOS from killing the app if (document.hidden) return; // Update a small piece of state periodically saveAppState({ lastActiveTime: Date.now() }); }; // Run keep-alive every 5 minutes when app is visible const keepAliveInterval = setInterval(keepAlive, 5 * 60 * 1000); // Handle iOS-specific memory warnings const handleMemoryWarning = () => { console.log('Memory warning detected - saving state and cleaning up'); saveAppState({ lastActiveTime: Date.now() }); // Force garbage collection if available if (window.gc) { window.gc(); } }; // Listen for memory pressure events window.addEventListener('memorywarning', handleMemoryWarning); // iOS-specific: prevent automatic refresh on return window.addEventListener('pageshow', (event) => { if (event.persisted) { console.log('Page restored from bfcache - preventing refresh'); // Restore app state const state = loadAppState(); console.log('Restored state:', state); } }); const appleMobileWebAppTitle = document.createElement('meta'); appleMobileWebAppTitle.name = 'apple-mobile-web-app-title'; appleMobileWebAppTitle.content = 'SamCloud'; document.head.appendChild(appleMobileWebAppTitle); // Clean up function return () => { document.head.removeChild(metaThemeColor); document.head.removeChild(appleMobileWebAppCapable); document.head.removeChild(appleMobileWebAppStatusBarStyle); document.head.removeChild(appleMobileWebAppTitle); clearInterval(keepAliveInterval); window.removeEventListener('memorywarning', handleMemoryWarning); }; }, []); return null; // This component doesn't render anything }; const savedTheme = localStorage.getItem('theme') || 'light' const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches const themeClass = savedTheme === 'system' ? (isSystemDark ? 'dark' : 'light') : savedTheme document.documentElement.classList.add(themeClass) createRoot(document.getElementById('root')!).render( )