import React, { lazy, Suspense, useEffect } from 'react'; import { BrowserRouter, Routes, Route, Navigate, Outlet, useNavigate, useLocation } from 'react-router-dom'; import Layout from './components/layout/Layout'; import Home from './screens/Home'; import { initializeUserId } from './constants/user'; import { trackScreenView } from './services/analyticsService'; // Ленивая загрузка компонентов const OnboardingWelcome = lazy(() => import('./screens/onboarding/OnboardingWelcome')); const OnboardingHowTo = lazy(() => import('./screens/onboarding/OnboardingHowTo')); const OnboardingStickerPacks = lazy(() => import('./screens/onboarding/OnboardingStickerPacks')); const TermsAndConditions = lazy(() => import('./screens/onboarding/TermsAndConditions')); const CreateSticker = lazy(() => import('./screens/CreateSticker')); const Gallery = lazy(() => import('./screens/Gallery')); const Profile = lazy(() => import('./screens/Profile')); const StickerPacks = lazy(() => import('./screens/StickerPacks')); const CreateStickerPack = lazy(() => import('./screens/CreateStickerPack')); const AddStickerToPackScreen = lazy(() => import('./screens/AddStickerToPackScreen')); const History = lazy(() => import('./screens/History')); const CropPhoto = lazy(() => import('./screens/CropPhoto')); // Компонент для отображения состояния загрузки const LoadingScreen = () => (
Загрузка...
); // Компонент для проверки онбординга const AppContent: React.FC = () => { const navigate = useNavigate(); const location = useLocation(); useEffect(() => { // Инициализируем ID пользователя при запуске приложения initializeUserId(); // Стабилизируем окно и отключаем вертикальные свайпы if (window.Telegram?.WebApp) { // Стабилизация окна (особенно важно для iPhone) window.Telegram.WebApp.expand(); // Отключаем вертикальные свайпы для предотвращения случайного сворачивания WebApp if (window.Telegram.WebApp.isVersionAtLeast('6.9')) { window.Telegram.WebApp.disableVerticalSwipes(); } } // Проверяем, видел ли пользователь онбординг и принял ли условия const hasSeenOnboarding = localStorage.getItem('hasSeenOnboarding') === 'true'; const hasAcceptedTerms = localStorage.getItem('hasAcceptedTerms') === 'true'; // Если не видел онбординг и не на странице онбординга или условий if (!hasSeenOnboarding && !location.pathname.includes('/onboarding')) { navigate('/onboarding/welcome'); } // Если видел онбординг, но не принял условия и не на странице условий else if (hasSeenOnboarding && !hasAcceptedTerms && !location.pathname.includes('/onboarding/terms')) { navigate('/onboarding/terms'); } }, [navigate, location.pathname]); // Отслеживаем изменение маршрута для аналитики useEffect(() => { // Получаем название экрана из пути let screenName = location.pathname; if (screenName === '/') { screenName = 'Главная'; } else { // Преобразуем путь в более читаемое название screenName = screenName .replace('/onboarding/welcome', 'Онбординг: Приветствие') .replace('/onboarding/how-to', 'Онбординг: Как использовать') .replace('/onboarding/sticker-packs', 'Онбординг: Стикер-паки') .replace('/onboarding/terms', 'Условия использования') .replace('/create', 'Создание стикера') .replace('/gallery', 'Галерея') .replace('/packs', 'Стикер-паки') .replace('/create-sticker-pack', 'Создание стикер-пака') .replace('/profile', 'Профиль') .replace('/history', 'История') .replace('/crop-photo', 'Обрезка фото'); // Если это добавление стикера в пак, извлекаем название пака if (screenName.includes('/add-sticker/')) { const packName = screenName.split('/add-sticker/')[1]; screenName = `Добавление стикера в пак: ${packName}`; } } // Отправляем событие просмотра экрана trackScreenView(screenName); }, [location.pathname]); return ( {/* Онбординг */} } /> }> } /> }> } /> }> } /> }> } /> {/* Основные экраны */} }> }> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }; const App: React.FC = () => { return ( ); }; export default App;