Update router and DI for offline-first flow
- Add setup and onboarding routes to router - Implement redirect logic for setup, onboarding, and mode checks - Register local database and task datasource in DI container - Add mode-aware task repository factory
This commit is contained in:
parent
04863ff008
commit
8c837ec9d1
@ -8,13 +8,17 @@ import '../../features/auth/data/datasources/auth_remote_datasource.dart';
|
|||||||
import '../../features/auth/data/repositories/auth_repository_impl.dart';
|
import '../../features/auth/data/repositories/auth_repository_impl.dart';
|
||||||
import '../../features/auth/domain/repositories/auth_repository.dart';
|
import '../../features/auth/domain/repositories/auth_repository.dart';
|
||||||
import '../../features/auth/presentation/viewmodels/auth_viewmodel.dart';
|
import '../../features/auth/presentation/viewmodels/auth_viewmodel.dart';
|
||||||
|
import '../../features/settings/data/settings_local_datasource.dart';
|
||||||
|
import '../../features/settings/domain/enums/app_mode.dart';
|
||||||
import '../../features/settings/presentation/viewmodels/settings_viewmodel.dart';
|
import '../../features/settings/presentation/viewmodels/settings_viewmodel.dart';
|
||||||
|
import '../../features/tasks/data/datasources/task_local_datasource.dart';
|
||||||
|
import '../../features/tasks/data/datasources/task_remote_datasource.dart';
|
||||||
|
import '../../features/tasks/data/repositories/local_task_repository_impl.dart';
|
||||||
|
import '../../features/tasks/data/repositories/task_repository_impl.dart';
|
||||||
|
import '../../features/tasks/domain/repositories/task_repository.dart';
|
||||||
import '../../features/tasks/presentation/viewmodels/daily_tasks_viewmodel.dart';
|
import '../../features/tasks/presentation/viewmodels/daily_tasks_viewmodel.dart';
|
||||||
import '../../features/tasks/presentation/viewmodels/task_form_viewmodel.dart';
|
import '../../features/tasks/presentation/viewmodels/task_form_viewmodel.dart';
|
||||||
import '../../features/tasks/domain/repositories/task_repository.dart';
|
import '../database/app_database.dart';
|
||||||
import '../../features/tasks/data/repositories/task_repository_impl.dart';
|
|
||||||
import '../../features/tasks/data/datasources/task_remote_datasource.dart';
|
|
||||||
import '../../features/settings/data/settings_local_datasource.dart';
|
|
||||||
import '../logging/app_logger.dart';
|
import '../logging/app_logger.dart';
|
||||||
import '../network/authenticated_client.dart';
|
import '../network/authenticated_client.dart';
|
||||||
|
|
||||||
@ -64,6 +68,14 @@ Future<void> init() async {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Settings Data Source (must be registered before SettingsViewModel)
|
||||||
|
getIt.registerLazySingleton<SettingsLocalDataSource>(
|
||||||
|
() => SettingsLocalDataSourceImpl(sharedPreferences: getIt()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Database (for local mode)
|
||||||
|
getIt.registerLazySingleton<AppDatabase>(() => AppDatabase());
|
||||||
|
|
||||||
// Task Data sources
|
// Task Data sources
|
||||||
getIt.registerLazySingleton<TaskRemoteDataSource>(
|
getIt.registerLazySingleton<TaskRemoteDataSource>(
|
||||||
() => TaskRemoteDataSourceImpl(
|
() => TaskRemoteDataSourceImpl(
|
||||||
@ -71,14 +83,28 @@ Future<void> init() async {
|
|||||||
client: getIt<http.Client>(),
|
client: getIt<http.Client>(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
getIt.registerLazySingleton<SettingsLocalDataSource>(
|
getIt.registerLazySingleton<TaskLocalDataSource>(
|
||||||
() => SettingsLocalDataSourceImpl(sharedPreferences: getIt()),
|
() => TaskLocalDataSourceImpl(database: getIt()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Repositories
|
// Task Repository (mode-aware)
|
||||||
getIt.registerLazySingleton<TaskRepository>(
|
// We use a factory that checks the current app mode
|
||||||
() => TaskRepositoryImpl(remoteDataSource: getIt(), logger: getIt()),
|
getIt.registerFactory<TaskRepository>(() {
|
||||||
|
final settingsDataSource = getIt<SettingsLocalDataSource>();
|
||||||
|
final appMode = settingsDataSource.getAppMode();
|
||||||
|
|
||||||
|
if (appMode == AppMode.local) {
|
||||||
|
return LocalTaskRepositoryImpl(
|
||||||
|
localDataSource: getIt(),
|
||||||
|
logger: getIt(),
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
return TaskRepositoryImpl(
|
||||||
|
remoteDataSource: getIt(),
|
||||||
|
logger: getIt(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ViewModels
|
// ViewModels
|
||||||
getIt.registerFactory<DailyTasksViewModel>(
|
getIt.registerFactory<DailyTasksViewModel>(
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
|
|
||||||
import '../core/di/injection_container.dart';
|
import '../core/di/injection_container.dart';
|
||||||
import '../features/auth/presentation/pages/login_page.dart';
|
import '../features/auth/presentation/pages/login_page.dart';
|
||||||
import '../features/auth/presentation/pages/register_page.dart';
|
import '../features/auth/presentation/pages/register_page.dart';
|
||||||
import '../features/auth/presentation/viewmodels/auth_viewmodel.dart';
|
import '../features/auth/presentation/viewmodels/auth_viewmodel.dart';
|
||||||
import '../features/tasks/presentation/pages/daily_agenda_page.dart';
|
import '../features/onboarding/presentation/pages/onboarding_page.dart';
|
||||||
import '../features/tasks/presentation/pages/calendar_page.dart';
|
import '../features/onboarding/presentation/pages/setup_page.dart';
|
||||||
import '../features/tasks/presentation/pages/task_form_page.dart';
|
|
||||||
import '../features/settings/presentation/pages/settings_page.dart';
|
import '../features/settings/presentation/pages/settings_page.dart';
|
||||||
|
import '../features/settings/presentation/viewmodels/settings_viewmodel.dart';
|
||||||
|
import '../features/tasks/presentation/pages/calendar_page.dart';
|
||||||
|
import '../features/tasks/presentation/pages/daily_agenda_page.dart';
|
||||||
|
import '../features/tasks/presentation/pages/task_form_page.dart';
|
||||||
|
|
||||||
class AppRouter {
|
class AppRouter {
|
||||||
static GoRouter? _router;
|
static GoRouter? _router;
|
||||||
@ -18,13 +22,41 @@ class AppRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static GoRouter _createRouter() {
|
static GoRouter _createRouter() {
|
||||||
|
final authViewModel = getIt<AuthViewModel>();
|
||||||
|
final settingsViewModel = getIt<SettingsViewModel>();
|
||||||
|
|
||||||
return GoRouter(
|
return GoRouter(
|
||||||
initialLocation: '/',
|
initialLocation: '/',
|
||||||
redirect: (context, state) {
|
redirect: (context, state) {
|
||||||
final authViewModel = getIt<AuthViewModel>();
|
final location = state.matchedLocation;
|
||||||
|
|
||||||
|
// 1. Check if setup is completed
|
||||||
|
if (!settingsViewModel.setupCompleted) {
|
||||||
|
if (location != '/setup') {
|
||||||
|
return '/setup';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Check if onboarding is shown
|
||||||
|
if (!settingsViewModel.onboardingShown) {
|
||||||
|
if (location != '/onboarding') {
|
||||||
|
return '/onboarding';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Local mode - allow access to main app, block auth routes
|
||||||
|
if (settingsViewModel.isLocalMode) {
|
||||||
|
if (location == '/login' || location == '/register') {
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Online mode - existing auth logic
|
||||||
final isAuthenticated = authViewModel.isAuthenticated;
|
final isAuthenticated = authViewModel.isAuthenticated;
|
||||||
final isAuthRoute =
|
final isAuthRoute = location == '/login' || location == '/register';
|
||||||
state.matchedLocation == '/login' || state.matchedLocation == '/register';
|
|
||||||
|
|
||||||
if (authViewModel.state == AuthState.initial) {
|
if (authViewModel.state == AuthState.initial) {
|
||||||
return null;
|
return null;
|
||||||
@ -40,8 +72,18 @@ class AppRouter {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
refreshListenable: getIt<AuthViewModel>(),
|
refreshListenable: Listenable.merge([authViewModel, settingsViewModel]),
|
||||||
routes: [
|
routes: [
|
||||||
|
GoRoute(
|
||||||
|
path: '/setup',
|
||||||
|
name: 'setup',
|
||||||
|
builder: (context, state) => const SetupPage(),
|
||||||
|
),
|
||||||
|
GoRoute(
|
||||||
|
path: '/onboarding',
|
||||||
|
name: 'onboarding',
|
||||||
|
builder: (context, state) => const OnboardingPage(),
|
||||||
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/login',
|
path: '/login',
|
||||||
name: 'login',
|
name: 'login',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user