import '../infrastructure/local/local.dart'; import '../infrastructure/remote/remote.dart'; import '../infrastructure/security/security.dart'; import 'application.dart'; abstract interface class AppDependencies { AuthUseCases get authUseCases; ExerciseUseCases get exerciseUseCases; MediaUseCases get mediaUseCases; ProgramUseCases get programUseCases; WorkoutTemplateUseCases get workoutTemplateUseCases; ActiveWorkoutSessionUseCases get activeWorkoutSessionUseCases; ActiveExerciseStepUseCases get activeExerciseStepUseCases; CloseWorkoutSessionUseCase get closeWorkoutSessionUseCase; WorkoutHistoryUseCases get workoutHistoryUseCases; ProgressionStatsUseCase get progressionStatsUseCase; ExercisePerformanceReferenceUseCase get exercisePerformanceReferenceUseCase; DataExportUseCase get dataExportUseCase; DataImportUseCase get dataImportUseCase; SyncUseCases get syncUseCases; ShareUseCases get shareUseCases; } final class AppBootstrap implements AppDependencies { AppBootstrap._({ required this.database, required this.authUseCases, required this.exerciseUseCases, required this.mediaUseCases, required this.programUseCases, required this.workoutTemplateUseCases, required this.activeWorkoutSessionUseCases, required this.activeExerciseStepUseCases, required this.watchCompanionProjectionUseCases, required this.watchCompanionCommandHandler, required this.closeWorkoutSessionUseCase, required this.workoutHistoryUseCases, required this.progressionStatsUseCase, required this.exercisePerformanceReferenceUseCase, required this.dataExportUseCase, required this.dataImportUseCase, required this.syncUseCases, required this.shareUseCases, required this.syncGateway, }); final AppDatabase database; @override final AuthUseCases authUseCases; @override final ExerciseUseCases exerciseUseCases; @override final MediaUseCases mediaUseCases; @override final ProgramUseCases programUseCases; @override final WorkoutTemplateUseCases workoutTemplateUseCases; @override final ActiveWorkoutSessionUseCases activeWorkoutSessionUseCases; @override final ActiveExerciseStepUseCases activeExerciseStepUseCases; final WatchCompanionProjectionUseCases watchCompanionProjectionUseCases; final WatchCompanionCommandHandler watchCompanionCommandHandler; @override final CloseWorkoutSessionUseCase closeWorkoutSessionUseCase; @override final WorkoutHistoryUseCases workoutHistoryUseCases; @override final ProgressionStatsUseCase progressionStatsUseCase; @override final ExercisePerformanceReferenceUseCase exercisePerformanceReferenceUseCase; @override final DataExportUseCase dataExportUseCase; @override final DataImportUseCase dataImportUseCase; @override final SyncUseCases syncUseCases; @override final ShareUseCases shareUseCases; final SyncGateway syncGateway; static Future create() async { final database = AppDatabase.open(); await database.customSelect('SELECT 1').get(); final exerciseRepository = DriftExerciseRepository(database); final mediaRepository = DriftMediaAssetRepository(database); final onlineAccountRepository = DriftOnlineAccountRepository(database); final syncMetadataRepository = DriftSyncMetadataRepository(database); final mappingRepository = DriftRemoteResourceMappingRepository(database); final localSyncChangeRepository = DriftLocalSyncChangeRepository(database); final starterSeedRepository = DriftStarterSeedRepository(database); final shareInboxRepository = DriftShareInboxRepository(database); final pendingShareActionRepository = DriftPendingShareActionRepository( database, ); final programRepository = DriftProgramRepository(database); final templateRepository = DriftWorkoutTemplateRepository(database); final activeSessionRepository = DriftActiveSessionRepository(database); final historyRepository = DriftWorkoutHistoryRepository(database); final progressionStatsRepository = DriftProgressionStatsRepository( database, ); final performanceReferenceRepository = DriftExercisePerformanceReferenceRepository(database); final localDataBackupRepository = DriftLocalDataBackupRepository(database); const localBackupMediaStore = PathProviderLocalMediaStorage(); final ids = LocalIdGenerator(); const clock = SystemClock(); const originDeviceId = 'local-device'; final activeWorkoutSessionUseCases = ActiveWorkoutSessionUseCases( sessionRepository: activeSessionRepository, templateRepository: templateRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ); final activeExerciseStepUseCases = ActiveExerciseStepUseCases( sessionRepository: activeSessionRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ); final watchCompanionProjectionUseCases = WatchCompanionProjectionUseCases( sessionRepository: activeSessionRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ); await SeedStarterContentUseCase( seedStateRepository: starterSeedRepository, contentRepository: starterSeedRepository, clock: clock, originDeviceId: originDeviceId, ).run(); final remoteAuthApi = HttpRemoteAuthApi( HttpApiClient(baseUrl: Uri.parse(HttpApiClient.defaultBaseUrl)), ); final remoteSyncApi = HttpRemoteSyncApi( HttpApiClient(baseUrl: Uri.parse(HttpApiClient.defaultBaseUrl)), ); final remoteShareApi = HttpRemoteShareApi( HttpApiClient(baseUrl: Uri.parse(HttpApiClient.defaultBaseUrl)), ); return AppBootstrap._( database: database, authUseCases: AuthUseCases( tokenStore: const SecureStorageAuthTokenStore(), accountRepository: onlineAccountRepository, remoteAuthApi: remoteAuthApi, clock: clock, ids: ids, ), exerciseUseCases: ExerciseUseCases( repository: exerciseRepository, programRepository: programRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ), mediaUseCases: MediaUseCases( mediaRepository: mediaRepository, exerciseRepository: exerciseRepository, storage: const PathProviderLocalMediaStorage(), clock: clock, ids: ids, originDeviceId: originDeviceId, ), programUseCases: ProgramUseCases( programRepository: programRepository, exerciseRepository: exerciseRepository, templateRepository: templateRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ), workoutTemplateUseCases: WorkoutTemplateUseCases( templateRepository: templateRepository, programRepository: programRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ), activeWorkoutSessionUseCases: activeWorkoutSessionUseCases, activeExerciseStepUseCases: activeExerciseStepUseCases, watchCompanionProjectionUseCases: watchCompanionProjectionUseCases, watchCompanionCommandHandler: WatchCompanionCommandHandler( sessionRepository: activeSessionRepository, activeSessionUseCases: activeWorkoutSessionUseCases, stepUseCases: activeExerciseStepUseCases, projectionSource: watchCompanionProjectionUseCases, ), closeWorkoutSessionUseCase: CloseWorkoutSessionUseCase( sessionRepository: activeSessionRepository, historyRepository: historyRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ), workoutHistoryUseCases: WorkoutHistoryUseCases( repository: historyRepository, clock: clock, ), progressionStatsUseCase: ProgressionStatsUseCase( repository: progressionStatsRepository, clock: clock, ), exercisePerformanceReferenceUseCase: ExercisePerformanceReferenceUseCase( repository: performanceReferenceRepository, ), dataExportUseCase: DataExportUseCase( repository: localDataBackupRepository, mediaStore: localBackupMediaStore, clock: clock, ), dataImportUseCase: DataImportUseCase( repository: localDataBackupRepository, mediaStore: localBackupMediaStore, clock: clock, ), syncUseCases: SyncUseCases( tokenStore: const SecureStorageAuthTokenStore(), remoteSyncApi: remoteSyncApi, metadataRepository: syncMetadataRepository, mappingRepository: mappingRepository, localChanges: localSyncChangeRepository, clock: clock, deviceId: originDeviceId, ), shareUseCases: ShareUseCases( tokenStore: const SecureStorageAuthTokenStore(), remoteShareApi: remoteShareApi, inboxRepository: shareInboxRepository, pendingActionRepository: pendingShareActionRepository, localChanges: localSyncChangeRepository, programRepository: programRepository, templateRepository: templateRepository, clock: clock, ids: ids, originDeviceId: originDeviceId, ), syncGateway: const NoOpSyncGateway(), ); } Future dispose() => database.close(); }