-
Notifications
You must be signed in to change notification settings - Fork 16
fix: resolve relay addition and order publishing issues in settings #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Fix NostrService relay update mechanism to prevent empty relay list errors during order publishing - Enhance relay validation with fallback WebSocket connectivity testing - Add proper error handling and state management in NostrService updateSettings() - Implement defensive checks in publishEvent() to prevent assertion failures - Add comprehensive localization support for relay-related UI messages - Update all tests to maintain coverage with new method signatures - Resolve BuildContext async gap warnings in relay selector This resolves the issue where users could add new relays through the settings screen but then encounter "relaysUrl.isNotEmpty" assertion failures when trying to publish orders.
|
Warning Rate limit exceeded@grunch has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 57 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
WalkthroughThis update introduces advanced relay URL validation, normalization, and connectivity testing to the relay management logic. It enhances the relay addition dialog with real-time validation and user feedback, adds new localization strings for relay operations in English, Spanish, and Italian, and strengthens the Nostr service's relay management and error handling. Comprehensive unit and widget tests are added for the new logic, with expanded mocking support. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant RelaySelectorWidget
participant RelaysNotifier
participant NostrService
User->>RelaySelectorWidget: Open add relay dialog
User->>RelaySelectorWidget: Enter relay URL and tap Add
RelaySelectorWidget->>RelaysNotifier: addRelayWithSmartValidation(input, error messages)
RelaysNotifier->>RelaysNotifier: normalizeRelayUrl(input)
alt Invalid URL
RelaysNotifier-->>RelaySelectorWidget: RelayValidationResult (error)
RelaySelectorWidget-->>User: Show error dialog
else Valid URL
RelaysNotifier->>RelaysNotifier: testRelayConnectivity(url)
alt Relay reachable
RelaysNotifier-->>RelaySelectorWidget: RelayValidationResult (success, healthy)
RelaySelectorWidget-->>User: Close dialog, show success snackbar
RelaySelectorWidget->>NostrService: (Relay added to settings)
else Relay unreachable
RelaysNotifier-->>RelaySelectorWidget: RelayValidationResult (success, not healthy)
RelaySelectorWidget-->>User: Close dialog, show partial success snackbar
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (2)
l10n.yaml (1)
6-6: Add missing newline at end of file.The file is missing a trailing newline character, which violates POSIX standards and triggers YAMLlint errors.
-synthetic-package: false +synthetic-package: falselib/features/relays/relays_notifier.dart (1)
156-160: Consider using async primitives instead of busy waiting.The busy-wait loop for connection establishment could be more efficient.
Consider using a Completer or StreamController to await the connection event:
final connectionCompleter = Completer<bool>(); // In onRelayConnectionDone callback: connectionCompleter.complete(true); // In onRelayConnectionError callback: connectionCompleter.complete(false); // Wait for connection final connected = await connectionCompleter.future .timeout(const Duration(seconds: 5), onTimeout: () => false);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
l10n.yaml(1 hunks)lib/features/relays/relays_notifier.dart(2 hunks)lib/features/relays/widgets/relay_selector.dart(2 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(1 hunks)lib/l10n/intl_it.arb(1 hunks)lib/services/nostr_service.dart(3 hunks)test/features/relays/relays_notifier_test.dart(1 hunks)test/features/relays/widgets/relay_selector_test.dart(1 hunks)test/mocks.dart(2 hunks)test/mocks.mocks.dart(21 hunks)test/notifiers/add_order_notifier_test.dart(1 hunks)test/notifiers/take_order_notifier_test.dart(4 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
test/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
Unit tests must be placed in the
test/directory
Files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
Files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.dartlib/features/relays/widgets/relay_selector.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dartlib/services/nostr_service.dartlib/features/relays/relays_notifier.dart
test/mocks*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
Mocks must be generated using Mockito in
test/mocks.dartandtest/mocks.mocks.dart
Files:
test/mocks.darttest/mocks.mocks.dart
lib/l10n/*.arb
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/l10n/*.arb: Internationalization must useflutter_intlwith ARB files inlib/l10n/
Use proper ARB metadata for parameterized strings
Files:
lib/l10n/intl_es.arblib/l10n/intl_it.arblib/l10n/intl_en.arb
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit Inference Engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_es.arblib/l10n/intl_it.arblib/l10n/intl_en.arb
lib/features/*/{screens,providers,notifiers,widgets}/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
Feature-based organization:
features/{feature}/{screens|providers|notifiers|widgets}/
Files:
lib/features/relays/widgets/relay_selector.dart
lib/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization
Always use latest APIs (e.g.,withValues()instead ofwithOpacity())
Always checkmountedbefore using context after async operations
Files:
lib/features/relays/widgets/relay_selector.dartlib/services/nostr_service.dartlib/features/relays/relays_notifier.dart
test/mocks.mocks.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
test/mocks.mocks.dart: The generated filetest/mocks.mocks.dartis auto-generated by Mockito and must not be manually edited
Do not add individual// ignore: must_be_immutablecomments to classes intest/mocks.mocks.dart
Never manually edittest/mocks.mocks.dart- it's auto-generated by Mockito
Mock files must have file-level// ignore_for_file: must_be_immutableand must not add more
Files:
test/mocks.mocks.dart
{lib/generated/**/*.dart,**/*.g.dart,**/*.mocks.dart}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Never manually edit generated files (
*.g.dart,*.mocks.dart,lib/generated/)
Files:
test/mocks.mocks.dart
{**/*.g.dart,**/*.mocks.dart}
📄 CodeRabbit Inference Engine (CLAUDE.md)
{**/*.g.dart,**/*.mocks.dart}: Never add ignore comments to generated files (*.g.dart,*.mocks.dart)
Never add ignore comments to generated files (*.g.dart,*.mocks.dart)
Files:
test/mocks.mocks.dart
{**/*.g.dart,**/*.mocks.dart,lib/generated/**/*.dart}
📄 CodeRabbit Inference Engine (CLAUDE.md)
{**/*.g.dart,**/*.mocks.dart,lib/generated/**/*.dart}: If analyzer issues exist in generated files, regenerate them instead of adding ignores
If analyzer issues exist in generated files, regenerate them instead of adding ignores
Files:
test/mocks.mocks.dart
lib/services/nostr_service.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/services/nostr_service.dart: All Nostr protocol interactions must go throughservices/nostr_service.dart
CustomtimeAgoWithLocale()method must be implemented in the NostrEvent extension
Files:
lib/services/nostr_service.dart
🧠 Learnings (35)
📚 Learning: applies to {lib/generated/**/*.dart,**/*.g.dart,**/*.mocks.dart} : never manually edit generated fil...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to {lib/generated/**/*.dart,**/*.g.dart,**/*.mocks.dart} : Never manually edit generated files (`*.g.dart`, `*.mocks.dart`, `lib/generated/`)
Applied to files:
l10n.yamltest/mocks.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: regenerate generated files using `dart run build_runner build -d`...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Regenerate generated files using `dart run build_runner build -d`
Applied to files:
l10n.yaml
📚 Learning: after modifying arb files, run `dart run build_runner build -d` to regenerate localization files...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: After modifying ARB files, run `dart run build_runner build -d` to regenerate localization files
Applied to files:
l10n.yaml
📚 Learning: applies to **/*.dart : remove unused imports and dependencies...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies
Applied to files:
l10n.yamltest/mocks.dart
📚 Learning: applies to lib/**/*.dart : always use localized strings instead of hardcoded text...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/**/*.dart : Always use localized strings instead of hardcoded text
Applied to files:
l10n.yamllib/features/relays/widgets/relay_selector.dart
📚 Learning: applies to test/mocks.mocks.dart : the generated file `test/mocks.mocks.dart` is auto-generated by m...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : The generated file `test/mocks.mocks.dart` is auto-generated by Mockito and must not be manually edited
Applied to files:
l10n.yamltest/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to {**/*.g.dart,**/*.mocks.dart} : never add ignore comments to generated files (`*.g.dart`,...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to {**/*.g.dart,**/*.mocks.dart} : Never add ignore comments to generated files (`*.g.dart`, `*.mocks.dart`)
Applied to files:
l10n.yamltest/mocks.dart
📚 Learning: applies to {**/*.g.dart,**/*.mocks.dart,lib/generated/**/*.dart} : if analyzer issues exist in gener...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to {**/*.g.dart,**/*.mocks.dart,lib/generated/**/*.dart} : If analyzer issues exist in generated files, regenerate them instead of adding ignores
Applied to files:
l10n.yamltest/mocks.dart
📚 Learning: applies to test/mocks.mocks.dart : never manually edit `test/mocks.mocks.dart` - it's auto-generated...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : Never manually edit `test/mocks.mocks.dart` - it's auto-generated by Mockito
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to test/mocks.mocks.dart : do not add individual `// ignore: must_be_immutable` comments to ...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : Do not add individual `// ignore: must_be_immutable` comments to classes in `test/mocks.mocks.dart`
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to test/mocks.mocks.dart : mock files must have file-level `// ignore_for_file: must_be_immu...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : Mock files must have file-level `// ignore_for_file: must_be_immutable` and must not add more
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to test/mocks*.dart : mocks must be generated using mockito in `test/mocks.dart` and `test/m...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks*.dart : Mocks must be generated using Mockito in `test/mocks.dart` and `test/mocks.mocks.dart`
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: mostroservice methods like takebuyorder() and takesellorder() return future and trigger side e...
Learnt from: chebizarro
PR: MostroP2P/mobile#110
File: test/notifiers/take_order_notifier_test.dart:72-74
Timestamp: 2025-06-04T19:35:20.209Z
Learning: MostroService methods like takeBuyOrder() and takeSellOrder() return Future<void> and trigger side effects through other mechanisms rather than direct return values. When testing these methods, focus on verifying method calls and testing state changes through the provider system rather than mocking return values.
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.mocks.dart
📚 Learning: applies to lib/features/*/providers/**/*.dart : providers are organized by feature in `features/{fea...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/features/*/providers/**/*.dart : Providers are organized by feature in `features/{feature}/providers/`
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: in abstractmostronotifier, state updates occur for all messages regardless of timestamp to hydrate t...
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.dart
📚 Learning: applies to lib/features/*/{screens,providers,notifiers,widgets}/**/*.dart : feature-based organizati...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/features/*/{screens,providers,notifiers,widgets}/**/*.dart : Feature-based organization: `features/{feature}/{screens|providers|notifiers|widgets}/`
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: in the mostro mobile codebase, `eventstorageprovider` is exported from `package:mostro_mobile/shared...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, `eventStorageProvider` is exported from `package:mostro_mobile/shared/providers/mostro_service_provider.dart` and not from a separate `event_storage_provider.dart` file.
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/mocks.mocks.dart
📚 Learning: applies to lib/shared/providers/mostro_database_provider.dart : database initialization must occur i...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/shared/providers/mostro_database_provider.dart : Database initialization must occur in `shared/providers/mostro_database_provider.dart`
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/mocks.mocks.dartlib/services/nostr_service.dart
📚 Learning: in the mostro mobile codebase, riverpod code generation is used with `@riverpod` annotations. provid...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `@Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.
Applied to files:
test/notifiers/add_order_notifier_test.darttest/notifiers/take_order_notifier_test.darttest/mocks.darttest/mocks.mocks.dart
📚 Learning: applies to test/**/*.dart : unit tests must be placed in the `test/` directory...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/**/*.dart : Unit tests must be placed in the `test/` directory
Applied to files:
test/notifiers/take_order_notifier_test.darttest/features/relays/relays_notifier_test.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to lib/data/models.dart : models must be exported through `data/models.dart`...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/data/models.dart : Models must be exported through `data/models.dart`
Applied to files:
test/mocks.darttest/mocks.mocks.dart
📚 Learning: applies to lib/data/repositories/**/*.dart : all data access must go through repository classes in `...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/data/repositories/**/*.dart : All data access must go through repository classes in `data/repositories/`
Applied to files:
test/mocks.darttest/mocks.mocks.dart
📚 Learning: applies to lib/services/nostr_service.dart : all nostr protocol interactions must go through `servic...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/services/nostr_service.dart : All Nostr protocol interactions must go through `services/nostr_service.dart`
Applied to files:
test/mocks.darttest/features/relays/relays_notifier_test.darttest/mocks.mocks.dartlib/services/nostr_service.dartlib/features/relays/relays_notifier.dart
📚 Learning: applies to lib/shared/**/*.dart : shared utilities and widgets must be placed in `shared/`...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/shared/**/*.dart : Shared utilities and widgets must be placed in `shared/`
Applied to files:
test/mocks.dart
📚 Learning: applies to lib/l10n/intl_{en,es,it}.arb : add new localization keys to all three arb files (en, es, ...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_it.arblib/l10n/intl_en.arb
📚 Learning: applies to lib/l10n/*.arb : use proper arb metadata for parameterized strings...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for parameterized strings
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_it.arblib/l10n/intl_en.arb
📚 Learning: applies to integration_test/**/*.dart : integration tests must be placed in the `integration_test/` ...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to integration_test/**/*.dart : Integration tests must be placed in the `integration_test/` directory
Applied to files:
test/features/relays/relays_notifier_test.darttest/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to lib/l10n/*.arb : internationalization must use `flutter_intl` with arb files in `lib/l10n...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/l10n/*.arb : Internationalization must use `flutter_intl` with ARB files in `lib/l10n/`
Applied to files:
lib/l10n/intl_en.arb
📚 Learning: use riverpod for all state management...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Use Riverpod for all state management
Applied to files:
test/mocks.mocks.dartlib/features/relays/relays_notifier.dart
📚 Learning: applies to lib/services/nostr_service.dart : custom `timeagowithlocale()` method must be implemented...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/services/nostr_service.dart : Custom `timeAgoWithLocale()` method must be implemented in the NostrEvent extension
Applied to files:
test/mocks.mocks.dartlib/services/nostr_service.dart
📚 Learning: in the nostr protocol, event.id will never be null in events returned by relay subscriptions, so nul...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/notifications/notification_service.dart:54-59
Timestamp: 2025-05-08T16:31:29.582Z
Learning: In the Nostr protocol, event.id will never be null in events returned by relay subscriptions, so null safety checks for this property are unnecessary.
Applied to files:
test/mocks.mocks.dartlib/services/nostr_service.dartlib/features/relays/relays_notifier.dart
📚 Learning: in abstractmostronotifier, the handleevent method is synchronous and returns void, not future....
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.
Applied to files:
test/mocks.mocks.dart
📚 Learning: applies to lib/core/mostro_fsm.dart : order state transitions must be managed by `core/mostro_fsm.da...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions must be managed by `core/mostro_fsm.dart`
Applied to files:
test/mocks.mocks.dart
📚 Learning: all changes should pass `flutter analyze` before commit...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: All changes should pass `flutter analyze` before commit
Applied to files:
test/features/relays/widgets/relay_selector_test.dart
📚 Learning: applies to lib/**/*.dart : always check `mounted` before using context after async operations...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/**/*.dart : Always check `mounted` before using context after async operations
Applied to files:
test/features/relays/widgets/relay_selector_test.dart
🪛 YAMLlint (1.37.1)
l10n.yaml
[error] 6-6: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (19)
test/notifiers/add_order_notifier_test.dart (1)
83-87: LGTM! Mock initialization pattern updated correctly.The change from constructor-based initialization to property assignment after instantiation aligns with the MockSettingsNotifier refactoring. This standardizes the mock initialization pattern across the test suite.
lib/l10n/intl_it.arb (1)
694-703: ✅ Relay localization keys consistent across all ARB filesVerified that all 12 relay-related keys from lib/l10n/intl_it.arb (
relayAddedSuccessfully,relayAddedUnreachable,relayErrorAlreadyExists,relayErrorConnectionTimeout,relayErrorInvalidDomain,relayErrorNoHttp,relayErrorNotValid,relayErrorOnlySecure,relayTestingMessage,relayUrl,relays, andrelaysInfoText) are also present in lib/l10n/intl_en.arb and lib/l10n/intl_es.arb. No discrepancies found—everything is in sync. LGTM, ready to merge.lib/l10n/intl_en.arb (1)
656-683: LGTM! Comprehensive English relay localization entries.The new relay management localization strings provide excellent user feedback covering all validation scenarios, testing states, and success conditions. The proper ARB metadata with placeholders ensures dynamic content can be displayed correctly.
These entries form the foundation for the enhanced relay validation and connectivity testing features mentioned in the PR objectives.
test/notifiers/take_order_notifier_test.dart (4)
123-132: LGTM! New mock pattern correctly implemented.The updated settingsProvider override properly follows the new MockSettingsNotifier pattern - instantiating without parameters and explicitly setting the state. The Settings object maintains the same configuration as before.
192-202: LGTM! Consistent implementation of mock pattern.The settingsProvider override correctly uses the new MockSettingsNotifier pattern with explicit state setting. The different mostroPublicKey value appears intentional for this test scenario.
260-270: Pattern correctly applied.The settingsProvider override maintains consistency with the new mock instantiation pattern and provides appropriate Settings configuration for the test.
315-325: Excellent consistency across all test methods.The final settingsProvider override correctly implements the new mock pattern, maintaining consistency with all other test methods in the file. This ensures reliable test behavior across the entire test suite.
test/mocks.dart (2)
37-37: LGTM! RelaysNotifier correctly added to mock generation.The addition of RelaysNotifier to the @GenerateMocks annotation is necessary to support testing of the new relay validation functionality introduced in this PR.
42-50: Excellent refactoring of MockSettingsNotifier constructor.The simplified constructor design improves separation of concerns by:
- Removing parameter dependencies
- Explicitly setting state with sensible defaults
- Making mock usage more predictable and easier to customize in tests
This aligns perfectly with the updated usage pattern seen in test files throughout the PR.
lib/features/relays/widgets/relay_selector.dart (1)
122-237: Excellent async implementation with proper BuildContext safety.This refactoring demonstrates excellent Flutter async patterns:
✅ Proper async handling: Loading states, error handling, and success feedback
✅ BuildContext safety: Localized strings captured before async operations
✅ Comprehensive UX: Different success messages based on relay health status
✅ Error differentiation: Specific error dialogs for various validation failures
✅ Integration: Seamless use of the newaddRelayWithSmartValidationmethodThe implementation follows coding guidelines by using localized strings and checking
mountedbefore using context after async operations.test/features/relays/relays_notifier_test.dart (1)
1-213: Excellent comprehensive test suite for RelaysNotifier.This test file demonstrates outstanding test engineering practices:
✅ Comprehensive Coverage: Tests URL normalization, domain validation, error scenarios, and real connectivity
✅ Proper Organization: Logical grouping with descriptive names makes tests easy to understand and maintain
✅ Network Test Safety: Real connectivity tests use appropriate timeouts and test against known working relays
✅ Edge Case Handling: Thorough testing of various domain formats and invalid inputs
✅ Clear Assertions: Descriptive reason parameters make test failures easy to debug
✅ Mock Integration: Properly uses MockSettingsNotifier from the established mocking systemThe tests provide excellent validation of the new relay management functionality and will help ensure reliability of the enhanced relay validation logic.
test/features/relays/widgets/relay_selector_test.dart (1)
1-336: LGTM! Comprehensive widget test coverage.The test file provides excellent coverage for the RelaySelector dialog, including:
- UI element verification
- Validation error handling
- Loading state management
- Success and error scenarios
- Edge cases like empty/whitespace input
The tests are well-structured and properly use mocks to isolate the widget behavior.
test/mocks.mocks.dart (1)
1-2411: Auto-generated file - no manual review needed.This is a Mockito-generated file that should not be manually edited. The new
MockRelaysNotifierand related fakes are properly generated to support the new relay validation functionality.lib/services/nostr_service.dart (3)
21-27: Good defensive programming with the safe getter.The nullable
_settingsfield with a safe getter that returns a default instance is a good pattern. This prevents null reference errors while the service is being initialized.
75-111: Excellent error handling and state management in updateSettings.The implementation correctly:
- Compares relay lists to avoid unnecessary updates
- Validates non-empty relay lists
- Handles failures by attempting to restore previous state
- Provides detailed logging for debugging
124-144: Well-implemented defensive checks in publishEvent.The defensive check for empty relay lists and the enhanced error message for the assertion error provide much better developer experience. This directly addresses the PR objective of fixing the "relaysUrl.isNotEmpty" assertion failure.
lib/features/relays/relays_notifier.dart (3)
9-21: Well-designed result class for relay validation.The
RelayValidationResultclass properly encapsulates all possible outcomes of relay validation, making it easy for the UI to handle different scenarios.
56-93: Excellent URL normalization and domain validation.The implementation correctly:
- Handles various input formats
- Enforces secure WebSocket usage
- Validates domain format while rejecting IP addresses
- Uses proper regex for domain validation
267-326: Comprehensive relay validation implementation.The
addRelayWithSmartValidationmethod excellently integrates all validation steps:
- URL normalization with specific error messages
- Duplicate checking
- Connectivity testing
- Only adds healthy relays
This implementation directly addresses the PR objectives by ensuring only valid, reachable relays are added.
In order to avoid potential conflicts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
lib/features/relays/relays_notifier.dart (1)
115-118: Potential issue with Nostr instance creation.The comment indicates creating an "isolated instance for testing," but
Nostr()constructor may not actually create a separate instance if the library uses internal singletons. This could lead to interference with the main app's Nostr operations.Based on the past review comment, this issue was already identified. The concern about using
Nostr()vsNostr.instancefor isolation remains valid and should be verified against the dart_nostr library documentation.
🧹 Nitpick comments (3)
lib/features/relays/relays_notifier.dart (3)
55-68: Security-conscious URL normalization with minor enhancement opportunity.The method correctly rejects insecure protocols and normalizes URLs appropriately. However, consider adding validation for maximum URL length to prevent potential DoS attacks.
String? normalizeRelayUrl(String input) { input = input.trim().toLowerCase(); + + // Prevent excessively long URLs + if (input.length > 2048) return null; if (!isValidDomainFormat(input)) return null;
154-159: Consider making connection timeout configurable.The hardcoded 5-second timeout and polling interval might not be optimal for all network conditions, especially on slower mobile connections.
Consider making the connection timeout configurable:
// Wait for connection establishment (max 5 seconds) int connectionWaitCount = 0; - while (!isConnected && connectionWaitCount < 50) { + const maxWaitMs = 5000; // Make this configurable if needed + const pollIntervalMs = 100; + while (!isConnected && connectionWaitCount < (maxWaitMs / pollIntervalMs)) { await Future.delayed(const Duration(milliseconds: 100)); connectionWaitCount++; }
180-185: Timeout values could be more flexible.The 8-second total timeout for EVENT/EOSE responses might be too long for mobile users expecting quick feedback, but could be too short for slower relays.
Consider making response timeouts configurable based on the use case (quick validation vs thorough testing):
// Wait for EVENT or EOSE responses (max 8 seconds total) + const responseTimeoutMs = 3000; // Shorter for better UX int waitCount = 0; - while (!receivedEvent && !receivedEose && waitCount < 80) { + while (!receivedEvent && !receivedEose && waitCount < (responseTimeoutMs / 100)) { await Future.delayed(const Duration(milliseconds: 100)); waitCount++; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
lib/features/relays/relays_notifier.dart(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
lib/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
Always use localized strings instead of hardcoded text
Pass BuildContext to methods that need localization
Always use latest APIs (e.g.,withValues()instead ofwithOpacity())
Always checkmountedbefore using context after async operations
Files:
lib/features/relays/relays_notifier.dart
**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
Files:
lib/features/relays/relays_notifier.dart
🧠 Learnings (9)
📚 Learning: in the nostr protocol, event.id will never be null in events returned by relay subscriptions, so nul...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/notifications/notification_service.dart:54-59
Timestamp: 2025-05-08T16:31:29.582Z
Learning: In the Nostr protocol, event.id will never be null in events returned by relay subscriptions, so null safety checks for this property are unnecessary.
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: applies to lib/services/nostr_service.dart : all nostr protocol interactions must go through `servic...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/services/nostr_service.dart : All Nostr protocol interactions must go through `services/nostr_service.dart`
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: applies to test/mocks.mocks.dart : do not add individual `// ignore: must_be_immutable` comments to ...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : Do not add individual `// ignore: must_be_immutable` comments to classes in `test/mocks.mocks.dart`
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: applies to test/mocks.mocks.dart : never manually edit `test/mocks.mocks.dart` - it's auto-generated...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to test/mocks.mocks.dart : Never manually edit `test/mocks.mocks.dart` - it's auto-generated by Mockito
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: applies to lib/services/nostr_service.dart : custom `timeagowithlocale()` method must be implemented...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/services/nostr_service.dart : Custom `timeAgoWithLocale()` method must be implemented in the NostrEvent extension
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: in abstractmostronotifier, the handleevent method is synchronous and returns void, not future....
Learnt from: Catrya
PR: MostroP2P/mobile#215
File: lib/features/order/notfiers/order_notifier.dart:0-0
Timestamp: 2025-07-20T23:33:17.689Z
Learning: In AbstractMostroNotifier, the handleEvent method is synchronous and returns void, not Future<void>. Do not suggest adding await to super.handleEvent() calls as this would cause compilation errors.
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: applies to lib/**/*.dart : always use localized strings instead of hardcoded text...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Applies to lib/**/*.dart : Always use localized strings instead of hardcoded text
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: all changes should pass `flutter analyze` before commit...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: All changes should pass `flutter analyze` before commit
Applied to files:
lib/features/relays/relays_notifier.dart
📚 Learning: use riverpod for all state management...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-30T14:10:43.895Z
Learning: Use Riverpod for all state management
Applied to files:
lib/features/relays/relays_notifier.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (6)
lib/features/relays/relays_notifier.dart (6)
1-4: New imports look appropriate for the enhanced functionality.The added imports support the new connectivity testing and validation features. The
dart:ioimport is needed for WebSocket operations, and theease.dartimport provides Nostr protocol message types.
9-21: Well-structured validation result class.The
RelayValidationResultclass provides a clean interface for returning detailed validation outcomes. The optional fields and default values are appropriate for the different validation scenarios.
70-92: Robust domain validation with comprehensive protocol handling.The domain validation logic correctly handles multiple protocol prefixes and uses appropriate regex patterns. The IP address rejection is a good security practice for relay URLs.
205-252: Well-implemented fallback connectivity test.The WebSocket fallback test provides a good alternative when the full Nostr protocol test fails. The timeout handling and response validation are appropriate.
263-323: Comprehensive relay validation with good error categorization.The smart validation method provides excellent user experience by categorizing different types of validation failures. The connectivity requirement ensures only working relays are added.
325-335: Improved relay health refresh with actual connectivity testing.The updated method now performs real connectivity tests instead of just marking all relays as healthy. This provides accurate health status for the UI.
| try { | ||
| await _cleanupTestConnection(Nostr.instance); | ||
| } catch (_) { | ||
| // Ignore cleanup errors | ||
| } | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent Nostr instance usage in error handling.
Line 197 uses Nostr.instance in the cleanup, but line 117 creates a new Nostr() instance. This inconsistency could lead to cleanup of the wrong instance.
} catch (e) {
// Protocol test failed with error
try {
- await _cleanupTestConnection(Nostr.instance);
+ // Note: testNostr is out of scope here, consider restructuring
+ // or storing the instance for proper cleanup
} catch (_) {
// Ignore cleanup errors
}Consider restructuring the error handling to properly clean up the correct Nostr instance, or use a try-finally block to ensure proper cleanup.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| try { | |
| await _cleanupTestConnection(Nostr.instance); | |
| } catch (_) { | |
| // Ignore cleanup errors | |
| } | |
| return false; | |
| } | |
| try { | |
| // Note: testNostr is out of scope here, consider restructuring | |
| // or storing the instance for proper cleanup | |
| } catch (_) { | |
| // Ignore cleanup errors | |
| } | |
| return false; | |
| } |
🤖 Prompt for AI Agents
In lib/features/relays/relays_notifier.dart around lines 196 to 202, the cleanup
uses Nostr.instance while earlier code at line 117 creates a new Nostr()
instance, causing inconsistent instance usage. To fix this, ensure the same
Nostr instance is used for both operations by storing the created instance in a
variable and referencing it in the cleanup. Alternatively, restructure the code
with a try-finally block to guarantee cleanup of the correct Nostr instance
regardless of errors.
Replace hardcoded English hintText in relay input field with localized string. Add relayUrlHint key to all ARB files (en, es, it) with appropriate translations: - English: 'relay.example.com or wss://relay.example.com' - Spanish: 'relay.ejemplo.com o wss://relay.ejemplo.com' - Italian: 'relay.esempio.com o wss://relay.esempio.com' This ensures the relay input field hint text supports multiple languages and complies with the project's localization guidelines.
Add required metadata blocks for relayAddedSuccessfully and relayAddedUnreachable
in Spanish and Italian ARB files to properly describe the {url} parameter:
Spanish (intl_es.arb):
- Add @relayAddedSuccessfully metadata with Spanish descriptions
- Add @relayAddedUnreachable metadata with Spanish descriptions
Italian (intl_it.arb):
- Add @relayAddedSuccessfully metadata with Italian descriptions
- Add @relayAddedUnreachable metadata with Italian descriptions
This ensures proper localization handling of parameterized strings and maintains
consistency with the English ARB file metadata structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No me permite usar mi relay local ws://localhost:7000
solo wss://
This resolves the issue where users could add new relays through the settings screen but then encounter "relaysUrl.isNotEmpty" assertion failures when trying to publish orders.
Fix #244
Summary by CodeRabbit
New Features
Localization
Bug Fixes
Tests
Chores