feat: migrate to Riverpod 3.x#613
Conversation
- Bump Flutter version from 3.35.7 to 3.44.1 across .fvmrc and all GitHub workflow files - Upgrade Gradle wrapper from 8.9 to 8.14.3 - Upgrade Android Gradle Plugin from 8.6.0 to 8.11.1 - Upgrade Kotlin from 2.1.0 to 2.2.20 - Add Android build flags (builtInKotlin=false, newDsl=false) to gradle.properties - Replace deprecated lucide_icons package with lucide_icons_flutter (0.257.0 → 3.1.14) - Replace deprecated cacheExtent with scrollCache
chore: migrate to Flutter's built-in Kotlin support and update Kotlin configuration - Remove explicit kotlin-android plugin from app/build.gradle (now provided by Flutter) - Move kotlinOptions from android block to top-level kotlin.compilerOptions block - Update jvmTarget syntax to use org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 - Update comment to clarify KGP is declared in settings.gradle with apply false ```
chore: migrate from flutter_riverpod 2.x to 3.x with legacy compatibility layer - Upgrade flutter_riverpod from 2.6.1 to 3.3.2 and hooks_riverpod from 2.6.1 to 3.3.2 - Add flutter_riverpod/legacy.dart imports across all provider files to maintain compatibility with 2.x API - Replace AutoDisposeStateNotifierProvider shorthand with StateNotifierProvider.autoDispose long form - Replace AutoDisposeProvider shorthand with Provider.autoDispose long form - Update test mocks to use ProviderContainer
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
WalkthroughThis PR migrates the Flutter app from Riverpod 2.x to 3.x by updating dependencies, switching imports to legacy Riverpod APIs, replacing the Lucide icon package, and refactoring tests to use real ChangesRiverpod 3.x Migration with Flutter and Toolchain Upgrades
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly Related PRs
Suggested Reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9477686ccf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/features/relays/relays_notifier.dart (1)
692-692:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winFix Spanish comment.
Line 692 contains a Spanish comment:
"🔥 RESET COMPLETO: Limpiar todos los relays y hacer sync fresco". All code comments must be in English per the coding guidelines.🔧 Proposed fix
- // 🔥 RESET COMPLETO: Limpiar todos los relays y hacer sync fresco + // Reset all relays and perform fresh sync🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/features/relays/relays_notifier.dart` at line 692, Replace the Spanish inline comment "🔥 RESET COMPLETO: Limpiar todos los relays y hacer sync fresco" with an English equivalent, e.g. "🔥 FULL RESET: Clear all relays and perform a fresh sync", so comments in relays_notifier.dart are in English.Source: Coding guidelines
🧹 Nitpick comments (2)
lib/features/auth/providers/auth_notifier_provider.dart (1)
1-2: Fix Riverpod import consistency in provider/notifier files
lib/features/auth/providers/auth_notifier_provider.dart,lib/features/chat/chat_room_provider.dart, andlib/features/chat/notifiers/chat_rooms_notifier.dartonly useProvider,StateNotifierProvider,StateProvider,Ref, andStateNotifier, so they can dropimport 'package:flutter_riverpod/flutter_riverpod.dart';and keep onlyimport 'package:flutter_riverpod/legacy.dart';.- Keep
lib/features/chat/notifiers/chat_room_notifier.dartimportingpackage:flutter_riverpod/flutter_riverpod.dartbecause it declaresProviderSubscription<Session?>.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/features/auth/providers/auth_notifier_provider.dart` around lines 1 - 2, The file imports both flutter_riverpod.dart and legacy.dart but only uses legacy APIs; remove the top-level import "package:flutter_riverpod/flutter_riverpod.dart" from auth_notifier_provider.dart and keep only "package:flutter_riverpod/legacy.dart"; ensure the file still compiles by verifying it only references Provider, StateNotifierProvider, StateProvider, Ref, and StateNotifier (the symbols used by the provider/notifier code) and that no ProviderSubscription or other flutter_riverpod-only types are referenced here.lib/features/settings/settings_notifier.dart (1)
2-3: ⚡ Quick winRoot cause: Incomplete Riverpod 3 migration in four files—keep only
legacy.dartimportsFour files (
settings_notifier.dart,trades_provider.dart,first_run_provider.dart, andnwc_provider.dart) retain both the oldflutter_riverpod/flutter_riverpod.dartand the newflutter_riverpod/legacy.dartimports. In Riverpod 3,StateNotifier(used by all four) is only exported from the legacy entrypoint. The mainflutter_riverpodimport has become redundant and should be removed from each file to complete the migration cleanly and avoid analyzer warnings about unused imports. This aligns with the pattern correctly applied in other migrated files likerelays_provider.dartandsettings_provider.dart.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@lib/features/settings/settings_notifier.dart` around lines 2 - 3, Remove the redundant import of "package:flutter_riverpod/flutter_riverpod.dart" and keep only "package:flutter_riverpod/legacy.dart" so StateNotifier and related legacy exports resolve correctly; update settings_notifier.dart (look for class SettingsNotifier and any StateNotifier/StateNotifierProvider usages) to import only the legacy entrypoint and repeat the same change in trades_provider.dart, first_run_provider.dart, and nwc_provider.dart to eliminate the unused-import analyzer warnings and complete the Riverpod 3 migration.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@android/app/build.gradle`:
- Around line 116-120: The comment stating that Kotlin is "provided by Flutter’s
built-in Kotlin support" is misleading because gradle.properties sets
android.builtInKotlin=false; update the comment near the kotlin {
compilerOptions { jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 }
} block to reflect that the project is opting out of AGP built-in Kotlin
(legacy/manual Kotlin plugin usage), or instead migrate to AGP built-in Kotlin
by removing/setting android.builtInKotlin to true and adjusting the Kotlin
plugin setup accordingly; ensure the comment accurately references
android.builtInKotlin and the kotlin { ... } configuration so future readers
understand which mode is in use.
In `@test/notifiers/take_order_notifier_test.dart`:
- Around line 50-56: The test constructs MockSessionNotifier with a throwaway
ProviderContainer (via createTestRef(refContainer)) and then injects it with
sessionNotifierProvider.overrideWith, causing ref-based reads in SessionNotifier
to resolve against the wrong provider graph; change each override (the
sessionNotifierProvider.overrideWith calls around the noted locations) to create
MockSessionNotifier using the override callback’s ref (i.e., overrideWith((ref)
=> MockSessionNotifier(ref, mockKeyManager, mockSessionStorage, testSettings)))
instead of prebuilding a ref from ProviderContainer, and remove the throwaway
createTestRef usage and its ProviderContainer/tearDown for those overrides so
provider wiring uses the same ref throughout.
In `@test/services/mostro_service_test.dart`:
- Around line 66-73: The file defines a file-scoped ProviderContainer named
dummyContainer (and dummyRef created via createTestRef) that's never disposed,
leaving Riverpod listeners from MockSubscriptionManager(dummyRef) alive for the
whole test suite; add a suite-level teardown to call dummyContainer.dispose()
(e.g., using tearDownAll(() => dummyContainer.dispose())) so
sessionNotifierProvider overrides and ref.onDispose handlers are cleaned up
after the suite.
---
Outside diff comments:
In `@lib/features/relays/relays_notifier.dart`:
- Line 692: Replace the Spanish inline comment "🔥 RESET COMPLETO: Limpiar todos
los relays y hacer sync fresco" with an English equivalent, e.g. "🔥 FULL RESET:
Clear all relays and perform a fresh sync", so comments in relays_notifier.dart
are in English.
---
Nitpick comments:
In `@lib/features/auth/providers/auth_notifier_provider.dart`:
- Around line 1-2: The file imports both flutter_riverpod.dart and legacy.dart
but only uses legacy APIs; remove the top-level import
"package:flutter_riverpod/flutter_riverpod.dart" from
auth_notifier_provider.dart and keep only
"package:flutter_riverpod/legacy.dart"; ensure the file still compiles by
verifying it only references Provider, StateNotifierProvider, StateProvider,
Ref, and StateNotifier (the symbols used by the provider/notifier code) and that
no ProviderSubscription or other flutter_riverpod-only types are referenced
here.
In `@lib/features/settings/settings_notifier.dart`:
- Around line 2-3: Remove the redundant import of
"package:flutter_riverpod/flutter_riverpod.dart" and keep only
"package:flutter_riverpod/legacy.dart" so StateNotifier and related legacy
exports resolve correctly; update settings_notifier.dart (look for class
SettingsNotifier and any StateNotifier/StateNotifierProvider usages) to import
only the legacy entrypoint and repeat the same change in trades_provider.dart,
first_run_provider.dart, and nwc_provider.dart to eliminate the unused-import
analyzer warnings and complete the Riverpod 3 migration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e908b7b5-7f68-4974-9cd5-9ab1a084dc01
⛔ Files ignored due to path filters (1)
pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (75)
.fvmrc.github/workflows/desktop.yml.github/workflows/flutter.yml.github/workflows/main.yml.github/workflows/release.ymlandroid/app/build.gradleandroid/gradle.propertiesandroid/gradle/wrapper/gradle-wrapper.propertiesandroid/settings.gradlelib/features/auth/notifiers/auth_notifier.dartlib/features/auth/providers/auth_notifier_provider.dartlib/features/chat/chat_room_provider.dartlib/features/chat/notifiers/chat_room_notifier.dartlib/features/chat/notifiers/chat_rooms_notifier.dartlib/features/chat/providers/active_chat_screens_provider.dartlib/features/chat/providers/chat_room_providers.dartlib/features/chat/providers/chat_tab_provider.dartlib/features/chat/widgets/chat_messages_list.dartlib/features/community/providers/community_selector_provider.dartlib/features/disputes/notifiers/dispute_chat_notifier.dartlib/features/disputes/providers/dispute_read_status_provider.dartlib/features/home/providers/home_order_providers.dartlib/features/key_manager/key_management_screen.dartlib/features/logs/logs_provider.dartlib/features/mostro/mostro_instance_provider.dartlib/features/mostro/mostro_nodes_notifier.dartlib/features/mostro/mostro_nodes_provider.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/features/notifications/providers/backup_reminder_provider.dartlib/features/notifications/providers/notifications_provider.dartlib/features/order/notifiers/abstract_mostro_notifier.dartlib/features/order/providers/order_notifier_provider.dartlib/features/order/providers/payment_methods_provider.dartlib/features/relays/relays_notifier.dartlib/features/relays/relays_provider.dartlib/features/restore/restore_mode_provider.dartlib/features/restore/restore_progress_notifier.dartlib/features/settings/about_screen.dartlib/features/settings/notification_settings_screen.dartlib/features/settings/settings_notifier.dartlib/features/settings/settings_provider.dartlib/features/settings/settings_screen.dartlib/features/trades/providers/trades_provider.dartlib/features/trades/widgets/status_filter_widget.dartlib/features/walkthrough/providers/first_run_provider.dartlib/features/wallet/providers/nwc_provider.dartlib/features/wallet/screens/connect_wallet_screen.dartlib/features/wallet/screens/wallet_settings_screen.dartlib/features/wallet/widgets/wallet_balance_widget.dartlib/features/wallet/widgets/wallet_status_card.dartlib/services/event_bus.dartlib/services/exchange_service.dartlib/shared/notifiers/locale_notifier.dartlib/shared/notifiers/navigation_notifier.dartlib/shared/notifiers/session_notifier.dartlib/shared/providers/drawer_provider.dartlib/shared/providers/exchange_service_provider.dartlib/shared/providers/navigation_notifier_provider.dartlib/shared/providers/session_notifier_provider.dartlib/shared/widgets/bottom_nav_bar.dartlib/shared/widgets/custom_drawer_overlay.dartlib/shared/widgets/ln_address_confirmation_widget.dartlib/shared/widgets/nwc_connection_status_indicator.dartlib/shared/widgets/nwc_invoice_widget.dartlib/shared/widgets/nwc_notification_listener.dartlib/shared/widgets/nwc_payment_receipt_widget.dartlib/shared/widgets/nwc_payment_widget.dartpubspec.yamltest/features/mostro/mostro_integration_test.darttest/features/mostro/mostro_nodes_notifier_test.darttest/features/mostro/mostro_nodes_performance_test.darttest/mocks.darttest/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/services/mostro_service_test.dart
chore: remove throwaway ref container and add suite-level teardown - Remove throwaway ProviderContainer and createTestRef() call from take_order_notifier_test setup; inline MockSessionNotifier construction in each override instead - Rename mockSessionNotifier to testSettings since the mock is no longer shared - Add tearDownAll(dummyContainer.dispose) in mostro_service_test to clean up the dummy container's subscription manager listeners at suite end - Replace Spanish comment with English
There was a problem hiding this comment.
Reviewed on the current head SHA.
No blocking issues found. CI is green, the Riverpod 3 migration looks consistent, and the Android/Gradle updates are coherent on this branch.
Non-blocking note: this PR still depends on #612 as stated in the description, so merge order still matters.
There was a problem hiding this comment.
I reviewed the current head and I do see one real blocking issue before merge.
Blocking issue:
- This PR is framed as a Riverpod 3 migration, but the implementation relies heavily on
flutter_riverpod/legacy.dartand on manufacturing a reusableRefin tests viacreateTestRef(container)from a probe provider. - That captured
Refis tied to the lifecycle/ownership of the probe provider read, not a generic application-wide ref. Using it as a stand-in to construct long-lived objects such asMostroService,MostroNodesNotifier, andMockSubscriptionManageris a fragile pattern for a framework migration becauseRefcarries lifecycle semantics (listen,onDispose, ownership context), not justread(). - In other words, the tests are making the code appear Riverpod-3-compatible by fabricating a reusable ref object outside the real provider that should own it.
Why I think this is a blocker:
- For a migration PR, the correctness bar is not only “does CI pass today”, but “are we depending on compatibility shims and test-only ref fabrication in a way that can hide lifecycle breakage”.
- If the new pattern for constructing/refactoring provider-owned objects is “capture a
Reffrom a probe and reuse it everywhere”, that is a shaky foundation and can mask bugs around listener ownership/disposal semantics. - This is especially relevant because the PR mixes direct
flutter_riverpod.dartimports andlegacy.dartimports across the tree, which reinforces that the migration is not yet conceptually settled.
What I would want:
- Either keep the scope honest as a temporary compatibility shim and avoid presenting it as the Riverpod 3 migration proper, or refactor the affected construction/testing patterns so provider-owned objects are exercised through their real provider contexts instead of a synthetic captured
Ref. - At minimum, I would not merge a framework migration whose test strategy depends on a probe-generated reusable
Refas the general substitute for ownership-aware provider refs.
I do not mean “rewrite the entire app to Notifier/AsyncNotifier now”, but I do think this lifecycle/testing pattern is too shaky to bless as the migration baseline.
Closes #512
Important
Depends on #612 — that PR must be merged first. This branch is based on it and
Riverpod 3.x requires the Flutter 3.44.1 / Dart 3.12 toolchain it introduces.
Upgrades
flutter_riverpod/hooks_riverpodto^3.3.2, keeping the existingStateNotifierarchitecture via the legacy compatibility layer (fullNotifiermigration is out of scope).flutter_riverpod/legacy.dartimports forStateNotifier/StateProvider.AutoDispose*aliases with the.autoDisposemodifier.Ref/ProviderSubscriptionare now sealed — drop them from@GenerateMocksand migrate 6 test files to a realProviderContainer.Validation:
flutter analyzeclean, 449 tests passing.Summary by CodeRabbit