2 Commits

8 changed files with 37 additions and 64 deletions

View File

@@ -6,7 +6,6 @@ import 'package:friflex_starter/app/theme/theme_notifier.dart';
import 'package:friflex_starter/di/di_container.dart'; import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/l10n/gen/app_localizations.dart'; import 'package:friflex_starter/l10n/gen/app_localizations.dart';
import 'package:friflex_starter/l10n/localization_notifier.dart'; import 'package:friflex_starter/l10n/localization_notifier.dart';
import 'package:friflex_starter/router/app_router.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
/// {@template app} /// {@template app}
@@ -14,39 +13,21 @@ import 'package:go_router/go_router.dart';
/// ///
/// Отвечает за: /// Отвечает за:
/// - Настройку провайдеров для темы и локализации /// - Настройку провайдеров для темы и локализации
/// - Инициализацию роутера приложения
/// {@endtemplate} /// {@endtemplate}
class AppRoot extends StatefulWidget { class AppRoot extends StatelessWidget {
/// {@macro app_root} /// {@macro app_root}
const AppRoot({required this.diContainer, super.key}); const AppRoot({required this.diContainer, required this.router, super.key});
/// Контейнер зависимостей /// Контейнер зависимостей
final DiContainer diContainer; final DiContainer diContainer;
@override
State<AppRoot> createState() => _AppRootState();
}
class _AppRootState extends State<AppRoot> {
/// Роутер приложения /// Роутер приложения
late final GoRouter router; final GoRouter router;
@override
void initState() {
super.initState();
router = AppRouter.createRouter(widget.diContainer.debugService);
}
@override
void dispose() {
router.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AppProviders( return AppProviders(
diContainer: widget.diContainer, diContainer: diContainer,
child: LocalizationConsumer( child: LocalizationConsumer(
builder: (localizationContext) { builder: (localizationContext) {
return ThemeConsumer( return ThemeConsumer(

View File

@@ -37,6 +37,7 @@
- Статический метод `show` безопасно не откроет модалку, если `updateEntity == null` - Статический метод `show` безопасно не откроет модалку, если `updateEntity == null`
Пример показа модального окна: Пример показа модального окна:
```dart ```dart
await SoftUpdateModal.show( await SoftUpdateModal.show(
context, context,
@@ -54,10 +55,9 @@ await SoftUpdateModal.show(
- `UpdateRoutes.buildRoutes()` — регистрирует экран hard-обновления по пути `/update` - `UpdateRoutes.buildRoutes()` — регистрирует экран hard-обновления по пути `/update`
## Структура модуля ## Структура модуля
``` ```md
features/update/ features/update/
├── data/ ├── data/
│ └── repository/ │ └── repository/

View File

@@ -26,7 +26,7 @@ final class UpdateMockRepository implements IUpdateRepository {
@override @override
Future<UpdateEntity> checkForUpdates({ Future<UpdateEntity> checkForUpdates({
required String versionCode, required String versionApp,
required String platform, required String platform,
}) async { }) async {
// Имитация задержки для асинхронной операции // Имитация задержки для асинхронной операции

View File

@@ -14,7 +14,7 @@ final class UpdateRepository implements IUpdateRepository {
@override @override
Future<UpdateEntity> checkForUpdates({ Future<UpdateEntity> checkForUpdates({
required String versionCode, required String versionApp,
required String platform, required String platform,
}) { }) {
// TODO: Реализовать реальную логику проверки обновлений // TODO: Реализовать реальную логику проверки обновлений

View File

@@ -6,11 +6,11 @@ import 'package:friflex_starter/features/update/domain/entity/update_entity.dart
/// {@endtemplate} /// {@endtemplate}
abstract interface class IUpdateRepository with DiBaseRepo { abstract interface class IUpdateRepository with DiBaseRepo {
/// Проверяет наличие обновлений /// Проверяет наличие обновлений
/// [versionCode] - текущий код версии приложения /// [versionApp] - текущий версия приложения
/// [platform] - платформа (например, 'android' или 'ios') /// [platform] - платформа (например, 'android' или 'ios')
/// Возвращает [UpdateEntity] с информацией об обновлении /// Возвращает [UpdateEntity] с информацией об обновлении
Future<UpdateEntity> checkForUpdates({ Future<UpdateEntity> checkForUpdates({
required String versionCode, required String versionApp,
required String platform, required String platform,
}); });
} }

View File

@@ -16,17 +16,17 @@ class UpdateCubit extends Cubit<UpdateState> {
final IUpdateRepository _updatesRepository; final IUpdateRepository _updatesRepository;
/// Метод для проверки доступности обновлений /// Метод для проверки доступности обновлений
/// [versionCode] - текущий код версии приложения /// [versionApp] - текущая версия приложения
/// [platform] - платформа (например, 'android' или 'ios') /// [platform] - платформа (например, 'android' или 'ios')
Future<void> checkForUpdates({ Future<void> checkForUpdates({
required String versionCode, required String versionApp,
required String platform, required String platform,
}) async { }) async {
if (state is UpdateLoadingState) return; if (state is UpdateLoadingState) return;
emit(const UpdateLoadingState()); emit(const UpdateLoadingState());
try { try {
final updateInfo = await _updatesRepository.checkForUpdates( final updateInfo = await _updatesRepository.checkForUpdates(
versionCode: versionCode, versionApp: versionApp,
platform: platform, platform: platform,
); );
emit(UpdateSuccessState(updateInfo)); emit(UpdateSuccessState(updateInfo));

View File

@@ -23,35 +23,23 @@ class AppRouter {
/// Метод для создания экземпляра GoRouter /// Метод для создания экземпляра GoRouter
static GoRouter createRouter(IDebugService debugService) { static GoRouter createRouter(IDebugService debugService) {
try { return GoRouter(
return _init(debugService); navigatorKey: rootNavigatorKey,
} on Object catch (error, stackTrace) { initialLocation: initialLocation,
debugService.logError( observers: [debugService.routeObserver],
'Ошибка при создании роутера', routes: [
error: error, StatefulShellRoute.indexedStack(
stackTrace: stackTrace, parentNavigatorKey: rootNavigatorKey,
); builder: (context, state, navigationShell) =>
throw StateError('Не удалось создать роутер: $error'); RootScreen(navigationShell: navigationShell),
} branches: [
MainRoutes.buildShellBranch(),
ProfileRoutes.buildShellBranch(),
],
),
DebugRoutes.buildRoutes(),
UpdateRoutes.buildRoutes(),
],
);
} }
/// Внутренний метод для инициализации роутера
static GoRouter _init(IDebugService debugService) => GoRouter(
navigatorKey: rootNavigatorKey,
initialLocation: initialLocation,
observers: [debugService.routeObserver],
routes: [
StatefulShellRoute.indexedStack(
parentNavigatorKey: rootNavigatorKey,
builder: (context, state, navigationShell) =>
RootScreen(navigationShell: navigationShell),
branches: [
MainRoutes.buildShellBranch(),
ProfileRoutes.buildShellBranch(),
],
),
DebugRoutes.buildRoutes(),
UpdateRoutes.buildRoutes(),
],
);
} }

View File

@@ -10,6 +10,7 @@ import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/features/debug/debug_service.dart'; import 'package:friflex_starter/features/debug/debug_service.dart';
import 'package:friflex_starter/features/debug/i_debug_service.dart'; import 'package:friflex_starter/features/debug/i_debug_service.dart';
import 'package:friflex_starter/features/error/error_screen.dart'; import 'package:friflex_starter/features/error/error_screen.dart';
import 'package:friflex_starter/router/app_router.dart';
import 'package:friflex_starter/runner/timer_runner.dart'; import 'package:friflex_starter/runner/timer_runner.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@@ -32,7 +33,7 @@ class AppRunner {
/// Тип окружения сборки приложения¬ /// Тип окружения сборки приложения¬
final AppEnv env; final AppEnv env;
/// Контейнер зависимостей приложения /// Сервис отладки
late IDebugService _debugService; late IDebugService _debugService;
/// Роутер приложения /// Роутер приложения
@@ -56,6 +57,9 @@ class AppRunner {
// Инициализация приложения // Инициализация приложения
await _initApp(); await _initApp();
// Инициализация роутера
router = AppRouter.createRouter(_debugService);
final diContainer = await _initDependencies( final diContainer = await _initDependencies(
debugService: _debugService, debugService: _debugService,
env: env, env: env,
@@ -63,7 +67,7 @@ class AppRunner {
); );
// Инициализация метода обработки ошибок // Инициализация метода обработки ошибок
_initErrorHandlers(_debugService); _initErrorHandlers(_debugService);
runApp(AppRoot(diContainer: diContainer)); runApp(AppRoot(diContainer: diContainer, router: router));
await _onAppLoaded(); await _onAppLoaded();
} on Object catch (e, stackTrace) { } on Object catch (e, stackTrace) {
await _onAppLoaded(); await _onAppLoaded();