mirror of
https://github.com/smmarty/friflex_flutter_starter.git
synced 2026-02-05 03:32:18 +00:00
Compare commits
8 Commits
main
...
6f839aea24
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f839aea24 | ||
|
|
617563fb6c | ||
|
|
75c0ac3285 | ||
|
|
4260c7cc65 | ||
|
|
2595692107 | ||
|
|
c86b4cc0bc | ||
|
|
d46c829959 | ||
|
|
84e5f5e869 |
BIN
.agent/skills/dist/flutter_dev.skill
vendored
BIN
.agent/skills/dist/flutter_dev.skill
vendored
Binary file not shown.
@@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
name: flutter_dev
|
|
||||||
description: Скилл для разработки Flutter-приложений по стандартам компании Friflex. Используйте этот скилл при написании кода, создании новых фич, проведении ревью или настройке архитектуры проекта. Включает правила именования, структуру слоев (data/domain/presentation) и стандарты Git.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Flutter Dev Skill (Friflex Standards)
|
|
||||||
|
|
||||||
Этот скилл содержит набор правил и инструкций для разработки Flutter-приложений. Основная цель — соблюдение единого стиля кода, архитектурных подходов и процессов разработки.
|
|
||||||
|
|
||||||
## Основные принципы
|
|
||||||
|
|
||||||
1. **Архитектура**: Проект делится на слои: `data`, `domain` и `presentation`.
|
|
||||||
2. **Именование**: Интерфейсы всегда начинаются с префикса `I`. Экраны имеют постфикс `Screen`.
|
|
||||||
3. **Документация**: Весь публичный API должен быть покрыт документацией `///`.
|
|
||||||
4. **Git**: Коммиты и PR на русском языке по стандарту Conventional Commits.
|
|
||||||
|
|
||||||
## Справочники (References)
|
|
||||||
|
|
||||||
Для получения детальной информации по конкретным областям обращайтесь к следующим файлам:
|
|
||||||
|
|
||||||
- [Правила именования и стиль кода](references/codestyle.md) — именование классов, методов, переменных и структура файлов.
|
|
||||||
- [Структура проекта и слои](references/project_structure.md) — детальное описание папок и взаимодействия между уровнями архитектуры.
|
|
||||||
- [Работа с Git и ветками](references/gitflow.md) — типы коммитов, именование веток и процессы релизов.
|
|
||||||
- [Документирование кода](references/documentation.md) — стандарты `///`, использование шаблонов и правила для TODO.
|
|
||||||
- [Стандарты проекта](references/project_standards.md) — управление сгенерированными файлами, `pubspec.lock` и сборка.
|
|
||||||
|
|
||||||
## Когда использовать этот скилл
|
|
||||||
|
|
||||||
- При создании новых классов или файлов (проверка именования).
|
|
||||||
- При реализации новой feature (выбор структуры папок).
|
|
||||||
- Перед созданием Pull Request (проверка соответствия стандартам).
|
|
||||||
- При возникновении вопросов по архитектурному взаимодействию слоев.
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
# Правила именования и стиль кода
|
|
||||||
|
|
||||||
Мы придерживаемся рекомендаций **Effective Dart** и внутренних правил компании.
|
|
||||||
|
|
||||||
## Именование
|
|
||||||
|
|
||||||
### Интерфейсы
|
|
||||||
- Начинаются с заглавной буквы **I**.
|
|
||||||
- Пример: `IAuthRepository`, `IUserRepository`.
|
|
||||||
|
|
||||||
### Классы и файлы
|
|
||||||
- **Классы**: `UpperCamelCase`. Приватные — с префиксом `_`. Должны содержать тип в конце (например, `UserEntity`).
|
|
||||||
- **Файлы**: `snake_case`. Структура: `[раздел]_[тип].dart`. Пример: `user_details_screen.dart`.
|
|
||||||
|
|
||||||
### Репозитории
|
|
||||||
- Основная реализация — без постфикса (`AuthRepository`).
|
|
||||||
- Альтернативные реализации — с постфиксами: `Network`, `Local`, `Mock`.
|
|
||||||
|
|
||||||
### Виджеты
|
|
||||||
- **Экраны**: Постфикс `Screen` (`ShopListScreen`).
|
|
||||||
- **Контент экрана**: Постфикс `View` (`ShopListView`).
|
|
||||||
- **Глобальные виджеты**: Префикс `App` (`AppButton`).
|
|
||||||
- В названии **не должно** быть слова `widget`.
|
|
||||||
|
|
||||||
## Методы и переменные
|
|
||||||
- **Методы**: Начинаются с глагола (`fetch`, `put`, `update`, `delete`). Не должны содержать `And/Or`.
|
|
||||||
- **Переменные/Константы**: `lowerCamelCase`.
|
|
||||||
|
|
||||||
## Структура класса (порядок элементов)
|
|
||||||
1. Конструкторы (default, named, factory).
|
|
||||||
2. Static элементы (methods, const fields).
|
|
||||||
3. Инстанс-поля (final, потом обычные; public, потом private).
|
|
||||||
4. Геттеры/Сеттеры.
|
|
||||||
5. Методы (overridden, public, protected, private).
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# Документирование кода
|
|
||||||
|
|
||||||
## Документация (///)
|
|
||||||
- Оформляется с использованием `///` над объектом.
|
|
||||||
- Обязательна для всех классов, конструкторов, полей, методов и фабрик.
|
|
||||||
- Должна быть краткой, емкой и указывать на назначение.
|
|
||||||
|
|
||||||
### Шаблоны
|
|
||||||
- **Классы**: Используйте `{@template name}` и `{@endtemplate}`.
|
|
||||||
- **Конструкторы**: Если один — `{@macro name}`.
|
|
||||||
- **Параметры**: Используйте ссылки в квадратных скобках `[paramName]`.
|
|
||||||
|
|
||||||
### Пример метода
|
|
||||||
```dart
|
|
||||||
/// Метод для расчета температуры.
|
|
||||||
/// Принимает:
|
|
||||||
/// - [grad] - параметр для расчета.
|
|
||||||
/// Возвращает температуру в градусах. Null при ошибке.
|
|
||||||
int? calcTemperature({required int grad}) { ... }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Комментарии (//)
|
|
||||||
- Используются только там, где код не очевиден.
|
|
||||||
- Не должны повторять то, что и так понятно из имен переменных или структуры.
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
- Формат определяется линтером.
|
|
||||||
- Указывать имя разработчика в контексте.
|
|
||||||
- Указывать ссылку на задачу в скобках, если она известна.
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Работа с Git и ветками
|
|
||||||
|
|
||||||
## Pull Requests
|
|
||||||
- Язык описания — **Русский**.
|
|
||||||
- Описание должно содержать суть изменений, ссылку на задачу и список deprecated-кода.
|
|
||||||
|
|
||||||
## Коммиты (Conventional Commits)
|
|
||||||
Типы:
|
|
||||||
- `feat`: Новая функциональность.
|
|
||||||
- `fix`: Исправление ошибок.
|
|
||||||
- `refactor`: Рефакторинг без смены логики.
|
|
||||||
- `docs`: Документация.
|
|
||||||
- `chore`: Инструменты, зависимости (`pubspec.yaml`).
|
|
||||||
- `test`, `build`, `ci`.
|
|
||||||
|
|
||||||
## Именование веток
|
|
||||||
Формат: `тип/PRIME-номер_описание`
|
|
||||||
- `feat/PRIME-123_auth`
|
|
||||||
- `fix/PRIME-456_typo`
|
|
||||||
|
|
||||||
## Процесс Feature-разработки
|
|
||||||
1. Создаем ветку от `main`.
|
|
||||||
2. Вносим изменения, делаем коммиты.
|
|
||||||
3. PR с названием по правилам (например, `feat(auth): PRIME-17 Добавить вход`).
|
|
||||||
4. После Review — **squash commit** в `main`.
|
|
||||||
5. Удаление ветки.
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
# Стандарты проекта
|
|
||||||
|
|
||||||
## Управление файлами
|
|
||||||
|
|
||||||
### Сгенерированные файлы (*.g.dart, *.freezed.dart)
|
|
||||||
- **Хранить в репозитории**.
|
|
||||||
- Это обеспечивает работоспособность `main` ветки сразу после чекаута без долгого ожидания генерации.
|
|
||||||
- Нужно контролировать конфликты при слиянии и периодически актуализировать.
|
|
||||||
|
|
||||||
### pubspec.lock
|
|
||||||
- **Хранить** для приложений (applications).
|
|
||||||
- **Не хранить** для пакетов (packages).
|
|
||||||
- По умолчанию хранить GMS версию как базовую.
|
|
||||||
|
|
||||||
## Сборка и запуск
|
|
||||||
- Используйте анализатор `friflex_lint_rules`.
|
|
||||||
- Перед созданием PR обязательно:
|
|
||||||
1. Форматирование кода (`dart format`).
|
|
||||||
2. Проверка анализатором на отсутствие ошибок.
|
|
||||||
|
|
||||||
## Технологический стек
|
|
||||||
- Роутинг: `go_router`.
|
|
||||||
- State Manager: `flutter_bloc`.
|
|
||||||
- DI: Ручная реализация через `InheritedWidget`.
|
|
||||||
- API: `dio`.
|
|
||||||
- Ресурсы: `flutter_gen`.
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# Структура проекта
|
|
||||||
|
|
||||||
Проект строится на основе фич и слоев.
|
|
||||||
|
|
||||||
## Общая иерархия
|
|
||||||
- `/assets` — графические ресурсы.
|
|
||||||
- `/lib` — основной код.
|
|
||||||
- `/app` — глобальные настройки, интерфейсы и реализации.
|
|
||||||
- `/di` — конфигурация зависимостей.
|
|
||||||
- `/routing` — описание путей.
|
|
||||||
- `/features` — функциональные модули приложения.
|
|
||||||
- `/gen` — сгенерированный код.
|
|
||||||
|
|
||||||
## Структура Feature-папки
|
|
||||||
Каждая фича делится на три слоя:
|
|
||||||
|
|
||||||
1. **Data** (Поставщик данных):
|
|
||||||
- `/dto` — модели данных для API.
|
|
||||||
- `/repository` — реализация интерфейсов репозиториев.
|
|
||||||
2. **Domain** (Бизнес-логика):
|
|
||||||
- `/entity` — чистые модели для использования в UI.
|
|
||||||
- `/repository` — **интерфейсы** репозиториев.
|
|
||||||
- `/state` — управление состоянием (BLoC).
|
|
||||||
- `/service` — реализации бизнес-сервисов.
|
|
||||||
3. **Presentation** (Представление):
|
|
||||||
- `/screens` — виджеты экранов (`*Screen`).
|
|
||||||
- `/components` — переиспользуемые компоненты внутри фичи.
|
|
||||||
|
|
||||||
## Правила взаимодействия
|
|
||||||
- **Data** → доступ к **Entity** (для маппинга), не знает про UI.
|
|
||||||
- **Domain** → не знает про **Data** (работает через интерфейсы) и **Presentation**.
|
|
||||||
- **Presentation** → работает через **Domain**, не знает про **Data**.
|
|
||||||
- Объекты внутри фичи инкапсулированы. Глобальные объекты выносятся в `/app`.
|
|
||||||
12
.metadata
12
.metadata
@@ -4,7 +4,7 @@
|
|||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "66dd93f9a27ffe2a9bfc8297506ce066ff51265f"
|
revision: "be698c48a6750c8cb8e61c740ca9991bb947aba2"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
@@ -13,11 +13,11 @@ project_type: app
|
|||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 66dd93f9a27ffe2a9bfc8297506ce066ff51265f
|
create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2
|
||||||
base_revision: 66dd93f9a27ffe2a9bfc8297506ce066ff51265f
|
base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2
|
||||||
- platform: web
|
- platform: android
|
||||||
create_revision: 66dd93f9a27ffe2a9bfc8297506ce066ff51265f
|
create_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2
|
||||||
base_revision: 66dd93f9a27ffe2a9bfc8297506ce066ff51265f
|
base_revision: be698c48a6750c8cb8e61c740ca9991bb947aba2
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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}
|
||||||
@@ -13,21 +14,39 @@ import 'package:go_router/go_router.dart';
|
|||||||
///
|
///
|
||||||
/// Отвечает за:
|
/// Отвечает за:
|
||||||
/// - Настройку провайдеров для темы и локализации
|
/// - Настройку провайдеров для темы и локализации
|
||||||
|
/// - Инициализацию роутера приложения
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
class AppRoot extends StatelessWidget {
|
class AppRoot extends StatefulWidget {
|
||||||
/// {@macro app_root}
|
/// {@macro app_root}
|
||||||
const AppRoot({required this.diContainer, required this.router, super.key});
|
const AppRoot({required this.diContainer, super.key});
|
||||||
|
|
||||||
/// Контейнер зависимостей
|
/// Контейнер зависимостей
|
||||||
final DiContainer diContainer;
|
final DiContainer diContainer;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AppRoot> createState() => _AppRootState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AppRootState extends State<AppRoot> {
|
||||||
/// Роутер приложения
|
/// Роутер приложения
|
||||||
final GoRouter router;
|
late 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: diContainer,
|
diContainer: widget.diContainer,
|
||||||
child: LocalizationConsumer(
|
child: LocalizationConsumer(
|
||||||
builder: (localizationContext) {
|
builder: (localizationContext) {
|
||||||
return ThemeConsumer(
|
return ThemeConsumer(
|
||||||
|
|||||||
@@ -37,7 +37,6 @@
|
|||||||
- Статический метод `show` безопасно не откроет модалку, если `updateEntity == null`
|
- Статический метод `show` безопасно не откроет модалку, если `updateEntity == null`
|
||||||
|
|
||||||
Пример показа модального окна:
|
Пример показа модального окна:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
await SoftUpdateModal.show(
|
await SoftUpdateModal.show(
|
||||||
context,
|
context,
|
||||||
@@ -55,9 +54,10 @@ await SoftUpdateModal.show(
|
|||||||
|
|
||||||
- `UpdateRoutes.buildRoutes()` — регистрирует экран hard-обновления по пути `/update`
|
- `UpdateRoutes.buildRoutes()` — регистрирует экран hard-обновления по пути `/update`
|
||||||
|
|
||||||
|
|
||||||
## Структура модуля
|
## Структура модуля
|
||||||
|
|
||||||
```md
|
```
|
||||||
features/update/
|
features/update/
|
||||||
├── data/
|
├── data/
|
||||||
│ └── repository/
|
│ └── repository/
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ final class UpdateMockRepository implements IUpdateRepository {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<UpdateEntity> checkForUpdates({
|
Future<UpdateEntity> checkForUpdates({
|
||||||
required String versionApp,
|
required String versionCode,
|
||||||
required String platform,
|
required String platform,
|
||||||
}) async {
|
}) async {
|
||||||
// Имитация задержки для асинхронной операции
|
// Имитация задержки для асинхронной операции
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ final class UpdateRepository implements IUpdateRepository {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<UpdateEntity> checkForUpdates({
|
Future<UpdateEntity> checkForUpdates({
|
||||||
required String versionApp,
|
required String versionCode,
|
||||||
required String platform,
|
required String platform,
|
||||||
}) {
|
}) {
|
||||||
// TODO: Реализовать реальную логику проверки обновлений
|
// TODO: Реализовать реальную логику проверки обновлений
|
||||||
|
|||||||
@@ -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 {
|
||||||
/// Проверяет наличие обновлений
|
/// Проверяет наличие обновлений
|
||||||
/// [versionApp] - текущий версия приложения
|
/// [versionCode] - текущий код версии приложения
|
||||||
/// [platform] - платформа (например, 'android' или 'ios')
|
/// [platform] - платформа (например, 'android' или 'ios')
|
||||||
/// Возвращает [UpdateEntity] с информацией об обновлении
|
/// Возвращает [UpdateEntity] с информацией об обновлении
|
||||||
Future<UpdateEntity> checkForUpdates({
|
Future<UpdateEntity> checkForUpdates({
|
||||||
required String versionApp,
|
required String versionCode,
|
||||||
required String platform,
|
required String platform,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,17 +16,17 @@ class UpdateCubit extends Cubit<UpdateState> {
|
|||||||
final IUpdateRepository _updatesRepository;
|
final IUpdateRepository _updatesRepository;
|
||||||
|
|
||||||
/// Метод для проверки доступности обновлений
|
/// Метод для проверки доступности обновлений
|
||||||
/// [versionApp] - текущая версия приложения
|
/// [versionCode] - текущий код версии приложения
|
||||||
/// [platform] - платформа (например, 'android' или 'ios')
|
/// [platform] - платформа (например, 'android' или 'ios')
|
||||||
Future<void> checkForUpdates({
|
Future<void> checkForUpdates({
|
||||||
required String versionApp,
|
required String versionCode,
|
||||||
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(
|
||||||
versionApp: versionApp,
|
versionCode: versionCode,
|
||||||
platform: platform,
|
platform: platform,
|
||||||
);
|
);
|
||||||
emit(UpdateSuccessState(updateInfo));
|
emit(UpdateSuccessState(updateInfo));
|
||||||
|
|||||||
@@ -23,7 +23,20 @@ class AppRouter {
|
|||||||
|
|
||||||
/// Метод для создания экземпляра GoRouter
|
/// Метод для создания экземпляра GoRouter
|
||||||
static GoRouter createRouter(IDebugService debugService) {
|
static GoRouter createRouter(IDebugService debugService) {
|
||||||
return GoRouter(
|
try {
|
||||||
|
return _init(debugService);
|
||||||
|
} on Object catch (error, stackTrace) {
|
||||||
|
debugService.logError(
|
||||||
|
'Ошибка при создании роутера',
|
||||||
|
error: error,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
);
|
||||||
|
throw StateError('Не удалось создать роутер: $error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Внутренний метод для инициализации роутера
|
||||||
|
static GoRouter _init(IDebugService debugService) => GoRouter(
|
||||||
navigatorKey: rootNavigatorKey,
|
navigatorKey: rootNavigatorKey,
|
||||||
initialLocation: initialLocation,
|
initialLocation: initialLocation,
|
||||||
observers: [debugService.routeObserver],
|
observers: [debugService.routeObserver],
|
||||||
@@ -41,5 +54,4 @@ class AppRouter {
|
|||||||
UpdateRoutes.buildRoutes(),
|
UpdateRoutes.buildRoutes(),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ 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';
|
||||||
|
|
||||||
@@ -33,7 +32,7 @@ class AppRunner {
|
|||||||
/// Тип окружения сборки приложения¬
|
/// Тип окружения сборки приложения¬
|
||||||
final AppEnv env;
|
final AppEnv env;
|
||||||
|
|
||||||
/// Сервис отладки
|
/// Контейнер зависимостей приложения
|
||||||
late IDebugService _debugService;
|
late IDebugService _debugService;
|
||||||
|
|
||||||
/// Роутер приложения
|
/// Роутер приложения
|
||||||
@@ -57,9 +56,6 @@ 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,
|
||||||
@@ -67,7 +63,7 @@ class AppRunner {
|
|||||||
);
|
);
|
||||||
// Инициализация метода обработки ошибок
|
// Инициализация метода обработки ошибок
|
||||||
_initErrorHandlers(_debugService);
|
_initErrorHandlers(_debugService);
|
||||||
runApp(AppRoot(diContainer: diContainer, router: router));
|
runApp(AppRoot(diContainer: diContainer));
|
||||||
await _onAppLoaded();
|
await _onAppLoaded();
|
||||||
} on Object catch (e, stackTrace) {
|
} on Object catch (e, stackTrace) {
|
||||||
await _onAppLoaded();
|
await _onAppLoaded();
|
||||||
|
|||||||
Reference in New Issue
Block a user