From 688a74da0b4e504e2851adbb9a3a28f4ffb2ea1e Mon Sep 17 00:00:00 2001 From: sembauke Date: Mon, 2 Mar 2026 19:13:37 +0100 Subject: [PATCH] chore(riverpod): establish migration base infrastructure --- .../riverpod-migration-claude-4-agents.md | 244 ++++ mobile-app/lib/app/app.dart | 99 +- mobile-app/lib/app/app.locator.dart | 76 +- mobile-app/lib/app/app.router.dart | 1264 +---------------- mobile-app/lib/app/app_router.dart | 236 +++ .../lib/core/navigation/app_dialog.dart | 74 + .../lib/core/navigation/app_navigator.dart | 76 + .../lib/core/navigation/app_snackbar.dart | 42 + .../lib/core/providers/service_providers.dart | 146 ++ mobile-app/lib/main.dart | 25 +- .../navigation/quick_actions_service.dart | 15 +- mobile-app/pubspec.lock | 90 +- mobile-app/pubspec.yaml | 7 +- mobile-app/test/helpers/test_helpers.dart | 26 +- .../test/helpers/test_helpers.mocks.dart | 995 +++---------- 15 files changed, 1141 insertions(+), 2274 deletions(-) create mode 100644 mobile-app/docs/riverpod-migration-claude-4-agents.md create mode 100644 mobile-app/lib/app/app_router.dart create mode 100644 mobile-app/lib/core/navigation/app_dialog.dart create mode 100644 mobile-app/lib/core/navigation/app_navigator.dart create mode 100644 mobile-app/lib/core/navigation/app_snackbar.dart create mode 100644 mobile-app/lib/core/providers/service_providers.dart diff --git a/mobile-app/docs/riverpod-migration-claude-4-agents.md b/mobile-app/docs/riverpod-migration-claude-4-agents.md new file mode 100644 index 000000000..b706055c1 --- /dev/null +++ b/mobile-app/docs/riverpod-migration-claude-4-agents.md @@ -0,0 +1,244 @@ +# Stacked -> Riverpod Migration Plan (Claude, 4 Agents) + +## Baseline (current repo snapshot) +- `83` files import `package:stacked/stacked.dart`. +- `40` classes extend `BaseViewModel`. +- `36` files use `ViewModelBuilder`. +- `23` files import `stacked_services`. +- `103` `locator()` usages. +- Heaviest area is `lib/ui/views/learn` (`48` stacked imports, `24` `BaseViewModel` classes). + +## Migration Goal +- Replace Stacked state management with Riverpod across the app. +- Remove `stacked`, `stacked_services`, and `stacked_generator` from `pubspec.yaml`. +- Keep user behavior unchanged while improving testability and typed state boundaries. + +## Architecture Decisions (to keep migration safe) +- Use `flutter_riverpod` for UI state (`Notifier`, `AsyncNotifier`, and `Provider`). +- Keep DI simple during migration: bridge current services into Riverpod providers first, then reduce direct `locator()` usage. +- Replace Stacked routing/services with a local compatibility layer before deleting Stacked packages: + - `Routes` constants + argument classes. + - App router `onGenerateRoute`. + - Navigation/Snackbar/Dialog wrappers not tied to Stacked. + +## Agent Setup +Use exactly these four agents and keep ownership boundaries strict. + +### Agent 1: Foundation + Compatibility Layer +- Owns: + - `pubspec.yaml` + - `lib/main.dart` + - `lib/app/**` (except feature-specific route targets) + - new `lib/core/providers/**` and `lib/core/navigation/**` +- Tasks: + - Add `flutter_riverpod`; remove Stacked-only dependencies when safe. + - Wrap app with `ProviderScope`. + - Introduce provider bridge for existing singleton services. + - Replace `@StackedApp`/generated locator-router path with local router + navigation wrappers. + - Keep route names and argument models compatible with existing call sites. +- Deliverables: + - App boots with no Stacked runtime dependency. + - Existing screens still reachable. + - No feature behavior changes. + +### Agent 2: Learn Domain Migration +- Owns: + - `lib/ui/views/learn/**` +- Tasks: + - Convert `BaseViewModel` classes to Riverpod notifiers/state objects. + - Replace `ViewModelBuilder` with `ConsumerWidget`/`ConsumerStatefulWidget`. + - Migrate busy/loading/error state to explicit async state. + - Prioritize complex files first: + - `challenge/challenge_viewmodel.dart` + - `widgets/scene/scene_viewmodel.dart` + - `landing/landing_viewmodel.dart` + - `daily_challenge/daily_challenge_viewmodel.dart` +- Deliverables: + - Learn feature no longer imports Stacked. + - No regression in challenge execution, progress display, and daily challenge navigation. + +### Agent 3: News + Podcast + Auth/Profile/Settings Migration +- Owns: + - `lib/ui/views/news/**` + - `lib/ui/views/podcast/**` + - `lib/ui/views/login/**` + - `lib/ui/views/profile/**` + - `lib/ui/views/settings/**` + - `lib/ui/widgets/drawer_widget/**` + - `lib/ui/widgets/setup_dialog_ui.dart` +- Tasks: + - Migrate remaining `BaseViewModel` and `ViewModelBuilder` usage to Riverpod. + - Replace `stacked_services` references with new navigation/dialog/snackbar abstractions. + - Update feature tests to use provider overrides instead of Stacked mock registration. +- Deliverables: + - Non-learn views no longer import Stacked. + - Navigation and dialogs still behave the same. + +### Agent 4: Quality Gate Agent (Required) +- Owns: + - CI checks, lint/test config, migration checklist doc updates. + - Test refactors in `test/**` and `integration_test/**` needed for Riverpod overrides. +- Tasks: + - Add/maintain migration checks: + - forbid Stacked imports in `lib/**` and `test/**`. + - enforce analyzer + tests per PR. + - Validate parity for core flows: + - login + - news feed pagination/open article + - podcast list/episode open + - learn challenge open/run/complete path + - Run final cleanup: + - remove Stacked generated files and stale comments (`@stacked-*` markers). +- Deliverables: + - Green `flutter analyze`, unit/widget tests, and selected integration tests. + - Final report: regressions found, fixed, and residual risk list. + +## Execution Order +1. Agent 1 lands the foundation PR first (ProviderScope + compatibility router/services). +2. Agent 2 and Agent 3 run in parallel on separate feature folders. +3. Agent 4 runs continuously on each branch and blocks merges on parity/lint/test failures. +4. Final sweep PR removes remaining Stacked deps and generated artifacts. + +## Agent Orchestration Rules +- You can launch multiple agents concurrently in one coordinator response, but apply dependency gating: + - Start Agent 1 first and wait for completion. + - After Agent 1 lands, start Agent 2 and Agent 3 in parallel. + - Keep Agent 4 active for quality checks throughout all phases. +- Do not allow Agent 2 or Agent 3 to modify foundation-owned files (`pubspec.yaml`, `lib/main.dart`, `lib/app/**`, `lib/core/**`) while Agent 1 work is pending. +- If Agent 4 reports failing quality gates, block merge and send fixes back to the owning agent. + +## Launch Runbook (for Claude Coordinator) +1. Launch Agent 1 only. +2. Wait for Agent 1 completion and ensure foundation checks pass: + - app boots + - routing works + - DI bridge compiles +3. Launch Agent 2 + Agent 3 concurrently. +4. Run Agent 4 continuously against each branch/PR. +5. Merge only when Agent 4 confirms all gates. + +## Small Branch Strategy (Per Feature) +Use a dedicated short-lived branch for each product feature area. + +### Branch Naming +- `feat/riverpod-feature-` +- Examples: + - `feat/riverpod-feature-learn` + - `feat/riverpod-feature-podcast` + - `feat/riverpod-feature-code-radio` + +### Feature Branch Backlog +1. `feat/riverpod-feature-learn`: `lib/ui/views/learn/**` +2. `feat/riverpod-feature-podcast`: `lib/ui/views/podcast/**` +3. `feat/riverpod-feature-news`: `lib/ui/views/news/**` +4. `feat/riverpod-feature-code-radio`: `lib/ui/views/code_radio/**` +5. `feat/riverpod-feature-login`: `lib/ui/views/login/**` +6. `feat/riverpod-feature-profile`: `lib/ui/views/profile/**` +7. `feat/riverpod-feature-settings`: `lib/ui/views/settings/**` +8. `feat/riverpod-feature-shared-ui`: `lib/ui/widgets/drawer_widget/**`, `lib/ui/widgets/setup_dialog_ui.dart` + +### Per-Feature Scope Rules +- Each feature branch may touch: + - feature views/viewmodels/widgets within its owned folders + - feature tests (`test/widget/**`, `integration_test/**`) tied to that feature + - minimal shared plumbing required to compile (with note in PR description) +- Each feature branch must not: + - refactor other feature folders + - include unrelated formatting churn + - change app foundation files owned by Agent 1 unless explicitly coordinated + +### Recommended Parallel Layout +- Run `learn` on its own branch (largest scope). +- Run `podcast`, `news`, and `code-radio` in parallel. +- Run `login`, `profile`, and `settings` in parallel once navigation compatibility is stable. +- Keep `shared-ui` as a separate branch to minimize merge conflicts. + +## Small Branch Strategy (Per Service) +Use short-lived branches with one service or one tightly-related service group per branch. + +### Branch Naming +- `feat/riverpod-svc-` +- Examples: + - `feat/riverpod-svc-authentication` + - `feat/riverpod-svc-news-api` + - `feat/riverpod-svc-learn-offline` + +### Service Branch Backlog +1. `feat/riverpod-svc-dio`: `lib/service/dio_service.dart` +2. `feat/riverpod-svc-locale`: `lib/service/locale_service.dart` +3. `feat/riverpod-svc-developer`: `lib/service/developer_service.dart` +4. `feat/riverpod-svc-authentication`: `lib/service/authentication/authentication_service.dart` +5. `feat/riverpod-svc-analytics`: `lib/service/firebase/analytics_service.dart` +6. `feat/riverpod-svc-remote-config`: `lib/service/firebase/remote_config_service.dart` +7. `feat/riverpod-svc-news-api`: `lib/service/news/api_service.dart` +8. `feat/riverpod-svc-news-bookmark`: `lib/service/news/bookmark_service.dart` +9. `feat/riverpod-svc-podcast-notification`: `lib/service/podcast/notification_service.dart` +10. `feat/riverpod-svc-podcast-database`: `lib/service/podcast/podcasts_service.dart` +11. `feat/riverpod-svc-podcast-download`: `lib/service/podcast/download_service.dart` +12. `feat/riverpod-svc-quick-actions`: `lib/service/navigation/quick_actions_service.dart` +13. `feat/riverpod-svc-audio`: `lib/service/audio/audio_service.dart` +14. `feat/riverpod-svc-learn-file`: `lib/service/learn/learn_file_service.dart` +15. `feat/riverpod-svc-learn-offline`: `lib/service/learn/learn_offline_service.dart` +16. `feat/riverpod-svc-learn-main`: `lib/service/learn/learn_service.dart` +17. `feat/riverpod-svc-daily-challenge`: `lib/service/learn/daily_challenge_service.dart` +18. `feat/riverpod-svc-daily-challenge-notification`: `lib/service/learn/daily_challenge_notification_service.dart` +19. `feat/riverpod-svc-scene-assets`: `lib/service/learn/scene_assets_service.dart` + +### Per-Branch Scope Rules +- Each service branch may touch: + - the service file itself + - provider wiring (`lib/core/providers/**`) + - the minimal consumer call sites needed to compile + - tests directly related to that service +- Each service branch must not: + - refactor unrelated UI state + - include broad formatting-only churn + - modify route tables unless required by that service + +### Per-Branch Done Criteria +- `flutter analyze` passes. +- relevant unit/widget tests pass. +- no new `stacked` imports are introduced. +- provider override path exists for tests using that service. + +## Merge Gates (must pass before merge) +- `flutter pub get` succeeds without dependency conflicts. +- `flutter analyze` passes. +- `flutter test` passes. +- No Stacked usage in app/test code: + - `rg -n "package:stacked|stacked_services|ViewModelBuilder|BaseViewModel|@StackedApp|StackedService" lib test` returns no hits. +- Manual smoke checks for login, news, podcast, and learn flows. + +## Claude Coordinator Prompt (copy/paste) +```text +You are coordinating a 4-agent migration in this Flutter repo from Stacked to Riverpod. + +Create and manage exactly 4 agents with these roles: +1) Foundation + compatibility layer (app bootstrap, routing, DI bridge) +2) Learn feature migration +3) News/Podcast/Auth/Profile/Settings migration +4) Quality gate agent (tests, lint, parity checks, final validation) + +Rules: +- Keep behavior unchanged. +- Keep agents inside their owned folders to avoid merge conflicts. +- Agent 1 merges first; Agent 2/3 then work in parallel; Agent 4 validates all branches. +- Prefer incremental PRs with runnable app after each PR. +- Do not leave any `stacked`/`stacked_services` imports in `lib` or `test`. + +Completion criteria: +- Riverpod is used for state in migrated features. +- `stacked`, `stacked_services`, and `stacked_generator` removed from dependencies. +- All checks pass: analyze, tests, smoke flows. +- Provide a final migration report with changed files, risk notes, and rollback points. +``` + +## Optional Parallel Kickoff Prompt (after Agent 1 lands) +```text +Agent 1 is complete and merged. Start the remaining migration phase now: + +- Run Agent 2 (Learn domain migration) and Agent 3 (News/Podcast/Auth/Profile/Settings migration) in parallel. +- Run Agent 4 (Quality gate) continuously while Agent 2/3 are active. +- Block merges on failing analyze/test/parity checks. +- Keep folder ownership strict to avoid conflicts. +``` diff --git a/mobile-app/lib/app/app.dart b/mobile-app/lib/app/app.dart index e48ccd570..5c5d0d1db 100644 --- a/mobile-app/lib/app/app.dart +++ b/mobile-app/lib/app/app.dart @@ -1,93 +1,10 @@ -import 'package:freecodecamp/service/audio/audio_service.dart'; -import 'package:freecodecamp/service/authentication/authentication_service.dart'; -import 'package:freecodecamp/service/developer_service.dart'; -import 'package:freecodecamp/service/firebase/analytics_service.dart'; -import 'package:freecodecamp/service/firebase/remote_config_service.dart'; -import 'package:freecodecamp/service/learn/learn_file_service.dart'; -import 'package:freecodecamp/service/learn/learn_offline_service.dart'; -import 'package:freecodecamp/service/learn/learn_service.dart'; -import 'package:freecodecamp/service/learn/daily_challenge_service.dart'; -import 'package:freecodecamp/service/learn/daily_challenge_notification_service.dart'; -import 'package:freecodecamp/service/locale_service.dart'; -import 'package:freecodecamp/service/navigation/quick_actions_service.dart'; -import 'package:freecodecamp/service/news/bookmark_service.dart'; -import 'package:freecodecamp/service/podcast/download_service.dart'; -import 'package:freecodecamp/service/podcast/notification_service.dart'; -import 'package:freecodecamp/service/podcast/podcasts_service.dart'; -import 'package:freecodecamp/service/dio_service.dart'; -import 'package:freecodecamp/service/news/api_service.dart'; - -import 'package:freecodecamp/ui/views/code_radio/code_radio_view.dart'; -import 'package:freecodecamp/ui/views/learn/challenge/templates/template_view.dart'; -import 'package:freecodecamp/ui/views/learn/landing/landing_view.dart'; -import 'package:freecodecamp/ui/views/learn/superblock/superblock_view.dart'; -import 'package:freecodecamp/ui/views/learn/chapter/chapter_view.dart'; -import 'package:freecodecamp/ui/views/learn/chapter/chapter_block_view.dart'; -import 'package:freecodecamp/ui/views/learn/daily_challenge/daily_challenge_view.dart'; -import 'package:freecodecamp/ui/views/login/native_login_view.dart'; -import 'package:freecodecamp/ui/views/news/news-author/news_author_view.dart'; -import 'package:freecodecamp/ui/views/news/news-bookmark/news_bookmark_view.dart'; -import 'package:freecodecamp/ui/views/news/news-feed/news_feed_view.dart'; -import 'package:freecodecamp/ui/views/news/news-image-viewer/news_image_view.dart'; -import 'package:freecodecamp/ui/views/news/news-tutorial/news_tutorial_view.dart'; -import 'package:freecodecamp/ui/views/news/news-view-handler/news_view_handler_view.dart'; -import 'package:freecodecamp/ui/views/podcast/episode/episode_view.dart'; -import 'package:freecodecamp/ui/views/podcast/podcast-list/podcast_list_view.dart'; -import 'package:freecodecamp/ui/views/profile/profile_view.dart'; -import 'package:freecodecamp/ui/views/settings/delete-account/delete_account_view.dart'; -import 'package:freecodecamp/ui/views/settings/settings_view.dart'; - -import 'package:stacked/stacked_annotations.dart'; -import 'package:stacked_services/stacked_services.dart'; - -// Run 'flutter pub run build_runner build --delete-conflicting-outputs' after any changes in this file to generate updated files -@StackedApp( - routes: [ - MaterialRoute(page: NewsViewHandlerView), - MaterialRoute(page: PodcastListView), - MaterialRoute(page: EpisodeView), - MaterialRoute(page: NewsTutorialView), - MaterialRoute(page: NewsBookmarkTutorialView), - MaterialRoute(page: NewsFeedView), - MaterialRoute(page: NewsAuthorView), - MaterialRoute(page: NewsImageView), - MaterialRoute(page: CodeRadioView), - MaterialRoute(page: ChallengeTemplateView), - MaterialRoute(page: ChapterView), - MaterialRoute(page: ChapterBlockView), - MaterialRoute(page: ProfileView), - MaterialRoute(page: LearnLandingView, initial: true), - MaterialRoute(page: NativeLoginView), - MaterialRoute(page: SuperBlockView), - MaterialRoute(page: SettingsView), - MaterialRoute(page: DeleteAccountView), - MaterialRoute(page: DailyChallengeView), - ], - dependencies: [ - LazySingleton(classType: NavigationService), - LazySingleton(classType: DialogService), - LazySingleton(classType: SnackbarService), - LazySingleton(classType: PodcastsDatabaseService), - LazySingleton(classType: NotificationService), - LazySingleton(classType: DailyChallengeNotificationService), - LazySingleton(classType: DeveloperService), - LazySingleton(classType: AuthenticationService), - LazySingleton(classType: AppAudioService), - LazySingleton(classType: DailyChallengeService), - LazySingleton(classType: DownloadService), - LazySingleton(classType: LearnService), - LazySingleton(classType: LearnFileService), - LazySingleton(classType: LearnOfflineService), - LazySingleton(classType: QuickActionsService), - LazySingleton(classType: AnalyticsService), - LazySingleton(classType: RemoteConfigService), - LazySingleton(classType: BookmarksDatabaseService), - LazySingleton(classType: LocaleService), - LazySingleton(classType: DioService), - LazySingleton(classType: NewsApiService), - ], - logger: StackedLogger(), -) +/// Legacy placeholder. +/// +/// This project previously used annotation-based code generation in this file. +/// Routing and dependency registration are now maintained in: +/// - `app.router.dart` (route names + argument objects) +/// - `app_router.dart` (MaterialApp.onGenerateRoute) +/// - `app.locator.dart` (GetIt registrations) class AppSetup { - //Serves no purpose besides having an annotation attached to it + const AppSetup._(); } diff --git a/mobile-app/lib/app/app.locator.dart b/mobile-app/lib/app/app.locator.dart index 203878340..e31699de2 100644 --- a/mobile-app/lib/app/app.locator.dart +++ b/mobile-app/lib/app/app.locator.dart @@ -1,15 +1,4 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// StackedLocatorGenerator -// ************************************************************************** - -// ignore_for_file: public_member_api_docs, implementation_imports, depend_on_referenced_packages - -import 'package:stacked_services/src/dialog/dialog_service.dart'; -import 'package:stacked_services/src/navigation/navigation_service.dart'; -import 'package:stacked_services/src/snackbar/snackbar_service.dart'; -import 'package:stacked_shared/stacked_shared.dart'; +import 'package:get_it/get_it.dart'; import '../service/audio/audio_service.dart'; import '../service/authentication/authentication_service.dart'; @@ -30,36 +19,39 @@ import '../service/podcast/download_service.dart'; import '../service/podcast/notification_service.dart'; import '../service/podcast/podcasts_service.dart'; -final locator = StackedLocator.instance; +final locator = GetIt.instance; -Future setupLocator({ - String? environment, - EnvironmentFilter? environmentFilter, -}) async { -// Register environments - locator.registerEnvironment( - environment: environment, environmentFilter: environmentFilter); +Future setupLocator() async { + _registerLazySingleton( + () => PodcastsDatabaseService(), + ); + _registerLazySingleton(() => NotificationService()); + _registerLazySingleton( + () => DailyChallengeNotificationService(), + ); + _registerLazySingleton(() => DeveloperService()); + _registerLazySingleton(() => AuthenticationService()); + _registerLazySingleton(() => AppAudioService()); + _registerLazySingleton(() => DailyChallengeService()); + _registerLazySingleton(() => DownloadService()); + _registerLazySingleton(() => LearnService()); + _registerLazySingleton(() => LearnFileService()); + _registerLazySingleton(() => LearnOfflineService()); + _registerLazySingleton(() => QuickActionsService()); + _registerLazySingleton(() => AnalyticsService()); + _registerLazySingleton(() => RemoteConfigService()); + _registerLazySingleton( + () => BookmarksDatabaseService(), + ); + _registerLazySingleton(() => LocaleService()); + _registerLazySingleton(() => DioService()); + _registerLazySingleton(() => NewsApiService()); +} -// Register dependencies - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => SnackbarService()); - locator.registerLazySingleton(() => PodcastsDatabaseService()); - locator.registerLazySingleton(() => NotificationService()); - locator.registerLazySingleton(() => DailyChallengeNotificationService()); - locator.registerLazySingleton(() => DeveloperService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => AppAudioService()); - locator.registerLazySingleton(() => DailyChallengeService()); - locator.registerLazySingleton(() => DownloadService()); - locator.registerLazySingleton(() => LearnService()); - locator.registerLazySingleton(() => LearnFileService()); - locator.registerLazySingleton(() => LearnOfflineService()); - locator.registerLazySingleton(() => QuickActionsService()); - locator.registerLazySingleton(() => AnalyticsService()); - locator.registerLazySingleton(() => RemoteConfigService()); - locator.registerLazySingleton(() => BookmarksDatabaseService()); - locator.registerLazySingleton(() => LocaleService()); - locator.registerLazySingleton(() => DioService()); - locator.registerLazySingleton(() => NewsApiService()); +void _registerLazySingleton( + T Function() factoryFunction, +) { + if (!locator.isRegistered()) { + locator.registerLazySingleton(factoryFunction); + } } diff --git a/mobile-app/lib/app/app.router.dart b/mobile-app/lib/app/app.router.dart index b02317648..8e545ca51 100644 --- a/mobile-app/lib/app/app.router.dart +++ b/mobile-app/lib/app/app.router.dart @@ -1,88 +1,28 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -// ************************************************************************** -// StackedNavigatorGenerator -// ************************************************************************** - -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'package:flutter/material.dart' as _i21; -import 'package:flutter/material.dart'; -import 'package:freecodecamp/models/learn/curriculum_model.dart' as _i25; -import 'package:freecodecamp/models/news/bookmarked_tutorial_model.dart' - as _i24; -import 'package:freecodecamp/models/podcasts/episodes_model.dart' as _i22; -import 'package:freecodecamp/models/podcasts/podcasts_model.dart' as _i23; -import 'package:freecodecamp/ui/views/code_radio/code_radio_view.dart' as _i10; -import 'package:freecodecamp/ui/views/learn/challenge/templates/template_view.dart' - as _i11; -import 'package:freecodecamp/ui/views/learn/chapter/chapter_block_view.dart' - as _i13; -import 'package:freecodecamp/ui/views/learn/chapter/chapter_view.dart' as _i12; -import 'package:freecodecamp/ui/views/learn/daily_challenge/daily_challenge_view.dart' - as _i20; -import 'package:freecodecamp/ui/views/learn/landing/landing_view.dart' as _i15; -import 'package:freecodecamp/ui/views/learn/superblock/superblock_view.dart' - as _i17; -import 'package:freecodecamp/ui/views/login/native_login_view.dart' as _i16; -import 'package:freecodecamp/ui/views/news/news-author/news_author_view.dart' - as _i8; -import 'package:freecodecamp/ui/views/news/news-bookmark/news_bookmark_view.dart' - as _i6; -import 'package:freecodecamp/ui/views/news/news-feed/news_feed_view.dart' - as _i7; -import 'package:freecodecamp/ui/views/news/news-image-viewer/news_image_view.dart' - as _i9; -import 'package:freecodecamp/ui/views/news/news-tutorial/news_tutorial_view.dart' - as _i5; -import 'package:freecodecamp/ui/views/news/news-view-handler/news_view_handler_view.dart' - as _i2; -import 'package:freecodecamp/ui/views/podcast/episode/episode_view.dart' as _i4; -import 'package:freecodecamp/ui/views/podcast/podcast-list/podcast_list_view.dart' - as _i3; -import 'package:freecodecamp/ui/views/profile/profile_view.dart' as _i14; -import 'package:freecodecamp/ui/views/settings/delete-account/delete_account_view.dart' - as _i19; -import 'package:freecodecamp/ui/views/settings/settings_view.dart' as _i18; -import 'package:stacked/stacked.dart' as _i1; -import 'package:stacked_services/stacked_services.dart' as _i26; +import 'package:flutter/widgets.dart'; +import 'package:freecodecamp/models/learn/curriculum_model.dart'; +import 'package:freecodecamp/models/news/bookmarked_tutorial_model.dart'; +import 'package:freecodecamp/models/podcasts/episodes_model.dart'; +import 'package:freecodecamp/models/podcasts/podcasts_model.dart'; class Routes { static const newsViewHandlerView = '/news-view-handler-view'; - static const podcastListView = '/podcast-list-view'; - static const episodeView = '/episode-view'; - static const newsTutorialView = '/news-tutorial-view'; - static const newsBookmarkTutorialView = '/news-bookmark-tutorial-view'; - static const newsFeedView = '/news-feed-view'; - static const newsAuthorView = '/news-author-view'; - static const newsImageView = '/news-image-view'; - static const codeRadioView = '/code-radio-view'; - static const challengeTemplateView = '/challenge-template-view'; - static const chapterView = '/chapter-view'; - static const chapterBlockView = '/chapter-block-view'; - static const profileView = '/profile-view'; - static const learnLandingView = '/'; - static const nativeLoginView = '/native-login-view'; - static const superBlockView = '/super-block-view'; - static const settingsView = '/settings-view'; - static const deleteAccountView = '/delete-account-view'; - static const dailyChallengeView = '/daily-challenge-view'; static const all = { @@ -108,252 +48,6 @@ class Routes { }; } -class StackedRouter extends _i1.RouterBase { - final _routes = <_i1.RouteDef>[ - _i1.RouteDef( - Routes.newsViewHandlerView, - page: _i2.NewsViewHandlerView, - ), - _i1.RouteDef( - Routes.podcastListView, - page: _i3.PodcastListView, - ), - _i1.RouteDef( - Routes.episodeView, - page: _i4.EpisodeView, - ), - _i1.RouteDef( - Routes.newsTutorialView, - page: _i5.NewsTutorialView, - ), - _i1.RouteDef( - Routes.newsBookmarkTutorialView, - page: _i6.NewsBookmarkTutorialView, - ), - _i1.RouteDef( - Routes.newsFeedView, - page: _i7.NewsFeedView, - ), - _i1.RouteDef( - Routes.newsAuthorView, - page: _i8.NewsAuthorView, - ), - _i1.RouteDef( - Routes.newsImageView, - page: _i9.NewsImageView, - ), - _i1.RouteDef( - Routes.codeRadioView, - page: _i10.CodeRadioView, - ), - _i1.RouteDef( - Routes.challengeTemplateView, - page: _i11.ChallengeTemplateView, - ), - _i1.RouteDef( - Routes.chapterView, - page: _i12.ChapterView, - ), - _i1.RouteDef( - Routes.chapterBlockView, - page: _i13.ChapterBlockView, - ), - _i1.RouteDef( - Routes.profileView, - page: _i14.ProfileView, - ), - _i1.RouteDef( - Routes.learnLandingView, - page: _i15.LearnLandingView, - ), - _i1.RouteDef( - Routes.nativeLoginView, - page: _i16.NativeLoginView, - ), - _i1.RouteDef( - Routes.superBlockView, - page: _i17.SuperBlockView, - ), - _i1.RouteDef( - Routes.settingsView, - page: _i18.SettingsView, - ), - _i1.RouteDef( - Routes.deleteAccountView, - page: _i19.DeleteAccountView, - ), - _i1.RouteDef( - Routes.dailyChallengeView, - page: _i20.DailyChallengeView, - ), - ]; - - final _pagesMap = { - _i2.NewsViewHandlerView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i2.NewsViewHandlerView(), - settings: data, - ); - }, - _i3.PodcastListView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i3.PodcastListView(), - settings: data, - ); - }, - _i4.EpisodeView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i4.EpisodeView( - key: args.key, episode: args.episode, podcast: args.podcast), - settings: data, - ); - }, - _i5.NewsTutorialView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i5.NewsTutorialView( - key: args.key, refId: args.refId, slug: args.slug), - settings: data, - ); - }, - _i6.NewsBookmarkTutorialView: (data) { - final args = - data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i6.NewsBookmarkTutorialView( - key: args.key, tutorial: args.tutorial), - settings: data, - ); - }, - _i7.NewsFeedView: (data) { - final args = data.getArgs( - orElse: () => const NewsFeedViewArguments(), - ); - return _i21.MaterialPageRoute( - builder: (context) => _i7.NewsFeedView( - key: args.key, - tagSlug: args.tagSlug, - authorId: args.authorId, - fromAuthor: args.fromAuthor, - fromTag: args.fromTag, - fromSearch: args.fromSearch, - tutorials: args.tutorials, - subject: args.subject), - settings: data, - ); - }, - _i8.NewsAuthorView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => - _i8.NewsAuthorView(key: args.key, authorSlug: args.authorSlug), - settings: data, - ); - }, - _i9.NewsImageView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i9.NewsImageView( - key: args.key, imgUrl: args.imgUrl, isDataUrl: args.isDataUrl), - settings: data, - ); - }, - _i10.CodeRadioView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i10.CodeRadioView(), - settings: data, - ); - }, - _i11.ChallengeTemplateView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i11.ChallengeTemplateView( - key: args.key, - block: args.block, - challengeId: args.challengeId, - challengeDate: args.challengeDate), - settings: data, - ); - }, - _i12.ChapterView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i12.ChapterView( - key: args.key, - superBlockDashedName: args.superBlockDashedName, - superBlockName: args.superBlockName), - settings: data, - ); - }, - _i13.ChapterBlockView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i13.ChapterBlockView( - key: args.key, moduleName: args.moduleName, blocks: args.blocks), - settings: data, - ); - }, - _i14.ProfileView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i14.ProfileView(), - settings: data, - ); - }, - _i15.LearnLandingView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i15.LearnLandingView(), - settings: data, - ); - }, - _i16.NativeLoginView: (data) { - final args = data.getArgs( - orElse: () => const NativeLoginViewArguments(), - ); - return _i21.MaterialPageRoute( - builder: (context) => - _i16.NativeLoginView(key: args.key, fromButton: args.fromButton), - settings: data, - ); - }, - _i17.SuperBlockView: (data) { - final args = data.getArgs(nullOk: false); - return _i21.MaterialPageRoute( - builder: (context) => _i17.SuperBlockView( - key: args.key, - superBlockDashedName: args.superBlockDashedName, - superBlockName: args.superBlockName, - hasInternet: args.hasInternet), - settings: data, - ); - }, - _i18.SettingsView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i18.SettingsView(), - settings: data, - ); - }, - _i19.DeleteAccountView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i19.DeleteAccountView(), - settings: data, - ); - }, - _i20.DailyChallengeView: (data) { - return _i21.MaterialPageRoute( - builder: (context) => const _i20.DailyChallengeView(), - settings: data, - ); - }, - }; - - @override - List<_i1.RouteDef> get routes => _routes; - - @override - Map get pagesMap => _pagesMap; -} - class EpisodeViewArguments { const EpisodeViewArguments({ this.key, @@ -361,29 +55,9 @@ class EpisodeViewArguments { required this.podcast, }); - final _i21.Key? key; - - final _i22.Episodes episode; - - final _i23.Podcasts podcast; - - @override - String toString() { - return '{"key": "$key", "episode": "$episode", "podcast": "$podcast"}'; - } - - @override - bool operator ==(covariant EpisodeViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.episode == episode && - other.podcast == podcast; - } - - @override - int get hashCode { - return key.hashCode ^ episode.hashCode ^ podcast.hashCode; - } + final Key? key; + final Episodes episode; + final Podcasts podcast; } class NewsTutorialViewArguments { @@ -393,27 +67,9 @@ class NewsTutorialViewArguments { required this.slug, }); - final _i21.Key? key; - + final Key? key; final String refId; - final String slug; - - @override - String toString() { - return '{"key": "$key", "refId": "$refId", "slug": "$slug"}'; - } - - @override - bool operator ==(covariant NewsTutorialViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && other.refId == refId && other.slug == slug; - } - - @override - int get hashCode { - return key.hashCode ^ refId.hashCode ^ slug.hashCode; - } } class NewsBookmarkTutorialViewArguments { @@ -422,25 +78,8 @@ class NewsBookmarkTutorialViewArguments { required this.tutorial, }); - final _i21.Key? key; - - final _i24.BookmarkedTutorial tutorial; - - @override - String toString() { - return '{"key": "$key", "tutorial": "$tutorial"}'; - } - - @override - bool operator ==(covariant NewsBookmarkTutorialViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && other.tutorial == tutorial; - } - - @override - int get hashCode { - return key.hashCode ^ tutorial.hashCode; - } + final Key? key; + final BookmarkedTutorial tutorial; } class NewsFeedViewArguments { @@ -455,51 +94,14 @@ class NewsFeedViewArguments { this.subject = '', }); - final _i21.Key? key; - + final Key? key; final String tagSlug; - final String authorId; - final bool fromAuthor; - final bool fromTag; - final bool fromSearch; - final List tutorials; - final String subject; - - @override - String toString() { - return '{"key": "$key", "tagSlug": "$tagSlug", "authorId": "$authorId", "fromAuthor": "$fromAuthor", "fromTag": "$fromTag", "fromSearch": "$fromSearch", "tutorials": "$tutorials", "subject": "$subject"}'; - } - - @override - bool operator ==(covariant NewsFeedViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.tagSlug == tagSlug && - other.authorId == authorId && - other.fromAuthor == fromAuthor && - other.fromTag == fromTag && - other.fromSearch == fromSearch && - other.tutorials == tutorials && - other.subject == subject; - } - - @override - int get hashCode { - return key.hashCode ^ - tagSlug.hashCode ^ - authorId.hashCode ^ - fromAuthor.hashCode ^ - fromTag.hashCode ^ - fromSearch.hashCode ^ - tutorials.hashCode ^ - subject.hashCode; - } } class NewsAuthorViewArguments { @@ -508,25 +110,8 @@ class NewsAuthorViewArguments { required this.authorSlug, }); - final _i21.Key? key; - + final Key? key; final String authorSlug; - - @override - String toString() { - return '{"key": "$key", "authorSlug": "$authorSlug"}'; - } - - @override - bool operator ==(covariant NewsAuthorViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && other.authorSlug == authorSlug; - } - - @override - int get hashCode { - return key.hashCode ^ authorSlug.hashCode; - } } class NewsImageViewArguments { @@ -536,29 +121,9 @@ class NewsImageViewArguments { required this.isDataUrl, }); - final _i21.Key? key; - + final Key? key; final String imgUrl; - final bool isDataUrl; - - @override - String toString() { - return '{"key": "$key", "imgUrl": "$imgUrl", "isDataUrl": "$isDataUrl"}'; - } - - @override - bool operator ==(covariant NewsImageViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.imgUrl == imgUrl && - other.isDataUrl == isDataUrl; - } - - @override - int get hashCode { - return key.hashCode ^ imgUrl.hashCode ^ isDataUrl.hashCode; - } } class ChallengeTemplateViewArguments { @@ -569,35 +134,10 @@ class ChallengeTemplateViewArguments { this.challengeDate, }); - final _i21.Key? key; - - final _i25.Block block; - + final Key? key; + final Block block; final String challengeId; - final DateTime? challengeDate; - - @override - String toString() { - return '{"key": "$key", "block": "$block", "challengeId": "$challengeId", "challengeDate": "$challengeDate"}'; - } - - @override - bool operator ==(covariant ChallengeTemplateViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.block == block && - other.challengeId == challengeId && - other.challengeDate == challengeDate; - } - - @override - int get hashCode { - return key.hashCode ^ - block.hashCode ^ - challengeId.hashCode ^ - challengeDate.hashCode; - } } class ChapterViewArguments { @@ -607,31 +147,9 @@ class ChapterViewArguments { required this.superBlockName, }); - final _i21.Key? key; - + final Key? key; final String superBlockDashedName; - final String superBlockName; - - @override - String toString() { - return '{"key": "$key", "superBlockDashedName": "$superBlockDashedName", "superBlockName": "$superBlockName"}'; - } - - @override - bool operator ==(covariant ChapterViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.superBlockDashedName == superBlockDashedName && - other.superBlockName == superBlockName; - } - - @override - int get hashCode { - return key.hashCode ^ - superBlockDashedName.hashCode ^ - superBlockName.hashCode; - } } class ChapterBlockViewArguments { @@ -641,29 +159,9 @@ class ChapterBlockViewArguments { required this.blocks, }); - final _i21.Key? key; - + final Key? key; final String moduleName; - - final List<_i25.Block> blocks; - - @override - String toString() { - return '{"key": "$key", "moduleName": "$moduleName", "blocks": "$blocks"}'; - } - - @override - bool operator ==(covariant ChapterBlockViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.moduleName == moduleName && - other.blocks == blocks; - } - - @override - int get hashCode { - return key.hashCode ^ moduleName.hashCode ^ blocks.hashCode; - } + final List blocks; } class NativeLoginViewArguments { @@ -672,25 +170,8 @@ class NativeLoginViewArguments { this.fromButton = false, }); - final _i21.Key? key; - + final Key? key; final bool fromButton; - - @override - String toString() { - return '{"key": "$key", "fromButton": "$fromButton"}'; - } - - @override - bool operator ==(covariant NativeLoginViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && other.fromButton == fromButton; - } - - @override - int get hashCode { - return key.hashCode ^ fromButton.hashCode; - } } class SuperBlockViewArguments { @@ -701,711 +182,8 @@ class SuperBlockViewArguments { required this.hasInternet, }); - final _i21.Key? key; - + final Key? key; final String superBlockDashedName; - final String superBlockName; - final bool hasInternet; - - @override - String toString() { - return '{"key": "$key", "superBlockDashedName": "$superBlockDashedName", "superBlockName": "$superBlockName", "hasInternet": "$hasInternet"}'; - } - - @override - bool operator ==(covariant SuperBlockViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && - other.superBlockDashedName == superBlockDashedName && - other.superBlockName == superBlockName && - other.hasInternet == hasInternet; - } - - @override - int get hashCode { - return key.hashCode ^ - superBlockDashedName.hashCode ^ - superBlockName.hashCode ^ - hasInternet.hashCode; - } -} - -extension NavigatorStateExtension on _i26.NavigationService { - Future navigateToNewsViewHandlerView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.newsViewHandlerView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToPodcastListView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.podcastListView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToEpisodeView({ - _i21.Key? key, - required _i22.Episodes episode, - required _i23.Podcasts podcast, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.episodeView, - arguments: - EpisodeViewArguments(key: key, episode: episode, podcast: podcast), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNewsTutorialView({ - _i21.Key? key, - required String refId, - required String slug, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.newsTutorialView, - arguments: - NewsTutorialViewArguments(key: key, refId: refId, slug: slug), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNewsBookmarkTutorialView({ - _i21.Key? key, - required _i24.BookmarkedTutorial tutorial, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.newsBookmarkTutorialView, - arguments: - NewsBookmarkTutorialViewArguments(key: key, tutorial: tutorial), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNewsFeedView({ - _i21.Key? key, - String tagSlug = '', - String authorId = '', - bool fromAuthor = false, - bool fromTag = false, - bool fromSearch = false, - List tutorials = const [], - String subject = '', - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.newsFeedView, - arguments: NewsFeedViewArguments( - key: key, - tagSlug: tagSlug, - authorId: authorId, - fromAuthor: fromAuthor, - fromTag: fromTag, - fromSearch: fromSearch, - tutorials: tutorials, - subject: subject), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNewsAuthorView({ - _i21.Key? key, - required String authorSlug, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.newsAuthorView, - arguments: NewsAuthorViewArguments(key: key, authorSlug: authorSlug), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNewsImageView({ - _i21.Key? key, - required String imgUrl, - required bool isDataUrl, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.newsImageView, - arguments: NewsImageViewArguments( - key: key, imgUrl: imgUrl, isDataUrl: isDataUrl), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToCodeRadioView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.codeRadioView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToChallengeTemplateView({ - _i21.Key? key, - required _i25.Block block, - required String challengeId, - DateTime? challengeDate, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.challengeTemplateView, - arguments: ChallengeTemplateViewArguments( - key: key, - block: block, - challengeId: challengeId, - challengeDate: challengeDate), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToChapterView({ - _i21.Key? key, - required String superBlockDashedName, - required String superBlockName, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.chapterView, - arguments: ChapterViewArguments( - key: key, - superBlockDashedName: superBlockDashedName, - superBlockName: superBlockName), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToChapterBlockView({ - _i21.Key? key, - required String moduleName, - required List<_i25.Block> blocks, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.chapterBlockView, - arguments: ChapterBlockViewArguments( - key: key, moduleName: moduleName, blocks: blocks), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToProfileView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.profileView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToLearnLandingView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.learnLandingView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToNativeLoginView({ - _i21.Key? key, - bool fromButton = false, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.nativeLoginView, - arguments: NativeLoginViewArguments(key: key, fromButton: fromButton), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToSuperBlockView({ - _i21.Key? key, - required String superBlockDashedName, - required String superBlockName, - required bool hasInternet, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.superBlockView, - arguments: SuperBlockViewArguments( - key: key, - superBlockDashedName: superBlockDashedName, - superBlockName: superBlockName, - hasInternet: hasInternet), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToSettingsView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.settingsView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToDeleteAccountView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.deleteAccountView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future navigateToDailyChallengeView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return navigateTo(Routes.dailyChallengeView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsViewHandlerView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.newsViewHandlerView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithPodcastListView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.podcastListView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithEpisodeView({ - _i21.Key? key, - required _i22.Episodes episode, - required _i23.Podcasts podcast, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.episodeView, - arguments: - EpisodeViewArguments(key: key, episode: episode, podcast: podcast), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsTutorialView({ - _i21.Key? key, - required String refId, - required String slug, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.newsTutorialView, - arguments: - NewsTutorialViewArguments(key: key, refId: refId, slug: slug), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsBookmarkTutorialView({ - _i21.Key? key, - required _i24.BookmarkedTutorial tutorial, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.newsBookmarkTutorialView, - arguments: - NewsBookmarkTutorialViewArguments(key: key, tutorial: tutorial), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsFeedView({ - _i21.Key? key, - String tagSlug = '', - String authorId = '', - bool fromAuthor = false, - bool fromTag = false, - bool fromSearch = false, - List tutorials = const [], - String subject = '', - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.newsFeedView, - arguments: NewsFeedViewArguments( - key: key, - tagSlug: tagSlug, - authorId: authorId, - fromAuthor: fromAuthor, - fromTag: fromTag, - fromSearch: fromSearch, - tutorials: tutorials, - subject: subject), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsAuthorView({ - _i21.Key? key, - required String authorSlug, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.newsAuthorView, - arguments: NewsAuthorViewArguments(key: key, authorSlug: authorSlug), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNewsImageView({ - _i21.Key? key, - required String imgUrl, - required bool isDataUrl, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.newsImageView, - arguments: NewsImageViewArguments( - key: key, imgUrl: imgUrl, isDataUrl: isDataUrl), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithCodeRadioView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.codeRadioView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithChallengeTemplateView({ - _i21.Key? key, - required _i25.Block block, - required String challengeId, - DateTime? challengeDate, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.challengeTemplateView, - arguments: ChallengeTemplateViewArguments( - key: key, - block: block, - challengeId: challengeId, - challengeDate: challengeDate), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithChapterView({ - _i21.Key? key, - required String superBlockDashedName, - required String superBlockName, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.chapterView, - arguments: ChapterViewArguments( - key: key, - superBlockDashedName: superBlockDashedName, - superBlockName: superBlockName), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithChapterBlockView({ - _i21.Key? key, - required String moduleName, - required List<_i25.Block> blocks, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.chapterBlockView, - arguments: ChapterBlockViewArguments( - key: key, moduleName: moduleName, blocks: blocks), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithProfileView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.profileView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithLearnLandingView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.learnLandingView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithNativeLoginView({ - _i21.Key? key, - bool fromButton = false, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.nativeLoginView, - arguments: NativeLoginViewArguments(key: key, fromButton: fromButton), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithSuperBlockView({ - _i21.Key? key, - required String superBlockDashedName, - required String superBlockName, - required bool hasInternet, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.superBlockView, - arguments: SuperBlockViewArguments( - key: key, - superBlockDashedName: superBlockDashedName, - superBlockName: superBlockName, - hasInternet: hasInternet), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithSettingsView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.settingsView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithDeleteAccountView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.deleteAccountView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - - Future replaceWithDailyChallengeView([ - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - ]) async { - return replaceWith(Routes.dailyChallengeView, - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } } diff --git a/mobile-app/lib/app/app_router.dart b/mobile-app/lib/app/app_router.dart new file mode 100644 index 000000000..e7012da26 --- /dev/null +++ b/mobile-app/lib/app/app_router.dart @@ -0,0 +1,236 @@ +// Standalone router — NOT generated by Stacked. +// +// Keeps all route names and argument classes identical to what the Stacked +// generator produced in app.router.dart so that existing call sites +// (NavigationService.navigateTo, NavigationService.replaceWith, etc.) continue +// to work without any changes. +// +// When a view is fully migrated off Stacked ViewModels the route entry here +// can be updated independently without touching the generated file. + +import 'package:flutter/material.dart'; +import 'package:freecodecamp/app/app.router.dart' + show + Routes, + EpisodeViewArguments, + NewsTutorialViewArguments, + NewsBookmarkTutorialViewArguments, + NewsFeedViewArguments, + NewsAuthorViewArguments, + NewsImageViewArguments, + ChallengeTemplateViewArguments, + ChapterViewArguments, + ChapterBlockViewArguments, + NativeLoginViewArguments, + SuperBlockViewArguments; +import 'package:freecodecamp/ui/views/code_radio/code_radio_view.dart'; +import 'package:freecodecamp/ui/views/learn/challenge/templates/template_view.dart'; +import 'package:freecodecamp/ui/views/learn/chapter/chapter_block_view.dart'; +import 'package:freecodecamp/ui/views/learn/chapter/chapter_view.dart'; +import 'package:freecodecamp/ui/views/learn/daily_challenge/daily_challenge_view.dart'; +import 'package:freecodecamp/ui/views/learn/landing/landing_view.dart'; +import 'package:freecodecamp/ui/views/learn/superblock/superblock_view.dart'; +import 'package:freecodecamp/ui/views/login/native_login_view.dart'; +import 'package:freecodecamp/ui/views/news/news-author/news_author_view.dart'; +import 'package:freecodecamp/ui/views/news/news-bookmark/news_bookmark_view.dart'; +import 'package:freecodecamp/ui/views/news/news-feed/news_feed_view.dart'; +import 'package:freecodecamp/ui/views/news/news-image-viewer/news_image_view.dart'; +import 'package:freecodecamp/ui/views/news/news-tutorial/news_tutorial_view.dart'; +import 'package:freecodecamp/ui/views/news/news-view-handler/news_view_handler_view.dart'; +import 'package:freecodecamp/ui/views/podcast/episode/episode_view.dart'; +import 'package:freecodecamp/ui/views/podcast/podcast-list/podcast_list_view.dart'; +import 'package:freecodecamp/ui/views/profile/profile_view.dart'; +import 'package:freecodecamp/ui/views/settings/delete-account/delete_account_view.dart'; +import 'package:freecodecamp/ui/views/settings/settings_view.dart'; + +/// Returns a [Route] for the given [RouteSettings], or `null` if the route is +/// unknown. Plug this directly into [MaterialApp.onGenerateRoute]. +Route? generateRoute(RouteSettings settings) { + switch (settings.name) { + // ------------------------------------------------------------------ + // Routes without arguments + // ------------------------------------------------------------------ + case Routes.learnLandingView: + return MaterialPageRoute( + builder: (_) => const LearnLandingView(), + settings: settings, + ); + + case Routes.newsViewHandlerView: + return MaterialPageRoute( + builder: (_) => const NewsViewHandlerView(), + settings: settings, + ); + + case Routes.podcastListView: + return MaterialPageRoute( + builder: (_) => const PodcastListView(), + settings: settings, + ); + + case Routes.codeRadioView: + return MaterialPageRoute( + builder: (_) => const CodeRadioView(), + settings: settings, + ); + + case Routes.profileView: + return MaterialPageRoute( + builder: (_) => const ProfileView(), + settings: settings, + ); + + case Routes.settingsView: + return MaterialPageRoute( + builder: (_) => const SettingsView(), + settings: settings, + ); + + case Routes.deleteAccountView: + return MaterialPageRoute( + builder: (_) => const DeleteAccountView(), + settings: settings, + ); + + case Routes.dailyChallengeView: + return MaterialPageRoute( + builder: (_) => const DailyChallengeView(), + settings: settings, + ); + + // ------------------------------------------------------------------ + // Routes with arguments + // ------------------------------------------------------------------ + case Routes.episodeView: + final args = settings.arguments as EpisodeViewArguments; + return MaterialPageRoute( + builder: (_) => EpisodeView( + key: args.key, + episode: args.episode, + podcast: args.podcast, + ), + settings: settings, + ); + + case Routes.newsTutorialView: + final args = settings.arguments as NewsTutorialViewArguments; + return MaterialPageRoute( + builder: (_) => NewsTutorialView( + key: args.key, + refId: args.refId, + slug: args.slug, + ), + settings: settings, + ); + + case Routes.newsBookmarkTutorialView: + final args = settings.arguments as NewsBookmarkTutorialViewArguments; + return MaterialPageRoute( + builder: (_) => NewsBookmarkTutorialView( + key: args.key, + tutorial: args.tutorial, + ), + settings: settings, + ); + + case Routes.newsFeedView: + final args = settings.arguments is NewsFeedViewArguments + ? settings.arguments as NewsFeedViewArguments + : const NewsFeedViewArguments(); + return MaterialPageRoute( + builder: (_) => NewsFeedView( + key: args.key, + tagSlug: args.tagSlug, + authorId: args.authorId, + fromAuthor: args.fromAuthor, + fromTag: args.fromTag, + fromSearch: args.fromSearch, + tutorials: args.tutorials, + subject: args.subject, + ), + settings: settings, + ); + + case Routes.newsAuthorView: + final args = settings.arguments as NewsAuthorViewArguments; + return MaterialPageRoute( + builder: (_) => NewsAuthorView( + key: args.key, + authorSlug: args.authorSlug, + ), + settings: settings, + ); + + case Routes.newsImageView: + final args = settings.arguments as NewsImageViewArguments; + return MaterialPageRoute( + builder: (_) => NewsImageView( + key: args.key, + imgUrl: args.imgUrl, + isDataUrl: args.isDataUrl, + ), + settings: settings, + ); + + case Routes.challengeTemplateView: + final args = settings.arguments as ChallengeTemplateViewArguments; + return MaterialPageRoute( + builder: (_) => ChallengeTemplateView( + key: args.key, + block: args.block, + challengeId: args.challengeId, + challengeDate: args.challengeDate, + ), + settings: settings, + ); + + case Routes.chapterView: + final args = settings.arguments as ChapterViewArguments; + return MaterialPageRoute( + builder: (_) => ChapterView( + key: args.key, + superBlockDashedName: args.superBlockDashedName, + superBlockName: args.superBlockName, + ), + settings: settings, + ); + + case Routes.chapterBlockView: + final args = settings.arguments as ChapterBlockViewArguments; + return MaterialPageRoute( + builder: (_) => ChapterBlockView( + key: args.key, + moduleName: args.moduleName, + blocks: args.blocks, + ), + settings: settings, + ); + + case Routes.nativeLoginView: + final args = settings.arguments is NativeLoginViewArguments + ? settings.arguments as NativeLoginViewArguments + : const NativeLoginViewArguments(); + return MaterialPageRoute( + builder: (_) => NativeLoginView( + key: args.key, + fromButton: args.fromButton, + ), + settings: settings, + ); + + case Routes.superBlockView: + final args = settings.arguments as SuperBlockViewArguments; + return MaterialPageRoute( + builder: (_) => SuperBlockView( + key: args.key, + superBlockDashedName: args.superBlockDashedName, + superBlockName: args.superBlockName, + hasInternet: args.hasInternet, + ), + settings: settings, + ); + + default: + return null; + } +} diff --git a/mobile-app/lib/core/navigation/app_dialog.dart b/mobile-app/lib/core/navigation/app_dialog.dart new file mode 100644 index 000000000..ad9035e22 --- /dev/null +++ b/mobile-app/lib/core/navigation/app_dialog.dart @@ -0,0 +1,74 @@ +// A thin dialog wrapper that does NOT depend on Stacked. +// +// Uses the [AppNavigator.navigatorKey] to obtain the current [BuildContext] +// and show Material dialogs without requiring a Stacked [DialogService]. +// +// Usage: +// final confirmed = await AppDialog.showConfirmation( +// title: 'Delete account', +// description: 'Are you sure you want to delete your account?', +// confirmLabel: 'Delete', +// cancelLabel: 'Cancel', +// ); + +import 'package:flutter/material.dart'; +import 'package:freecodecamp/core/navigation/app_navigator.dart'; + +class AppDialog { + AppDialog._(); + + static BuildContext? get _context => + AppNavigator.navigatorKey.currentContext; + + /// Show a simple confirmation dialog with an OK/Cancel choice. + /// Returns `true` if the user tapped the confirm button, `false` otherwise. + static Future showConfirmation({ + required String title, + String description = '', + String confirmLabel = 'OK', + String cancelLabel = 'Cancel', + Color backgroundColor = const Color(0xFF2A2A40), + }) async { + final ctx = _context; + if (ctx == null) return false; + + final result = await showDialog( + context: ctx, + builder: (dialogContext) => AlertDialog( + backgroundColor: backgroundColor, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0)), + title: Text(title), + content: description.isNotEmpty ? Text(description) : null, + actions: [ + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(false), + child: Text(cancelLabel), + ), + TextButton( + onPressed: () => Navigator.of(dialogContext).pop(true), + child: Text(confirmLabel), + ), + ], + ), + ); + return result ?? false; + } + + /// Show a general-purpose dialog with a custom [builder]. + /// Returns whatever value the dialog resolves with. + static Future showCustom({ + required WidgetBuilder builder, + bool barrierDismissible = true, + RouteSettings? routeSettings, + }) async { + final ctx = _context; + if (ctx == null) return null; + + return showDialog( + context: ctx, + barrierDismissible: barrierDismissible, + routeSettings: routeSettings, + builder: builder, + ); + } +} diff --git a/mobile-app/lib/core/navigation/app_navigator.dart b/mobile-app/lib/core/navigation/app_navigator.dart new file mode 100644 index 000000000..489a6c01a --- /dev/null +++ b/mobile-app/lib/core/navigation/app_navigator.dart @@ -0,0 +1,76 @@ +// A thin navigation wrapper that does NOT depend on Stacked. +// +// The [AppNavigator] class holds a [GlobalKey] that is also +// set on the [MaterialApp], so any code that previously relied on a global +// navigator key can switch to [AppNavigator.navigatorKey] without changing +// call-site logic. +// +// Usage: +// // Navigate to a named route: +// AppNavigator.navigateTo(Routes.profileView); +// +// // Navigate with arguments: +// AppNavigator.navigateTo( +// Routes.episodeView, +// arguments: EpisodeViewArguments(episode: ep, podcast: p), +// ); +// +// // Pop the top-most route: +// AppNavigator.pop(); + +import 'package:flutter/material.dart'; + +class AppNavigator { + AppNavigator._(); + + /// The single [GlobalKey] used throughout the app. + /// Pass this to [MaterialApp.navigatorKey]. + static final GlobalKey navigatorKey = + GlobalKey(); + + // --------------------------------------------------------------------------- + // Navigation helpers + // --------------------------------------------------------------------------- + + static NavigatorState? get _navigator => navigatorKey.currentState; + + /// Push a named route onto the navigator. + static Future navigateTo( + String routeName, { + Object? arguments, + }) { + return _navigator!.pushNamed(routeName, arguments: arguments); + } + + /// Replace the current route with a new named route. + static Future replaceWith( + String routeName, { + Object? arguments, + }) { + return _navigator!.pushReplacementNamed( + routeName, + arguments: arguments, + ); + } + + /// Pop the top-most route off the navigator. + static void pop([T? result]) { + _navigator?.pop(result); + } + + /// Pop until the predicate is satisfied (e.g., pop to a specific route). + static void popUntil(RoutePredicate predicate) { + _navigator?.popUntil(predicate); + } + + /// Pop the current route and push a new named route. + static Future popAndPushNamed( + String routeName, { + Object? arguments, + }) { + return _navigator!.popAndPushNamed( + routeName, + arguments: arguments, + ); + } +} diff --git a/mobile-app/lib/core/navigation/app_snackbar.dart b/mobile-app/lib/core/navigation/app_snackbar.dart new file mode 100644 index 000000000..3360652d0 --- /dev/null +++ b/mobile-app/lib/core/navigation/app_snackbar.dart @@ -0,0 +1,42 @@ +// A thin SnackBar wrapper that does NOT depend on Stacked. +// +// Uses the [AppNavigator.navigatorKey] to obtain the current [BuildContext] +// and show Material snack bars without requiring a Stacked [SnackbarService]. +// +// Usage: +// AppSnackbar.show(title: 'Done', message: 'Operation completed.'); + +import 'package:flutter/material.dart'; +import 'package:freecodecamp/core/navigation/app_navigator.dart'; + +class AppSnackbar { + AppSnackbar._(); + + /// Show a simple snack bar with an optional [message] beneath the [title]. + static void show({ + required String title, + String message = '', + Duration duration = const Duration(seconds: 3), + Color backgroundColor = const Color(0xFF2A2A40), + Color textColor = Colors.white, + }) { + final context = + AppNavigator.navigatorKey.currentContext; + if (context == null) return; + + final combinedMessage = + message.isNotEmpty ? '$title\n$message' : title; + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + combinedMessage, + style: TextStyle(color: textColor), + ), + backgroundColor: backgroundColor, + duration: duration, + behavior: SnackBarBehavior.floating, + ), + ); + } +} diff --git a/mobile-app/lib/core/providers/service_providers.dart b/mobile-app/lib/core/providers/service_providers.dart new file mode 100644 index 000000000..07d725255 --- /dev/null +++ b/mobile-app/lib/core/providers/service_providers.dart @@ -0,0 +1,146 @@ +// Provider bridge: exposes existing GetIt/StackedLocator singletons as +// Riverpod providers. All services remain owned by the locator for now; these +// providers simply fetch from it so that future feature views can read them via +// ref.read/ref.watch without touching the locator directly. +// +// Usage: +// final auth = ref.watch(authenticationServiceProvider); +// +// When a service is fully migrated off the locator, replace the provider body +// with a standalone Riverpod implementation. + +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:freecodecamp/app/app.locator.dart'; +import 'package:freecodecamp/service/audio/audio_service.dart'; +import 'package:freecodecamp/service/authentication/authentication_service.dart'; +import 'package:freecodecamp/service/developer_service.dart'; +import 'package:freecodecamp/service/dio_service.dart'; +import 'package:freecodecamp/service/firebase/analytics_service.dart'; +import 'package:freecodecamp/service/firebase/remote_config_service.dart'; +import 'package:freecodecamp/service/learn/daily_challenge_notification_service.dart'; +import 'package:freecodecamp/service/learn/daily_challenge_service.dart'; +import 'package:freecodecamp/service/learn/learn_file_service.dart'; +import 'package:freecodecamp/service/learn/learn_offline_service.dart'; +import 'package:freecodecamp/service/learn/learn_service.dart'; +import 'package:freecodecamp/service/locale_service.dart'; +import 'package:freecodecamp/service/navigation/quick_actions_service.dart'; +import 'package:freecodecamp/service/news/api_service.dart'; +import 'package:freecodecamp/service/news/bookmark_service.dart'; +import 'package:freecodecamp/service/podcast/download_service.dart'; +import 'package:freecodecamp/service/podcast/notification_service.dart'; +import 'package:freecodecamp/service/podcast/podcasts_service.dart'; + +// --------------------------------------------------------------------------- +// Core / infrastructure services +// --------------------------------------------------------------------------- + +/// Provides the [AuthenticationService] singleton registered in the locator. +final authenticationServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [DioService] singleton registered in the locator. +final dioServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [LocaleService] singleton registered in the locator. +final localeServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [DeveloperService] singleton registered in the locator. +final developerServiceProvider = Provider( + (ref) => locator(), +); + +// --------------------------------------------------------------------------- +// Firebase services +// --------------------------------------------------------------------------- + +/// Provides the [AnalyticsService] singleton registered in the locator. +final analyticsServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [RemoteConfigService] singleton registered in the locator. +final remoteConfigServiceProvider = Provider( + (ref) => locator(), +); + +// --------------------------------------------------------------------------- +// Audio service +// --------------------------------------------------------------------------- + +/// Provides the [AppAudioService] singleton registered in the locator. +final appAudioServiceProvider = Provider( + (ref) => locator(), +); + +// --------------------------------------------------------------------------- +// Learn services +// --------------------------------------------------------------------------- + +/// Provides the [LearnService] singleton registered in the locator. +final learnServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [LearnFileService] singleton registered in the locator. +final learnFileServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [LearnOfflineService] singleton registered in the locator. +final learnOfflineServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [DailyChallengeService] singleton registered in the locator. +final dailyChallengeServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [DailyChallengeNotificationService] singleton registered in the locator. +final dailyChallengeNotificationServiceProvider = + Provider( + (ref) => locator(), +); + +// --------------------------------------------------------------------------- +// News / Podcast services +// --------------------------------------------------------------------------- + +/// Provides the [NewsApiService] singleton registered in the locator. +final newsApiServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [BookmarksDatabaseService] singleton registered in the locator. +final bookmarksDatabaseServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [PodcastsDatabaseService] singleton registered in the locator. +final podcastsDatabaseServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [DownloadService] singleton registered in the locator. +final downloadServiceProvider = Provider( + (ref) => locator(), +); + +/// Provides the [NotificationService] singleton registered in the locator. +final notificationServiceProvider = Provider( + (ref) => locator(), +); + +// --------------------------------------------------------------------------- +// Navigation helpers +// --------------------------------------------------------------------------- + +/// Provides the [QuickActionsService] singleton registered in the locator. +final quickActionsServiceProvider = Provider( + (ref) => locator(), +); diff --git a/mobile-app/lib/main.dart b/mobile-app/lib/main.dart index 37e092e32..03b906bc0 100644 --- a/mobile-app/lib/main.dart +++ b/mobile-app/lib/main.dart @@ -5,8 +5,10 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:freecodecamp/app/app.locator.dart'; -import 'package:freecodecamp/app/app.router.dart'; +import 'package:freecodecamp/app/app_router.dart'; +import 'package:freecodecamp/core/navigation/app_navigator.dart'; import 'package:freecodecamp/firebase_options.dart'; import 'package:freecodecamp/l10n/app_localizations.dart'; import 'package:freecodecamp/service/audio/audio_service.dart'; @@ -21,7 +23,6 @@ import 'package:freecodecamp/service/news/api_service.dart'; import 'package:freecodecamp/service/podcast/notification_service.dart'; import 'package:freecodecamp/ui/theme/fcc_theme.dart'; import 'package:freecodecamp/utils/upgrade_controller.dart'; -import 'package:stacked_services/stacked_services.dart'; import 'package:upgrader/upgrader.dart'; Future main({bool testing = false}) async { @@ -50,10 +51,16 @@ Future main({bool testing = false}) async { } } await RemoteConfigService().init(); - await NotificationService().init(); + await locator().init(); await DailyChallengeNotificationService().init(); - runApp(const FreeCodeCampMobileApp()); + runApp( + // ProviderScope is the root of the Riverpod tree. + // All feature views can now consume providers via ref.watch / ref.read. + const ProviderScope( + child: FreeCodeCampMobileApp(), + ), + ); await QuickActionsService().init(); } @@ -76,14 +83,18 @@ class FreeCodeCampMobileApp extends StatelessWidget { supportedLocales: locator().locales, locale: snapshot.data ?? locator().locale, debugShowCheckedModeBanner: false, - navigatorKey: StackedService.navigatorKey, - onGenerateRoute: StackedRouter().onGenerateRoute, + // Use the shared AppNavigator key. + // The key is a plain GlobalKey and works with all + // named-route navigation in the app. + navigatorKey: AppNavigator.navigatorKey, + // Standalone router — no Stacked runtime required. + onGenerateRoute: generateRoute, navigatorObservers: [ locator().getAnalyticsObserver() ], builder: (context, child) { return UpgradeAlert( - navigatorKey: StackedService.navigatorKey, + navigatorKey: AppNavigator.navigatorKey, dialogStyle: Platform.isIOS ? UpgradeDialogStyle.cupertino : UpgradeDialogStyle.material, diff --git a/mobile-app/lib/service/navigation/quick_actions_service.dart b/mobile-app/lib/service/navigation/quick_actions_service.dart index a724c14a6..36c3f7b7f 100644 --- a/mobile-app/lib/service/navigation/quick_actions_service.dart +++ b/mobile-app/lib/service/navigation/quick_actions_service.dart @@ -1,9 +1,8 @@ import 'dart:io'; -import 'package:freecodecamp/app/app.locator.dart'; import 'package:freecodecamp/app/app.router.dart'; +import 'package:freecodecamp/core/navigation/app_navigator.dart'; import 'package:quick_actions/quick_actions.dart'; -import 'package:stacked_services/stacked_services.dart'; class QuickActionsService { static final QuickActionsService _quickActionsService = @@ -11,8 +10,6 @@ class QuickActionsService { QuickActions quickActions = const QuickActions(); - final NavigationService _navigationService = locator(); - factory QuickActionsService() { return _quickActionsService; } @@ -45,19 +42,19 @@ class QuickActionsService { await quickActions.initialize((shortcutType) { switch (shortcutType) { case 'action_tutorials': - _navigationService.replaceWith(Routes.newsViewHandlerView); + AppNavigator.replaceWith(Routes.newsViewHandlerView); break; case 'action_learn': - _navigationService.replaceWith(Routes.learnLandingView); + AppNavigator.replaceWith(Routes.learnLandingView); break; case 'action_code_radio': - _navigationService.replaceWith(Routes.codeRadioView); + AppNavigator.replaceWith(Routes.codeRadioView); break; case 'action_podcasts': - _navigationService.replaceWith(Routes.podcastListView); + AppNavigator.replaceWith(Routes.podcastListView); break; case 'action_daily_challenges': - _navigationService.replaceWith(Routes.dailyChallengeView); + AppNavigator.replaceWith(Routes.dailyChallengeView); break; default: } diff --git a/mobile-app/pubspec.lock b/mobile-app/pubspec.lock index d1bf02de9..75d451316 100644 --- a/mobile-app/pubspec.lock +++ b/mobile-app/pubspec.lock @@ -744,6 +744,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.6" + flutter_riverpod: + dependency: "direct main" + description: + name: flutter_riverpod + sha256: "9532ee6db4a943a1ed8383072a2e3eeda041db5657cdf6d2acecf3c21ecbe7e1" + url: "https://pub.dev" + source: hosted + version: "2.6.1" flutter_scroll_shadow: dependency: "direct main" description: @@ -834,14 +842,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2 - url: "https://pub.dev" - source: hosted - version: "2.4.4" frontend_server_client: dependency: transitive description: @@ -855,16 +855,8 @@ packages: description: flutter source: sdk version: "0.0.0" - get: - dependency: transitive - description: - name: get - sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425 - url: "https://pub.dev" - source: hosted - version: "4.7.2" get_it: - dependency: transitive + dependency: "direct main" description: name: get_it sha256: d85128a5dae4ea777324730dc65edd9c9f43155c109d5cc0a69cab74139fbac1 @@ -1124,14 +1116,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.2" - logger: - dependency: transitive - description: - name: logger - sha256: "7ad7215c15420a102ec687bb320a7312afd449bac63bfb1c60d9787c27b9767f" - url: "https://pub.dev" - source: hosted - version: "1.4.0" logging: dependency: transitive description: @@ -1180,14 +1164,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.4.4" - nested: - dependency: transitive - description: - name: nested - sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" - source: hosted - version: "1.0.0" normalize: dependency: transitive description: @@ -1372,14 +1348,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.3" - provider: - dependency: transitive - description: - name: provider - sha256: "489024f942069c2920c844ee18bb3d467c69e48955a4f32d1677f71be103e310" - url: "https://pub.dev" - source: hosted - version: "6.1.4" pub_semver: dependency: transitive description: @@ -1436,14 +1404,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.2.2" - recase: + riverpod: dependency: transitive description: - name: recase - sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + name: riverpod + sha256: "59062512288d3056b2321804332a13ffdd1bf16df70dcc8e506e411280a72959" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "2.6.1" rxdart: dependency: transitive description: @@ -1625,38 +1593,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.12.1" - stacked: - dependency: "direct main" - description: - name: stacked - sha256: ed19ecdc2dcc682b9be9c7e34646e603c0f770437a914b15c7d2d13391c92a09 - url: "https://pub.dev" - source: hosted - version: "3.4.3" - stacked_generator: - dependency: "direct dev" - description: - name: stacked_generator - sha256: eaa6447e3fd4d4010b746629b5518364d7fa7f6453ffb6416ad449fd352d1181 - url: "https://pub.dev" - source: hosted - version: "1.6.1" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - sha256: a70c5c86f89a9258139ff174bf045a527099ea8552f8497ebb0b755469841bb4 - url: "https://pub.dev" - source: hosted - version: "1.6.0" - stacked_shared: + state_notifier: dependency: transitive description: - name: stacked_shared - sha256: "26e11dcfe23df81d565d0180eb5bcf4742efed066ba3328623b458f21a82b346" + name: state_notifier + sha256: b8677376aa54f2d7c58280d5a007f9e8774f1968d1fb1c096adcb4792fba29bb url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.0.0" stream_channel: dependency: transitive description: diff --git a/mobile-app/pubspec.yaml b/mobile-app/pubspec.yaml index 600ad62c1..2fbc0fd6f 100644 --- a/mobile-app/pubspec.yaml +++ b/mobile-app/pubspec.yaml @@ -29,10 +29,12 @@ dependencies: flutter_local_notifications: 19.1.0 flutter_localizations: sdk: flutter + flutter_riverpod: 2.6.1 flutter_scroll_shadow: 1.2.6 flutter_secure_storage: 9.2.4 flutter_svg: 2.1.0 focus_detector: 2.0.1 + get_it: 7.7.0 graphql: 5.2.0 html: 0.15.5+1 infinite_scroll_pagination: 5.0.0 @@ -47,8 +49,6 @@ dependencies: share_plus: 10.1.4 # NOTE: v11 has breaking changes shared_preferences: 2.5.3 # TODO: update deprecated code sqflite: 2.4.2 - stacked: 3.4.3 - stacked_services: 1.6.0 timezone: 0.10.1 ua_client_hints: 1.4.1 upgrader: 11.3.1 @@ -67,8 +67,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - mockito: 5.4.4 # NOTE: 5.4.6+ is blocked by stacked_generator - stacked_generator: 1.6.1 + mockito: 5.4.4 flutter: fonts: diff --git a/mobile-app/test/helpers/test_helpers.dart b/mobile-app/test/helpers/test_helpers.dart index 22e51461b..88583d475 100644 --- a/mobile-app/test/helpers/test_helpers.dart +++ b/mobile-app/test/helpers/test_helpers.dart @@ -5,42 +5,21 @@ import 'package:freecodecamp/service/learn/daily_challenge_service.dart'; import 'package:freecodecamp/service/news/bookmark_service.dart'; import 'package:mockito/annotations.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:stacked_services/stacked_services.dart'; -// @stacked-import import 'test_helpers.mocks.dart'; @GenerateMocks([], customMocks: [ - MockSpec(onMissingStub: OnMissingStub.returnDefault), - MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec(onMissingStub: OnMissingStub.returnDefault), MockSpec( - onMissingStub: OnMissingStub.returnDefault), + onMissingStub: OnMissingStub.returnDefault, + ), MockSpec(onMissingStub: OnMissingStub.returnDefault), -// @stacked-mock-spec ]) void registerServices() { - getAndRegisterNavigationService(); - getAndRegisterDialogService(); getAndRegisterNewsBookmarkService(); getAndRegisterAuthenticationService(); getAndRegisterDailyChallengeService(); -// @stacked-mock-register -} - -MockNavigationService getAndRegisterNavigationService() { - _removeRegistrationIfExists(); - final service = MockNavigationService(); - locator.registerSingleton(service); - return service; -} - -MockDialogService getAndRegisterDialogService() { - _removeRegistrationIfExists(); - final service = MockDialogService(); - locator.registerSingleton(service); - return service; } BookmarksDatabaseService getAndRegisterNewsBookmarkService() { @@ -63,7 +42,6 @@ MockDailyChallengeService getAndRegisterDailyChallengeService() { locator.registerSingleton(service); return service; } -// @stacked-mock-create void _removeRegistrationIfExists() { if (locator.isRegistered()) { diff --git a/mobile-app/test/helpers/test_helpers.mocks.dart b/mobile-app/test/helpers/test_helpers.mocks.dart index 86d0f68f9..623b32da1 100644 --- a/mobile-app/test/helpers/test_helpers.mocks.dart +++ b/mobile-app/test/helpers/test_helpers.mocks.dart @@ -3,37 +3,35 @@ // Do not manually edit this file. // ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i5; -import 'dart:ui' as _i11; +import 'dart:async' as _i4; -import 'package:auth0_flutter/auth0_flutter.dart' as _i4; -import 'package:dio/dio.dart' as _i13; -import 'package:flutter/material.dart' as _i10; +import 'package:auth0_flutter/auth0_flutter.dart' as _i3; +import 'package:dio/dio.dart' as _i10; +import 'package:flutter/material.dart' as _i11; import 'package:flutter_local_notifications/src/flutter_local_notifications_plugin.dart' - as _i16; + as _i14; import 'package:flutter_local_notifications/src/initialization_settings.dart' - as _i17; + as _i15; import 'package:flutter_local_notifications/src/notification_details.dart' - as _i19; + as _i17; import 'package:flutter_local_notifications/src/platform_specifics/android/schedule_mode.dart' - as _i21; -import 'package:flutter_local_notifications/src/types.dart' as _i22; + as _i19; +import 'package:flutter_local_notifications/src/types.dart' as _i20; import 'package:flutter_local_notifications_platform_interface/flutter_local_notifications_platform_interface.dart' - as _i18; -import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i3; -import 'package:freecodecamp/models/learn/challenge_model.dart' as _i8; -import 'package:freecodecamp/models/learn/curriculum_model.dart' as _i15; -import 'package:freecodecamp/models/learn/daily_challenge_model.dart' as _i7; -import 'package:freecodecamp/models/main/user_model.dart' as _i6; + as _i16; +import 'package:flutter_secure_storage/flutter_secure_storage.dart' as _i2; +import 'package:freecodecamp/models/learn/challenge_model.dart' as _i7; +import 'package:freecodecamp/models/learn/curriculum_model.dart' as _i13; +import 'package:freecodecamp/models/learn/daily_challenge_model.dart' as _i6; +import 'package:freecodecamp/models/main/user_model.dart' as _i5; import 'package:freecodecamp/service/authentication/authentication_service.dart' - as _i12; + as _i8; import 'package:freecodecamp/service/learn/daily_challenge_service.dart' - as _i14; + as _i12; import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/src/dummies.dart' as _i9; -import 'package:shared_preferences/shared_preferences.dart' as _i23; -import 'package:stacked_services/stacked_services.dart' as _i2; -import 'package:timezone/timezone.dart' as _i20; +import 'package:shared_preferences/shared_preferences.dart' as _i21; +import 'package:timezone/timezone.dart' as _i18; // ignore_for_file: type=lint // ignore_for_file: avoid_redundant_argument_values @@ -48,20 +46,9 @@ import 'package:timezone/timezone.dart' as _i20; // ignore_for_file: camel_case_types // ignore_for_file: subtype_of_sealed_class -class _FakeSnackbarService_0 extends _i1.SmartFake - implements _i2.SnackbarService { - _FakeSnackbarService_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeFlutterSecureStorage_1 extends _i1.SmartFake - implements _i3.FlutterSecureStorage { - _FakeFlutterSecureStorage_1( +class _FakeFlutterSecureStorage_0 extends _i1.SmartFake + implements _i2.FlutterSecureStorage { + _FakeFlutterSecureStorage_0( Object parent, Invocation parentInvocation, ) : super( @@ -70,8 +57,8 @@ class _FakeFlutterSecureStorage_1 extends _i1.SmartFake ); } -class _FakeAuth0_2 extends _i1.SmartFake implements _i4.Auth0 { - _FakeAuth0_2( +class _FakeAuth0_1 extends _i1.SmartFake implements _i3.Auth0 { + _FakeAuth0_1( Object parent, Invocation parentInvocation, ) : super( @@ -80,9 +67,9 @@ class _FakeAuth0_2 extends _i1.SmartFake implements _i4.Auth0 { ); } -class _FakeStreamController_3 extends _i1.SmartFake - implements _i5.StreamController { - _FakeStreamController_3( +class _FakeStreamController_2 extends _i1.SmartFake + implements _i4.StreamController { + _FakeStreamController_2( Object parent, Invocation parentInvocation, ) : super( @@ -91,8 +78,8 @@ class _FakeStreamController_3 extends _i1.SmartFake ); } -class _FakeFccUserModel_4 extends _i1.SmartFake implements _i6.FccUserModel { - _FakeFccUserModel_4( +class _FakeFccUserModel_3 extends _i1.SmartFake implements _i5.FccUserModel { + _FakeFccUserModel_3( Object parent, Invocation parentInvocation, ) : super( @@ -101,9 +88,9 @@ class _FakeFccUserModel_4 extends _i1.SmartFake implements _i6.FccUserModel { ); } -class _FakeDailyChallenge_5 extends _i1.SmartFake - implements _i7.DailyChallenge { - _FakeDailyChallenge_5( +class _FakeDailyChallenge_4 extends _i1.SmartFake + implements _i6.DailyChallenge { + _FakeDailyChallenge_4( Object parent, Invocation parentInvocation, ) : super( @@ -112,8 +99,8 @@ class _FakeDailyChallenge_5 extends _i1.SmartFake ); } -class _FakeChallenge_6 extends _i1.SmartFake implements _i8.Challenge { - _FakeChallenge_6( +class _FakeChallenge_5 extends _i1.SmartFake implements _i7.Challenge { + _FakeChallenge_5( Object parent, Invocation parentInvocation, ) : super( @@ -122,593 +109,39 @@ class _FakeChallenge_6 extends _i1.SmartFake implements _i8.Challenge { ); } -/// A class which mocks [NavigationService]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockNavigationService extends _i1.Mock implements _i2.NavigationService { - @override - String get previousRoute => (super.noSuchMethod( - Invocation.getter(#previousRoute), - returnValue: _i9.dummyValue( - this, - Invocation.getter(#previousRoute), - ), - returnValueForMissingStub: _i9.dummyValue( - this, - Invocation.getter(#previousRoute), - ), - ) as String); - - @override - String get currentRoute => (super.noSuchMethod( - Invocation.getter(#currentRoute), - returnValue: _i9.dummyValue( - this, - Invocation.getter(#currentRoute), - ), - returnValueForMissingStub: _i9.dummyValue( - this, - Invocation.getter(#currentRoute), - ), - ) as String); - - @override - _i10.GlobalKey<_i10.NavigatorState>? nestedNavigationKey(int? index) => - (super.noSuchMethod( - Invocation.method( - #nestedNavigationKey, - [index], - ), - returnValueForMissingStub: null, - ) as _i10.GlobalKey<_i10.NavigatorState>?); - - @override - void config({ - bool? enableLog, - bool? defaultPopGesture, - bool? defaultOpaqueRoute, - Duration? defaultDurationTransition, - bool? defaultGlobalState, - _i2.Transition? defaultTransitionStyle, - String? defaultTransition, - }) => - super.noSuchMethod( - Invocation.method( - #config, - [], - { - #enableLog: enableLog, - #defaultPopGesture: defaultPopGesture, - #defaultOpaqueRoute: defaultOpaqueRoute, - #defaultDurationTransition: defaultDurationTransition, - #defaultGlobalState: defaultGlobalState, - #defaultTransitionStyle: defaultTransitionStyle, - #defaultTransition: defaultTransition, - }, - ), - returnValueForMissingStub: null, - ); - - @override - _i5.Future? navigateWithTransition( - _i10.Widget? page, { - bool? opaque, - String? transition = r'', - Duration? duration, - bool? popGesture, - int? id, - _i10.Curve? curve, - bool? fullscreenDialog = false, - bool? preventDuplicates = true, - _i2.Transition? transitionClass, - _i2.Transition? transitionStyle, - String? routeName, - }) => - (super.noSuchMethod( - Invocation.method( - #navigateWithTransition, - [page], - { - #opaque: opaque, - #transition: transition, - #duration: duration, - #popGesture: popGesture, - #id: id, - #curve: curve, - #fullscreenDialog: fullscreenDialog, - #preventDuplicates: preventDuplicates, - #transitionClass: transitionClass, - #transitionStyle: transitionStyle, - #routeName: routeName, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? replaceWithTransition( - _i10.Widget? page, { - bool? opaque, - String? transition = r'', - Duration? duration, - bool? popGesture, - int? id, - _i10.Curve? curve, - bool? fullscreenDialog = false, - bool? preventDuplicates = true, - _i2.Transition? transitionClass, - _i2.Transition? transitionStyle, - String? routeName, - }) => - (super.noSuchMethod( - Invocation.method( - #replaceWithTransition, - [page], - { - #opaque: opaque, - #transition: transition, - #duration: duration, - #popGesture: popGesture, - #id: id, - #curve: curve, - #fullscreenDialog: fullscreenDialog, - #preventDuplicates: preventDuplicates, - #transitionClass: transitionClass, - #transitionStyle: transitionStyle, - #routeName: routeName, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - bool back({ - dynamic result, - int? id, - }) => - (super.noSuchMethod( - Invocation.method( - #back, - [], - { - #result: result, - #id: id, - }, - ), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); - - @override - void popUntil( - _i10.RoutePredicate? predicate, { - int? id, - }) => - super.noSuchMethod( - Invocation.method( - #popUntil, - [predicate], - {#id: id}, - ), - returnValueForMissingStub: null, - ); - - @override - void popRepeated(int? popTimes) => super.noSuchMethod( - Invocation.method( - #popRepeated, - [popTimes], - ), - returnValueForMissingStub: null, - ); - - @override - _i5.Future? navigateTo( - String? routeName, { - dynamic arguments, - int? id, - bool? preventDuplicates = true, - Map? parameters, - _i10.RouteTransitionsBuilder? transition, - }) => - (super.noSuchMethod( - Invocation.method( - #navigateTo, - [routeName], - { - #arguments: arguments, - #id: id, - #preventDuplicates: preventDuplicates, - #parameters: parameters, - #transition: transition, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? navigateToView( - _i10.Widget? view, { - dynamic arguments, - int? id, - bool? opaque, - _i10.Curve? curve, - Duration? duration, - bool? fullscreenDialog = false, - bool? popGesture, - bool? preventDuplicates = true, - _i2.Transition? transition, - _i2.Transition? transitionStyle, - }) => - (super.noSuchMethod( - Invocation.method( - #navigateToView, - [view], - { - #arguments: arguments, - #id: id, - #opaque: opaque, - #curve: curve, - #duration: duration, - #fullscreenDialog: fullscreenDialog, - #popGesture: popGesture, - #preventDuplicates: preventDuplicates, - #transition: transition, - #transitionStyle: transitionStyle, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? replaceWith( - String? routeName, { - dynamic arguments, - int? id, - bool? preventDuplicates = true, - Map? parameters, - _i10.RouteTransitionsBuilder? transition, - }) => - (super.noSuchMethod( - Invocation.method( - #replaceWith, - [routeName], - { - #arguments: arguments, - #id: id, - #preventDuplicates: preventDuplicates, - #parameters: parameters, - #transition: transition, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? clearStackAndShow( - String? routeName, { - dynamic arguments, - int? id, - Map? parameters, - }) => - (super.noSuchMethod( - Invocation.method( - #clearStackAndShow, - [routeName], - { - #arguments: arguments, - #id: id, - #parameters: parameters, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? clearStackAndShowView( - _i10.Widget? view, { - dynamic arguments, - int? id, - }) => - (super.noSuchMethod( - Invocation.method( - #clearStackAndShowView, - [view], - { - #arguments: arguments, - #id: id, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? clearTillFirstAndShow( - String? routeName, { - dynamic arguments, - int? id, - bool? preventDuplicates = true, - Map? parameters, - }) => - (super.noSuchMethod( - Invocation.method( - #clearTillFirstAndShow, - [routeName], - { - #arguments: arguments, - #id: id, - #preventDuplicates: preventDuplicates, - #parameters: parameters, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? clearTillFirstAndShowView( - _i10.Widget? view, { - dynamic arguments, - int? id, - }) => - (super.noSuchMethod( - Invocation.method( - #clearTillFirstAndShowView, - [view], - { - #arguments: arguments, - #id: id, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); - - @override - _i5.Future? pushNamedAndRemoveUntil( - String? routeName, { - _i10.RoutePredicate? predicate, - dynamic arguments, - int? id, - }) => - (super.noSuchMethod( - Invocation.method( - #pushNamedAndRemoveUntil, - [routeName], - { - #predicate: predicate, - #arguments: arguments, - #id: id, - }, - ), - returnValueForMissingStub: null, - ) as _i5.Future?); -} - -/// A class which mocks [DialogService]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockDialogService extends _i1.Mock implements _i2.DialogService { - @override - void registerCustomDialogBuilders( - Map? builders) => - super.noSuchMethod( - Invocation.method( - #registerCustomDialogBuilders, - [builders], - ), - returnValueForMissingStub: null, - ); - - @override - void registerCustomDialogBuilder({ - required dynamic variant, - required _i10.Widget Function( - _i10.BuildContext, - _i2.DialogRequest, - dynamic Function(_i2.DialogResponse), - )? builder, - }) => - super.noSuchMethod( - Invocation.method( - #registerCustomDialogBuilder, - [], - { - #variant: variant, - #builder: builder, - }, - ), - returnValueForMissingStub: null, - ); - - @override - _i5.Future<_i2.DialogResponse?> showDialog({ - String? title, - String? description, - String? cancelTitle, - _i11.Color? cancelTitleColor, - String? buttonTitle = r'Ok', - _i11.Color? buttonTitleColor, - bool? barrierDismissible = false, - _i10.RouteSettings? routeSettings, - _i10.GlobalKey<_i10.NavigatorState>? navigatorKey, - _i2.DialogPlatform? dialogPlatform, - }) => - (super.noSuchMethod( - Invocation.method( - #showDialog, - [], - { - #title: title, - #description: description, - #cancelTitle: cancelTitle, - #cancelTitleColor: cancelTitleColor, - #buttonTitle: buttonTitle, - #buttonTitleColor: buttonTitleColor, - #barrierDismissible: barrierDismissible, - #routeSettings: routeSettings, - #navigatorKey: navigatorKey, - #dialogPlatform: dialogPlatform, - }, - ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), - returnValueForMissingStub: - _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); - - @override - _i5.Future<_i2.DialogResponse?> showCustomDialog({ - dynamic variant, - String? title, - String? description, - bool? hasImage = false, - String? imageUrl, - bool? showIconInMainButton = false, - String? mainButtonTitle, - bool? showIconInSecondaryButton = false, - String? secondaryButtonTitle, - bool? showIconInAdditionalButton = false, - String? additionalButtonTitle, - bool? takesInput = false, - _i11.Color? barrierColor = const _i11.Color(2315255808), - bool? barrierDismissible = false, - String? barrierLabel = r'', - bool? useSafeArea = true, - _i10.RouteSettings? routeSettings, - _i10.GlobalKey<_i10.NavigatorState>? navigatorKey, - _i10.RouteTransitionsBuilder? transitionBuilder, - dynamic customData, - R? data, - }) => - (super.noSuchMethod( - Invocation.method( - #showCustomDialog, - [], - { - #variant: variant, - #title: title, - #description: description, - #hasImage: hasImage, - #imageUrl: imageUrl, - #showIconInMainButton: showIconInMainButton, - #mainButtonTitle: mainButtonTitle, - #showIconInSecondaryButton: showIconInSecondaryButton, - #secondaryButtonTitle: secondaryButtonTitle, - #showIconInAdditionalButton: showIconInAdditionalButton, - #additionalButtonTitle: additionalButtonTitle, - #takesInput: takesInput, - #barrierColor: barrierColor, - #barrierDismissible: barrierDismissible, - #barrierLabel: barrierLabel, - #useSafeArea: useSafeArea, - #routeSettings: routeSettings, - #navigatorKey: navigatorKey, - #transitionBuilder: transitionBuilder, - #customData: customData, - #data: data, - }, - ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), - returnValueForMissingStub: _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); - - @override - _i5.Future<_i2.DialogResponse?> showConfirmationDialog({ - String? title, - String? description, - String? cancelTitle = r'Cancel', - _i11.Color? cancelTitleColor, - String? confirmationTitle = r'Ok', - _i11.Color? confirmationTitleColor, - bool? barrierDismissible = false, - _i10.RouteSettings? routeSettings, - _i2.DialogPlatform? dialogPlatform, - }) => - (super.noSuchMethod( - Invocation.method( - #showConfirmationDialog, - [], - { - #title: title, - #description: description, - #cancelTitle: cancelTitle, - #cancelTitleColor: cancelTitleColor, - #confirmationTitle: confirmationTitle, - #confirmationTitleColor: confirmationTitleColor, - #barrierDismissible: barrierDismissible, - #routeSettings: routeSettings, - #dialogPlatform: dialogPlatform, - }, - ), - returnValue: _i5.Future<_i2.DialogResponse?>.value(), - returnValueForMissingStub: - _i5.Future<_i2.DialogResponse?>.value(), - ) as _i5.Future<_i2.DialogResponse?>); - - @override - void completeDialog(_i2.DialogResponse? response) => - super.noSuchMethod( - Invocation.method( - #completeDialog, - [response], - ), - returnValueForMissingStub: null, - ); -} - /// A class which mocks [AuthenticationService]. /// /// See the documentation for Mockito's code generation for more information. class MockAuthenticationService extends _i1.Mock - implements _i12.AuthenticationService { - @override - _i2.SnackbarService get snackbar => (super.noSuchMethod( - Invocation.getter(#snackbar), - returnValue: _FakeSnackbarService_0( - this, - Invocation.getter(#snackbar), - ), - returnValueForMissingStub: _FakeSnackbarService_0( - this, - Invocation.getter(#snackbar), - ), - ) as _i2.SnackbarService); - - @override - set snackbar(_i2.SnackbarService? _snackbar) => super.noSuchMethod( - Invocation.setter( - #snackbar, - _snackbar, - ), - returnValueForMissingStub: null, - ); - + implements _i8.AuthenticationService { @override - _i3.FlutterSecureStorage get store => (super.noSuchMethod( + _i2.FlutterSecureStorage get store => (super.noSuchMethod( Invocation.getter(#store), - returnValue: _FakeFlutterSecureStorage_1( + returnValue: _FakeFlutterSecureStorage_0( this, Invocation.getter(#store), ), - returnValueForMissingStub: _FakeFlutterSecureStorage_1( + returnValueForMissingStub: _FakeFlutterSecureStorage_0( this, Invocation.getter(#store), ), - ) as _i3.FlutterSecureStorage); + ) as _i2.FlutterSecureStorage); @override - _i4.Auth0 get auth0 => (super.noSuchMethod( + _i3.Auth0 get auth0 => (super.noSuchMethod( Invocation.getter(#auth0), - returnValue: _FakeAuth0_2( + returnValue: _FakeAuth0_1( this, Invocation.getter(#auth0), ), - returnValueForMissingStub: _FakeAuth0_2( + returnValueForMissingStub: _FakeAuth0_1( this, Invocation.getter(#auth0), ), - ) as _i4.Auth0); + ) as _i3.Auth0); @override - set auth0(_i4.Auth0? _auth0) => super.noSuchMethod( + set auth0(_i3.Auth0? _auth0) => super.noSuchMethod( Invocation.setter( #auth0, _auth0, @@ -717,7 +150,7 @@ class MockAuthenticationService extends _i1.Mock ); @override - set userModel(_i5.Future<_i6.FccUserModel>? _userModel) => super.noSuchMethod( + set userModel(_i4.Future<_i5.FccUserModel>? _userModel) => super.noSuchMethod( Invocation.setter( #userModel, _userModel, @@ -742,20 +175,20 @@ class MockAuthenticationService extends _i1.Mock ); @override - _i5.StreamController get progress => (super.noSuchMethod( + _i4.StreamController get progress => (super.noSuchMethod( Invocation.getter(#progress), - returnValue: _FakeStreamController_3( + returnValue: _FakeStreamController_2( this, Invocation.getter(#progress), ), - returnValueForMissingStub: _FakeStreamController_3( + returnValueForMissingStub: _FakeStreamController_2( this, Invocation.getter(#progress), ), - ) as _i5.StreamController); + ) as _i4.StreamController); @override - set progress(_i5.StreamController? _progress) => super.noSuchMethod( + set progress(_i4.StreamController? _progress) => super.noSuchMethod( Invocation.setter( #progress, _progress, @@ -803,44 +236,44 @@ class MockAuthenticationService extends _i1.Mock ) as String); @override - _i5.Stream get isLoggedIn => (super.noSuchMethod( + _i4.Stream get isLoggedIn => (super.noSuchMethod( Invocation.getter(#isLoggedIn), - returnValue: _i5.Stream.empty(), - returnValueForMissingStub: _i5.Stream.empty(), - ) as _i5.Stream); + returnValue: _i4.Stream.empty(), + returnValueForMissingStub: _i4.Stream.empty(), + ) as _i4.Stream); @override - _i5.Future hasRequiredTokens() => (super.noSuchMethod( + _i4.Future hasRequiredTokens() => (super.noSuchMethod( Invocation.method( #hasRequiredTokens, [], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future writeTokensToStorage() => (super.noSuchMethod( + _i4.Future writeTokensToStorage() => (super.noSuchMethod( Invocation.method( #writeTokensToStorage, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future setRequiredTokens() => (super.noSuchMethod( + _i4.Future setRequiredTokens() => (super.noSuchMethod( Invocation.method( #setRequiredTokens, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - void extractCookies(_i13.Response? res) => super.noSuchMethod( + void extractCookies(_i10.Response? res) => super.noSuchMethod( Invocation.method( #extractCookies, [res], @@ -849,33 +282,33 @@ class MockAuthenticationService extends _i1.Mock ); @override - _i5.Future setCurrentClientMode() => (super.noSuchMethod( + _i4.Future setCurrentClientMode() => (super.noSuchMethod( Invocation.method( #setCurrentClientMode, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future init() => (super.noSuchMethod( + _i4.Future init() => (super.noSuchMethod( Invocation.method( #init, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future<_i6.FccUserModel> parseUserModel(Map? data) => + _i4.Future<_i5.FccUserModel> parseUserModel(Map? data) => (super.noSuchMethod( Invocation.method( #parseUserModel, [data], ), - returnValue: _i5.Future<_i6.FccUserModel>.value(_FakeFccUserModel_4( + returnValue: _i4.Future<_i5.FccUserModel>.value(_FakeFccUserModel_3( this, Invocation.method( #parseUserModel, @@ -883,18 +316,18 @@ class MockAuthenticationService extends _i1.Mock ), )), returnValueForMissingStub: - _i5.Future<_i6.FccUserModel>.value(_FakeFccUserModel_4( + _i4.Future<_i5.FccUserModel>.value(_FakeFccUserModel_3( this, Invocation.method( #parseUserModel, [data], ), )), - ) as _i5.Future<_i6.FccUserModel>); + ) as _i4.Future<_i5.FccUserModel>); @override - _i5.Future login( - _i10.BuildContext? context, + _i4.Future login( + _i11.BuildContext? context, String? connectionType, { String? email, String? otp, @@ -911,29 +344,29 @@ class MockAuthenticationService extends _i1.Mock #otp: otp, }, ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future logout() => (super.noSuchMethod( + _i4.Future logout() => (super.noSuchMethod( Invocation.method( #logout, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future fetchUser() => (super.noSuchMethod( + _i4.Future fetchUser() => (super.noSuchMethod( Invocation.method( #fetchUser, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override void routeToLogin([bool? fromButton = false]) => super.noSuchMethod( @@ -949,29 +382,29 @@ class MockAuthenticationService extends _i1.Mock /// /// See the documentation for Mockito's code generation for more information. class MockDailyChallengeService extends _i1.Mock - implements _i14.DailyChallengeService { + implements _i12.DailyChallengeService { @override - _i5.Future> fetchAllDailyChallenges() => + _i4.Future> fetchAllDailyChallenges() => (super.noSuchMethod( Invocation.method( #fetchAllDailyChallenges, [], ), - returnValue: _i5.Future>.value( - <_i7.DailyChallengeOverview>[]), + returnValue: _i4.Future>.value( + <_i6.DailyChallengeOverview>[]), returnValueForMissingStub: - _i5.Future>.value( - <_i7.DailyChallengeOverview>[]), - ) as _i5.Future>); + _i4.Future>.value( + <_i6.DailyChallengeOverview>[]), + ) as _i4.Future>); @override - _i5.Future<_i7.DailyChallenge> fetchChallengeByDate(String? date) => + _i4.Future<_i6.DailyChallenge> fetchChallengeByDate(String? date) => (super.noSuchMethod( Invocation.method( #fetchChallengeByDate, [date], ), - returnValue: _i5.Future<_i7.DailyChallenge>.value(_FakeDailyChallenge_5( + returnValue: _i4.Future<_i6.DailyChallenge>.value(_FakeDailyChallenge_4( this, Invocation.method( #fetchChallengeByDate, @@ -979,22 +412,22 @@ class MockDailyChallengeService extends _i1.Mock ), )), returnValueForMissingStub: - _i5.Future<_i7.DailyChallenge>.value(_FakeDailyChallenge_5( + _i4.Future<_i6.DailyChallenge>.value(_FakeDailyChallenge_4( this, Invocation.method( #fetchChallengeByDate, [date], ), )), - ) as _i5.Future<_i7.DailyChallenge>); + ) as _i4.Future<_i6.DailyChallenge>); @override - _i5.Future<_i7.DailyChallenge> fetchTodayChallenge() => (super.noSuchMethod( + _i4.Future<_i6.DailyChallenge> fetchTodayChallenge() => (super.noSuchMethod( Invocation.method( #fetchTodayChallenge, [], ), - returnValue: _i5.Future<_i7.DailyChallenge>.value(_FakeDailyChallenge_5( + returnValue: _i4.Future<_i6.DailyChallenge>.value(_FakeDailyChallenge_4( this, Invocation.method( #fetchTodayChallenge, @@ -1002,19 +435,19 @@ class MockDailyChallengeService extends _i1.Mock ), )), returnValueForMissingStub: - _i5.Future<_i7.DailyChallenge>.value(_FakeDailyChallenge_5( + _i4.Future<_i6.DailyChallenge>.value(_FakeDailyChallenge_4( this, Invocation.method( #fetchTodayChallenge, [], ), )), - ) as _i5.Future<_i7.DailyChallenge>); + ) as _i4.Future<_i6.DailyChallenge>); @override - _i5.Future postChallengeCompleted({ + _i4.Future postChallengeCompleted({ required String? challengeId, - required _i7.DailyChallengeLanguage? language, + required _i6.DailyChallengeLanguage? language, }) => (super.noSuchMethod( Invocation.method( @@ -1025,15 +458,15 @@ class MockDailyChallengeService extends _i1.Mock #language: language, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future<_i8.Challenge> getDailyChallenge( + _i4.Future<_i7.Challenge> getDailyChallenge( String? date, - _i15.Block? block, { - _i7.DailyChallengeLanguage? language, + _i13.Block? block, { + _i6.DailyChallengeLanguage? language, }) => (super.noSuchMethod( Invocation.method( @@ -1044,7 +477,7 @@ class MockDailyChallengeService extends _i1.Mock ], {#language: language}, ), - returnValue: _i5.Future<_i8.Challenge>.value(_FakeChallenge_6( + returnValue: _i4.Future<_i7.Challenge>.value(_FakeChallenge_5( this, Invocation.method( #getDailyChallenge, @@ -1056,7 +489,7 @@ class MockDailyChallengeService extends _i1.Mock ), )), returnValueForMissingStub: - _i5.Future<_i8.Challenge>.value(_FakeChallenge_6( + _i4.Future<_i7.Challenge>.value(_FakeChallenge_5( this, Invocation.method( #getDailyChallenge, @@ -1067,20 +500,20 @@ class MockDailyChallengeService extends _i1.Mock {#language: language}, ), )), - ) as _i5.Future<_i8.Challenge>); + ) as _i4.Future<_i7.Challenge>); } /// A class which mocks [FlutterLocalNotificationsPlugin]. /// /// See the documentation for Mockito's code generation for more information. class MockFlutterLocalNotificationsPlugin extends _i1.Mock - implements _i16.FlutterLocalNotificationsPlugin { + implements _i14.FlutterLocalNotificationsPlugin { @override - _i5.Future initialize( - _i17.InitializationSettings? initializationSettings, { - _i18.DidReceiveNotificationResponseCallback? + _i4.Future initialize( + _i15.InitializationSettings? initializationSettings, { + _i16.DidReceiveNotificationResponseCallback? onDidReceiveNotificationResponse, - _i18.DidReceiveBackgroundNotificationResponseCallback? + _i16.DidReceiveBackgroundNotificationResponseCallback? onDidReceiveBackgroundNotificationResponse, }) => (super.noSuchMethod( @@ -1093,28 +526,28 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock onDidReceiveBackgroundNotificationResponse, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future<_i18.NotificationAppLaunchDetails?> + _i4.Future<_i16.NotificationAppLaunchDetails?> getNotificationAppLaunchDetails() => (super.noSuchMethod( Invocation.method( #getNotificationAppLaunchDetails, [], ), - returnValue: _i5.Future<_i18.NotificationAppLaunchDetails?>.value(), + returnValue: _i4.Future<_i16.NotificationAppLaunchDetails?>.value(), returnValueForMissingStub: - _i5.Future<_i18.NotificationAppLaunchDetails?>.value(), - ) as _i5.Future<_i18.NotificationAppLaunchDetails?>); + _i4.Future<_i16.NotificationAppLaunchDetails?>.value(), + ) as _i4.Future<_i16.NotificationAppLaunchDetails?>); @override - _i5.Future show( + _i4.Future show( int? id, String? title, String? body, - _i19.NotificationDetails? notificationDetails, { + _i17.NotificationDetails? notificationDetails, { String? payload, }) => (super.noSuchMethod( @@ -1128,12 +561,12 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock ], {#payload: payload}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future cancel( + _i4.Future cancel( int? id, { String? tag, }) => @@ -1143,30 +576,30 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock [id], {#tag: tag}, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future cancelAll() => (super.noSuchMethod( + _i4.Future cancelAll() => (super.noSuchMethod( Invocation.method( #cancelAll, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future zonedSchedule( + _i4.Future zonedSchedule( int? id, String? title, String? body, - _i20.TZDateTime? scheduledDate, - _i19.NotificationDetails? notificationDetails, { - required _i21.AndroidScheduleMode? androidScheduleMode, + _i18.TZDateTime? scheduledDate, + _i17.NotificationDetails? notificationDetails, { + required _i19.AndroidScheduleMode? androidScheduleMode, String? payload, - _i22.DateTimeComponents? matchDateTimeComponents, + _i20.DateTimeComponents? matchDateTimeComponents, }) => (super.noSuchMethod( Invocation.method( @@ -1184,18 +617,18 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock #matchDateTimeComponents: matchDateTimeComponents, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future periodicallyShow( + _i4.Future periodicallyShow( int? id, String? title, String? body, - _i18.RepeatInterval? repeatInterval, - _i19.NotificationDetails? notificationDetails, { - required _i21.AndroidScheduleMode? androidScheduleMode, + _i16.RepeatInterval? repeatInterval, + _i17.NotificationDetails? notificationDetails, { + required _i19.AndroidScheduleMode? androidScheduleMode, String? payload, }) => (super.noSuchMethod( @@ -1213,19 +646,19 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock #payload: payload, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future periodicallyShowWithDuration( + _i4.Future periodicallyShowWithDuration( int? id, String? title, String? body, Duration? repeatDurationInterval, - _i19.NotificationDetails? notificationDetails, { - _i21.AndroidScheduleMode? androidScheduleMode = - _i21.AndroidScheduleMode.exact, + _i17.NotificationDetails? notificationDetails, { + _i19.AndroidScheduleMode? androidScheduleMode = + _i19.AndroidScheduleMode.exact, String? payload, }) => (super.noSuchMethod( @@ -1243,44 +676,44 @@ class MockFlutterLocalNotificationsPlugin extends _i1.Mock #payload: payload, }, ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); @override - _i5.Future> + _i4.Future> pendingNotificationRequests() => (super.noSuchMethod( Invocation.method( #pendingNotificationRequests, [], ), returnValue: - _i5.Future>.value( - <_i18.PendingNotificationRequest>[]), + _i4.Future>.value( + <_i16.PendingNotificationRequest>[]), returnValueForMissingStub: - _i5.Future>.value( - <_i18.PendingNotificationRequest>[]), - ) as _i5.Future>); + _i4.Future>.value( + <_i16.PendingNotificationRequest>[]), + ) as _i4.Future>); @override - _i5.Future> getActiveNotifications() => + _i4.Future> getActiveNotifications() => (super.noSuchMethod( Invocation.method( #getActiveNotifications, [], ), - returnValue: _i5.Future>.value( - <_i18.ActiveNotification>[]), + returnValue: _i4.Future>.value( + <_i16.ActiveNotification>[]), returnValueForMissingStub: - _i5.Future>.value( - <_i18.ActiveNotification>[]), - ) as _i5.Future>); + _i4.Future>.value( + <_i16.ActiveNotification>[]), + ) as _i4.Future>); } /// A class which mocks [SharedPreferences]. /// /// See the documentation for Mockito's code generation for more information. -class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { +class MockSharedPreferences extends _i1.Mock implements _i21.SharedPreferences { @override Set getKeys() => (super.noSuchMethod( Invocation.method( @@ -1356,7 +789,7 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { ) as List?); @override - _i5.Future setBool( + _i4.Future setBool( String? key, bool? value, ) => @@ -1368,12 +801,12 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { value, ], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future setInt( + _i4.Future setInt( String? key, int? value, ) => @@ -1385,12 +818,12 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { value, ], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future setDouble( + _i4.Future setDouble( String? key, double? value, ) => @@ -1402,12 +835,12 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { value, ], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future setString( + _i4.Future setString( String? key, String? value, ) => @@ -1419,12 +852,12 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { value, ], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future setStringList( + _i4.Future setStringList( String? key, List? value, ) => @@ -1436,47 +869,47 @@ class MockSharedPreferences extends _i1.Mock implements _i23.SharedPreferences { value, ], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future remove(String? key) => (super.noSuchMethod( + _i4.Future remove(String? key) => (super.noSuchMethod( Invocation.method( #remove, [key], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future commit() => (super.noSuchMethod( + _i4.Future commit() => (super.noSuchMethod( Invocation.method( #commit, [], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future clear() => (super.noSuchMethod( + _i4.Future clear() => (super.noSuchMethod( Invocation.method( #clear, [], ), - returnValue: _i5.Future.value(false), - returnValueForMissingStub: _i5.Future.value(false), - ) as _i5.Future); + returnValue: _i4.Future.value(false), + returnValueForMissingStub: _i4.Future.value(false), + ) as _i4.Future); @override - _i5.Future reload() => (super.noSuchMethod( + _i4.Future reload() => (super.noSuchMethod( Invocation.method( #reload, [], ), - returnValue: _i5.Future.value(), - returnValueForMissingStub: _i5.Future.value(), - ) as _i5.Future); + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); }