-
Notifications
You must be signed in to change notification settings - Fork 16
feat: add custom messages for cant-do error reasons #288
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
- Add handling for 10 specific cant-do reasons in snackbar notifications - Implement custom messages for: pending_order_exists, not_allowed_by_status, invalid_invoice, invalid_trade_index, is_not_your_order, invalid_signature, invalid_peer, invalid_pubkey, order_already_canceled, out_of_range_sats_amount
WalkthroughThe PR adds reason-specific cantDo notification handling, shortens several localization strings (EN/ES/IT), updates two localization method signatures used in the trade detail widget, and adds a sendNotification stub to test mocks. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant App
participant NotificationListener
participant I18n as S
participant UI as Snackbar
User->>App: Trigger action/event
App-->>NotificationListener: Emit notification { action: cantDo, values: { reason, action } }
NotificationListener->>NotificationListener: Inspect values['action']== 'cantDo' and values['reason']
alt Recognized reason (e.g., pending_order_exists, out_of_range_sats_amount, not_allowed_by_status)
NotificationListener->>I18n: Request localized message for that reason
else Unknown reason
NotificationListener->>I18n: Request generic mapped title
end
NotificationListener->>UI: Show Snackbar with localized message
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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)
✨ 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. CodeRabbit Commands (Invoked using PR/Issue comments)Type 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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
lib/features/trades/widgets/mostro_message_detail_widget.dart (2)
241-269: Make cantDo fallback user-friendly and aligned with PRThe default currently leaks internal state/action text. Per PR goals, fall back to a generic “Action not allowed” message.
- default: - return '${tradeState.status.toString()} - ${tradeState.action}'; // This is a fallback message for developers + default: + // Generic fallback for unmapped cant-do reasons + return S.of(context)!.notificationCantDoMessage;
241-269: Pass real min/max to outOfRangeFiatAmount (avoid literal placeholders in UI)Currently it renders "{fiat_min}" / "{fiat_max}" literally. Use configured bounds when available; otherwise fall back to the generic cant-do message.
- case CantDoReason.outOfRangeFiatAmount: - return S.of(context)!.outOfRangeFiatAmount('{fiat_min}', '{fiat_max}'); + case CantDoReason.outOfRangeFiatAmount: + final mi = ref.read(orderRepositoryProvider).mostroInstance; + final min = mi?.minOrderAmount?.toString(); + final max = mi?.maxOrderAmount?.toString(); + if (min != null && max != null) { + return S.of(context)!.outOfRangeFiatAmount(min, max); + } + return S.of(context)!.notificationCantDoMessage;
🧹 Nitpick comments (5)
lib/l10n/intl_es.arb (1)
139-141: Minor wording consistency: “sats” lowercase.Most strings elsewhere use “sats”. Consider “La cantidad de sats…”.
lib/l10n/intl_en.arb (1)
140-140: Style nit: use “sats” (lowercase) for consistency.“The sats amount is out of the allowed range.”
lib/shared/widgets/notification_listener_widget.dart (2)
41-60: Replace long if-else chain with a map for clarity and maintainability.This reduces branching and makes adding new reasons trivial.
- if (cantDoReason == 'pending_order_exists') { - message = S.of(context)!.pendingOrderExists; - } else if (cantDoReason == 'not_allowed_by_status') { - message = S.of(context)!.notAllowedByStatus; - } else if (cantDoReason == 'invalid_invoice') { - message = S.of(context)!.invalidInvoice; - } else if (cantDoReason == 'invalid_trade_index') { - message = S.of(context)!.invalidTradeIndex; - } else if (cantDoReason == 'is_not_your_order') { - message = S.of(context)!.isNotYourOrder; - } else if (cantDoReason == 'invalid_signature') { - message = S.of(context)!.invalidSignature; - } else if (cantDoReason == 'invalid_peer') { - message = S.of(context)!.invalidPeer; - } else if (cantDoReason == 'invalid_pubkey') { - message = S.of(context)!.invalidPubkey; - } else if (cantDoReason == 'order_already_canceled') { - message = S.of(context)!.orderAlreadyCanceled; - } else if (cantDoReason == 'out_of_range_sats_amount') { - message = S.of(context)!.outOfRangeSatsAmount; - } else { - // Use generic cant-do message for other reasons - message = NotificationMessageMapper.getLocalizedTitle(context, next.action!); - } + final reasons = <String, String>{ + 'pending_order_exists': S.of(context)!.pendingOrderExists, + 'not_allowed_by_status': S.of(context)!.notAllowedByStatus, + 'invalid_invoice': S.of(context)!.invalidInvoice, + 'invalid_trade_index': S.of(context)!.invalidTradeIndex, + 'is_not_your_order': S.of(context)!.isNotYourOrder, + 'invalid_signature': S.of(context)!.invalidSignature, + 'invalid_peer': S.of(context)!.invalidPeer, + 'invalid_pubkey': S.of(context)!.invalidPubkey, + 'order_already_canceled': S.of(context)!.orderAlreadyCanceled, + 'out_of_range_sats_amount': S.of(context)!.outOfRangeSatsAmount, + }; + message = (cantDoReason != null && reasons.containsKey(cantDoReason)) + ? reasons[cantDoReason]! + : NotificationMessageMapper.getLocalizedTitle(context, next.action!);
62-67: Optional: handle additional likely reason ‘out_of_range_fiat_amount’.If protocol may send it, map to S.of(context)!.outOfRangeFiatAmount to keep parity.
Would you like me to add this mapping now?
lib/features/trades/widgets/mostro_message_detail_widget.dart (1)
241-269: Deduplicate cantDo reason-to-message mappingCant-do reason mapping is now in multiple places (this widget and notification listener). Extract a single mapper (e.g., CantDoReasonLocalizer.map(reason, context, values)) and reuse to avoid drift.
I can sketch a small helper and update both call sites if you want.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
lib/features/trades/widgets/mostro_message_detail_widget.dart(1 hunks)lib/l10n/intl_en.arb(2 hunks)lib/l10n/intl_es.arb(2 hunks)lib/l10n/intl_it.arb(2 hunks)lib/shared/widgets/notification_listener_widget.dart(2 hunks)test/mocks.mocks.dart(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
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_en.arblib/l10n/intl_it.arb
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.darttest/mocks.mocks.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/trades/widgets/mostro_message_detail_widget.darttest/mocks.mocks.dart
**/*.mocks.dart
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.mocks.dart: Never manually edit Mockito-generated*.mocks.dartfiles
Do not add ignore comments to*.mocks.dart; regenerate instead if analyzer issues appear
Files:
test/mocks.mocks.dart
test/mocks.mocks.dart
📄 CodeRabbit inference engine (CLAUDE.md)
test/mocks.mocks.dart: Do not manually modifytest/mocks.mocks.dart(auto-generated by Mockito)
Do not add additional ignore directives; file already has file-level ignores
Files:
test/mocks.mocks.dart
test/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place unit tests under
test/
Files:
test/mocks.mocks.dart
🧠 Learnings (5)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
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.arb
📚 Learning: 2025-05-06T15:49:26.443Z
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:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-08-15T01:37:12.243Z
Learnt from: Catrya
PR: MostroP2P/mobile#270
File: lib/shared/widgets/order_filter.dart:133-135
Timestamp: 2025-08-15T01:37:12.243Z
Learning: The MostroP2P/mobile project requires Flutter >=3.27.0 as specified in pubspec.yaml, which supports the Color.withValues() method, so usage of withValues() throughout the codebase is valid and should not be flagged as a compatibility issue.
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to test/mocks.mocks.dart : Do not manually modify `test/mocks.mocks.dart` (auto-generated by Mockito)
Applied to files:
test/mocks.mocks.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 (5)
lib/l10n/intl_es.arb (1)
124-147: Generic messages parity and usage verified
intl_it.arb includes the same four no-argument keys, and no call sites invoke them with placeholders.lib/l10n/intl_en.arb (1)
124-147: Generic no-arg messages verified, Italian locale in sync. Verified there are no remaining calls passing arguments to notAllowedByStatus or outOfRangeSatsAmount, and intl_it.arb contains matching no-arg entries.lib/shared/widgets/notification_listener_widget.dart (1)
4-4: UnifyActionimport path:notification_listener_widget.dartimports frompackage:mostro_mobile/data/models/enums/action.dartwhile mocks/tests import viapackage:mostro_mobile/data/enums.dart. Confirm thatdata/enums.dartre-exports the sameActionenum; otherwise, consolidate to one import to prevent duplicate types.lib/features/trades/widgets/mostro_message_detail_widget.dart (1)
251-256: Approve zero-arg localized getters Verified via ripgrep that there are no remaining calls toS.of(context)!.notAllowedByStatus(orS.of(context)!.outOfRangeSatsAmount(; changes approved.lib/l10n/intl_it.arb (1)
124-124: All four translation keys are present in intl_en.arb, intl_es.arb, and intl_it.arb—please regenerate l10n
Run your locale generation command (e.g.flutter pub run intl_utils:generate).
grunch
left a comment
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.
great job! utACK
fix #269
cant-doreasons in snackbar notificationspending_order_exists,not_allowed_by_status,invalid_invoice,invalid_trade_index,is_not_your_order,invalid_signature,invalid_peer,invalid_pubkey,order_already_canceled,out_of_range_sats_amountcant-doit will continue to be seen as before: "Action not allowed"Summary by CodeRabbit
New Features
Style
Tests