feat(router): enhance deep link handling with logging and support for various content types

This commit is contained in:
mso7nueh
2025-12-19 15:15:54 +03:00
parent 22b2e5f249
commit a1304e4612

View File

@@ -1,3 +1,4 @@
import 'dart:developer' as developer;
import 'package:eatvio_app/core/routing/auth_routes.dart';
import 'package:eatvio_app/core/routing/content_routes.dart';
import 'package:eatvio_app/core/routing/main_navigation_routes.dart';
@@ -13,6 +14,9 @@ import 'package:go_router/go_router.dart';
class AppRouter {
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
// Домены для deep links
static const List<String> _deepLinkHosts = ['eatvio.ru', 'www.eatvio.ru'];
static GoRouter appRouter = GoRouter(
initialLocation: RouteConstants.updateScreen,
navigatorKey: navigatorKey,
@@ -27,51 +31,128 @@ class AppRouter {
);
/// Обработка редиректов для deep links
/// Возвращает null для обычной навигации, чтобы не мешать внутренним переходам
static String? _handleRedirect(BuildContext context, GoRouterState state) {
final segments = state.uri.pathSegments;
if (segments.length == 4) {
final type = segments[1];
switch (type) {
case 'diary':
FlutterNativeSplash.remove();
return '/diary-screen';
}
final uri = state.uri;
final host = uri.host.toLowerCase();
final segments = uri.pathSegments;
// Проверяем, является ли это deep link по домену
final isDeepLink = _deepLinkHosts.contains(host);
// Если это не deep link, не мешаем обычной навигации
if (!isDeepLink) {
return null;
}
if (segments.length == 3) {
// Логирование для отладки
developer.log(
'Deep link detected: host=$host, path=${uri.path}, segments=$segments',
name: 'AppRouter',
);
// Проверка на пустой путь или некорректный формат
if (segments.isEmpty) {
developer.log('Empty segments in deep link, redirecting to feed', name: 'AppRouter');
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
}
// Проверка языка (первый сегмент должен быть ru или en)
if (segments[0] != 'ru' && segments[0] != 'en') {
developer.log(
'Invalid language segment: ${segments[0]}, redirecting to feed',
name: 'AppRouter',
);
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
}
// Обработка deep links с учетом языка
// Формат: /{lang}/{type}/{identifier?}
if (segments.length == 4) {
// Формат: /{lang}/diary/{...}
final type = segments[1];
if (type == 'diary') {
developer.log('Deep link: diary, redirecting to diary-screen', name: 'AppRouter');
FlutterNativeSplash.remove();
return RouteConstants.diaryScreen;
}
developer.log(
'Unknown deep link type for 4 segments: $type, redirecting to feed',
name: 'AppRouter',
);
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
} else if (segments.length == 3) {
// Формат: /{lang}/{type}/{identifier}
final type = segments[1];
final contentIdentifier = segments[2];
switch (type) {
case 'recipe':
developer.log('Deep link: recipe/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/about-recipes-screen?slug=$contentIdentifier';
case 'blog_post':
developer.log('Deep link: blog_post/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/blog-post-screen?id=$contentIdentifier';
case 'plan':
developer.log('Deep link: plan/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/about-plan-screen?slug=$contentIdentifier';
case 'diet':
developer.log('Deep link: diet/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/about-diet-screen?slug=$contentIdentifier';
case 'chat':
developer.log('Deep link: chat/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/chat-select-screen';
return RouteConstants.chatSelectScreen;
case 'profile':
developer.log('Deep link: profile/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/profile-screen?slug=$contentIdentifier';
}
}
if (segments.length == 2) {
final type = segments[1];
switch (type) {
case 'chat':
case 'diary':
developer.log('Deep link: diary/$contentIdentifier', name: 'AppRouter');
FlutterNativeSplash.remove();
return '/chat-select-screen';
return RouteConstants.diaryScreen;
default:
developer.log(
'Unknown deep link type: $type, redirecting to feed',
name: 'AppRouter',
);
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
}
} else if (segments.length == 2) {
// Формат: /{lang}/{type} - только для chat
final type = segments[1];
if (type == 'chat') {
developer.log('Deep link: chat', name: 'AppRouter');
FlutterNativeSplash.remove();
return RouteConstants.chatSelectScreen;
} else {
developer.log(
'Unknown deep link type for 2 segments: $type, redirecting to feed',
name: 'AppRouter',
);
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
}
} else {
// Неизвестный формат deep link
developer.log(
'Unknown deep link format: ${segments.length} segments, redirecting to feed',
name: 'AppRouter',
);
FlutterNativeSplash.remove();
return RouteConstants.feedScreen;
}
return null;
}
static void navigateToRegisterViaSocial({required AuthResultEntity authResult, required String provider}) {