feat : notifications screen#257
Conversation
WalkthroughAdds a complete notifications subsystem: models/enums, Sembast-backed repository and providers, Riverpod notifiers, UI widgets and screen, app bar/bell integration, route to /notifications, localized strings, and supporting utils. Removes legacy notification notifier/provider and updates order notifiers to use the new notification pipeline. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Mostro as AbstractMostroNotifier
participant Notifier as NotificationsNotifier
participant Repo as NotificationsRepository
participant DB as Sembast
participant UI as UI (Bell/Screen)
Note over Mostro: Receives domain event (Action)
Mostro->>Notifier: notify(action, values, orderId?, eventId?)
Notifier->>Repo: notificationExists(id)
Repo->>DB: query by id
DB-->>Repo: exists?
alt Not exists
Notifier->>Repo: addNotification(NotificationModel)
Repo->>DB: upsert record
DB-->>Repo: ok
end
Notifier-->>UI: emit temporary state (SnackBar)
Repo-->>UI: stream updated notifications list
UI-->>User: Bell badge and list update
sequenceDiagram
autonumber
actor User
participant Screen as NotificationsScreen
participant Item as NotificationItem
participant Repo as NotificationsRepository
participant Router as GoRouter
User->>Screen: Open /notifications
Screen->>Repo: watchNotifications()
Repo-->>Screen: Stream<List<NotificationModel>>
User->>Item: Tap notification
alt Unread
Item->>Repo: markAsRead(id)
end
alt Has orderId and actionable
Item->>Router: push(route for action/orderId)
else No navigation
Item-->>User: Stay on screen
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ 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.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
lib/l10n/intl_it.arb (1)
587-590:cancelPendingButton&completePurchaseButtonare defined twiceKeys must be unique across the ARB. The second definitions at Lines 587-590 shadow the first ones at Lines 494-498 and will corrupt the generated localization code.
Either reuse the first keys or rename the second set, e.g.:
- "cancelPendingButton": "ANNULLAMENTO IN SOSPESO", - "completePurchaseButton": "COMPLETA ACQUISTO", + "cancelPendingTradeButton": "ANNULLAMENTO IN SOSPESO", + "completePurchaseTradeButton": "COMPLETA ACQUISTO",Don’t forget to update all Dart references accordingly.
Also applies to: 494-498
🧹 Nitpick comments (13)
lib/features/notifications/widgets/notification_text_resolver.dart (1)
8-135: Consider refactoring large switch statement for maintainability.While the current approach works well, the large switch statement (125+ lines) could become harder to maintain as more notification types are added.
Consider using a Map-based approach for better maintainability:
static final Map<String, String Function(S)> _notificationKeyMap = { 'notification_new_order_title': (s) => s.notification_new_order_title, 'notification_new_order_message': (s) => s.notification_new_order_message, // ... other mappings }; String resolveNotificationText(BuildContext context, String key) { final s = S.of(context); if (s == null) return key; final resolver = _notificationKeyMap[key]; return resolver?.call(s) ?? key; }This approach would be more maintainable and less prone to errors when adding new notification types.
lib/features/notifications/widgets/notification_header.dart (1)
26-33: Consider defensive null handling in text style composition.The nested null-aware operators could result in a null TextStyle if any intermediate value is null. Consider using a more defensive approach or providing fallback values.
TextStyle? _getTitleStyle(BuildContext context) { - return Theme.of(context).textTheme.titleMedium?.copyWith( - fontWeight: FontWeight.w600, - color: notification.isRead - ? Theme.of(context).textTheme.bodyMedium?.color?.withValues(alpha: 0.7) - : Theme.of(context).textTheme.titleMedium?.color, - ); + final theme = Theme.of(context); + final baseStyle = theme.textTheme.titleMedium; + final baseColor = notification.isRead + ? theme.textTheme.bodyMedium?.color ?? theme.textTheme.titleMedium?.color + : theme.textTheme.titleMedium?.color; + + return baseStyle?.copyWith( + fontWeight: FontWeight.w600, + color: notification.isRead + ? baseColor?.withValues(alpha: 0.7) + : baseColor, + ); }lib/shared/widgets/notification_history_bell_widget.dart (2)
14-18: Consider using ModalRoute or more robust route checking.Using
GoRouterState.of(context).uri.pathdirectly may not be the most robust approach for route checking, especially if route parameters or query strings are involved.- final currentRoute = GoRouterState.of(context).uri.path; - - if (currentRoute == '/notifications') { - return const SizedBox.shrink(); - } + final location = GoRouter.of(context).routerDelegate.currentConfiguration.uri.path; + if (location == '/notifications') { + return const SizedBox.shrink(); + }
26-26: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.cream1reduces flexibility and theme consistency. Consider using theme-based colors.- color: AppTheme.cream1, + color: Theme.of(context).iconTheme.color,lib/features/notifications/widgets/detail_row.dart (4)
27-27: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.textSecondaryreduces theme flexibility. Consider using theme-based colors.- color: AppTheme.textSecondary.withValues(alpha: 0.7), + color: Theme.of(context).iconTheme.color?.withValues(alpha: 0.7),
34-34: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.textSecondaryreduces theme flexibility.- color: AppTheme.textSecondary, + color: Theme.of(context).textTheme.bodySmall?.color?.withValues(alpha: 0.8),
42-42: Consider more robust monospace font detection.The current logic only checks for 'npub' and '#' strings. Consider a more comprehensive approach for detecting identifiers that benefit from monospace fonts.
- fontFamily: value.contains('npub') || value.contains('#') ? 'monospace' : null, + fontFamily: _shouldUseMonospace(value) ? 'monospace' : null,Add a helper method:
bool _shouldUseMonospace(String value) { return value.contains('npub') || value.contains('#') || value.contains('bc1') || // Bitcoin addresses RegExp(r'^[0-9a-fA-F]{8,}$').hasMatch(value); // Hex strings }
43-43: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.textPrimaryreduces theme flexibility.- color: AppTheme.textPrimary, + color: Theme.of(context).textTheme.bodySmall?.color,lib/features/notifications/widgets/notification_menu.dart (3)
46-46: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.statusSuccessreduces theme flexibility.- color: AppTheme.statusSuccess + color: Theme.of(context).colorScheme.primary
67-67: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.statusErrorreduces theme flexibility.- color: AppTheme.statusError, + color: Theme.of(context).colorScheme.error,
73-73: Use theme colors instead of hard-coded AppTheme values.Hard-coding
AppTheme.statusErrorreduces theme flexibility.- color: AppTheme.statusError, + color: Theme.of(context).colorScheme.error,lib/shared/widgets/notification_listener_widget.dart (1)
61-71: Use constants for timeout typesConsider using constants for the timeout types to prevent typos and improve maintainability.
+ static const String _timeoutTypeMaker = 'maker'; + static const String _timeoutTypeTaker = 'taker'; + // Handle timeout reversal with different messages based on type if (next.action == actions.Action.timeoutReversal) { final type = next.values['type'] as String?; - if (type == 'maker') { + if (type == _timeoutTypeMaker) { message = S.of(context)!.orderTimeoutMaker; - } else if (type == 'taker') { + } else if (type == _timeoutTypeTaker) { message = S.of(context)!.orderTimeoutTaker; } else {lib/features/notifications/widgets/notification_item.dart (1)
64-84: Functional tap handler with planned navigation.The notification marking as read works correctly. The TODO for navigation implementation is appropriate for this stage - the comprehensive switch statement structure is ready for future navigation logic.
Would you like me to help implement the navigation logic for different notification types based on the order context?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (39)
lib/core/app_routes.dart(2 hunks)lib/core/app_theme.dart(1 hunks)lib/data/models.dart(1 hunks)lib/data/models/enums/notification_type.dart(1 hunks)lib/data/models/notification.dart(1 hunks)lib/data/repositories/notifications_history_repository.dart(1 hunks)lib/features/notifications/notifiers/notification_temporary_state.dart(1 hunks)lib/features/notifications/notifiers/notifications_notifier.dart(1 hunks)lib/features/notifications/notifiers/notifications_state.dart(1 hunks)lib/features/notifications/providers/notifications_provider.dart(1 hunks)lib/features/notifications/screens/notifications_screen.dart(1 hunks)lib/features/notifications/utils/notification_message_mapper.dart(1 hunks)lib/features/notifications/widgets/detail_row.dart(1 hunks)lib/features/notifications/widgets/notification_content.dart(1 hunks)lib/features/notifications/widgets/notification_details.dart(1 hunks)lib/features/notifications/widgets/notification_footer.dart(1 hunks)lib/features/notifications/widgets/notification_header.dart(1 hunks)lib/features/notifications/widgets/notification_item.dart(1 hunks)lib/features/notifications/widgets/notification_menu.dart(1 hunks)lib/features/notifications/widgets/notification_message.dart(1 hunks)lib/features/notifications/widgets/notification_text_resolver.dart(1 hunks)lib/features/notifications/widgets/notification_type_icon.dart(1 hunks)lib/features/notifications/widgets/notifications_actions_menu.dart(1 hunks)lib/features/notifications/widgets/order_id_chip.dart(1 hunks)lib/features/notifications/widgets/timestamp_text.dart(1 hunks)lib/features/notifications/widgets/unread_indicator.dart(1 hunks)lib/features/order/notfiers/abstract_mostro_notifier.dart(5 hunks)lib/features/order/notfiers/order_notifier.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/shared/notifiers/notification_notifier.dart(0 hunks)lib/shared/providers.dart(0 hunks)lib/shared/providers/notification_notifier_provider.dart(0 hunks)lib/shared/providers/notifications_history_repository_provider.dart(1 hunks)lib/shared/utils/datetime_extensions_utils.dart(1 hunks)lib/shared/widgets/mostro_app_bar.dart(3 hunks)lib/shared/widgets/notification_history_bell_widget.dart(1 hunks)lib/shared/widgets/notification_listener_widget.dart(3 hunks)
💤 Files with no reviewable changes (3)
- lib/shared/providers.dart
- lib/shared/providers/notification_notifier_provider.dart
- lib/shared/notifiers/notification_notifier.dart
🧰 Additional context used
📓 Path-based instructions (9)
lib/data/models.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
Models must be exported through
data/models.dart
Files:
lib/data/models.dart
lib/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
Always checkmountedbefore using context after async operations
Files:
lib/data/models.dartlib/shared/providers/notifications_history_repository_provider.dartlib/core/app_theme.dartlib/shared/widgets/notification_history_bell_widget.dartlib/data/models/enums/notification_type.dartlib/features/notifications/widgets/unread_indicator.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/widgets/notification_message.dartlib/features/notifications/widgets/notification_text_resolver.dartlib/features/notifications/widgets/notification_header.dartlib/features/notifications/widgets/notification_footer.dartlib/features/notifications/widgets/timestamp_text.dartlib/features/notifications/widgets/order_id_chip.dartlib/shared/utils/datetime_extensions_utils.dartlib/features/notifications/utils/notification_message_mapper.dartlib/features/notifications/widgets/notifications_actions_menu.dartlib/features/notifications/widgets/notification_content.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/widgets/detail_row.dartlib/features/notifications/widgets/notification_menu.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/widgets/notification_type_icon.dartlib/features/notifications/notifiers/notification_temporary_state.dartlib/data/models/notification.dartlib/features/notifications/widgets/notification_details.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.dart
**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
Files:
lib/data/models.dartlib/shared/providers/notifications_history_repository_provider.dartlib/core/app_theme.dartlib/shared/widgets/notification_history_bell_widget.dartlib/data/models/enums/notification_type.dartlib/features/notifications/widgets/unread_indicator.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/widgets/notification_message.dartlib/features/notifications/widgets/notification_text_resolver.dartlib/features/notifications/widgets/notification_header.dartlib/features/notifications/widgets/notification_footer.dartlib/features/notifications/widgets/timestamp_text.dartlib/features/notifications/widgets/order_id_chip.dartlib/shared/utils/datetime_extensions_utils.dartlib/features/notifications/utils/notification_message_mapper.dartlib/features/notifications/widgets/notifications_actions_menu.dartlib/features/notifications/widgets/notification_content.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/widgets/detail_row.dartlib/features/notifications/widgets/notification_menu.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/widgets/notification_type_icon.dartlib/features/notifications/notifiers/notification_temporary_state.dartlib/data/models/notification.dartlib/features/notifications/widgets/notification_details.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.dart
lib/shared/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
Shared utilities and widgets must be placed in
shared/
Files:
lib/shared/providers/notifications_history_repository_provider.dartlib/shared/widgets/notification_history_bell_widget.dartlib/shared/utils/datetime_extensions_utils.dartlib/shared/widgets/notification_listener_widget.dartlib/shared/widgets/mostro_app_bar.dart
lib/features/*/{screens,providers,notifiers,widgets}/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
Feature-based organization:
features/{feature}/{screens|providers|notifiers|widgets}/
Files:
lib/features/notifications/widgets/unread_indicator.dartlib/features/notifications/widgets/notification_message.dartlib/features/notifications/widgets/notification_text_resolver.dartlib/features/notifications/widgets/notification_header.dartlib/features/notifications/widgets/notification_footer.dartlib/features/notifications/widgets/timestamp_text.dartlib/features/notifications/widgets/order_id_chip.dartlib/features/notifications/widgets/notifications_actions_menu.dartlib/features/notifications/widgets/notification_content.dartlib/features/notifications/widgets/detail_row.dartlib/features/notifications/widgets/notification_menu.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/widgets/notification_type_icon.dartlib/features/notifications/notifiers/notification_temporary_state.dartlib/features/notifications/widgets/notification_details.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/features/notifications/notifiers/notifications_notifier.dart
lib/core/app_routes.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
GoRouter must be configured in
core/app_routes.dart
Files:
lib/core/app_routes.dart
lib/l10n/*.arb
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/l10n/*.arb: Internationalization ARB files must be located inlib/l10n/
Add new localization keys to all three ARB files (en, es, it)
Use proper ARB metadata for parameterized strings
Files:
lib/l10n/intl_en.arblib/l10n/intl_es.arblib/l10n/intl_it.arb
lib/features/*/providers/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
Providers are organized by feature in
features/{feature}/providers/
Files:
lib/features/notifications/providers/notifications_provider.dart
lib/data/repositories/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
All data access must go through repository classes in
data/repositories/
Files:
lib/data/repositories/notifications_history_repository.dart
🧠 Learnings (32)
📓 Common learnings
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.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Use Riverpod for all state management
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.
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/background/background.dart:74-77
Timestamp: 2025-05-08T16:29:52.154Z
Learning: In the Mostro Mobile background service architecture, events aren't stored by the background process. Instead, the background service only checks if events exist in the eventStore and sends notifications for new ones, while the foreground process is responsible for storing and processing events. This is an intentional design decision to separate concerns.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Encapsulate business logic in Notifiers
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.
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.
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.
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.
📚 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-08-03T09:43:38.727Z
Learning: Applies to lib/data/models.dart : Models must be exported through `data/models.dart`
Applied to files:
lib/data/models.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/widgets/notification_message.dartlib/features/notifications/widgets/notification_header.dartlib/features/notifications/widgets/timestamp_text.dartlib/features/notifications/widgets/notification_content.dartlib/features/notifications/notifiers/notifications_state.dartlib/data/models/notification.dartlib/features/notifications/widgets/notification_details.dartlib/features/notifications/widgets/notification_item.dartlib/shared/widgets/mostro_app_bar.dart
📚 Learning: applies to lib/generated/l10n*.dart : generated localization files must be in `lib/generated/l10n.da...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/generated/l10n*.dart : Generated localization files must be in `lib/generated/l10n.dart` and language-specific files
Applied to files:
lib/data/models.dartlib/features/notifications/widgets/notification_text_resolver.dartlib/shared/utils/datetime_extensions_utils.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-08-03T09:43:38.727Z
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:
lib/data/models.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:
lib/data/models.dartlib/shared/providers/notifications_history_repository_provider.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.dart
📚 Learning: in the cantdo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'ca...
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Applied to files:
lib/data/models.dartlib/features/notifications/utils/notification_message_mapper.dartlib/data/models/notification.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-08-03T09:43:38.727Z
Learning: Applies to lib/services/nostr_service.dart : All Nostr protocol interactions must go through `services/nostr_service.dart`
Applied to files:
lib/data/models.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/providers/notifications_provider.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.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:
lib/data/models.dartlib/shared/providers/notifications_history_repository_provider.dartlib/shared/widgets/notification_history_bell_widget.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.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-08-03T09:43:38.727Z
Learning: Applies to lib/shared/providers/mostro_database_provider.dart : Database initialization must occur in `shared/providers/mostro_database_provider.dart`
Applied to files:
lib/data/models.dartlib/shared/providers/notifications_history_repository_provider.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.dart
📚 Learning: applies to test/mocks.mocks.dart : `test/mocks.mocks.dart` is auto-generated by mockito and must not...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to test/mocks.mocks.dart : `test/mocks.mocks.dart` is auto-generated by Mockito and must not be manually edited
Applied to files:
lib/data/models.dartlib/features/order/notfiers/order_notifier.dart
📚 Learning: applies to {**/*.g.dart,**/*.mocks.dart,lib/generated/**} : never manually edit generated files (`*....
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to {**/*.g.dart,**/*.mocks.dart,lib/generated/**} : Never manually edit generated files (`*.g.dart`, `*.mocks.dart`, `lib/generated/`)
Applied to files:
lib/data/models.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-08-03T09:43:38.727Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions must be managed by `core/mostro_fsm.dart`
Applied to files:
lib/data/models.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/notifiers/notification_temporary_state.dartlib/shared/widgets/mostro_app_bar.dart
📚 Learning: use riverpod for all state management...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Use Riverpod for all state management
Applied to files:
lib/shared/providers/notifications_history_repository_provider.dartlib/shared/widgets/notification_history_bell_widget.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/shared/widgets/mostro_app_bar.dartlib/features/notifications/notifiers/notifications_notifier.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:
lib/shared/providers/notifications_history_repository_provider.dartlib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/features/notifications/widgets/notification_message.dartlib/features/notifications/widgets/timestamp_text.dartlib/features/notifications/utils/notification_message_mapper.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/notifiers/notifications_state.dartlib/features/notifications/providers/notifications_provider.dartlib/features/notifications/notifiers/notification_temporary_state.dartlib/data/models/notification.dartlib/features/notifications/widgets/notification_item.dartlib/features/notifications/screens/notifications_screen.dartlib/features/notifications/notifiers/notifications_notifier.dartlib/data/repositories/notifications_history_repository.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/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/shared/widgets/notification_listener_widget.dartlib/features/notifications/notifiers/notifications_notifier.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:
lib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dart
📚 Learning: encapsulate business logic in notifiers...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Encapsulate business logic in Notifiers
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/order/notfiers/order_notifier.dartlib/features/notifications/notifiers/notifications_notifier.dart
📚 Learning: in the mostro mobile background service architecture, events aren't stored by the background process...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/background/background.dart:74-77
Timestamp: 2025-05-08T16:29:52.154Z
Learning: In the Mostro Mobile background service architecture, events aren't stored by the background process. Instead, the background service only checks if events exist in the eventStore and sends notifications for new ones, while the foreground process is responsible for storing and processing events. This is an intentional design decision to separate concerns.
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dart
📚 Learning: in the mostro mobile codebase, mostromessage objects have an 'action' member that can be directly ac...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/shared/providers/app_init_provider.dart:78-95
Timestamp: 2025-05-06T16:08:19.352Z
Learning: In the Mostro Mobile codebase, MostroMessage objects have an 'action' member that can be directly accessed (e.g., mostroMessage.action).
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/notifications/utils/notification_message_mapper.dart
📚 Learning: in the context of the mostro mobile app, the `tradestate` class is specifically constructed using th...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/features/trades/models/trade_state.dart:1-15
Timestamp: 2025-05-08T16:06:33.665Z
Learning: In the context of the Mostro Mobile app, the `TradeState` class is specifically constructed using the `tradeStateProvider`. While some fields are nullable (`lastAction` and `orderPayload`), they are still marked as required parameters to ensure they are explicitly considered during state construction.
Applied to files:
lib/features/order/notfiers/abstract_mostro_notifier.dartlib/features/notifications/notifiers/notification_temporary_state.dart
📚 Learning: applies to **/*.dart : remove unused imports and dependencies...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies
Applied to files:
lib/features/order/notfiers/order_notifier.dartlib/core/app_routes.dart
📚 Learning: applies to lib/core/app_routes.dart : gorouter must be configured in `core/app_routes.dart`...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/core/app_routes.dart : GoRouter must be configured in `core/app_routes.dart`
Applied to files:
lib/core/app_routes.dartlib/shared/widgets/notification_listener_widget.dartlib/shared/widgets/mostro_app_bar.dart
📚 Learning: applies to lib/features/*/{screens,providers,notifiers,widgets}/** : feature-based organization: `fe...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/features/*/{screens,providers,notifiers,widgets}/** : Feature-based organization: `features/{feature}/{screens|providers|notifiers|widgets}/`
Applied to files:
lib/core/app_routes.dartlib/features/notifications/screens/notifications_screen.dart
📚 Learning: applies to lib/**/*.dart : use `s.of(context).yourkey` for all user-facing strings...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/**/*.dart : Use `S.of(context).yourKey` for all user-facing strings
Applied to files:
lib/features/notifications/widgets/notification_text_resolver.dartlib/shared/utils/datetime_extensions_utils.dartlib/shared/widgets/notification_listener_widget.dart
📚 Learning: applies to lib/main.dart : locales for the timeago package must be configured in `main.dart` with `t...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/main.dart : Locales for the timeago package must be configured in `main.dart` with `timeago.setLocaleMessages()`
Applied to files:
lib/features/notifications/widgets/timestamp_text.dartlib/shared/utils/datetime_extensions_utils.dart
📚 Learning: custom `timeagowithlocale()` method must be implemented in the nostrevent extension...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Custom `timeAgoWithLocale()` method must be implemented in the NostrEvent extension
Applied to files:
lib/shared/utils/datetime_extensions_utils.dart
📚 Learning: applies to lib/l10n/*.arb : add new localization keys to all three arb files (en, es, it)...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_en.arblib/l10n/intl_es.arblib/l10n/intl_it.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-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for parameterized strings
Applied to files:
lib/l10n/intl_en.arblib/l10n/intl_es.arb
📚 Learning: regenerate localization files after arb modifications...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Regenerate localization files after ARB modifications
Applied to files:
lib/l10n/intl_en.arb
📚 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-08-03T09:43:38.727Z
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/notifications/notifiers/notifications_state.dartlib/features/notifications/notifiers/notification_temporary_state.dart
📚 Learning: in the mostro mobile codebase, widgetstateproperty is used instead of the deprecated materialstatepr...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/shared/widgets/mostro_reactive_button.dart:22-32
Timestamp: 2025-05-08T15:39:07.322Z
Learning: In the Mostro Mobile codebase, WidgetStateProperty is used instead of the deprecated MaterialStateProperty for styling buttons with state-dependent properties.
Applied to files:
lib/shared/widgets/mostro_app_bar.dart
📚 Learning: applies to lib/data/repositories/** : all data access must go through repository classes in `data/re...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/data/repositories/** : All data access must go through repository classes in `data/repositories/`
Applied to files:
lib/data/repositories/notifications_history_repository.dart
🪛 RuboCop (1.76.1)
lib/l10n/intl_en.arb
[warning] 723-723: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_es.arb
[warning] 753-753: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_it.arb
[warning] 761-761: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
🔇 Additional comments (56)
lib/core/app_theme.dart (1)
44-44: LGTM! Consistent color addition for notifications.The new
statusInfocolor follows the established naming pattern for status colors and uses an appropriate blue color for informational notifications. The addition integrates well with the existing color system.lib/features/notifications/widgets/order_id_chip.dart (1)
4-34: Well-implemented order ID display widget.The
OrderIdChipwidget follows good practices:
- Proper use of theme constants for styling consistency
- Smart formatting logic that truncates long order IDs while preserving readability
- Appropriate monospace font for technical identifiers
- Clean StatelessWidget implementation
The formatting approach (first 8 chars + "..." + last 5 chars) provides a good balance between brevity and uniqueness for identification purposes.
lib/shared/utils/datetime_extensions_utils.dart (1)
4-13: All required timeago locales are configured inmain.dart.The
timeago.setLocaleMessagescalls for Spanish (es) and Italian (it) are already present in the_initializeTimeAgoLocalizationmethod, and English remains the default. No further changes are needed.lib/features/notifications/widgets/unread_indicator.dart (1)
4-18: Simple and effective unread indicator widget.Clean implementation of a focused widget that serves its purpose well. The 8x8 pixel circular indicator with the theme's green color provides a clear visual cue for unread notifications.
lib/data/models.dart (1)
5-5: Correct model export following established pattern.The addition of the notification model export follows the coding guideline that models must be exported through
data/models.dartand maintains consistency with the existing export structure.lib/data/models/enums/notification_type.dart (1)
1-9: LGTM! Well-structured enum definition.The
NotificationTypeenum is properly defined with descriptive values that clearly categorize different types of notifications. This provides a solid foundation for the notification system implementation.lib/core/app_routes.dart (2)
23-23: LGTM! Proper import addition.The import for
NotificationsScreenis correctly placed and follows the existing import organization pattern.
263-271: LGTM! Correctly implemented notifications route.The new
/notificationsroute is properly configured following the existing pattern:
- Uses the same
buildPageWithDefaultTransitionfor consistency- Follows the established route structure
- Correctly references the
NotificationsScreenwidgetThis implementation aligns with the coding guideline requiring GoRouter configuration in
core/app_routes.dart.lib/shared/providers/notifications_history_repository_provider.dart (1)
5-8: LGTM! Well-implemented Riverpod provider.The
notificationsRepositoryProvideris correctly implemented:
- Follows established Riverpod patterns in the codebase
- Properly watches the
mostroDatabaseProviderfor database dependency- Creates and returns the
NotificationsStorageinstance implementingNotificationsRepository- Enables proper dependency injection throughout the app
lib/features/order/notfiers/abstract_mostro_notifier.dart (4)
9-9: LGTM! Correct migration to new notifications system.The import has been properly updated from the old notification provider to the new
notificationsProvider, aligning with the comprehensive notifications system refactor.
73-73: LGTM! Consistent provider reference update.The provider reference has been correctly updated to use the new
notificationsProvider.notifier, maintaining consistency with the notification system migration.
87-89: LGTM! Proper migration to new notification API.All notification calls have been correctly migrated from
showInformationtonotifywith the following improvements:
- Added
orderIdparameter for proper notification history tracking- Maintained all existing
valuesparameters for localization- Consistent API usage across all notification types
This migration properly integrates with the new notification system that supports both temporary and persistent notifications.
Also applies to: 92-94, 100-100, 104-106, 109-111, 115-118, 122-125, 128-130, 134-140, 158-160, 165-169, 172-175, 207-209, 212-212, 216-219
225-225: LGTM! Appropriate use of temporary notifications for default case.The default case correctly uses
showTemporaryfor unknown actions, which is appropriate since these shouldn't be persisted in the notification history.lib/features/order/notfiers/order_notifier.dart (3)
9-9: LGTM! Correct migration to new notifications system.The import has been properly updated to use the new
notificationsProvider, maintaining consistency with the notification system refactor across the codebase.
353-353: LGTM! Consistent provider reference update.The provider reference has been correctly updated to use
notificationsProvider.notifier, aligning with the new notification system architecture.
359-359: LGTM! Proper API migration for timeout notifications.The notification calls have been correctly migrated:
- Changed from
showCustomMessagetoshowTemporary- Now uses
Action.timeoutReversalfor proper action classification- Includes
valuesparameter with user role type ('maker' or 'taker') for appropriate localization- Uses temporary notifications appropriately since timeout notifications don't need to persist in history
This maintains the intended behavior while integrating with the new notification system.
Also applies to: 363-363
lib/features/notifications/widgets/timestamp_text.dart (1)
1-19: Timeago localization setup verifiedThe
timeago.setLocaleMessages()calls for supported locales are defined in_initializeTimeAgoLocalization()and this function is correctly invoked inmain.dartbefore the app launches. No further action is needed—this ensurestimeAgoWithLocalewill work across locales.lib/features/notifications/widgets/notification_footer.dart (1)
1-22: LGTM! Proper conditional rendering and layout.The widget correctly uses conditional rendering for the optional
OrderIdChipand employs a clean Row/Spacer layout pattern. The null check with the non-null assertion operator is safe within the conditional context.lib/features/notifications/widgets/notification_content.dart (1)
1-25: LGTM! Good composition pattern with proper spacing.The widget effectively composes notification display components with appropriate visual hierarchy through consistent spacing. The left alignment using
CrossAxisAlignment.startis suitable for text-heavy content.lib/features/notifications/widgets/notification_message.dart (1)
1-37: LGTM! Well-structured widget with proper styling and conditional rendering.The widget demonstrates good practices:
- Clean separation of styling logic in
_getMessageStyle- Proper conditional rendering of
NotificationDetails- Text overflow handling with
maxLinesandTextOverflow.ellipsis- Theme-based styling with appropriate opacity for read/unread states
lib/shared/widgets/notification_history_bell_widget.dart (1)
44-67: LGTM! Well-implemented badge component.The badge implementation handles count display correctly with the 99+ cap, uses appropriate constraints, and follows good positioning practices.
lib/features/notifications/widgets/notification_menu.dart (1)
37-56: LGTM! Well-structured menu item builder.The conditional rendering and clean separation of menu item builders follows good practices. The use of localization is correct.
lib/features/notifications/utils/notification_message_mapper.dart (2)
6-71: LGTM! Comprehensive and well-structured title mapping.The switch statement covers a wide range of Action enum values with appropriate fallback. The mapping keys follow a consistent naming convention.
74-141: LGTM! Consistent message mapping implementation.The message mapping mirrors the title mapping structure well, maintaining consistency in the key naming pattern and providing appropriate defaults.
lib/l10n/intl_en.arb (1)
718-803: Excellent comprehensive notification localization implementation.The notification strings are well-organized with clear sections for:
- UI elements (notifications screen, actions menu)
- Event-specific titles and messages for all notification types
- Detail labels for notification metadata
- Confirmation dialogs
The ARB metadata is properly structured with appropriate placeholders and descriptions. The localization keys follow consistent naming patterns and support the full notifications feature implementation.
Ensure these keys are added to the Spanish (
intl_es.arb) and Italian (intl_it.arb) files as required by the coding guidelines.lib/features/notifications/notifiers/notifications_state.dart (1)
5-39: Well-designed state class with proper separation of concerns.The
NotificationsStateclass effectively separates persistent notification history (viaAsyncValue<List<NotificationModel>>) from temporary notification display (NotificationTemporaryState). The implementation follows Riverpod best practices with:
- Immutable design with
constconstructor- Proper
copyWithmethod for state updates- Value-based equality comparison and consistent hashCode
- Helpful
toStringfor debuggingThe use of
AsyncValuefor history notifications enables proper loading/error state handling in the UI.lib/features/notifications/notifiers/notification_temporary_state.dart (1)
3-42: Clean and flexible temporary notification state implementation.The
NotificationTemporaryStateclass provides a flexible design for temporary notifications with:
- Optional
Actionfor notification context- Generic
Map<String, dynamic>for flexible data storage- Boolean
showflag for visibility control- Proper immutable pattern with
copyWithmethod- Standard equality comparison and debugging support
The design allows for diverse notification scenarios while maintaining type safety and immutability.
lib/features/notifications/widgets/notifications_actions_menu.dart (1)
8-131: Excellent popup menu implementation with proper UX considerations.The
NotificationsActionsMenuwidget demonstrates solid Flutter and Riverpod practices:
- Clean separation of UI building methods (
_buildMarkAllAsReadMenuItem,_buildClearAllMenuItem)- Proper confirmation dialog for the destructive "Clear All" action - excellent UX
- Consistent theming with
AppThemecolors andHeroIcons- Proper localization with
S.of(context)throughout- Appropriate visual feedback with colored SnackBars
- Proper Riverpod integration using
ConsumerWidgetandref.read()The color coding (success green for mark as read, error red for clear all) provides clear visual cues to users.
lib/features/notifications/widgets/notification_type_icon.dart (1)
7-137: Excellent icon mapping implementation with semantic design.The
NotificationTypeIconwidget provides a comprehensive and semantically meaningful icon system:Strengths:
- Clean nested switch statements handling all
NotificationTypeandActioncombinations- Semantic color mapping (success = green, error = red, warning = yellow, etc.)
- Consistent 40x40 container with rounded corners and opacity background
- Good separation of concerns with private helper methods
- The
_IconDatahelper class improves code readabilityDesign highlights:
- Icons match their semantic meaning (credit card for payments, exclamation triangle for disputes)
- Color choices reinforce the notification importance and context
- Consistent sizing and styling throughout
The implementation covers all notification types comprehensively and provides clear visual distinction between different notification categories.
lib/data/models/notification.dart (1)
4-108: NotificationModel is properly exportedConfirmed that
lib/data/models.dartincludes:export 'package:mostro_mobile/data/models/notification.dart';No further action required.
lib/features/notifications/providers/notifications_provider.dart (1)
7-30: Well-structured Riverpod providers implementationThe providers are properly implemented following Riverpod best practices:
- Proper separation of concerns with dedicated providers for different aspects
- Correct handling of async states in
unreadNotificationsCountProvider- Clean dependency management between providers
lib/shared/widgets/mostro_app_bar.dart (4)
3-7: LGTM! Import additions support new functionality.The new imports for
go_routerandNotificationBellWidgetcorrectly support the enhanced app bar functionality.
67-78: Well-designed constructor with sensible defaults.The optional parameters provide excellent flexibility while maintaining backward compatibility. The default values (drawer button shown, back button hidden) align with typical app bar usage patterns.
82-110: Excellent conditional leading widget implementation.The logic correctly prioritizes the back button over the drawer button and uses proper navigation patterns. The styling is consistent with the app theme and the Riverpod state management integration is appropriate.
112-134: Clean integration of new parameters with AppBar.The default actions implementation properly includes the NotificationBellWidget, supporting the new notifications feature. The parameter integration maintains existing styling while providing excellent customization options.
lib/features/notifications/widgets/notification_item.dart (5)
1-10: LGTM! Imports follow feature-based organization.The imports correctly follow the codebase's feature-based organization pattern and include all necessary dependencies for the notification item functionality.
12-50: Well-structured notification item widget.The ConsumerWidget implementation with Card and InkWell provides excellent UX. The Row layout effectively organizes the notification components, and the separation into helper methods keeps the build method clean.
52-62: Good theming integration with proper fallbacks.The styling methods correctly use theme-based colors and handle edge cases with appropriate fallbacks. The visual distinction between read/unread notifications enhances user experience.
86-95: Clean menu action handling.The action handler properly integrates with the notifications provider and includes user-friendly confirmation for destructive actions.
97-131: Excellent delete confirmation dialog implementation.The dialog follows Material Design guidelines with proper theming, localization, and visual hierarchy. The error color for the delete button provides clear visual feedback for the destructive action.
lib/features/notifications/notifiers/notifications_notifier.dart (7)
1-20: Solid StateNotifier foundation with proper Riverpod integration.The imports follow feature-based organization, and the constructor correctly initializes the repository via Riverpod dependency injection. The initial state setup with loading notifications is appropriate.
22-30: Excellent async loading implementation.The method properly handles loading states, error cases, and maintains immutable state updates. The error handling includes stack traces for debugging.
33-53: Robust read state management implementation.Both methods correctly update the repository first, then synchronize local state. The use of
whenDatasafely handles AsyncValue transformations, and the immutable update patterns are exemplary.
55-79: Consistent CRUD operations with proper repository synchronization.All methods follow the repository-first pattern correctly, ensuring data persistence before state updates. The addNotification prepending logic maintains chronological order appropriately.
81-95: Clean temporary notification state management.The methods provide clear separation between persistent and temporary notifications. The implementations are straightforward and maintain immutable state updates correctly.
97-109: Well-structured notification creation from Action enum.The method properly constructs NotificationModel instances with appropriate mapping utilities. The reuse of
addNotificationmaintains consistency with the established patterns.
111-114: Excellent convenience method for unified notification flow.The method effectively combines temporary display with persistence, providing a clean single interface for the complete notification workflow.
lib/data/repositories/notifications_history_repository.dart (7)
7-17: Excellent repository interface design.The interface provides comprehensive CRUD operations with streaming support and proper abstractions. The method signatures are consistent and follow repository pattern best practices.
19-24: Solid repository implementation structure.The class properly extends BaseStorage and implements the repository interface. The constructor follows dependency injection patterns consistently with the codebase.
26-54: Robust serialization with proper enum and null handling.The serialization methods correctly handle enum conversions, null safety, and nested data structures. The DateTime handling and Map deep copying demonstrate good attention to detail.
57-99: Well-implemented CRUD operations with appropriate sorting.The methods properly utilize BaseStorage functionality and implement logical sorting (newest first) for notifications. The reuse of inherited methods maintains consistency.
69-89: Efficient read state management with proper transaction usage.The
markAsReadmethod includes appropriate null checking, whilemarkAllAsReadefficiently uses transactions and only updates unread notifications for better performance.
101-106: Clean streaming implementation for real-time updates.The method correctly leverages BaseStorage functionality and maintains consistent sorting with other methods, enabling reactive UI updates.
108-114: Effective filtering for unread notifications.The method properly filters unread notifications while maintaining consistent sorting, supporting features like unread count badges.
lib/l10n/intl_es.arb (1)
748-833: Comprehensive notification localization support.The Spanish translations provide excellent coverage for all notification functionality, with proper key organization and ARB format compliance. This thoroughly supports the notifications feature for Spanish-speaking users.
lib/l10n/intl_it.arb (1)
756-842: Verify that every new key is replicated inintl_en.arbandintl_es.arbCoding guidelines mandate that all three localization files are kept in sync.
Please confirm the English and Spanish ARBs contain the same notification keys (and any renamed keys from the previous comment) before merging.
| return RefreshIndicator( | ||
| onRefresh: () async { | ||
| return ref.refresh(notificationsProvider); | ||
| }, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Consider awaiting the provider refresh
The ref.refresh(notificationsProvider) call returns a Future but it's not being awaited. This might cause the refresh indicator to disappear before the refresh is complete.
return RefreshIndicator(
onRefresh: () async {
- return ref.refresh(notificationsProvider);
+ await ref.refresh(notificationsProvider);
},📝 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.
| return RefreshIndicator( | |
| onRefresh: () async { | |
| return ref.refresh(notificationsProvider); | |
| }, | |
| return RefreshIndicator( | |
| onRefresh: () async { | |
| await ref.refresh(notificationsProvider); | |
| }, |
🤖 Prompt for AI Agents
In lib/features/notifications/screens/notifications_screen.dart around lines 72
to 75, the call to ref.refresh(notificationsProvider) returns a Future but is
not awaited, which can cause the RefreshIndicator to stop prematurely. Modify
the onRefresh callback to await the ref.refresh call by adding the await keyword
before it, ensuring the refresh indicator remains visible until the refresh
completes.
| /// Helper function to resolve localization keys | ||
| String resolveNotificationText(BuildContext context, String key) { | ||
| final s = S.of(context)!; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve null safety for localization access.
The null assertion operator ! after S.of(context) could cause runtime crashes if the localization delegate isn't properly configured.
-String resolveNotificationText(BuildContext context, String key) {
- final s = S.of(context)!;
+String resolveNotificationText(BuildContext context, String key) {
+ final s = S.of(context);
+ if (s == null) {
+ return key; // Fallback if localization is not available
+ }🤖 Prompt for AI Agents
In lib/features/notifications/widgets/notification_text_resolver.dart around
lines 4 to 6, the use of the null assertion operator (!) after S.of(context) can
lead to runtime crashes if the localization delegate is not set up correctly.
Modify the code to safely handle the possibility that S.of(context) might return
null by adding a null check or providing a fallback value, thus improving null
safety and preventing potential crashes.
|
@BraCR10 can you address rabbit comments and fix conflicts? |
- Complete Action-to-notification mapping system in NotificationMessageMapper - Obsolete notification_text_resolver.dart - Notification widgets to use centralized mapper - Localization integration for all notification types - Duplicate code and unused localization keys
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
lib/l10n/intl_es.arb (1)
902-902: Fix duplicate key collisions in Spanish localization.Similar to the Italian file, the keys
"paymentMethod"and"orderId"are defined multiple times:
"paymentMethod"appears at line 587 and line 902"orderId"appears at line 670 and line 909This creates hash collisions that will break
flutter gen-l10n.Remove the duplicate entries:
- "paymentMethod": "Método de Pago",- "orderId": "ID de Orden",The existing definitions should be sufficient for both contexts.
Also applies to: 909-909
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
lib/data/models/notification.dart(1 hunks)lib/features/notifications/notifiers/notification_temporary_state.dart(1 hunks)lib/features/notifications/notifiers/notifications_notifier.dart(1 hunks)lib/features/notifications/utils/notification_message_mapper.dart(1 hunks)lib/features/notifications/widgets/notification_details.dart(1 hunks)lib/features/notifications/widgets/notification_header.dart(1 hunks)lib/features/notifications/widgets/notification_message.dart(1 hunks)lib/features/order/notfiers/abstract_mostro_notifier.dart(6 hunks)lib/features/order/notfiers/order_notifier.dart(3 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(2 hunks)lib/l10n/intl_it.arb(2 hunks)lib/shared/widgets/notification_listener_widget.dart(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
- lib/features/notifications/widgets/notification_message.dart
- lib/features/order/notfiers/abstract_mostro_notifier.dart
- lib/features/order/notfiers/order_notifier.dart
- lib/features/notifications/widgets/notification_details.dart
- lib/features/notifications/notifiers/notification_temporary_state.dart
- lib/features/notifications/widgets/notification_header.dart
- lib/data/models/notification.dart
- lib/features/notifications/notifiers/notifications_notifier.dart
🧰 Additional context used
📓 Path-based instructions (4)
lib/shared/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
Shared utilities and widgets must be placed in
shared/
Files:
lib/shared/widgets/notification_listener_widget.dart
lib/**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/**/*.dart: UseS.of(context).yourKeyfor all user-facing strings
Always checkmountedbefore using context after async operations
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/notifications/utils/notification_message_mapper.dart
**/*.dart
📄 CodeRabbit Inference Engine (CLAUDE.md)
**/*.dart: Remove unused imports and dependencies
Useconstconstructors where possible
Files:
lib/shared/widgets/notification_listener_widget.dartlib/features/notifications/utils/notification_message_mapper.dart
lib/l10n/*.arb
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/l10n/*.arb: Internationalization ARB files must be located inlib/l10n/
Add new localization keys to all three ARB files (en, es, it)
Use proper ARB metadata for parameterized strings
Files:
lib/l10n/intl_es.arblib/l10n/intl_en.arblib/l10n/intl_it.arb
🧠 Learnings (18)
📓 Common learnings
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.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Use Riverpod for all state management
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/features/*/{screens,providers,notifiers,widgets}/** : Feature-based organization: `features/{feature}/{screens|providers|notifiers|widgets}/`
📚 Learning: applies to lib/**/*.dart : use `s.of(context).yourkey` for all user-facing strings...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/**/*.dart : Use `S.of(context).yourKey` for all user-facing strings
Applied to files:
lib/shared/widgets/notification_listener_widget.dartlib/features/notifications/utils/notification_message_mapper.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/shared/widgets/notification_listener_widget.dartlib/features/notifications/utils/notification_message_mapper.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:
lib/shared/widgets/notification_listener_widget.dartlib/features/notifications/utils/notification_message_mapper.dart
📚 Learning: use riverpod for all state management...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Use Riverpod for all state management
Applied to files:
lib/shared/widgets/notification_listener_widget.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:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: applies to lib/core/app_routes.dart : gorouter must be configured in `core/app_routes.dart`...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/core/app_routes.dart : GoRouter must be configured in `core/app_routes.dart`
Applied to files:
lib/shared/widgets/notification_listener_widget.dart
📚 Learning: in the mostro mobile codebase, mostromessage objects have an 'action' member that can be directly ac...
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/shared/providers/app_init_provider.dart:78-95
Timestamp: 2025-05-06T16:08:19.352Z
Learning: In the Mostro Mobile codebase, MostroMessage objects have an 'action' member that can be directly accessed (e.g., mostroMessage.action).
Applied to files:
lib/features/notifications/utils/notification_message_mapper.dart
📚 Learning: all changes should pass `flutter analyze` before commit...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: All changes should pass `flutter analyze` before commit
Applied to files:
lib/features/notifications/utils/notification_message_mapper.dartlib/l10n/intl_it.arb
📚 Learning: in the cantdo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'ca...
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Applied to files:
lib/features/notifications/utils/notification_message_mapper.dartlib/l10n/intl_it.arb
📚 Learning: zero `flutter analyze` issues must be maintained...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Zero `flutter analyze` issues must be maintained
Applied to files:
lib/features/notifications/utils/notification_message_mapper.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-08-03T09:43:38.727Z
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/notifications/utils/notification_message_mapper.dart
📚 Learning: applies to **/*.dart : use `const` constructors where possible...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to **/*.dart : Use `const` constructors where possible
Applied to files:
lib/features/notifications/utils/notification_message_mapper.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-08-03T09:43:38.727Z
Learning: Applies to lib/core/mostro_fsm.dart : Order state transitions must be managed by `core/mostro_fsm.dart`
Applied to files:
lib/features/notifications/utils/notification_message_mapper.dart
📚 Learning: applies to lib/generated/l10n*.dart : generated localization files must be in `lib/generated/l10n.da...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/generated/l10n*.dart : Generated localization files must be in `lib/generated/l10n.dart` and language-specific files
Applied to files:
lib/features/notifications/utils/notification_message_mapper.dartlib/l10n/intl_it.arb
📚 Learning: applies to lib/l10n/*.arb : add new localization keys to all three arb files (en, es, it)...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_en.arblib/l10n/intl_it.arb
📚 Learning: regenerate localization files after arb modifications...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Regenerate localization files after ARB modifications
Applied to files:
lib/l10n/intl_es.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-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for parameterized strings
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_en.arblib/l10n/intl_it.arb
🪛 RuboCop (1.76.1)
lib/l10n/intl_es.arb
[warning] 902-902: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 909-909: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_en.arb
[warning] 806-806: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 876-876: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 883-883: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_it.arb
[warning] 910-910: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 917-917: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
🔇 Additional comments (14)
lib/shared/widgets/notification_listener_widget.dart (4)
4-6: LGTM on import updates!The imports correctly reflect the new notifications architecture with proper feature-based organization and the new message mapping utility.
16-17: Clean provider integration!The switch to
temporaryNotificationProviderand the simplifiedshowcondition makes the notification triggering logic more straightforward.
36-37: Excellent refactoring!Using
NotificationMessageMapper.getLocalizedTitle()centralizes the localization logic and eliminates the code duplication that was previously noted. This follows DRY principles and makes maintenance easier.
47-47: Correct method call update!The change to
clearTemporary()properly aligns with the new notification system that separates temporary and persistent notifications.lib/l10n/intl_en.arb (2)
801-886: Comprehensive notification localization coverage!The notification strings provide excellent coverage of all notification types with consistent naming patterns. The pairing of titles and messages for each notification type, along with the detailed labels, will support a rich notification experience.
876-883: Address reported duplicate keys.Static analysis is reporting duplicate keys at these lines. The verification script above will help identify all actual duplicates that need to be resolved.
lib/features/notifications/utils/notification_message_mapper.dart (4)
5-10: Excellent documentation and design!The class documentation clearly explains the exhaustive mapping approach and the compiler's role in enforcing completeness. The static utility pattern is appropriate for this mapping functionality.
12-89: Excellent exhaustive switch implementation!The switch statement properly covers all Action enum values without a default case, ensuring compile-time enforcement of completeness. The logical grouping of related actions is well done.
92-170: Well-structured message key mapping!The exhaustive switch pattern is consistent with the title mapping, and the differentiation between buy/sell order messages provides appropriate context for users.
172-313: Excellent centralized localization solution!The helper methods properly follow the
S.of(context)!pattern from coding guidelines. The comprehensive_resolveLocalizationKeymethod centralizes all notification localization logic, effectively addressing the code duplication concerns mentioned in previous reviews. The fallback to return the key is a sensible approach for error handling.lib/l10n/intl_it.arb (2)
598-598: LGTM! Key renames improve clarity.The renamed keys
cancelPendingTradeButtonandcompletePurchaseTradeButtonare more specific and clearer about their context compared to the original names. This improves code maintainability and reduces ambiguity.Also applies to: 601-601
835-920: Comprehensive notifications localization added successfully.The Italian translations for the notifications feature are well-structured and comprehensive, covering:
- UI elements (screen titles, buttons, empty states)
- Notification event messages for all trading scenarios
- Detail labels and confirmation dialogs
- Proper ARB formatting with appropriate metadata
The translations maintain consistency with the existing Italian localization style.
lib/l10n/intl_es.arb (2)
583-583: LGTM! Consistent key renames across localization files.The renamed keys match the changes in the Italian localization file, maintaining consistency. The added "Trade" suffix makes these button labels more specific and contextually clear.
Also applies to: 586-586
826-912: Comprehensive Spanish notifications localization added.The Spanish translations for the notifications feature are well-implemented, providing:
- Complete UI element translations (titles, buttons, messages)
- Detailed notification event messages for all trading scenarios
- Proper localization detail labels and confirmation dialogs
- Consistent structure with the Italian localization file
The translations are contextually appropriate for Spanish-speaking users.
| "orderTimeout": "Order timeout occurred", | ||
| "orderCanceled": "The order was canceled" | ||
| "orderCanceled": "The order was canceled", |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify duplicate key warnings.
Static analysis is reporting duplicate keys, but the visible content doesn't show duplicates at these lines. Please verify if there are actual duplicate keys in the file that need to be resolved.
🏁 Script executed:
#!/bin/bash
# Check for duplicate keys in the ARB file
echo "Checking for duplicate keys in intl_en.arb..."
rg -n '"([^"]+)":' lib/l10n/intl_en.arb | cut -d':' -f3 | cut -d'"' -f2 | sort | uniq -dLength of output: 789
Remove duplicate keys in lib/l10n/intl_en.arb
Static analysis confirms that several localization keys are defined more than once in lib/l10n/intl_en.arb. Please de-duplicate these entries so each key appears only once, then regenerate your localization files. Duplicate keys include (but are not limited to):
• “{”
• “Active”
• “Cancel Trade”
• “Created on”
• “Dispute started”
• “Error”
• “If you confirm, you will accept the cooperative cancellation initiated by your counterparty.”
• “If you confirm, you will start a cooperative cancellation with your counterparty.”
• “ORDER DETAILS”
• “Order ID”
• “Order ID copied to clipboard”
• “Order taken”
• “Payment Method”
• “Payment methods”
• “Pending”
• “Proof of Work”
• “RATE”
• “Rating”
• “Retry”
• “String”
• “Success”
• “The amount of satoshis”
• “The expiration time in minutes”
• “The fiat amount”
• “The fiat currency code”
• “The order ID”
• “The relay URL that was added”
• “Time Left”
• “Version”
• “You are chatting with {handle}”
• “You have canceled the order ID”
• “int”
Actions required:
- Remove all redundant key definitions in
lib/l10n/intl_en.arb. - Ensure the remaining entries are correct and unique.
- Regenerate localization delegates (e.g., via
flutter pub run intl_utils:generate).
🤖 Prompt for AI Agents
In lib/l10n/intl_en.arb around lines 798 to 799, there are multiple duplicate
localization keys present. Remove all redundant duplicate key definitions so
that each key appears only once in the file. After cleaning up the duplicates,
verify that the remaining entries are correct and unique. Finally, regenerate
the localization delegates using the appropriate command such as `flutter pub
run intl_utils:generate` to update the localization files accordingly.
2441216 to
d4fc147
Compare
Updates notification-related labels in the application to improve clarity and avoid key duplication. This change introduces more descriptive keys in the ARB files, enhancing the maintainability and readability of the localization resources.
|
Thanks Sir, I think that I fixed all changes suggested by rabbit, pls let me know if more changes are required |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
lib/l10n/intl_en.arb (1)
806-806: Duplicate key"retry"shadows the previous definition – breaksflutter intlgeneration
"retry"was already defined at Line 215. Re-defining it here (Line 806) violates JSON uniqueness and causesflutter gen-l10nto fail.- "retry": "Retry",Either remove this entry or give the notifications screen its own distinct key (e.g.
"retryNotifications").
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
lib/features/notifications/widgets/notification_details.dart(1 hunks)lib/features/notifications/widgets/notification_item.dart(1 hunks)lib/features/notifications/widgets/notification_menu.dart(1 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(2 hunks)lib/l10n/intl_it.arb(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- lib/features/notifications/widgets/notification_menu.dart
- lib/features/notifications/widgets/notification_details.dart
- lib/features/notifications/widgets/notification_item.dart
- lib/l10n/intl_it.arb
🧰 Additional context used
📓 Path-based instructions (1)
lib/l10n/*.arb
📄 CodeRabbit Inference Engine (CLAUDE.md)
lib/l10n/*.arb: Internationalization ARB files must be located inlib/l10n/
Add new localization keys to all three ARB files (en, es, it)
Use proper ARB metadata for parameterized strings
Files:
lib/l10n/intl_es.arblib/l10n/intl_en.arb
🧠 Learnings (8)
📓 Common learnings
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.
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Use Riverpod for all state management
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/features/*/{screens,providers,notifiers,widgets}/** : Feature-based organization: `features/{feature}/{screens|providers|notifiers|widgets}/`
📚 Learning: applies to lib/l10n/*.arb : add new localization keys to all three arb files (en, es, it)...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_es.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-08-03T09:43:38.727Z
Learning: Applies to lib/l10n/*.arb : Use proper ARB metadata for parameterized strings
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_en.arb
📚 Learning: regenerate localization files after arb modifications...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Regenerate localization files after ARB modifications
Applied to files:
lib/l10n/intl_es.arblib/l10n/intl_en.arb
📚 Learning: zero `flutter analyze` issues must be maintained...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Zero `flutter analyze` issues must be maintained
Applied to files:
lib/l10n/intl_en.arb
📚 Learning: all changes should pass `flutter analyze` before commit...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: All changes should pass `flutter analyze` before commit
Applied to files:
lib/l10n/intl_en.arb
📚 Learning: in the cantdo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'ca...
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/data/models/cant_do.dart:10-27
Timestamp: 2025-07-08T05:40:47.527Z
Learning: In the CantDo model parsing in lib/data/models/cant_do.dart, the inconsistent key naming between 'cant_do' (top-level) and 'cant-do' (nested) is required by the protocol specification and should not be changed as it would break message parsing compatibility.
Applied to files:
lib/l10n/intl_en.arb
📚 Learning: applies to lib/generated/l10n*.dart : generated localization files must be in `lib/generated/l10n.da...
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-03T09:43:38.727Z
Learning: Applies to lib/generated/l10n*.dart : Generated localization files must be in `lib/generated/l10n.dart` and language-specific files
Applied to files:
lib/l10n/intl_en.arb
🪛 RuboCop (1.76.1)
lib/l10n/intl_en.arb
[warning] 806-806: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
🔇 Additional comments (4)
lib/l10n/intl_en.arb (1)
801-887: Add the newly introduced notification keys tointl_es.arbandintl_it.arb, then regenerate localization filesPer team guidelines (
lib/l10n/*.arbmust stay in sync), every key added here needs matching entries in the Spanish and Italian ARB files—otherwiseflutter gen-l10nthrows missing-key warnings and untranslated strings appear at runtime. Please:
- Copy all keys in the 801-887 range to
intl_es.arbandintl_it.arbwith appropriate translations or placeholders.- Run
flutter pub run intl_utils:generate(or equivalent) to regeneratelib/generated/l10n.dart.Let me know if you’d like an automated script to verify cross-locale consistency.
lib/l10n/intl_es.arb (3)
828-897: Excellent comprehensive notification localization.The notification system strings are well-translated and provide comprehensive coverage for all trading scenarios. The Spanish translations are contextually appropriate and maintain consistency with the existing vocabulary in the file.
The naming convention with
notification_prefixes for titles and messages creates a clear organizational structure that will be easy to maintain.
898-912: Notification details and confirmations are well-implemented.The notification detail labels and confirmation dialogs provide clear, user-friendly Spanish text. The confirmation messages for destructive actions like "confirmDeleteNotification" and "confirmClearAll" appropriately communicate the permanence of the actions.
828-912: ✔ All notification keys are synchronized across localesI’ve verified that all 68 new notification-related keys added to
lib/l10n/intl_es.arbalso exist in bothlib/l10n/intl_en.arbandlib/l10n/intl_it.arb. No missing entries were found.
| } | ||
| }, | ||
| "cancelPendingButton": "CANCELACIÓN PENDIENTE", | ||
| "cancelPendingTradeButton": "CANCELACIÓN PENDIENTE", |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify key consistency across all localization files.
The keys have been renamed from cancelPendingButton to cancelPendingTradeButton and completePurchaseButton to completePurchaseTradeButton. Ensure these same key changes exist in the English and Italian ARB files to maintain consistency.
Also applies to: 586-586
🏁 Script executed:
#!/bin/bash
# Description: Check if the renamed keys exist consistently across all ARB files
echo "Checking for new key names in all ARB files:"
echo "----------------------------------------"
# Check for the new key names
rg -l "cancelPendingTradeButton|completePurchaseTradeButton" lib/l10n/*.arb
echo -e "\nChecking for old key names that might still exist:"
echo "------------------------------------------------"
# Check if old key names still exist anywhere
rg -l "cancelPendingButton|completePurchaseButton" lib/l10n/*.arb
echo -e "\nDetailed content check:"
echo "----------------------"
# Show the actual content for these keys in all files
for file in lib/l10n/*.arb; do
echo "=== $file ==="
rg "cancelPendingTradeButton|completePurchaseTradeButton|cancelPendingButton|completePurchaseButton" "$file" || echo "No matches found"
echo
doneLength of output: 2066
Inconsistent localization key renaming across ARB files
The new keys cancelPendingTradeButton and completePurchaseTradeButton have been added only to intl_es.arb and intl_it.arb, while the old keys remain everywhere. To maintain consistency and avoid orphaned entries, please:
• lib/l10n/intl_en.arb
– Add definitions for
• "cancelPendingTradeButton": "CANCEL PENDING",
• "completePurchaseTradeButton": "COMPLETE PURCHASE"
– Remove the old keys
• "cancelPendingButton"
• "completePurchaseButton"
• lib/l10n/intl_es.arb
– Remove the old keys
• "cancelPendingButton": "CANCELACIÓN PENDIENTE",
• "completePurchaseButton": "COMPLETAR COMPRA",
• lib/l10n/intl_it.arb
– Remove the old keys
• "cancelPendingButton": "CANCELLAZIONE IN ATTESA",
• "completePurchaseButton": "COMPLETA ACQUISTO",
Ensuring that only the Trade-specific keys remain in all three ARB files will prevent confusion and keep the localization files clean.
🤖 Prompt for AI Agents
In lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, and lib/l10n/intl_it.arb around
line 583, add the new keys "cancelPendingTradeButton" and
"completePurchaseTradeButton" with their respective translations to intl_en.arb,
and remove the old keys "cancelPendingButton" and "completePurchaseButton" from
all three ARB files to maintain consistency and avoid orphaned entries.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
lib/features/order/notfiers/order_notifier.dart (2)
210-213: Duplicate send path on canceled state — confirm no double emit.You also emit on the “keep session” branch. Fine, but verify the upstream deduper so users don’t see two “canceled” notifications for the same order.
If duplicates are still observed in edge races, gate with a short-circuit (e.g., skip if
state.action == Action.canceledand last notification for this order is canceled).
395-410: Guard after dispose and prefer const map; also confirm payload key.
- Add a
mountedguard to avoid reading providers after dispose.- Use
constfor the payload maps.- Confirm the mapper expects
values['type'](vs.role). If it’srole, adjust the key to match.Apply:
void _showTimeoutNotification({required bool isCreatedByUser}) { try { - final notificationNotifier = ref.read(notificationActionsProvider.notifier); + if (!mounted) return; + final notificationNotifier = ref.read(notificationActionsProvider.notifier); @@ - notificationNotifier.showTemporary(Action.timeoutReversal, values: {'type': 'maker'}); + notificationNotifier.showTemporary( + Action.timeoutReversal, + values: const {'type': 'maker'}, + ); @@ - notificationNotifier.showTemporary(Action.timeoutReversal, values: {'type': 'taker'}); + notificationNotifier.showTemporary( + Action.timeoutReversal, + values: const {'type': 'taker'}, + );
📜 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 (1)
lib/features/order/notfiers/order_notifier.dart(4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
{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/features/order/notfiers/order_notifier.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/features/order/notfiers/order_notifier.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/features/order/notfiers/order_notifier.dart
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories
📚 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, `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:
lib/features/order/notfiers/order_notifier.dart
🔇 Additional comments (1)
lib/features/order/notfiers/order_notifier.dart (1)
9-9: Remove legacy notifier references and migrate tonotificationActionsProvider
– lib/features/notifications/notifiers/notifications_notifier.dart still declaresvoid showCustomMessage(...)under the old API; replace its usage withref.read(notificationActionsProvider.notifier)calls and delete the legacyNotificationNotifierclass and its import.⛔ Skipped due to learnings
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.Learnt from: Catrya PR: MostroP2P/mobile#272 File: lib/features/relays/widgets/relay_selector.dart:13-15 Timestamp: 2025-08-21T14:45:43.974Z Learning: In the Mostro mobile app's RelaySelector widget (lib/features/relays/widgets/relay_selector.dart), watching relaysProvider.notifier correctly triggers rebuilds because the relaysProvider itself depends on settingsProvider (line 8 in relays_provider.dart). When blacklist changes via toggleMostroRelayBlacklist(), the settingsProvider updates, causing relaysProvider to rebuild, which then notifies widgets watching the notifier. The UI correctly reflects active/inactive states in real-time through this dependency chain.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.
| logger.i('Session deleted for canceled order $orderId (was in ${currentState.status})'); | ||
|
|
||
| // Send cancellation notification using centralized function | ||
| sendNotification(Action.canceled); | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Cancellation notification: ensure idempotency and correct await/ordering.
Sending sendNotification(Action.canceled) here is right, but please ensure:
- The notifications layer dedupes by orderId+action to prevent double entries when both direct and public events fire.
- If
sendNotificationis async, await it to avoid dropped errors and to ensure ordering relative to navigation/cleanup.
If idempotency isn’t built-in, consider adding an idempotencyKey like order:$orderId:canceled at the repository level.
🏁 Script executed:
#!/bin/bash
set -e
# Search for all references and definition of sendNotification in the Dart codebase
rg -n --type=dart 'sendNotification' -g '*.dart'
# Search specifically for the function signature to see if it's async/returns Future
rg -nP --type=dart 'Future<.*>sendNotification' -g 'lib/**/*.dart'
# Search for any idempotency or deduplication logic around notifications
rg -n --type=dart 'idempotent|dedupe|deduplication' -g 'lib/**/*.dart'Length of output: 2841
🏁 Script executed:
#!/bin/bash
set -e
echo "=== sendNotification signature and context ==="
rg -nC3 --type=dart 'void sendNotification' -g 'lib/features/order/notfiers/abstract_mostro_notifier.dart'
echo
echo "=== sendNotification implementation (lines 60–140) ==="
sed -n '60,140p' lib/features/order/notfiers/abstract_mostro_notifier.dartLength of output: 3893
Ensure notification deduplication and signature consistency
- Verify that
notificationActionsProvider.notifydeduplicates byorderId+Action.canceled. If it doesn’t, add an idempotency key (e.g.order:$orderId:canceled) in the provider or at the repository layer to prevent duplicate cancellation notifications. - Refactor
sendNotification(defined at lib/features/order/notfiers/abstract_mostro_notifier.dart:72) to returnFuture<void>andawaitits invocation in lib/features/order/notfiers/order_notifier.dart (around line 193) if you need to enforce ordering or capture errors before subsequent cleanup/navigation.
🤖 Prompt for AI Agents
In lib/features/order/notfiers/order_notifier.dart around lines 190 to 194, the
review flags two issues: cancellation notifications may be sent multiple times
and sendNotification is not awaited. Ensure notification deduplication by having
notificationActionsProvider.notify (or the repository layer it calls) use an
idempotency key built from the orderId and action (for example
"order:{orderId}:canceled") so duplicate notify calls are ignored; alternatively
add that key to the provider call when sending cancellations. Then refactor
sendNotification (defined at
lib/features/order/notfiers/abstract_mostro_notifier.dart line ~72) to return
Future<void> instead of void, update its implementations accordingly, and await
sendNotification(...) here so notification delivery errors are surfaced and
ordering is enforced before proceeding with cleanup/navigation.
answering to myself, now I'm not receiving push notifications on main, apparently is not related to this PR but is something we must address after this PR is merge, so don't worry about that right now |
Sorry, I did not get this point, currently the most recent is put at the top of the notification screen, isn't it? |
hmm I just made a quick test and I received 3 notifications really quick, like someone took your order, we are waiting for buyer invoice if I remember right, and the last one was pay the invoice, so when I saw them I think all three notifications were "in the last minute" or something like that, maybe you need to order them by seconds? I will test again to see if that was what happened |
|
Hi @BraCR10 I just checked and yes, if the notifications have different times shown, the notifications are ordered correctly, but the last two notifications on this screen have the same time shown ("hace un momento"), they don't really have the same time, first came "orden tomada" and then came "pago requerido", so in that case it's not showing the correct order. What is the reason of displaying that hexadecimal value on bottom right on every card? |
|
Hello @grunch so I’m going to change it to show the most accurate time taking seconds into account. The hexadecimal are the first of the order ID , however in some screen it is reduced too much due to the width so only 3 digits are seen, should I remove it? |
|
I think that if the hexadecimal it is the order ID, it should be displayed, because it may happen that a user has several orders at the same time and it would be better to identify which order the notification is from, but to improve the UI, please place the order ID on a line below, not to the side where it cannot be seen, and put |
I think the order is correct but the notification text needs to be improved, as the "Orden Tomada" text seems to be waiting for the counterparty who just took it. However, it's the notification that it's moved to |
|
Thanks for your feedback guys, so just to sum up:
Is it correct ? |
the order id is an uuid value, not a hexadecimal and yes, please remove it, when the user tap on the notification it should be redirected to that order id, but don't do that now, after merge this PR we will create a new issue to address that |
let's finish the logic that need to be done to merge this PR, what is missing we can address it later with new PRs,
yes
just delete the id, about displaying it we can think about it later
if you can do it quickly ok do it, but what I think is right now, don't spend much time on changing texts, we all can do those changes later, we need you finish this PR to start working in the next notification PR |
…n' into feat/bracr10/notifications-screen
|
HI @grunch , the changes have been made
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
lib/l10n/intl_es.arb (3)
316-316: Fix duplicate key: "proofOfWork" defined twiceKeep one definition to avoid ARB collisions.
- "proofOfWork": "Prueba de Trabajo",Also applies to: 754-754
607-614: Rename duplicate "forAmount" key in intl_es.arb
Duplicate entries for"forAmount"at lines 607 and 725 will collide at build time; rename the second instance to disambiguate:- "forAmount": "por {amount} {currency}", - "@forAmount": { + "forAmountWithCurrency": "por {amount} {currency}", + "@forAmountWithCurrency": { "placeholders": { "amount": { "type": "String" }, "currency": { "type": "String" } } },Then update all Dart call sites to use
S.of(context)!.forAmountWithCurrency.
252-252: Remove or rename duplicate “createdOn” entry
“createdOn” is defined at lines 252 and 708, causing the latter ("Creado el:") to shadow the former. Remove the second occurrence or rename it (e.g."createdOnLabelWithColon") and update any affected usages.
🧹 Nitpick comments (6)
lib/l10n/intl_es.arb (3)
247-251: Add missing space before {sats}Minor readability nit in two strings.
- "youAreSellingText": "Estás vendiendo{sats} sats por {amount} {price} {premium}", - "youAreBuyingText": "Estás comprando{sats} sats por {amount} {price} {premium}", + "youAreSellingText": "Estás vendiendo {sats} sats por {amount} {price} {premium}", + "youAreBuyingText": "Estás comprando {sats} sats por {amount} {price} {premium}",
935-940: Unify Spanish for “hold invoice” → “factura retenida”Consistent terminology with the rest of the ES file.
- "notification_hold_invoice_payment_accepted_message": "El pago de la factura hold ha sido aceptado", - "notification_hold_invoice_payment_settled_message": "El pago de la factura hold ha sido liquidado", - "notification_hold_invoice_payment_canceled_message": "El pago de la factura hold ha sido cancelado", + "notification_hold_invoice_payment_accepted_message": "El pago de la factura retenida ha sido aceptado", + "notification_hold_invoice_payment_settled_message": "El pago de la factura retenida ha sido liquidado", + "notification_hold_invoice_payment_canceled_message": "El pago de la factura retenida ha sido cancelado",
417-417: Translate comment labels to ES for consistencyKeep comment strings consistent across locales.
- "@_comment_take_order_screen": "Take Order Screen Strings", + "@_comment_take_order_screen": "Cadenas de la Pantalla Tomar Orden", ... - "@_comment_notification_units": "Notification time units", + "@_comment_notification_units": "Unidades de tiempo de notificaciones",Also applies to: 986-987
lib/features/notifications/widgets/notification_footer.dart (1)
12-16: Trim widget tree: return child directly instead of a single-child RowRow with one child adds unnecessary depth. Return the widget directly (or wrap with Align if layout needs it).
@override Widget build(BuildContext context) { - return Row( - children: [ - TimestampText(notification: notification), - ], - ); + return TimestampText(notification: notification); }lib/l10n/intl_en.arb (2)
878-941: Capitalize notification titles consistentlyTitles mix “Title Case” (e.g., Contact Buyer) and sentence case (e.g., New order available). Pick one style for all
*_titlekeys for consistency (non-blocking).
943-962: Label casing consistency in details/unitsConsider aligning “Retry Interval”, “Attempts left”, “seconds/minutes” casing with existing UI labels (“Payment Method”, etc.) for uniformity. Non-blocking.
📜 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/notifications/widgets/notification_footer.dart(1 hunks)lib/features/notifications/widgets/timestamp_text.dart(1 hunks)lib/l10n/intl_en.arb(1 hunks)lib/l10n/intl_es.arb(4 hunks)lib/l10n/intl_it.arb(5 hunks)lib/shared/utils/datetime_extensions_utils.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- lib/features/notifications/widgets/timestamp_text.dart
- lib/shared/utils/datetime_extensions_utils.dart
- lib/l10n/intl_it.arb
🧰 Additional context used
📓 Path-based instructions (4)
{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/features/notifications/widgets/notification_footer.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/features/notifications/widgets/notification_footer.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/features/notifications/widgets/notification_footer.dart
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.arb
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
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_en.arb
🔇 Additional comments (4)
lib/l10n/intl_es.arb (2)
896-988: Notifications block LGTMGood coverage of titles/messages, detail labels, and units.
896-988: Remove duplicate keys and ensure all locales are in sync
- In lib/l10n/intl_es.arb, remove duplicate entries for:
@forAmount, forAmount, createdOn, amount, count, currency, description, error, expiration_seconds, fiat_amount, fiat_code, max, maxAmount, min, minAmount, order_id, placeholders, premium, proofOfWork, reviews, sats, time, type, url- Add these keys to lib/l10n/intl_en.arb (present in es only):
@forAmount, @someoneIsBuyingFixedTitle, @someoneIsSellingFixedTitle, @youAreBuyingTitle, @youAreSellingTitle, amount, myActiveTrades, placeholders, sats- Add these keys to lib/l10n/intl_it.arb (present in es only):
@forAmount, createdOn, forAmount, myActiveTrades, proofOfWork- Regenerate localization artifacts:
dart run build_runner build -d (or flutter gen-l10n)⛔ Skipped due to learnings
Learnt from: CR PR: MostroP2P/mobile#0 File: CLAUDE.md:0-0 Timestamp: 2025-08-28T20:32:34.592Z Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)Learnt from: CR PR: MostroP2P/mobile#0 File: CLAUDE.md:0-0 Timestamp: 2025-08-28T20:32:34.592Z Learning: Run `dart run build_runner build -d` after ARB/localization changes to regenerate codelib/l10n/intl_en.arb (2)
870-941: Notifications block reads well; keys/namespacing look consistentGood structure: screen texts plus title/message pairs per event, consistent
notification_*prefixing. Nice addition ofnotAvailableShortfallback.
870-962: Locale parity verified for es/it ARB files
All new notification keys from intl_en.arb are present in intl_es.arb and intl_it.arb.
|
@BraCR10 please send a lightning invoice with amount of 300000 sats here as a comment |
|
Hi @grunch ! Address: bracr10@pay.bitcoinjungle.app |
paid! preimage: 3da9a09f4119f38a2ad86aceff8665455620ecab656ee2bc31fef0a1086e11cf |
|
Confirmed , thanks ! |



Notifications Screen Implementation
Closes #91
Overview
This pull request introduces a notifications system that uses the previous temporary SnackBar-based approach with a persistent notification center. The implementation provides users with a complete history of their activities produced by
lib/features/order/notfiers/abstract_mostro_notifier.dartProblem Statement
The previous notification system relied on temporary SnackBar messages that disappeared after a few seconds, providing no historical context or detailed information about trade events. Users had no way to review past notifications or access detailed information about specific actions that occurred during their trading sessions.
Solution Architecture
The new notification system is built around a persistent storage model using Sembast database integration with a UI layer. The architecture follows a modular approach with clear separation of concerns between data persistence, state management, and user interface components.
Data Layer
The foundation of the new system is built on
lib/data/models/notification.dart, which defines the notification model. This model works in conjunction withlib/data/models/enums/notification_type.dartthat categorizes notifications into seven distinct types: orderUpdate, payment, dispute, cancellation, tradeUpdate, message, and system notifications.The persistence layer is handled through
lib/data/repositories/notifications_history_repository.dart, which implements a repository pattern with a clean interface abstraction. The repository provides full CRUD operations, bulk management features, and filtering options. The implementation usesBaseStorageas the storage mechanism, ensuring reliable persistence across app restarts.State Management Integration
The notification system integrates seamlessly with the existing Riverpod-based state management architecture. The central component
lib/features/notifications/notifiers/notifications_notifier.dartreplaces the previous notification approach with unified logic that handles all notification lifecycle events. This notifier works withlib/features/notifications/notifiers/notifications_state.dartto maintain immutable state andlib/features/notifications/providers/notifications_provider.dartfor proper dependency injection.Message Localization and Mapping
In this implementation is the comprehensive message mapping system built around
lib/features/notifications/utils/notification_message_mapper.dart. This utility maps each Mostro action to appropriate localized title and message keys, ensuring that every notification type has specific, contextually relevant messaging. The system covers over 25 different action types to provide better info of each notification.The notification details are handled through

lib/features/notifications/widgets/notification_details.dart, where each action type receives customized detail presentation. This includes smart formatting for hash truncation, amount display, timeout conversion, and localized labeling. So keep this in mind when you need to provide more details about an action, as it should be presented in the best possible way and formatted well in that widget.User Interface Implementation
The notification screen itself is implemented in
lib/features/notifications/screens/notifications_screen.dart, providing users with a comprehensive view of their notification history.The integration with the existing app architecture required enhancements to
lib/shared/widgets/mostro_app_bar.dart, making it more modular and flexible. The app bar now supports notification bell integration through configurable properties while maintaining backward compatibility with existing usage patterns.A new interactive bell widget
lib/shared/widgets/notification_history_bell_widget.dartprovides live notification badges with unread count indicators. This widget automatically integrates with the enhanced app bar when notification functionality is enabled, providing users with immediate visual feedback about new notifications.System Migration
The implementation involved removing the legacy notification system components, specifically
lib/shared/notifiers/notification_notifier.dartandlib/shared/providers/notification_notifier_provider.dart. These components implemented the old SnackBar-based approach that provided only temporary messaging without persistence or detailed information.Existing notification triggers continue to work seamlessly, but now feed into the new persistent notification system instead of generating temporary messages.
Internationalization Expansion
This implementation includes a significant expansion of the internationalization system, adding over 90 new localization keys across three languages. The localization covers notification titles, detailed messages, UI labels, action buttons, and contextual information display.
English and Spanish translations have been personally verified for accuracy and consistency. Italian translations were generated using AI-assisted translation and require review The localization system is designed to be easily extensible for additional languages while maintaining consistency across all notification types.
Integration Points
The notification system integrates with the existing order management system through enhancements to
lib/features/order/notfiers/abstract_mostro_notifier.dart.The routing system in
lib/core/app_routes.darthas been updated to include the new notifications screen, maintaining the existing app structure.Technical Considerations
One important architectural note concerns the existing
lib/notifications/notification_service.dart, which handles OS-level push notifications through the system notification bar. This is separate from the new in-app notification system implemented inlib/features/notifications/. The naming similarity could potentially cause confusion for developers navigating the codebase, and consideration should be given to reorganizing these components for clarity.Sumary
26 new files added, 13 existing files modified, and 2 legacy files removed. Code includes comprehensive UI components, business logic, and localization content across multiple languages.
The modular architecture ensures maintainable code with clear separation between data persistence, business logic, and user interface components.
I welcome feedback on the architectural decisions, user experience design, Italian translations, performance optimizations, and any additional functionality that would enhance the notification system.
Summary by CodeRabbit