forked from eatvio/eatvio_app
304 lines
14 KiB
Dart
304 lines
14 KiB
Dart
import 'dart:async';
|
||
import 'package:dio/dio.dart';
|
||
import 'package:eatvio_app/core/app_config.dart';
|
||
import 'package:eatvio_app/core/firebase_api.dart';
|
||
import 'package:eatvio_app/core/locator_service.dart';
|
||
import 'package:eatvio_app/core/prefs.dart';
|
||
import 'package:eatvio_app/core/prefs_keys.dart';
|
||
import 'package:eatvio_app/core/routing/route_constants.dart';
|
||
import 'package:eatvio_app/core/token_storage.dart';
|
||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||
import 'package:eatvio_app/features/calendar/presentation/pages/calendar_screen.dart';
|
||
import 'package:eatvio_app/features/chat/presentation/pages/chat_screen.dart';
|
||
import 'package:eatvio_app/features/diary/presentation/pages/diary_screen.dart';
|
||
import 'package:eatvio_app/features/chat/presentation/pages/empty_chat_screen.dart';
|
||
import 'package:eatvio_app/features/chat/presentation/pages/payment_screen.dart';
|
||
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
|
||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/become_consultant_screen.dart';
|
||
import 'package:eatvio_app/features/consultant/become_consultant/presentation/pages/stepper_become_consultant_screen.dart';
|
||
import 'package:eatvio_app/features/consultant_rating/presentation/consultant_rating_screen.dart';
|
||
import 'package:eatvio_app/features/create_diet/presentation/create_diet_screen.dart';
|
||
import 'package:eatvio_app/features/create_diet/presentation/diet_preview_screen.dart';
|
||
import 'package:eatvio_app/features/create_plan/presentation/create_plan_screen.dart';
|
||
import 'package:eatvio_app/features/create_recipe/presentation/pages/recipe_create_screen.dart';
|
||
import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart';
|
||
import 'package:eatvio_app/features/feed/models/recipes_model.dart';
|
||
import 'package:eatvio_app/features/glossary/presentation/pages/glossary_screen.dart';
|
||
import 'package:eatvio_app/features/menu/presentation/pages/blocked_users_screen.dart';
|
||
import 'package:eatvio_app/features/menu/presentation/pages/notifications_settings_screen.dart';
|
||
import 'package:eatvio_app/features/my_diets/presentation/my_diets_screen.dart';
|
||
import 'package:eatvio_app/features/my_finance/presentation/pages/card_settings.dart';
|
||
import 'package:eatvio_app/features/my_finance/presentation/pages/user_finance_screen.dart';
|
||
import 'package:eatvio_app/features/my_plans/presentation/my_plans_screen.dart';
|
||
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
|
||
import 'package:eatvio_app/features/personal_diet_suggestion/presentation/personal_diet_suggestion_screen.dart';
|
||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||
import 'package:eatvio_app/features/profile/presentation/pages/profile_screen.dart';
|
||
import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.dart';
|
||
import 'package:eatvio_app/features/recipe/presentation/pages/my_recipes_screen.dart';
|
||
import 'package:eatvio_app/features/support/presentation/pages/support_screen.dart';
|
||
import 'package:eatvio_app/features/update_screen/presentation/update_screen.dart';
|
||
import 'package:eatvio_app/features/user_details/presentation/user_details_screen.dart';
|
||
import 'package:eatvio_app/features/welcome/presentation/pages/welcome_screen.dart';
|
||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultant_finances_screen.dart';
|
||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/consultations_archive_screen.dart';
|
||
import 'package:eatvio_app/features/finances_and_consultations_archive/presentation/user_purchases_screen.dart';
|
||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
import 'package:package_info_plus/package_info_plus.dart';
|
||
import 'package:version/version.dart';
|
||
|
||
/// Остальные маршруты приложения
|
||
class OtherRoutes {
|
||
/// Создание остальных маршрутов
|
||
static List<RouteBase> createRoutes() {
|
||
return [
|
||
// Welcome and update screens
|
||
GoRoute(
|
||
path: RouteConstants.welcomeScreen,
|
||
name: 'welcomeScreen',
|
||
builder: (context, state) => const WelcomeScreen(),
|
||
redirect: (context, state) async {
|
||
try {
|
||
// Prefs уже инициализирован в locator_service, но на всякий случай проверяем
|
||
final prefs = await sl.getAsync<Prefs>();
|
||
final welcomeScreenWasShowed = prefs.getBool(PrefsKeys.welcomeScreenWasShowed) ?? false;
|
||
if (!welcomeScreenWasShowed) {
|
||
return null;
|
||
}
|
||
|
||
if (await TokenStorage.haveTokenInStorage()) {
|
||
try {
|
||
final profileRepository = sl<ProfileRepository>();
|
||
final profile = await profileRepository.getMyProfile();
|
||
|
||
final firebaseApi = sl<FirebaseApi>();
|
||
await firebaseApi.registerPushToken();
|
||
|
||
if (profile.emailVerifiedAt != null || (prefs.getBool(PrefsKeys.isEmailVerificationSkipped) ?? false)) {
|
||
return RouteConstants.feedScreen;
|
||
}
|
||
return RouteConstants.verifyEmailScreen;
|
||
} catch (e) {
|
||
return '/auth-screen';
|
||
}
|
||
} else {
|
||
return '/auth-screen';
|
||
}
|
||
} catch (e) {
|
||
return '/auth-screen';
|
||
}
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: RouteConstants.updateScreen,
|
||
name: 'updateScreen',
|
||
builder: (context, state) => const UpdateScreen(),
|
||
redirect: (context, state) async {
|
||
try {
|
||
// Проверка версии с таймаутом, чтобы не блокировать запуск приложения
|
||
final versions = await sl<Dio>()
|
||
.get('${sl<AppConfig>().baseUrl}/api/app_versions')
|
||
.timeout(
|
||
const Duration(seconds: 5),
|
||
onTimeout: () {
|
||
// При таймауте пропускаем проверку и идем дальше
|
||
throw TimeoutException('Version check timeout');
|
||
},
|
||
)
|
||
.then((response) => response.data)
|
||
.catchError((e) {
|
||
// При любой ошибке пропускаем проверку версии
|
||
return null;
|
||
});
|
||
|
||
if (versions == null) {
|
||
// Если проверка не удалась, пропускаем экран обновления
|
||
return RouteConstants.welcomeScreen;
|
||
}
|
||
|
||
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||
String version = packageInfo.version;
|
||
Version currentVersion = Version.parse(version);
|
||
Version latestVersion = Version.parse(versions['min_version']);
|
||
if (latestVersion > currentVersion) {
|
||
return null;
|
||
} else {
|
||
return RouteConstants.welcomeScreen;
|
||
}
|
||
} catch (e) {
|
||
// При любой ошибке пропускаем экран обновления
|
||
return RouteConstants.welcomeScreen;
|
||
}
|
||
},
|
||
),
|
||
|
||
// Archive routes
|
||
GoRoute(path: ConsultationsArchiveScreen.path, name: ConsultationsArchiveScreen.name, builder: (context, state) => const ConsultationsArchiveScreen()),
|
||
GoRoute(path: ConsultantFinancesScreen.path, name: ConsultantFinancesScreen.name, builder: (context, state) => const ConsultantFinancesScreen()),
|
||
GoRoute(path: UserPurchasesScreen.path, name: UserPurchasesScreen.name, builder: (context, state) => const UserPurchasesScreen()),
|
||
|
||
// Finance routes
|
||
GoRoute(path: RouteConstants.userFinanceScreen, name: 'userFinanceScreen', builder: (context, state) => const UserFinanceScreen()),
|
||
GoRoute(
|
||
path: CardSettingsScreen.path,
|
||
name: CardSettingsScreen.name,
|
||
builder: (context, state) {
|
||
final chosenPlanId = state.extra as int?;
|
||
return CardSettingsScreen(chosenPlanId: chosenPlanId);
|
||
},
|
||
),
|
||
|
||
// Content creation routes
|
||
GoRoute(
|
||
path: RecipeCreateScreen.path,
|
||
name: RecipeCreateScreen.name,
|
||
builder: (context, state) {
|
||
if (state.extra is Map<String, dynamic>) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
return RecipeCreateScreen(
|
||
recipe: data['recipe'] as Recipe?,
|
||
autoValidate: data['autoValidate'] as bool? ?? false,
|
||
);
|
||
}
|
||
return RecipeCreateScreen(recipe: state.extra != null ? state.extra as Recipe : null);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: CreateDietScreen.path,
|
||
name: CreateDietScreen.name,
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>?;
|
||
final diet = data?['diet'] as Diet?;
|
||
final isEditing = data?['isEditing'] as bool?;
|
||
return CreateDietScreen(diet: diet, isEditing: isEditing);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: DietPreviewScreen.path,
|
||
name: DietPreviewScreen.name,
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
final diet = data['diet'] as Diet;
|
||
final isImageInBase64 = data['isImageInBase64'] as bool;
|
||
return DietPreviewScreen(diet: diet, isImageInBase64: isImageInBase64);
|
||
},
|
||
),
|
||
GoRoute(path: RouteConstants.createPlanScreen, name: 'createPlanScreen', builder: (context, state) => const CreatePlanScreen()),
|
||
GoRoute(path: MyDietsScreen.path, name: MyDietsScreen.name, builder: (context, state) => const MyDietsScreen()),
|
||
GoRoute(path: MyPlansScreen.path, name: MyPlansScreen.name, builder: (context, state) => const MyPlansScreen()),
|
||
GoRoute(path: MyRecipesScreen.path, name: MyRecipesScreen.name, builder: (context, state) => const MyRecipesScreen()),
|
||
|
||
// Profile routes
|
||
GoRoute(
|
||
path: RouteConstants.profileScreen,
|
||
name: 'profileScreen',
|
||
builder: (context, state) {
|
||
final slug = state.uri.queryParameters['slug'];
|
||
if (slug != null) {
|
||
return ProfileScreen(slug: slug);
|
||
}
|
||
return ProfileScreen(slug: state.extra as String);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: '${RouteConstants.subsScreen}/:slug',
|
||
name: 'subsScreen',
|
||
builder: (context, state) => SubsScreen(slug: state.pathParameters['slug'], subType: state.extra as SubType),
|
||
),
|
||
|
||
// Chat routes
|
||
GoRoute(
|
||
path: RouteConstants.chatScreen,
|
||
name: 'chatScreen',
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
final uuid = data['uuid'] as String;
|
||
final sendInitialMessage = data['sendInitialMessage'] as bool?;
|
||
return ChatScreen(uuid: uuid, sendInitialMessage: sendInitialMessage);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: RouteConstants.emptyChatScreen,
|
||
name: 'emptyChatScreen',
|
||
builder: (context, state) => EmptyChatScreen(user: state.extra as ProfileModel),
|
||
),
|
||
|
||
// Consultant routes
|
||
GoRoute(path: RouteConstants.becomeConsultantScreen, name: 'becomeConsultantScreen', builder: (context, state) => const BecomeConsultantScreen()),
|
||
GoRoute(
|
||
path: RouteConstants.stepperBecomeConsultantScreen,
|
||
name: 'stepperBecomeConsultantScreen',
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
final slug = data['slug'] as String?;
|
||
final isCanceled = data['isCanceled'] as bool?;
|
||
return StepperBecomeConsultantScreen(slug: slug, isCanceled: isCanceled,);
|
||
},
|
||
),
|
||
GoRoute(path: RouteConstants.calendarScreen, name: 'calendarScreen', builder: (context, state) => const CalendarScreen()),
|
||
GoRoute(path: RouteConstants.supportScreen, name: 'supportScreen', builder: (context, state) => const SupportScreen()),
|
||
GoRoute(
|
||
path: RouteConstants.photoViewScreen,
|
||
name: 'photoViewScreen',
|
||
builder: (context, state) => PhotoViewScreen(imageUrls: state.extra as List<String>, index: int.parse(state.pathParameters['index']!)),
|
||
),
|
||
|
||
// Other routes
|
||
GoRoute(
|
||
path: RouteConstants.glossaryScreen,
|
||
name: 'glossaryScreen',
|
||
builder: (context, state) => GlossaryScreen(passKey: state.extra as String),
|
||
),
|
||
GoRoute(path: RouteConstants.blockedUsersScreen, name: 'blockedUsersScreen', builder: (context, state) => const BlockedUsersScreen()),
|
||
GoRoute(
|
||
path: RouteConstants.notificationsSettingsScreen,
|
||
name: 'notificationsSettingsScreen',
|
||
builder: (context, state) => const NotificationsSettingsScreen(),
|
||
),
|
||
GoRoute(
|
||
path: UserDetailsScreen.path,
|
||
name: UserDetailsScreen.name,
|
||
builder: (context, state) => UserDetailsScreen(slug: state.extra as String),
|
||
),
|
||
GoRoute(path: DevToolsScreen.path, name: DevToolsScreen.name, builder: (context, state) => const DevToolsScreen()),
|
||
GoRoute(path: ConsultantRatingScreen.path, name: ConsultantRatingScreen.name, builder: (context, state) => const ConsultantRatingScreen()),
|
||
GoRoute(
|
||
path: InfoByOrderScreen.path,
|
||
name: InfoByOrderScreen.name,
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
final planId = data['planId'] as int;
|
||
final successfulPayment = data['successfulPayment'] as bool?;
|
||
final customerSlug = data['customerSlug'] as String?;
|
||
return InfoByOrderScreen(planId: planId, successfulPayment: successfulPayment, customerSlug: customerSlug);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: PaymentScreen.path,
|
||
name: PaymentScreen.name,
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, dynamic>;
|
||
final planId = data['planId'] as int;
|
||
final url = data['url'] as String;
|
||
return PaymentScreen(url: url, planId: planId);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: UserDiaryScreen.path,
|
||
name: UserDiaryScreen.name,
|
||
builder: (context, state) {
|
||
final data = state.extra as Map<String, int>;
|
||
final diaryId = data['diaryId'] as int;
|
||
return UserDiaryScreen(diaryId: diaryId);
|
||
},
|
||
),
|
||
GoRoute(
|
||
path: PersonalDietSuggestionScreen.path,
|
||
name: PersonalDietSuggestionScreen.name,
|
||
builder: (context, state) => PersonalDietSuggestionScreen(dietId: state.extra as int),
|
||
),
|
||
];
|
||
}
|
||
}
|