Skip to content

Conversation

@mohit7705
Copy link

@mohit7705 mohit7705 commented Jan 10, 2026

Summary

This PR fixes the SnackBar UX issue where SnackBars were appearing at the bottom
and blocking the bottom navigation bar. It also resolves all flutter analyze
warnings and stabilizes crypto-related tests.

What was done

  • Migrated SnackBars to top-positioned notifications using showTopSnackBar
  • Ensured bottom navigation remains clickable while SnackBars are visible
  • Fixed use_build_context_synchronously issues across widgets
  • Resolved analyzer errors and warnings
  • Verified crypto tests (ChaCha20-Poly1305) pass successfully

Before

  • SnackBars appeared at the bottom
  • Bottom navigation was blocked
  • Poor UX during longer notifications

After

  • SnackBars appear at the top
  • Bottom navigation remains usable
  • Consistent behavior across all screens

Verification

  • flutter analyze → ✅ no issues
  • Tests → ✅ passed

Summary by CodeRabbit

  • New Features

    • Adds a top-positioned notification (top snackbar) for clearer, more visible error and success messages.
  • Refactor

    • Unified in-app notifications across screens and widgets to use the new top snackbar for consistent user feedback (copy, upload, errors, success).
  • Localization

    • Added and clarified several error messages for clearer feedback (uploading, invoice update, order cancellation).

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 10, 2026

Walkthrough

Adds a top-floating snackbar utility showTopSnackBar and replaces most ScaffoldMessenger SnackBar usages across the app with it. Also exposes test helper listeners via a new public getter on FakeSecureStorage and changes FakeMostroService to use a private _ref with a public getter.

Changes

Cohort / File(s) Summary
New Utility
lib/common/top_snackbar.dart
Adds showTopSnackBar(BuildContext, String, {Color? backgroundColor, Duration duration = const Duration(seconds: 3)}) to display a top-floating SnackBar with status-bar-aware margin.
Test Infrastructure
integration_test/test_helpers.dart
Adds private _listeners and exposes it via new public getter getListeners on FakeSecureStorage; changes FakeMostroService to store Ref in private final Ref _ref; with public getter Ref get ref => _ref; (constructor updated to FakeMostroService(this._ref)).
Core/Handler
lib/core/deep_link_handler.dart
Replaces inline ScaffoldMessenger SnackBar with showTopSnackBar for deep-link error reporting.
Auth Screens
lib/features/auth/screens/login_screen.dart, lib/features/auth/screens/register_screen.dart
Switches AuthFailure error display from ScaffoldMessenger SnackBar to showTopSnackBar.
Chat Widgets
lib/features/chat/widgets/encrypted_file_message.dart, .../encrypted_image_message.dart, .../message_bubble.dart, .../message_input.dart
Replaces SnackBar usages with showTopSnackBar for file/image open errors, upload errors, and clipboard feedback; updates some i18n keys.
Disputes Feature
lib/features/disputes/widgets/dispute_input_section.dart, .../dispute_message_bubble.dart
Uses showTopSnackBar for dispute actions and copy-to-clipboard feedback.
Key Manager
lib/features/key_manager/key_management_screen.dart
Replaces mnemonic import success/failure SnackBars with showTopSnackBar (color-coded).
Notifications
lib/features/notifications/widgets/notifications_actions_menu.dart
Replaces SnackBar with showTopSnackBar for "mark all as read" and "clear all" actions.
Order Screens
lib/features/order/screens/add_lightning_invoice_screen.dart, .../add_order_screen.dart
Replaces SnackBar with showTopSnackBar for validation/error prompts and user guidance.
Settings
lib/features/settings/about_screen.dart
Replaces error and copy-to-clipboard SnackBars with showTopSnackBar.
Trades
lib/features/trades/screens/trade_detail_screen.dart
Reformats dispute-creation snackbar code; presentation simplified (removed explicit backgroundColor).
Shared Widgets
lib/shared/widgets/clickable_text_widget.dart, .../exchange_rate_widget.dart, .../notification_listener_widget.dart, .../order_cards.dart
Replaces various SnackBar feedback (clipboard, refresh, notifications, order ID copy) with showTopSnackBar; adds mounted checks in some copy flows.
Localization
lib/l10n/intl_en.arb
Updates couldNotOpenFile, errorOpeningFile punctuation and adds errorUploadingFile, failedToUpdateInvoice, failedToCancelOrder.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Catrya
  • grunch

Poem

"I hopped in with a tiny tap,
Top snackbars dancing on the map.
Errors and copies, seen on top,
A carrot cheer, then I hop-hop-hop. 🥕"

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: moving SnackBars to top and resolving flutter analyze issues, which are the primary objectives of this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lib/features/notifications/widgets/notifications_actions_menu.dart (1)

90-120: Fix: don’t call showTopSnackBar with a dialog context after pop() (may be unmounted). (Line 90-120)
Use the parent BuildContext captured by _showClearAllConfirmationDialog(...) for the snackbar, and use a dedicated dialogContext only for Navigator.pop().

Proposed fix
-  void _showClearAllConfirmationDialog(BuildContext context, WidgetRef ref) {
+  void _showClearAllConfirmationDialog(BuildContext context, WidgetRef ref) {
     showDialog(
       context: context,
-      builder: (context) => AlertDialog(
+      builder: (dialogContext) => AlertDialog(
         backgroundColor: AppTheme.backgroundDark,
         title: Text(
           S.of(context)!.clearAll,
           style: const TextStyle(color: AppTheme.textPrimary),
         ),
         ...
         actions: [
           TextButton(
-            onPressed: () => Navigator.of(context).pop(),
+            onPressed: () => Navigator.of(dialogContext).pop(),
             child: Text(
               S.of(context)!.cancel,
               style: const TextStyle(color: AppTheme.textSecondary),
             ),
           ),
           TextButton(
             onPressed: () {
               ref.read(notificationsDatabaseProvider).clearAll();
-              Navigator.of(context).pop();
-              showTopSnackBar(
-                context,
+              Navigator.of(dialogContext).pop();
+              showTopSnackBar(
+                context,
                 S.of(context)!.clearAll,
                 backgroundColor: AppTheme.statusError,
-       );
+              );
             },
             child: Text(
               S.of(context)!.clearAll,
               style: const TextStyle(color: AppTheme.statusError),
             ),
           ),
         ],
       ),
     );
   }
🤖 Fix all issues with AI agents
In @lib/features/chat/widgets/encrypted_file_message.dart:
- Around line 498-503: Replace the hardcoded snack bar message in the
showTopSnackBar call with a localized string from the generated localization
class (S.of(context).couldNotOpenFile) that accepts or formats the error detail
(result.message); update the showTopSnackBar invocation in
encrypted_file_message.dart (where showTopSnackBar is called) to use
S.of(context).couldNotOpenFile and pass/format result.message, and add the
corresponding couldNotOpenFile key/placeholder to the ARB resource files so the
localization generator produces the S.couldNotOpenFile accessor.
- Around line 508-512: The snack bar shows a hardcoded English message; replace
the literal in the showTopSnackBar call with a localized string from the
generated localization class (use S.of(context).errorOpeningFile) and
interpolate the error details into that localized string; add the corresponding
"errorOpeningFile" key to ARB files (e.g., intl_en.arb) with a placeholder for
the error message so the call to showTopSnackBar(context,
S.of(context).errorOpeningFile(e.toString()), ...) uses the localized text
instead of the hardcoded literal.

In @lib/features/chat/widgets/message_input.dart:
- Around line 131-135: Replace the hard-coded snack bar message in the
showTopSnackBar call with a localized string: add an errorUploadingFile entry to
your ARB files (e.g., intl_en.arb) and use S.of(context).errorUploadingFile
(include the error details via interpolation if desired, e.g., formatted with
the localized string) in place of the literal 'Error uploading file: $e'; update
the showTopSnackBar invocation in message_input.dart accordingly so all
user-facing text uses S.of(context).

In @lib/features/order/screens/add_lightning_invoice_screen.dart:
- Around line 83-86: The user-facing error string in the showTopSnackBar call
should be localized: add a failedToCancelOrder key to the ARB files (e.g.,
intl_en.arb) that supports interpolation for the error detail, then replace the
hardcoded string in add_lightning_invoice_screen.dart where showTopSnackBar(...)
is called with S.of(context)!.failedToCancelOrder (or
S.of(context)!.failedToCancelOrder(error) if using parameterized messages) so
the displayed message uses the localized resource and include the exception text
via the ARB interpolation; ensure the localization getter name matches the ARB
key and update localization generation if necessary.
- Around line 67-70: The snack bar error message is hardcoded; replace the
literal string in the showTopSnackBar call with a localized string (use
S.of(context)!.failedToUpdateInvoice and include the dynamic error details if
needed), update ARB files (e.g., intl_en.arb) to add the failedToUpdateInvoice
key and run codegen, and ensure the call sites (showTopSnackBar(...)) pass the
localized text instead of the hardcoded message.

In @lib/shared/widgets/order_cards.dart:
- Around line 231-239: Add the top snack bar import and replace the bottom
SnackBar usage in the onPressed callback in order_cards.dart: import
'package:mostro_mobile/common/top_snackbar.dart'; then inside the onPressed that
currently calls Clipboard.setData(...) and
ScaffoldMessenger.of(context).showSnackBar(...), keep the
Clipboard.setData(ClipboardData(text: orderId)) call but remove the
ScaffoldMessenger call and instead invoke showTopSnackBar with the same success
message text (S.of(context)!.orderIdCopiedMessage) so the copy confirmation uses
the top snack bar API consistently with other notifications.
🧹 Nitpick comments (10)
integration_test/test_helpers.dart (1)

191-194: Consider returning an unmodifiable view of the listeners map.

The getter exposes the internal _listeners map directly, allowing tests to mutate the fake storage's internal state. While this may be intentional for testing purposes, returning an unmodifiable view would prevent accidental modifications.

🔒 Proposed fix to return unmodifiable map
  final Map<String, List<ValueChanged<String?>>> _listeners = {};

  @override
- Map<String, List<ValueChanged<String?>>> get getListeners => _listeners;
+ Map<String, List<ValueChanged<String?>>> get getListeners => 
+     Map.unmodifiable(_listeners);
lib/features/chat/widgets/encrypted_file_message.dart (1)

118-118: Consider localizing additional hardcoded strings.

While not part of the changed lines, the file contains additional hardcoded English strings at lines 118 ('Failed to load image') and 370 ('Failed to load file') that should also be localized for consistency.

Based on coding guidelines: "Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals."

Also applies to: 370-370

lib/shared/widgets/exchange_rate_widget.dart (1)

2-2: Localize the new “Refreshing exchange rate...” message (don’t add new hard-coded UI strings).
The new snackbar text is user-facing and should go through S.of(context) rather than a literal. As per coding guidelines, localize all user-facing strings via ARB files and access them with S.of(context).

Proposed change
 import 'package:flutter/material.dart';
 import 'package:mostro_mobile/common/top_snackbar.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
 import 'package:intl/intl.dart';
 import 'package:mostro_mobile/core/app_theme.dart';
 import 'package:mostro_mobile/shared/providers/exchange_service_provider.dart';
+import 'package:mostro_mobile/generated/l10n.dart';
 ...
                       showTopSnackBar(
                         context,
-                        'Refreshing exchange rate...',
+                        S.of(context)!.refreshingExchangeRate,
                       );

Also applies to: 49-55

lib/features/disputes/widgets/dispute_input_section.dart (1)

2-2: Don’t surface raw $message / $error in snackbars; localize the copy.
Consider switching to localized, generic success/failure strings and logging errors separately (if needed), instead of interpolating user input / exception text into a top snackbar. As per coding guidelines, localize all user-facing strings via S.of(context).

Proposed change
       if (mounted) {
         showTopSnackBar(
           context,
-          'Message sent: $message',
+          S.of(context)!.messageSent,
           backgroundColor: Colors.green,
-          );
+        );
       }
 ...
       if (mounted) {
         showTopSnackBar(
           context,
-          'Failed to send message: $error',
+          S.of(context)!.failedToSendMessage,
           backgroundColor: Colors.red,
-     );
+        );
       }

Also applies to: 130-144

lib/shared/widgets/clickable_text_widget.dart (1)

2-2: Localize clipboard feedback and avoid echoing the copied value in the snackbar.
Prefer a short localized “Copied to clipboard” (optionally include only a label, not the full copied text). As per coding guidelines, localize all user-facing strings via S.of(context).

Proposed change
 import 'package:flutter/gestures.dart';
 import 'package:mostro_mobile/common/top_snackbar.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:mostro_mobile/core/app_theme.dart';
+import 'package:mostro_mobile/generated/l10n.dart';
 ...
   showTopSnackBar(
     context,
-    '${widget.leftText} ${widget.clickableText} copied to clipboard',
+    S.of(context)!.copiedToClipboard,
   );

Also applies to: 38-48

lib/features/disputes/widgets/dispute_message_bubble.dart (1)

2-2: Await clipboard copy before showing success, and prefer fully-localized message (no fallback literal).
This avoids showing a “copied” toast if the clipboard write fails, and keeps user-facing strings consistently localized. As per coding guidelines, localize all user-facing strings via S.of(context).

Proposed change
-  void _copyToClipboard(BuildContext context, String text) {
-    Clipboard.setData(ClipboardData(text: text));
-     showTopSnackBar(
+  Future<void> _copyToClipboard(BuildContext context, String text) async {
+    await Clipboard.setData(ClipboardData(text: text));
+    showTopSnackBar(
       context,
-      S.of(context)?.messageCopiedToClipboard ?? 'Message copied to clipboard',
+      S.of(context)!.messageCopiedToClipboard,
       backgroundColor: Colors.green,
       duration: const Duration(seconds: 1),
-   );
+    );
   }

Also applies to: 90-97

lib/shared/widgets/notification_listener_widget.dart (1)

55-105: Defer showTopSnackBar + clearTemporary() to post-frame to avoid build-phase side-effects. (Line 55-105)
This keeps UI declarative and matches the project’s “post-frame for snackbars/dialogs” guidance. Based on learnings / coding guidelines.

Proposed adjustment
     ref.listen<TemporaryNotification>(currentTemporaryNotificationProvider, (previous, next) {
       if (next.show) {
         String message;
         ...
-        showTopSnackBar(
-          context,
-          message,
-        );
-        // Clear notification after showing to prevent repetition
-        ref.read(notificationActionsProvider.notifier).clearTemporary();
+        WidgetsBinding.instance.addPostFrameCallback((_) {
+          if (!context.mounted) return;
+          showTopSnackBar(context, message);
+          // Clear notification after showing to prevent repetition
+          ref.read(notificationActionsProvider.notifier).clearTemporary();
+        });
       }
     });
lib/features/settings/about_screen.dart (1)

864-873: Consider awaiting Clipboard.setData before showing “copied” toast. (Line 864-873)
This keeps the confirmation aligned with actual completion (and makes error handling possible).

Possible tweak
-  void _copyToClipboard(BuildContext context, String text) {
-    Clipboard.setData(ClipboardData(text: text));
-    if (context.mounted) {
-       showTopSnackBar(
-         context,
-         S.of(context)!.copiedToClipboard,
-         backgroundColor: AppTheme.statusSuccess,
-     );
-    }
-  }
+  Future<void> _copyToClipboard(BuildContext context, String text) async {
+    await Clipboard.setData(ClipboardData(text: text));
+    if (!context.mounted) return;
+    showTopSnackBar(
+      context,
+      S.of(context)!.copiedToClipboard,
+      backgroundColor: AppTheme.statusSuccess,
+    );
+  }
lib/features/trades/screens/trade_detail_screen.dart (2)

724-736: Use showTopSnackBar here too (this screen still shows bottom SnackBars).

Lines 725-736 and Line 739-746 still use ScaffoldMessenger.of(context).showSnackBar(...), which seems to miss the PR’s “top snackbar” migration and can reintroduce the bottom-nav blocking UX on this screen.

Proposed diff
 import 'package:mostro_mobile/features/disputes/providers/dispute_providers.dart';
+import 'package:mostro_mobile/common/top_snackbar.dart';
 import 'package:mostro_mobile/generated/l10n.dart';
@@
             final repository = ref.read(disputeRepositoryProvider);
             final success = await repository.createDispute(orderId);
 
-            if (success && context.mounted) {
-            ScaffoldMessenger.of(context).showSnackBar(
-              SnackBar(
-              content: Text(S.of(context)!.disputeCreatedSuccessfully),
-              ),
-           );
-            } else if (context.mounted) {
-              ScaffoldMessenger.of(context).showSnackBar(
-               SnackBar(
-               content: Text(S.of(context)!.disputeCreationFailed),
-               ),
-             );
-            }
+            if (!context.mounted) return;
+            if (success) {
+              showTopSnackBar(context, S.of(context)!.disputeCreatedSuccessfully);
+            } else {
+              showTopSnackBar(context, S.of(context)!.disputeCreationFailed);
+            }
           } catch (e) {
-            if (context.mounted) {
-              ScaffoldMessenger.of(context).showSnackBar(
-                SnackBar(
-                content: Text(
-                S.of(context)!.disputeCreationErrorWithMessage(e.toString()),
-                ),
-               ),
-              );
-            }
+            if (!context.mounted) return;
+            // Consider logging `e` (sanitized) instead of showing raw details to the user.
+            showTopSnackBar(context, S.of(context)!.disputeCreationFailed);
           }

Also applies to: 738-746


738-746: Avoid showing e.toString() to users in SnackBars.

Line 742 currently surfaces the raw exception string in a user-facing message; this can leak internal/network details. Prefer a generic localized error + sanitized logging (and include stackTrace via catch (e, st) if you log).
Based on coding guidelines, keep user-facing strings localized (which you already do) and avoid leaking implementation details.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e07942 and b495f7a.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (21)
  • integration_test/test_helpers.dart
  • lib/common/top_snackbar.dart
  • lib/core/deep_link_handler.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/shared/widgets/order_cards.dart
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{dart,flutter}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{dart,flutter}: Run flutter analyze after any code change - Mandatory before commits to ensure zero linting issues
Run flutter test after any code change - Mandatory before commits to ensure all unit tests pass

Files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/shared/widgets/order_cards.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • integration_test/test_helpers.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/common/top_snackbar.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes
All code comments must be in English - use clear, concise English for variable names, function names, and comments
Always check mounted before using BuildContext after async operations to prevent errors on disposed widgets
Use const constructors where possible for better performance and immutability
Remove unused imports and dependencies to maintain code cleanliness and reduce build size

**/*.dart: Application code should be organized under lib/, grouped by domain with lib/features/<feature>/ structure, shared utilities in lib/shared/, dependency wiring in lib/core/, and services in lib/services/
Persistence, APIs, and background jobs should live in lib/data/ and lib/background/; generated localization output must be in lib/generated/ and must stay untouched
Apply flutter format . to enforce canonical Dart formatting (two-space indentation, trailing commas) before committing
Resolve every analyzer warning in Dart code
Name Riverpod providers using the <Feature>Provider or <Feature>Notifier convention
Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals

Files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/shared/widgets/order_cards.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • integration_test/test_helpers.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/common/top_snackbar.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
lib/features/**/screens/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/features/**/screens/**/*.dart: Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs
Use S.of(context)!.yourKey for all user-facing strings instead of hardcoded text

Files:

  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/features/auth/screens/register_screen.dart
lib/shared/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Follow existing feature patterns when adding new shared utilities - refer to order, chat, and auth features as implementation examples

Files:

  • lib/shared/widgets/order_cards.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/shared/widgets/exchange_rate_widget.dart
integration_test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Ensure integration test coverage for flows touching networking, background work, or session recovery in integration_test/

Files:

  • integration_test/test_helpers.dart
🧠 Learnings (21)
📓 Common learnings
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs

Applied to files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/shared/widgets/order_cards.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/common/top_snackbar.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Use `S.of(context)!.yourKey` for all user-facing strings instead of hardcoded text

Applied to files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/trades/screens/trade_detail_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
📚 Learning: 2025-08-15T01:37:12.243Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 270
File: lib/shared/widgets/order_filter.dart:133-135
Timestamp: 2025-08-15T01:37:12.243Z
Learning: The MostroP2P/mobile project requires Flutter >=3.27.0 as specified in pubspec.yaml, which supports the Color.withValues() method, so usage of withValues() throughout the codebase is valid and should not be flagged as a compatibility issue.

Applied to files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Localize all user-facing strings via ARB files and access them with `S.of(context)` rather than hard-coded literals

Applied to files:

  • lib/features/disputes/widgets/dispute_input_section.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/core/app_routes.dart : Use GoRouter for all navigation configuration instead of Navigator API - maintain all routes in app_routes.dart

Applied to files:

  • lib/features/key_manager/key_management_screen.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/auth/screens/login_screen.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes

Applied to files:

  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/settings/about_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/providers/**/*.dart : Organize Riverpod providers by feature in `features/{feature}/providers/` using Notifier pattern for complex state logic

Applied to files:

  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/settings/about_screen.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Name Riverpod providers using the `<Feature>Provider` or `<Feature>Notifier` convention

Applied to files:

  • lib/features/key_manager/key_management_screen.dart
  • lib/features/chat/widgets/message_bubble.dart
  • lib/shared/widgets/notification_listener_widget.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/encrypted_image_message.dart
  • lib/shared/widgets/exchange_rate_widget.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/shared/**/*.dart : Follow existing feature patterns when adding new shared utilities - refer to order, chat, and auth features as implementation examples

Applied to files:

  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/auth/screens/register_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/features/chat/widgets/message_input.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/providers/**/*.dart : Use Notifier pattern instead of simple StateNotifier for complex state logic requiring business rule encapsulation

Applied to files:

  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/notifiers/**/*.dart : Encapsulate business logic in Notifiers - Notifiers should expose state via providers and handle all complex state transitions

Applied to files:

  • lib/features/chat/widgets/message_bubble.dart
  • lib/features/notifications/widgets/notifications_actions_menu.dart
  • lib/shared/widgets/notification_listener_widget.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/core/mostro_fsm.dart : Use MostroFSM for managing order state transitions - all state changes must go through FSM state methods

Applied to files:

  • lib/features/order/screens/add_order_screen.dart
📚 Learning: 2025-10-21T21:47:03.451Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:157-182
Timestamp: 2025-10-21T21:47:03.451Z
Learning: In MostroP2P/mobile, for Action.canceled handling in abstract_mostro_notifier.dart (Riverpod StateNotifier), do not add mounted checks after async sessionNotifier.deleteSession(orderId) as they break order state synchronization during app restart. The Action.canceled flow contains critical business logic that must complete fully; Riverpod handles provider disposal automatically. Mounted checks should only protect UI operations, not business logic in StateNotifiers.

Applied to files:

  • lib/features/order/screens/add_order_screen.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/core/deep_link_handler.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to test/mocks.mocks.dart : Never manually modify `test/mocks.mocks.dart` - it already has file-level `// ignore_for_file: must_be_immutable` ignore directives

Applied to files:

  • integration_test/test_helpers.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Always check `mounted` before using BuildContext after async operations to prevent errors on disposed widgets

Applied to files:

  • lib/shared/widgets/clickable_text_widget.dart
  • lib/features/chat/widgets/message_input.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Remove unused imports and dependencies to maintain code cleanliness and reduce build size

Applied to files:

  • lib/features/disputes/widgets/dispute_message_bubble.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/shared/widgets/dynamic_countdown_widget.dart : Use exact `order_expires_at` timestamps from Mostro protocol for DynamicCountdownWidget precision and localize display with `S.of(context)!.timeLeftLabel()`

Applied to files:

  • lib/features/disputes/widgets/dispute_message_bubble.dart
  • lib/shared/widgets/exchange_rate_widget.dart
🔇 Additional comments (15)
lib/common/top_snackbar.dart (1)

3-27: Clean utility implementation with good UX considerations.

The function correctly:

  • Clears existing snackbars to prevent queue buildup
  • Positions the snackbar at the top using floating behavior and appropriate margins
  • Accounts for status bar padding using MediaQuery.of(context).padding.top
  • Provides sensible defaults while allowing customization

The callers appropriately handle mounted checks before invoking this function (e.g., in deep_link_handler.dart lines 54, 61, 110, 119).

lib/features/chat/widgets/message_bubble.dart (1)

2-2: LGTM! Clean migration to top snackbar.

The clipboard feedback has been correctly migrated to use showTopSnackBar, maintaining the same duration while adding consistent theming with AppTheme.backgroundCard. Since this is called from a synchronous onLongPress callback, no mounted check is needed.

Also applies to: 158-163

lib/core/deep_link_handler.dart (1)

3-3: LGTM! Proper error handling with mounted checks.

The migration correctly uses showTopSnackBar with appropriate safeguards:

  • Null check prevents errors if context is unavailable
  • All call sites (lines 54, 61, 110, 119) verify mounted after async operations before invoking this function
  • Red background provides clear visual feedback for errors

This follows the coding guideline: "Always check mounted before using BuildContext after async operations."

Also applies to: 150-158

lib/features/auth/screens/login_screen.dart (1)

24-27: LGTM: Proper snackbar refactor.

The replacement of ScaffoldMessenger with showTopSnackBar is correctly implemented within the ref.listen callback, which is the appropriate place for side effects like showing notifications.

lib/features/auth/screens/register_screen.dart (1)

43-47: LGTM: Proper snackbar refactor.

The replacement of ScaffoldMessenger with showTopSnackBar is correctly implemented within the ref.listen callback, which is the appropriate place for side effects like showing notifications.

lib/features/key_manager/key_management_screen.dart (1)

2-2: SnackBar migration looks correct (mounted checks + localized messages).
This aligns well with the PR goal and avoids use_build_context_synchronously pitfalls.

Also applies to: 94-107

lib/features/chat/widgets/encrypted_image_message.dart (2)

4-4: Nice, centralized snackbar utility import for consistent UX. (Line 4)
No concerns with adopting showTopSnackBar here.


351-395: Async + context safety in _openImage looks correct; top snackbar swap is safe. (Line 351-395)
Caching S.of(context)!... strings before await and guarding with mounted before showTopSnackBar(...) addresses use_build_context_synchronously cleanly.

lib/shared/widgets/notification_listener_widget.dart (1)

2-2: Import change is fine; aligns with new snackbar standardization. (Line 2)

lib/features/settings/about_screen.dart (2)

2-2: OK to import the shared top-snackbar helper here. (Line 2)


736-742: _showErrorSnackBar migration looks good (keeps styling consistent). (Line 736-742)

lib/features/order/screens/add_order_screen.dart (2)

4-4: Import is fine; consistent with snackbar standardization. (Line 4)


390-435: Validation feedback via showTopSnackBar is consistent and preserves early-return flow. (Line 390-435)
No functional concerns with these replacements.

lib/features/notifications/widgets/notifications_actions_menu.dart (2)

2-2: Import change is fine. (Line 2)


72-87: “Mark all read” snackbar migration looks good. (Line 72-87)

Comment on lines 498 to 503
showTopSnackBar(
context,
'Could not open file: ${result.message}',
backgroundColor: Colors.orange,
duration: const Duration(seconds: 3),
);
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use localized strings for user-facing error messages.

The error message uses a hardcoded English string. Per coding guidelines, all user-facing strings must be localized via ARB files and accessed using S.of(context).

🌐 Proposed fix to use localized strings
-          showTopSnackBar(
-            context,
-            'Could not open file: ${result.message}',
-             backgroundColor: Colors.orange,
-            duration: const Duration(seconds: 3),
-     );
+          showTopSnackBar(
+            context,
+            '${S.of(context)!.couldNotOpenFile}: ${result.message}',
+            backgroundColor: Colors.orange,
+            duration: const Duration(seconds: 3),
+          );

Note: You'll need to add couldNotOpenFile key to your ARB files (e.g., intl_en.arb).

Based on coding guidelines: "Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals."

🤖 Prompt for AI Agents
In @lib/features/chat/widgets/encrypted_file_message.dart around lines 498 -
503, Replace the hardcoded snack bar message in the showTopSnackBar call with a
localized string from the generated localization class
(S.of(context).couldNotOpenFile) that accepts or formats the error detail
(result.message); update the showTopSnackBar invocation in
encrypted_file_message.dart (where showTopSnackBar is called) to use
S.of(context).couldNotOpenFile and pass/format result.message, and add the
corresponding couldNotOpenFile key/placeholder to the ARB resource files so the
localization generator produces the S.couldNotOpenFile accessor.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Localized all user-facing error messages and resolved analyzer issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the hardcoded strings still exist in the encrypted_file_message.dart file
echo "=== Checking for hardcoded strings in encrypted_file_message.dart ==="
rg -n "Could not open file|Error opening file|Failed to load image|Failed to load file" lib/features/chat/widgets/encrypted_file_message.dart

echo ""
echo "=== Checking what localization keys exist in ARB files ==="
fd -e arb -x cat {} \; | head -100

Length of output: 4301


🏁 Script executed:

#!/bin/bash
# Search for potential localization keys that might already exist for these error messages
echo "=== Searching for file-related error keys in ARB files ==="
rg -i "file|open|load|error|download" lib/l10n/*.arb | grep -E "(openFile|loadFile|errorOpen|errorLoad|failedLoad|failedOpen|couldNot)" | head -30

echo ""
echo "=== List all ARB files to check what's available ==="
fd -e arb lib/l10n/

Length of output: 2631


🏁 Script executed:

#!/bin/bash
# Check for "failed" related localization keys
echo "=== Searching for 'failed' related keys in ARB files ==="
rg -i "failed.*file|failed.*load|failed.*image" lib/l10n/intl_en.arb

echo ""
echo "=== Check the actual lines in encrypted_file_message.dart ==="
sed -n '118p;370p;500p;510p' lib/features/chat/widgets/encrypted_file_message.dart

Length of output: 437


@mohit7705, I appreciate your effort in adding localization keys to the ARB files! However, the error messages in this file are not yet fully localized. Here's what I found:

Current Status 🔍

✅ Good news: You've added these localization keys to the ARB files:

  • couldNotOpenFile
  • errorOpeningFile
  • failedToLoadImage
  • openFile

❌ Issue: The Dart code still uses hardcoded English strings instead of calling these keys:

Line 118:  'Failed to load image',              // Should use S.of(context)!.failedToLoadImage
Line 370:  'Failed to load file',                // Missing ARB key
Line 500:  'Could not open file: ${result.message}',  // Should use S.of(context)!.couldNotOpenFile
Line 510:  'Error opening file: $e',            // Should use S.of(context)!.errorOpeningFile

What needs to be done 📝

  1. Add missing ARB key for "Failed to load file" to all three ARB files (en, es, it)

  2. Update the code to use the localization keys:

    // Line 118
    S.of(context)!.failedToLoadImage
    
    // Line 370
    S.of(context)!.failedToLoadFile  // (after adding to ARB)
    
    // Line 500
    '${S.of(context)!.couldNotOpenFile}: ${result.message}'
    
    // Line 510
    '${S.of(context)!.errorOpeningFile}: $e'
  3. Regenerate localization files after updating ARB:

    dart run build_runner build -d

Would you like me to help plan these changes?


🧠 Learnings used
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Localize all user-facing strings via ARB files and access them with `S.of(context)` rather than hard-coded literals

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Use `S.of(context)!.yourKey` for all user-facing strings instead of hardcoded text

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/l10n/**/*.arb : Add new localization keys to all three ARB files (en, es, it) - use `S.of(context)!.keyName` for all user-facing strings

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/generated/l10n*.dart : Never manually edit generated localization files - regenerate with `dart run build_runner build -d` after modifying ARB files

Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained

Comment on lines 83 to 86
showTopSnackBar(
context,
'Failed to cancel order: ${e.toString()}',
);
Copy link
Contributor

@coderabbitai coderabbitai bot Jan 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use localized strings for user-facing error messages.

The error message uses a hardcoded English string. Per coding guidelines, all user-facing strings must be localized via ARB files and accessed using S.of(context).

🌐 Proposed fix to use localized strings
-                           showTopSnackBar(
-                            context,
-                            'Failed to cancel order: ${e.toString()}',
-                         );
+                          showTopSnackBar(
+                            context,
+                            '${S.of(context)!.failedToCancelOrder}: ${e.toString()}',
+                          );

Note: You'll need to add failedToCancelOrder key to your ARB files (e.g., intl_en.arb).

Based on coding guidelines: "Use S.of(context)!.yourKey for all user-facing strings instead of hardcoded text" and "Localize all user-facing strings via ARB files."

🤖 Prompt for AI Agents
In @lib/features/order/screens/add_lightning_invoice_screen.dart around lines 83
- 86, The user-facing error string in the showTopSnackBar call should be
localized: add a failedToCancelOrder key to the ARB files (e.g., intl_en.arb)
that supports interpolation for the error detail, then replace the hardcoded
string in add_lightning_invoice_screen.dart where showTopSnackBar(...) is called
with S.of(context)!.failedToCancelOrder (or
S.of(context)!.failedToCancelOrder(error) if using parameterized messages) so
the displayed message uses the localized resource and include the exception text
via the ARB interpolation; ensure the localization getter name matches the ARB
key and update localization generation if necessary.

✅ Confirmed as addressed by @mohit7705

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced hardcoded error string with localized S.of(context).failedToCancelOrder and added the key to intl_en.arb.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mohit7705 Great! Thank you for localizing the error message. 🎉

Just a reminder: per the coding guidelines, please ensure you've added the failedToCancelOrder key to all three ARB files (intl_en.arb, intl_es.arb, and intl_it.arb), not just intl_en.arb. This ensures the message is available in all supported languages.

After updating the ARB files, don't forget to regenerate the localization files with:

dart run build_runner build -d

🧠 Learnings used
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:157-182
Timestamp: 2025-10-21T21:47:03.451Z
Learning: In MostroP2P/mobile, for Action.canceled handling in abstract_mostro_notifier.dart (Riverpod StateNotifier), do not add mounted checks after async sessionNotifier.deleteSession(orderId) as they break order state synchronization during app restart. The Action.canceled flow contains critical business logic that must complete fully; Riverpod handles provider disposal automatically. Mounted checks should only protect UI operations, not business logic in StateNotifiers.

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Use `S.of(context)!.yourKey` for all user-facing strings instead of hardcoded text

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Localize all user-facing strings via ARB files and access them with `S.of(context)` rather than hard-coded literals

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/l10n/**/*.arb : Add new localization keys to all three ARB files (en, es, it) - use `S.of(context)!.keyName` for all user-facing strings

Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/shared/widgets/dynamic_countdown_widget.dart : Use exact `order_expires_at` timestamps from Mostro protocol for DynamicCountdownWidget precision and localize display with `S.of(context)!.timeLeftLabel()`

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/generated/l10n*.dart : Never manually edit generated localization files - regenerate with `dart run build_runner build -d` after modifying ARB files

Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @lib/l10n/intl_en.arb:
- Around line 1231-1234: The ARB entries (couldNotOpenFile, errorOpeningFile,
errorUploadingFile, failedToUpdateInvoice) currently interpolate raw {error}
into user-facing strings; change callers to map known error types to friendly,
non-sensitive messages (e.g., "file not found", "permission denied", "upload
failed") or sanitize the error into a short, generic message before passing into
these keys, and send the full raw exception to internal logs; update all sites
that format these messages to pass a sanitizedError or errorCode instead of the
raw exception and ensure the raw error is logged via the existing logging
facility.
🧹 Nitpick comments (2)
lib/shared/widgets/order_cards.dart (1)

2-2: Consider grouping internal imports together.

The new import is placed between Flutter core imports, which breaks the existing pattern where mostro_mobile imports are grouped together (lines 5-6, 8-11). Consider moving this import to line 5 or 6 to maintain consistent import organization.

♻️ Suggested import reordering

Move the import after line 4 to group it with other internal imports:

 import 'package:flutter/material.dart';
-import 'package:mostro_mobile/common/top_snackbar.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:mostro_mobile/common/top_snackbar.dart';
 import 'package:mostro_mobile/core/app_theme.dart';
lib/l10n/intl_en.arb (1)

1235-1262: Add placeholder descriptions for {error} (helps translators + consistency).

Proposed diff
   "@failedToUpdateInvoice": {
-  "placeholders": {
-    "error": { "type": "String" }
-   }
- },
+    "placeholders": {
+      "error": {
+        "type": "String",
+        "description": "Technical error message (keep concise / user-safe)."
+      }
+    }
+  },

   "@failedToCancelOrder": {
-  "placeholders": {
-    "error": { "type": "String" }
-  }
- },
+    "placeholders": {
+      "error": {
+        "type": "String",
+        "description": "Technical error message (keep concise / user-safe)."
+      }
+    }
+  },

   "@errorUploadingFile": {
-  "placeholders": {
-    "error": { "type": "String" }
-  }
-},
+    "placeholders": {
+      "error": {
+        "type": "String",
+        "description": "Technical error message (keep concise / user-safe)."
+      }
+    }
+  },

   "@couldNotOpenFile": {
-   "placeholders": {
-    "error": { "type": "String" }
-   }
-  },
+    "placeholders": {
+      "error": {
+        "type": "String",
+        "description": "Technical error message (keep concise / user-safe)."
+      }
+    }
+  },

   "@errorOpeningFile": {
-   "placeholders": {
-    "error": { "type": "String" }
-   }
-  },
+    "placeholders": {
+      "error": {
+        "type": "String",
+        "description": "Technical error message (keep concise / user-safe)."
+      }
+    }
+  },
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b495f7a and 670510d.

📒 Files selected for processing (5)
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/l10n/intl_en.arb
  • lib/shared/widgets/order_cards.dart
🚧 Files skipped from review as they are similar to previous changes (3)
  • lib/features/chat/widgets/message_input.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/features/chat/widgets/encrypted_file_message.dart
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{dart,flutter}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{dart,flutter}: Run flutter analyze after any code change - Mandatory before commits to ensure zero linting issues
Run flutter test after any code change - Mandatory before commits to ensure all unit tests pass

Files:

  • lib/shared/widgets/order_cards.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes
All code comments must be in English - use clear, concise English for variable names, function names, and comments
Always check mounted before using BuildContext after async operations to prevent errors on disposed widgets
Use const constructors where possible for better performance and immutability
Remove unused imports and dependencies to maintain code cleanliness and reduce build size

**/*.dart: Application code should be organized under lib/, grouped by domain with lib/features/<feature>/ structure, shared utilities in lib/shared/, dependency wiring in lib/core/, and services in lib/services/
Persistence, APIs, and background jobs should live in lib/data/ and lib/background/; generated localization output must be in lib/generated/ and must stay untouched
Apply flutter format . to enforce canonical Dart formatting (two-space indentation, trailing commas) before committing
Resolve every analyzer warning in Dart code
Name Riverpod providers using the <Feature>Provider or <Feature>Notifier convention
Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals

Files:

  • lib/shared/widgets/order_cards.dart
lib/shared/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

Follow existing feature patterns when adding new shared utilities - refer to order, chat, and auth features as implementation examples

Files:

  • lib/shared/widgets/order_cards.dart
lib/l10n/**/*.arb

📄 CodeRabbit inference engine (CLAUDE.md)

Add new localization keys to all three ARB files (en, es, it) - use S.of(context)!.keyName for all user-facing strings

Files:

  • lib/l10n/intl_en.arb
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-10-21T21:47:03.451Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:157-182
Timestamp: 2025-10-21T21:47:03.451Z
Learning: In MostroP2P/mobile, for Action.canceled handling in abstract_mostro_notifier.dart (Riverpod StateNotifier), do not add mounted checks after async sessionNotifier.deleteSession(orderId) as they break order state synchronization during app restart. The Action.canceled flow contains critical business logic that must complete fully; Riverpod handles provider disposal automatically. Mounted checks should only protect UI operations, not business logic in StateNotifiers.

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/order_cards.dart
📚 Learning: 2025-08-15T01:37:12.243Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 270
File: lib/shared/widgets/order_filter.dart:133-135
Timestamp: 2025-08-15T01:37:12.243Z
Learning: The MostroP2P/mobile project requires Flutter >=3.27.0 as specified in pubspec.yaml, which supports the Color.withValues() method, so usage of withValues() throughout the codebase is valid and should not be flagged as a compatibility issue.

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/shared/widgets/order_cards.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Name Riverpod providers using the `<Feature>Provider` or `<Feature>Notifier` convention

Applied to files:

  • lib/shared/widgets/order_cards.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/l10n/**/*.arb : Add new localization keys to all three ARB files (en, es, it) - use `S.of(context)!.keyName` for all user-facing strings

Applied to files:

  • lib/l10n/intl_en.arb
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/generated/l10n*.dart : Never manually edit generated localization files - regenerate with `dart run build_runner build -d` after modifying ARB files

Applied to files:

  • lib/l10n/intl_en.arb
🔇 Additional comments (2)
lib/shared/widgets/order_cards.dart (1)

232-238: LGTM! Clean migration to top snackbar.

The switch from ScaffoldMessenger to showTopSnackBar correctly maintains the copy-to-clipboard functionality while improving UX by preventing the notification from blocking the bottom navigation bar. The synchronous callback safely uses context without requiring mounted checks, and the localization pattern is consistent with the codebase.

lib/l10n/intl_en.arb (1)

1231-1262: Ensure the new/updated keys are added to intl_es.arb and intl_it.arb too.

Repo guideline for lib/l10n/**/*.arb requires all three locales to stay in sync (including the {error} placeholder metadata).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @lib/features/chat/widgets/encrypted_file_message.dart:
- Around line 508-512: The closing parenthesis/brace for the showTopSnackBar
call has trailing whitespace; remove the extra spaces so the call is formatted
as a single properly indented expression (the call using showTopSnackBar with
arguments S.of(context)!.errorOpeningFile and backgroundColor: Colors.red), then
run "flutter format ." to enforce canonical Dart formatting before committing.
- Around line 498-503: The call to showTopSnackBar has spacing inconsistencies;
remove the extra space before the backgroundColor parameter and the excessive
whitespace before the closing parenthesis in the showTopSnackBar(...) invocation
(refer to the showTopSnackBar call where context and
S.of(context)!.couldNotOpenFile are passed), then run `flutter format .` to
apply canonical Dart formatting and commit the formatted changes.

In @lib/l10n/intl_en.arb:
- Around line 1231-1235: The Spanish and Italian localization files are missing
three new keys introduced in English: errorUploadingFile, failedToUpdateInvoice,
and failedToCancelOrder; add these keys to the Spanish and Italian ARB files
(intl_es.arb, intl_it.arb) with appropriate translations (Spanish for
errorUploadingFile, failedToUpdateInvoice, failedToCancelOrder; Italian for the
same three keys), matching the JSON/ARB format used in intl_en.arb and keeping
the same key names and punctuation.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 670510d and aac472a.

📒 Files selected for processing (4)
  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/chat/widgets/message_input.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
  • lib/l10n/intl_en.arb
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/chat/widgets/message_input.dart
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{dart,flutter}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{dart,flutter}: Run flutter analyze after any code change - Mandatory before commits to ensure zero linting issues
Run flutter test after any code change - Mandatory before commits to ensure all unit tests pass

Files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes
All code comments must be in English - use clear, concise English for variable names, function names, and comments
Always check mounted before using BuildContext after async operations to prevent errors on disposed widgets
Use const constructors where possible for better performance and immutability
Remove unused imports and dependencies to maintain code cleanliness and reduce build size

**/*.dart: Application code should be organized under lib/, grouped by domain with lib/features/<feature>/ structure, shared utilities in lib/shared/, dependency wiring in lib/core/, and services in lib/services/
Persistence, APIs, and background jobs should live in lib/data/ and lib/background/; generated localization output must be in lib/generated/ and must stay untouched
Apply flutter format . to enforce canonical Dart formatting (two-space indentation, trailing commas) before committing
Resolve every analyzer warning in Dart code
Name Riverpod providers using the <Feature>Provider or <Feature>Notifier convention
Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals

Files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
lib/l10n/**/*.arb

📄 CodeRabbit inference engine (CLAUDE.md)

Add new localization keys to all three ARB files (en, es, it) - use S.of(context)!.keyName for all user-facing strings

Files:

  • lib/l10n/intl_en.arb
lib/features/**/screens/**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

lib/features/**/screens/**/*.dart: Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs
Use S.of(context)!.yourKey for all user-facing strings instead of hardcoded text

Files:

  • lib/features/order/screens/add_lightning_invoice_screen.dart
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Use `S.of(context)!.yourKey` for all user-facing strings instead of hardcoded text

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Localize all user-facing strings via ARB files and access them with `S.of(context)` rather than hard-coded literals

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/l10n/**/*.arb : Add new localization keys to all three ARB files (en, es, it) - use `S.of(context)!.keyName` for all user-facing strings

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/l10n/intl_en.arb
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/generated/l10n*.dart : Never manually edit generated localization files - regenerate with `dart run build_runner build -d` after modifying ARB files

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-10-14T21:12:06.887Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:141-154
Timestamp: 2025-10-14T21:12:06.887Z
Learning: In the MostroP2P mobile codebase, the notification system uses a two-layer localization pattern: providers/notifiers (without BuildContext access) call `showCustomMessage()` with string keys (e.g., 'orderTimeoutMaker', 'orderCanceled'), and the UI layer's `NotificationListenerWidget` has a switch statement that maps these keys to localized strings using `S.of(context)`. This architectural pattern properly separates concerns while maintaining full localization support for all user-facing messages.

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : All code comments must be in English - use clear, concise English for variable names, function names, and comments

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/l10n/intl_en.arb
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Run `dart run build_runner build -d` to regenerate localization, mocks, and models when ARB or annotated files change

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
📚 Learning: 2025-07-08T05:40:47.527Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/chat/widgets/encrypted_file_message.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to **/*.dart : Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-08-15T01:37:12.243Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 270
File: lib/shared/widgets/order_filter.dart:133-135
Timestamp: 2025-08-15T01:37:12.243Z
Learning: The MostroP2P/mobile project requires Flutter >=3.27.0 as specified in pubspec.yaml, which supports the Color.withValues() method, so usage of withValues() throughout the codebase is valid and should not be flagged as a compatibility issue.

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/features/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*.dart : Name Riverpod providers using the `<Feature>Provider` or `<Feature>Notifier` convention

Applied to files:

  • lib/features/chat/widgets/encrypted_file_message.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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/chat/widgets/encrypted_file_message.dart
  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/shared/widgets/dynamic_countdown_widget.dart : Use exact `order_expires_at` timestamps from Mostro protocol for DynamicCountdownWidget precision and localize display with `S.of(context)!.timeLeftLabel()`

Applied to files:

  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-10-21T21:47:03.451Z
Learnt from: Catrya
Repo: MostroP2P/mobile PR: 327
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:157-182
Timestamp: 2025-10-21T21:47:03.451Z
Learning: In MostroP2P/mobile, for Action.canceled handling in abstract_mostro_notifier.dart (Riverpod StateNotifier), do not add mounted checks after async sessionNotifier.deleteSession(orderId) as they break order state synchronization during app restart. The Action.canceled flow contains critical business logic that must complete fully; Riverpod handles provider disposal automatically. Mounted checks should only protect UI operations, not business logic in StateNotifiers.

Applied to files:

  • lib/features/order/screens/add_lightning_invoice_screen.dart
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/core/app_routes.dart : Use GoRouter for all navigation configuration instead of Navigator API - maintain all routes in app_routes.dart

Applied to files:

  • lib/features/order/screens/add_lightning_invoice_screen.dart
🔇 Additional comments (5)
lib/features/order/screens/add_lightning_invoice_screen.dart (3)

2-2: LGTM: Import addition is correct.

The new import for top_snackbar.dart is properly added to support the standardized top-positioned notification system.


67-70: LGTM: Proper error handling with mounted check.

The showTopSnackBar usage correctly guards against use_build_context_synchronously warnings with the context.mounted check on line 66, and uses properly localized error messaging.


83-86: LGTM: Consistent error handling pattern.

The second showTopSnackBar usage mirrors the first with proper context.mounted check on line 82 and localized error messaging, maintaining consistency across error handlers.

lib/features/chat/widgets/encrypted_file_message.dart (2)

4-4: LGTM!

The import addition for the top snackbar utility is necessary and aligns with the PR's objective to move SnackBar notifications to the top of the screen.


118-118: LGTM!

The localized string usage is correct and follows the coding guidelines requiring all user-facing strings to use S.of(context) rather than hard-coded literals.

Also applies to: 370-370

Comment on lines +1231 to +1235
"couldNotOpenFile": "Could not open file.",
"errorOpeningFile": "Error opening file.",
"errorUploadingFile": "Error uploading file.",
"failedToUpdateInvoice": "Failed to update invoice.",
"failedToCancelOrder": "Failed to cancel order.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify that the new and updated localization keys exist in Spanish and Italian ARB files

echo "=== Checking Spanish ARB file (intl_es.arb) ==="
for key in "couldNotOpenFile" "errorOpeningFile" "errorUploadingFile" "failedToUpdateInvoice" "failedToCancelOrder"; do
  echo -n "Checking key '$key': "
  if grep -q "\"$key\":" lib/l10n/intl_es.arb; then
    echo "✓ Found"
  else
    echo "✗ MISSING"
  fi
done

echo ""
echo "=== Checking Italian ARB file (intl_it.arb) ==="
for key in "couldNotOpenFile" "errorOpeningFile" "errorUploadingFile" "failedToUpdateInvoice" "failedToCancelOrder"; do
  echo -n "Checking key '$key': "
  if grep -q "\"$key\":" lib/l10n/intl_it.arb; then
    echo "✓ Found"
  else
    echo "✗ MISSING"
  fi
done

Repository: MostroP2P/mobile

Length of output: 598


Add missing localization keys to Spanish and Italian ARB files.

The English localization updates are correct, but three new keys are missing from the Spanish and Italian files:

  • errorUploadingFile (new)
  • failedToUpdateInvoice (new)
  • failedToCancelOrder (new)

Per coding guidelines, all new localization keys must be added to all three ARB files (en, es, it). Add these keys to lib/l10n/intl_es.arb and lib/l10n/intl_it.arb with appropriate Spanish and Italian translations.

🤖 Prompt for AI Agents
In @lib/l10n/intl_en.arb around lines 1231 - 1235, The Spanish and Italian
localization files are missing three new keys introduced in English:
errorUploadingFile, failedToUpdateInvoice, and failedToCancelOrder; add these
keys to the Spanish and Italian ARB files (intl_es.arb, intl_it.arb) with
appropriate translations (Spanish for errorUploadingFile, failedToUpdateInvoice,
failedToCancelOrder; Italian for the same three keys), matching the JSON/ARB
format used in intl_en.arb and keeping the same key names and punctuation.

Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of changing the snackbar position, but it’s necessary that the PR be only for that implementation so it can be tested. The dependency updates due to vulnerabilities should be a separate additional PR. Can you split them?

Copilot AI review requested due to automatic review settings January 12, 2026 21:09
@mohit7705
Copy link
Author

hi @AndreaDiazCorreia
Thanks for the feedback!
I’ve removed the dependency updates from this PR and kept it focused only on the snackbar position change so it can be tested in isolation.
I’ll submit the dependency updates as a separate PR.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@grunch
Copy link
Member

grunch commented Jan 12, 2026

Hi @mohit7705 please fix the checks that failed

@mohit7705
Copy link
Author

hi @grunch
can you verify this ?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
integration_test/test_helpers.dart (1)

191-194: Consider wiring registerListener to populate _listeners.

The getListeners getter exposes the _listeners map, but the registerListener method (lines 220-223) doesn't add listeners to it. This means getListeners will always return an empty map unless tests manually populate _listeners.

If you intend for tests to verify listener registration behavior, consider implementing the stub:

♻️ Optional enhancement
 @override
 void registerListener(
     {required String key, required ValueChanged<String?> listener}) {
-  // TODO: implement registerListener
+  _listeners.putIfAbsent(key, () => []).add(listener);
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aac472a and 50f4727.

📒 Files selected for processing (1)
  • integration_test/test_helpers.dart
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{dart,flutter}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{dart,flutter}: Run flutter analyze after any code change - Mandatory before commits to ensure zero linting issues
Run flutter test after any code change - Mandatory before commits to ensure all unit tests pass

Files:

  • integration_test/test_helpers.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.dart: Use Riverpod for all state management - encapsulate business logic in Notifiers and access data only through repository classes
All code comments must be in English - use clear, concise English for variable names, function names, and comments
Always check mounted before using BuildContext after async operations to prevent errors on disposed widgets
Use const constructors where possible for better performance and immutability
Remove unused imports and dependencies to maintain code cleanliness and reduce build size

**/*.dart: Application code should be organized under lib/, grouped by domain with lib/features/<feature>/ structure, shared utilities in lib/shared/, dependency wiring in lib/core/, and services in lib/services/
Persistence, APIs, and background jobs should live in lib/data/ and lib/background/; generated localization output must be in lib/generated/ and must stay untouched
Apply flutter format . to enforce canonical Dart formatting (two-space indentation, trailing commas) before committing
Resolve every analyzer warning in Dart code
Name Riverpod providers using the <Feature>Provider or <Feature>Notifier convention
Localize all user-facing strings via ARB files and access them with S.of(context) rather than hard-coded literals

Files:

  • integration_test/test_helpers.dart
integration_test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Ensure integration test coverage for flows touching networking, background work, or session recovery in integration_test/

Files:

  • integration_test/test_helpers.dart
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: All changes must pass `flutter analyze` with zero issues before committing to ensure code quality standards are maintained
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to lib/features/**/screens/**/*.dart : Keep UI code declarative and side-effect free - use post-frame callbacks for side effects like SnackBars/dialogs
📚 Learning: 2025-11-27T12:10:12.082Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-27T12:10:12.082Z
Learning: Applies to test/mocks.mocks.dart : Never manually modify `test/mocks.mocks.dart` - it already has file-level `// ignore_for_file: must_be_immutable` ignore directives

Applied to files:

  • integration_test/test_helpers.dart
📚 Learning: 2025-11-27T12:10:26.407Z
Learnt from: CR
Repo: MostroP2P/mobile PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-27T12:10:26.407Z
Learning: Applies to **/*_test.dart : Place unit tests beside their feature counterparts using the `*_test.dart` suffix and prefer Mockito fakes generated via `build_runner`

Applied to files:

  • integration_test/test_helpers.dart
📚 Learning: 2025-06-04T19:35:20.209Z
Learnt from: chebizarro
Repo: MostroP2P/mobile PR: 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:

  • integration_test/test_helpers.dart
🔇 Additional comments (1)
integration_test/test_helpers.dart (1)

270-275: Good encapsulation refactor.

The change from a public field to a private field with a getter follows best practices and maintains backward compatibility.

Minor nit: Line 274 appears to have inconsistent indentation (one space before @override instead of two). Consider running flutter format . to normalize.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mohit7705 please check CodeRabbit's comments and do what they asks, such as Add missing localization keys to Spanish and Italian ARB files, regenerate the localization files etc
I marked as unresolved the comments that are not yet resolved.

Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that some localization keys are still missing in the other languages, as indicated by CodeRabbit, along with a few suggestions. Could you review it so I can start testing?

@Catrya
Copy link
Member

Catrya commented Jan 19, 2026

Hi @mohit7705 , how's this PR going? Do you think you can complete it?

@mohit7705
Copy link
Author

hi @Catrya ,
I'm currently in the middle of my exam, so replies might be a bit slow. I’ll get back to you as soon as I can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants