import flet as ft from view import resolve_view, PUBLIC_ROUTES, PROTECTED_PREFIXES async def _redirect_to_login(page: ft.Page): """Сброс сессии и принудительный редирект на логин.""" page.session.store.remove("auth_token") page.session.store.remove("url_key") page.session.store.remove("session_key") page.session.store.remove("user_id") await page.push_route("/login") async def _handle_route_change(page: ft.Page, e: ft.RouteChangeEvent): route = page.route token = page.session.store.get("auth_token") url_key = page.session.store.get("url_key") or "" session_key = page.session.store.get("session_key") or "" # Публичные маршруты — без проверки токена if route in PUBLIC_ROUTES: views = resolve_view(page, route) page.views.clear() page.views.extend(views) page.update() return # Защищённый маршрут без токена → логин if not token: await page.push_route("/login") return # Маршруты с ключом — первый сегмент после префикса = url_key for prefix in PROTECTED_PREFIXES: if route.startswith(prefix): rest = route[len(prefix):] key_in_url = rest.split("/")[0] # берём только первый сегмент if not url_key or not session_key or key_in_url != url_key: await _redirect_to_login(page) return break views = resolve_view(page, route) # Неизвестный маршрут → на страницу пользователя if views is None: await page.push_route(f"/user/{url_key}") return page.views.clear() page.views.extend(views) page.update() # Запустить асинхронную загрузку данных, если вью её поддерживает last_view = views[-1] if views else None if last_view is not None and hasattr(last_view, "load"): page.run_task(last_view.load) def setup_router(page: ft.Page): """Привязывает router к странице. Вызывается один раз в main().""" async def _on_route_change(e: ft.RouteChangeEvent): await _handle_route_change(page, e) page.on_route_change = _on_route_change