import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:go_router/go_router.dart'; import 'session/session_cubit.dart'; import 'session/session_state.dart'; import '../features/auth/view/login_page.dart'; import '../features/auth/view/profile_page.dart'; import '../features/home/view/home_page.dart'; import '../features/splash/view/splash_page.dart'; import 'di.dart'; class Routes { const Routes._(); static const splash = '/'; static const login = '/login'; static const profile = '/profile'; static const home = '/home'; } /// التوجيه يُشتقّ من `SessionCubit` وحده — لا `Navigator.push` بعد الدخول /// موزّعة في الشاشات، فلا تتناقض حالتان. final appRouter = GoRouter( initialLocation: Routes.splash, refreshListenable: _CubitListenable(sl().stream), redirect: (context, state) { final session = sl().state; final loc = state.matchedLocation; // قبل أن نعرف: نبقى على الإقلاع ولا نقرّر شيئاً. if (!session.isReady) return loc == Routes.splash ? null : Routes.splash; return switch (session.status) { SessionStatus.unauthenticated => loc == Routes.login ? null : Routes.login, SessionStatus.needsProfile => loc == Routes.profile ? null : Routes.profile, SessionStatus.authenticated => (loc == Routes.login || loc == Routes.profile || loc == Routes.splash) ? Routes.home : null, SessionStatus.unknown => Routes.splash, }; }, routes: [ GoRoute( path: Routes.splash, builder: (context, state) => const SplashPage(), ), GoRoute( path: Routes.login, builder: (context, state) => const LoginPage(), ), GoRoute( path: Routes.profile, builder: (context, state) => const ProfilePage(), ), GoRoute( path: Routes.home, builder: (context, state) => const HomePage(), ), ], ); /// جسر بين تيّار الـCubit و`refreshListenable` الذي يطلبه go_router. class _CubitListenable extends ChangeNotifier { _CubitListenable(Stream stream) { _sub = stream.listen((_) => notifyListeners()); } late final StreamSubscription _sub; @override void dispose() { _sub.cancel(); super.dispose(); } }