-
Notifications
You must be signed in to change notification settings - Fork 16
Disputes UI only #285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disputes UI only #285
Conversation
…improve state handling
WalkthroughAdds a disputes feature: new dispute domain and UI models, mock repository/service, Riverpod providers/notifier, many dispute UI widgets and screen, chat tab provider integration, router entry Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Chat as ChatRoomsScreen
participant Tabs as ChatTabs
participant Disputes as DisputesList
participant Router as GoRouter
participant Screen as DisputeChatScreen
participant Mock as DisputeMockData
User->>Chat: open Chats screen
Chat->>Tabs: render tabs (provider-driven)
Tabs->>Disputes: render disputes tab when active
User->>Disputes: tap dispute item
Disputes->>Router: context.push("/dispute_details/{id}")
Router->>Screen: instantiate DisputeChatScreen(disputeId)
Screen->>Mock: DisputeMockData.getDisputeById(disputeId)
Mock-->>Screen: DisputeData or null
alt dispute found
Screen->>Screen: render messages + conditional input
else not found
Screen->>User: show "Dispute not found"
end
sequenceDiagram
autonumber
actor User
participant Screen as DisputeChatScreen
participant Messages as DisputeMessagesList
participant Notifier as DisputeChatNotifier
participant Mock as DisputeMockData
Screen->>Messages: build with disputeId/status/disputeData
Messages->>Mock: getMockMessages(disputeId, status)
Mock-->>Messages: List<DisputeChat>
User->>Messages: long-press or view message
User->>Screen: send message
Screen->>Notifier: sendMessage(text)
Notifier-->>Messages: state updated -> UI rebuilds with new bubble
Note right of Mock: mock-only data/service behavior (debug)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 26
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
lib/features/order/screens/take_order_screen.dart (2)
379-383: Guard setState after async gapsetState is called after awaiting showDialog; if the widget was disposed, this will throw.
- // Dialog was dismissed without entering amount, reset loading state - setState(() { - _isSubmitting = false; - }); + // Dialog was dismissed without entering amount, reset loading state + if (!mounted) return; + setState(() { + _isSubmitting = false; + });
108-110: Avoid duplicated currency inforAmountWithCurrency
Remove the currency code fromamountStringso the ARB templates (for {amount} {currency},por {amount} {currency},per {amount} {currency}) append it exactly once. For example in lib/features/order/screens/take_order_screen.dart:- final amountString = '${order.fiatAmount} ${order.currency} $currencyFlag'; + final amountString = '${order.fiatAmount} $currencyFlag';lib/features/chat/widgets/trade_information_tab.dart (1)
26-37: Don’t fabricate dates; show “Unknown date” when missing.Current fallback subtracts one hour from now, which misleads users. Return null and let the formatter show the localized “Unknown date”.
Apply this diff:
- /// Get a valid creation date for the order - /// Uses order.createdAt if valid, otherwise falls back to current time - DateTime _getOrderCreationDate() { + /// Get a valid creation date for the order + /// Uses order.createdAt if valid, otherwise returns null + DateTime? _getOrderCreationDate() { if (order?.createdAt != null && order!.createdAt! > 0) { // Convert Unix timestamp to DateTime return DateTime.fromMillisecondsSinceEpoch(order!.createdAt! * 1000); } - - // Fallback: use current time minus a reasonable amount - // This is better than showing "Unknown date" - return DateTime.now().subtract(const Duration(hours: 1)); + return null; }And adjust formatter signature:
- String _formatOrderDate(DateTime? date, BuildContext context) { + String _formatOrderDate(DateTime? date, BuildContext context) { if (date == null) { return S.of(context)!.unknownDate; } - return DateFormat('MMMM d, yyyy').format(date); + // Locale-aware format + final locale = Localizations.localeOf(context).toString(); + return DateFormat.yMMMd(locale).format(date); }lib/features/chat/screens/chat_rooms_list.dart (2)
66-66: Localize without hardcoded fallbacks; avoid nullable access on S.of(context)Per guidelines, prefer fully localized strings. The generated S.of(context) is non-null; drop the fallback and the optional chaining.
- S.of(context)?.chat ?? 'Chat', + S.of(context).chat,
137-138: Localize empty state message (no hardcoded fallback)Keep UX consistent with i18n.
- return EmptyStateView( - message: S.of(context)?.noMessagesAvailable ?? 'No messages available', - ); + return EmptyStateView( + message: S.of(context).noMessagesAvailable, + );lib/l10n/intl_it.arb (1)
760-771: Duplicate ARB keys will break i18n generation or shadow values. Remove duplicates.
- Key duplicated: forAmount (also defined at Line 619).
- Key duplicated: retry (already at Line 215).
- Key duplicated: orderIdLabel (already at Line 641).
Apply this minimal cleanup:
- "forAmount": "per {amount}", - "forAmountWithCurrency": "per {amount} {currency}", + "forAmountWithCurrency": "per {amount} {currency}", @@ - "retry": "Riprova", @@ - "orderIdLabel": "ID Ordine",Then ensure call sites reuse the existing
retryandorderIdLabel, andforAmount(Line 619) or the newforAmountWithCurrencywhere needed.Also applies to: 965-966, 976-976
🧹 Nitpick comments (45)
lib/data/models/dispute_event.dart (1)
6-7: Prefer a typed status over raw StringAn enum (e.g., DisputeStatus) avoids typos and enables exhaustiveness in UI.
Example:
enum DisputeStatus { initiated, inProgress, resolved, unknown }lib/l10n/intl_es.arb (2)
903-917: Minor wording nit: prefer “Clave pública del administrador”."adminPubkey" value is "Pubkey del administrador". For consistency with other strings (e.g., “Clave Pública”), consider:
- adminPubkey: "Clave pública del administrador"
731-741: Remove deprecated “forAmount” keys and metadata from all ARB locales
No Dart references remain; legacy entries still exist in:
- lib/l10n/intl_en.arb (line 243)
- lib/l10n/intl_es.arb (line 586)
- lib/l10n/intl_it.arb (lines 619, 760)
Remove each"forAmount"translation and its corresponding@forAmountmetadata to prevent accidental use.lib/l10n/intl_en.arb (1)
703-713: Remove deprecated “forAmount” entries from all locales
• lib/l10n/intl_en.arb:243
• lib/l10n/intl_es.arb:586
• lib/l10n/intl_it.arb:619, 760lib/features/chat/widgets/trade_information_tab.dart (1)
19-24: Use locale-aware date format.Hardcoded
'MMMM d, yyyy'won’t match non-English locales. Switch toDateFormat.yMMMd(locale).lib/features/disputes/widgets/dispute_icon.dart (1)
9-16: Make these widgets const; consider semantics for accessibility
- Minor perf/readability win: the Padding/Icon subtree can be const.
- If the icon is decorative, exclude it from semantics; if meaningful, add a localized semanticLabel.
- return Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Icon( - Icons.warning_amber, - color: Colors.amber, - size: 32, - ), - ); + return const Padding( + padding: EdgeInsets.only(top: 8.0), + child: Icon( + Icons.warning_amber, + color: Colors.amber, + size: 32, + ), + );Optionally, one of:
- child: Icon( + child: ExcludeSemantics( + child: Icon( Icons.warning_amber, color: Colors.amber, size: 32, - ), + ), + ),or (if meaningful and localized):
- child: Icon( + child: Icon( Icons.warning_amber, - color: Colors.amber, + semanticLabel: S.of(context).disputeWarningIconLabel, + color: Colors.amber, size: 32, ),lib/features/disputes/widgets/dispute_order_id.dart (1)
11-16: Avoid overflow for long IDsAdd single-line ellipsis to keep list rows tidy with long order IDs.
- return Text( - orderId, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - fontWeight: FontWeight.w500, - ), - ); + return Text( + orderId, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + fontWeight: FontWeight.w500, + ), + );lib/features/disputes/widgets/dispute_description.dart (1)
12-20: LGTM: concise, single-line descriptionEllipsis and size fit list density. Consider using textTheme.bodySmall?.copyWith(color: AppTheme.textSecondary) if you want to inherit dynamic typography; optional.
lib/features/disputes/widgets/disputes_list.dart (2)
25-28: Normalize status values.This file uses 'in-progress' while other widgets switch on description/status enums/keys. Prefer a typed DisputeStatus enum or a single canonical string set to avoid mismatches.
87-88: Avoid hardcoded route strings.Use a shared route builder/constant (e.g., AppRoutes.disputeDetails(disputeId)) to prevent drift with router definitions.
lib/features/disputes/widgets/dispute_header.dart (1)
14-27: Prevent overflow in narrow layouts.Wrap the title in Expanded and ellipsize to avoid layout overflow beside the badge.
- return Row( + return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( + Expanded( + child: Text( S.of(context)!.disputeForOrder, - style: const TextStyle( + overflow: TextOverflow.ellipsis, + style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16, - ), - ), + ), + ), + ), DisputeStatusBadge(status: dispute.status), ], );lib/features/disputes/widgets/dispute_info_card.dart (1)
70-97: Fixed-width label can truncate in longer locales.Consider making label width responsive (e.g., using IntrinsicWidth or flex) to accommodate translations.
lib/features/disputes/widgets/dispute_status_content.dart (1)
16-17: Prefer a typed status over free-form strings.String compares for 'resolved'/'closed' are brittle. Use a DisputeStatus enum or normalized status mapping.
lib/data/repositories/dispute_repository.dart (1)
3-8: Keep UI-only repo behind a feature flag and inject a clock.
- Gate this mock via a feature flag/env to avoid shipping in production.
- Inject a clock (e.g., via constructor) for test determinism instead of
DateTime.now().Also applies to: 9-30, 45-48
lib/features/disputes/widgets/dispute_list_item.dart (1)
18-21: Prefer InkWell (with Material) over GestureDetector for tap semantics and rippleImproves accessibility (focus/semantics), hover/click feedback, and consistency with app patterns.
- return GestureDetector( - onTap: onTap, - child: Container( + return Material( + color: Colors.transparent, + child: InkWell( + onTap: onTap, + child: Container( decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.white.withValues(alpha: 0.05), width: 1.0, ), ), ), child: Padding( padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - DisputeIcon(), + const DisputeIcon(), const SizedBox(width: 16), Expanded( child: DisputeContent(dispute: dispute), ), ], ), ), - ), - ), - ); + ), + ), + );Also applies to: 29-43
lib/features/disputes/widgets/dispute_communication_section.dart (1)
7-15: Avoid stringly-typed status; use an enumPrevents typos (“in-progress” vs “in_progress”) and eases refactors.
Example:
enum DisputeStatus { initiated, inProgress, resolved } final DisputeStatus status; const DisputeCommunicationSection({ required this.status, ... });lib/services/dispute_service.dart (2)
12-22: Drop redundant awaits to reduce stack depthMethods simply forward repository futures; return them directly.
- Future<List<Dispute>> getUserDisputes() async { - return await _disputeRepository.getUserDisputes(); - } + Future<List<Dispute>> getUserDisputes() { + return _disputeRepository.getUserDisputes(); + } - Future<Dispute?> getDispute(String disputeId) async { - return await _disputeRepository.getDispute(disputeId); - } + Future<Dispute?> getDispute(String disputeId) { + return _disputeRepository.getDispute(disputeId); + } - Future<void> sendDisputeMessage(String disputeId, String message) async { - await _disputeRepository.sendDisputeMessage(disputeId, message); - } + Future<void> sendDisputeMessage(String disputeId, String message) { + return _disputeRepository.sendDisputeMessage(disputeId, message); + }
24-27: Consider injection for testabilityAllow passing a repository in ctor to mock/stub in tests.
-class DisputeService { - static final DisputeService _instance = DisputeService._internal(); - factory DisputeService() => _instance; - DisputeService._internal(); - - final DisputeRepository _disputeRepository = DisputeRepository(); +class DisputeService { + static final DisputeService _instance = DisputeService._internal(); + factory DisputeService({DisputeRepository? repository}) => + (_instance.._instance._disputeRepository = repository ?? _instance._disputeRepository); + DisputeService._internal(); + + DisputeRepository _disputeRepository = DisputeRepository();lib/features/disputes/screens/dispute_chat_screen.dart (3)
41-51: Localize the app bar title and prefer theme text stylesFollow l10n and app typography instead of hardcoded TextStyle.
- title: Text( - 'Dispute Chat', - style: const TextStyle( - color: Colors.white, - fontSize: 18, - fontWeight: FontWeight.w600, - ), - ), + title: Text( + S.of(context).disputeChatTitle, + style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Colors.white), + ),Also applies to: 45-51
60-65: Wrap the communication section with Expanded (after removing it from the widget itself)Ensures proper flex layout ownership at the parent.
- DisputeCommunicationSection( - disputeId: disputeId, - disputeData: mockDispute, - status: mockDispute.status, - ), + Expanded( + child: DisputeCommunicationSection( + disputeId: disputeId, + disputeData: mockDispute, + status: mockDispute.status, + ), + ),
66-69: Stringly-typed status checks are brittlePrefer an enum (e.g., DisputeStatus.resolved) to avoid typos and enable exhaustive switches.
lib/features/disputes/widgets/dispute_input_section.dart (2)
83-90: Prefer IconButton/ElevatedButton and theme colorsImproves accessibility (semantics/disabled state/focus), and uses app color scheme.
- GestureDetector( - onTap: _isLoading ? null : _sendMessage, - child: Container( - width: 40, - height: 40, - decoration: BoxDecoration( - color: _canSend() ? Colors.blue : Colors.grey[600], - shape: BoxShape.circle, - ), - child: _isLoading + IconButton.filled( + onPressed: _canSend() ? _sendMessage : null, + style: ButtonStyle( + backgroundColor: WidgetStateProperty.resolveWith((states) { + final scheme = Theme.of(context).colorScheme; + return states.contains(WidgetState.disabled) + ? scheme.surfaceVariant + : scheme.primary; + }), + fixedSize: const WidgetStatePropertyAll(Size(40, 40)), + shape: const WidgetStatePropertyAll(CircleBorder()), + ), + icon: _isLoading ? Padding( padding: const EdgeInsets.all(8.0), child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2, ), ) - : const Icon( - Icons.send, - color: Colors.white, - size: 20, - ), - ), - ), + : const Icon(Icons.send, color: Colors.white, size: 20), + ),Also applies to: 98-103
115-123: Minor UX: dismiss keyboard after sending; keep mounted checksOptional polish.
final message = _messageController.text.trim(); _messageController.clear(); + FocusScope.of(context).unfocus();Also applies to: 146-152
lib/features/disputes/widgets/dispute_status_badge.dart (3)
74-88: Standardize localization access (avoid null/force unwrap).Use
S.of(context).keyconsistently; remove!. This aligns with our localization guideline and avoids unnecessary null assertions.- return S.of(context)!.disputeStatusInitiated; + return S.of(context).disputeStatusInitiated; ... - return S.of(context)!.disputeStatusInProgress; + return S.of(context).disputeStatusInProgress; ... - return S.of(context)!.disputeStatusResolved; + return S.of(context).disputeStatusResolved; ... - return S.of(context)!.disputeStatusClosed; + return S.of(context).disputeStatusClosed; ... - return S.of(context)!.disputeStatusInitiated; + return S.of(context).disputeStatusInitiated;
40-55: Avoid hardcoded Colors; route through AppTheme.Replace
Colors.bluewith theme tokens (e.g., addstatusInfoBackground/statusInfoTextinAppThemeand use them here) to keep visual consistency and enable theming.Also applies to: 57-72
7-10: Strongly type status (enum/sealed) instead of String.Using a
DisputeStatusenum or sealed class will remove normalization needs and prevent invalid states at compile time.Also applies to: 33-38, 40-55, 57-72
lib/features/disputes/notifiers/dispute_chat_notifier.dart (2)
19-36: Expose immutable state to consumers.Wrap assigned lists with
List.unmodifiable(...)to prevent accidental mutation by downstream code reading provider state.- void loadMessages(String disputeId) { + void loadMessages(String disputeId) { // Stub implementation - load mock messages - state = [ + state = List.unmodifiable([ DisputeChat( id: '1', message: 'Hello, I have an issue with this order', timestamp: DateTime.now().subtract(const Duration(minutes: 5)), isFromUser: true, ), DisputeChat( id: '2', message: 'I understand. Let me review the details.', timestamp: DateTime.now().subtract(const Duration(minutes: 3)), isFromUser: false, adminPubkey: 'admin_pubkey_123', ), - ]; + ]); }
39-46: Avoid duplicating providers; re-export the existing family.
disputeChatProviderduplicatesdisputeChatNotifierProvider. Prefer a direct alias to prevent confusion and rebuild indirection.-final disputeChatNotifierProvider = +final disputeChatNotifierProvider = StateNotifierProvider.family<DisputeChatNotifier, List<DisputeChat>, String>( (ref, disputeId) { final notifier = DisputeChatNotifier(); notifier.loadMessages(disputeId); return notifier; }, );Then in
providers/dispute_providers.dart, alias it:-final disputeChatProvider = StateNotifierProvider.family<DisputeChatNotifier, List<DisputeChat>, String>( - (ref, disputeId) { - return ref.watch(disputeChatNotifierProvider(disputeId).notifier); - }, -); +final disputeChatProvider = disputeChatNotifierProvider;lib/features/disputes/widgets/dispute_messages_list.dart (7)
37-39: Checkmountedbefore scheduling scroll.Prevents acting on a disposed State during rapid navigations.
- WidgetsBinding.instance.addPostFrameCallback((_) { - _scrollToBottom(animate: false); - }); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + _scrollToBottom(animate: false); + });
108-110: Normalize status comparisons (trim/lowercase).Avoids subtle mismatches from casing/whitespace.
- if (widget.status == 'resolved') + if (widget.status.trim().toLowerCase() == 'resolved') _buildResolutionNotification(context),- if (widget.status == 'initiated') { + if (widget.status.trim().toLowerCase() == 'initiated') { return const SizedBox.shrink(); }Also applies to: 148-150
122-140: Remove hardcoded fallbacks; require localized strings.Per guidelines, avoid English literals in UI. Use
S.of(context).keydirectly (ensure ARB keys exist).- S.of(context)?.waitingAdminAssignment ?? 'Waiting for admin assignment', + S.of(context).waitingAdminAssignment,- S.of(context)?.waitingAdminDescription ?? 'Your dispute has been submitted. An admin will be assigned to help resolve this issue.', + S.of(context).waitingAdminDescription,- S.of(context)?.adminAssigned ?? 'Admin has been assigned to this dispute', + S.of(context).adminAssigned,- S.of(context)?.disputeResolvedMessage ?? 'This dispute has been resolved. Check your wallet for any refunds or payments.', + S.of(context).disputeResolvedMessage,Also applies to: 168-176, 199-206
153-176: Avoid hardcoded Colors; move banner palette to AppTheme.Replace
Colors.blue[...]/Colors.green[...]with theme tokens (e.g.,AppTheme.infoBackground/Text,AppTheme.successBackground/Text) for consistency and dark-mode flexibility.Also applies to: 183-205
76-76: Fix typo in comment (“scrollable”).- // Messages list with info card at top (scrolleable) + // Messages list with info card at top (scrollable)
95-103: Consider adding stable keys to message items.If
DisputeMessageBubblesupportskey, passValueKey(message.id)to improve list diffing and avoid rebuild artifacts.
213-221: Prefer sourcing messages via providers, not mock directly.To align with our architecture (Riverpod Notifiers + repositories), consume
disputeChatProvider(disputeId)instead of callingDisputeMockData.getMockMessages(...)from the widget.lib/features/disputes/providers/dispute_providers.dart (2)
17-20: Dead code:getDisputeByIdnever returns null.
DisputeMockData.getDisputeByIdfalls back to a default dispute; this null check is unreachable. Either makegetDisputeByIdnon-nullable and remove this check, or allow nulls consistently.- final disputeData = DisputeMockData.getDisputeById(disputeId); - if (disputeData == null) return null; + final disputeData = DisputeMockData.getDisputeById(disputeId);
45-50: Alias the existing notifier provider instead of wrapping it.Reduces indirection and unnecessary rebuild coupling.
-final disputeChatProvider = StateNotifierProvider.family<DisputeChatNotifier, List<DisputeChat>, String>( - (ref, disputeId) { - return ref.watch(disputeChatNotifierProvider(disputeId).notifier); - }, -); +final disputeChatProvider = disputeChatNotifierProvider;lib/features/disputes/data/dispute_mock_data.dart (3)
42-51: MakegetDisputeByIdnon-nullable to reflect actual behavior.It always returns a dispute (default fallback). Update signature and call sites to simplify logic.
- static DisputeData? getDisputeById(String disputeId) { + static DisputeData getDisputeById(String disputeId) { try { return mockDisputes.firstWhere( (dispute) => dispute.disputeId == disputeId, ); } catch (e) { return _getDefaultMockDispute(disputeId); } }
130-142: Type safety forinitiatorRole.Use
UserRoleinstead ofStringto avoid invalid inputs.- static String createMockDispute({ + static String createMockDispute({ required String orderId, - required String reason, - required String initiatorRole, + required String reason, + required UserRole initiatorRole, required Map<String, dynamic> orderDetails, }) {
53-114: Normalize status input once.Consider normalizing
status(trim().toLowerCase()) before comparisons to accept flexible inputs.lib/data/models/dispute.dart (3)
449-465: Avoid hardcoded UI strings in model; deprecatedescriptionand localize in UI viadescriptionKey.Models should not emit user-facing text. Use
descriptionKeyin widgets withS.of(context)and deprecate this getter.- /// Backward compatibility getter for description - String get description { + /// Backward compatibility getter for description + @Deprecated('Use descriptionKey + UI localization (S.of(context)) instead. ' + 'This getter will be removed.') + String get description {
409-413: Also normalize legacy event timestamps.
createdAtunconditionally multiplies by 1000 if int; handle ms vs s like above.- createdAt: DateTime.fromMillisecondsSinceEpoch( - disputeEvent.createdAt is int - ? disputeEvent.createdAt * 1000 - : DateTime.now().millisecondsSinceEpoch - ), + createdAt: DateTime.fromMillisecondsSinceEpoch( + disputeEvent.createdAt is int + ? ((disputeEvent.createdAt as int) < 10000000000 + ? (disputeEvent.createdAt as int) * 1000 + : (disputeEvent.createdAt as int)) + : DateTime.now().millisecondsSinceEpoch + ),
471-475: Prefer semantic nulls over sentinel strings for fallbacks.Returning
'unknownOrderId'/'unknownCounterparty'pushes string handling into model. Consider returning null and letting UI localize withS.of(context).unknown.lib/l10n/intl_it.arb (2)
936-951: Minor Italian polish.“Citare” suona innaturale qui; “riportare” o “ripetere” il token è più idiomatico.
- "askAdminQuoteToken": "Chiedi all'amministratore di citare questo token:", + "askAdminQuoteToken": "Chiedi all'amministratore di riportare questo token:",
111-116: One typo: double period.
...il token per la tua disputa..→ single period.- "adminTookDisputeUsers": "L'amministratore {admin_npub} gestirà la tua disputa. Devi contattare l'amministratore direttamente, ma se qualcuno ti contatta prima, assicurati di chiedergli di fornirti il token per la tua disputa..", + "adminTookDisputeUsers": "L'amministratore {admin_npub} gestirà la tua disputa. Devi contattare l'amministratore direttamente, ma se qualcuno ti contatta prima, assicurati di chiedergli di fornirti il token per la tua disputa.",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (32)
lib/core/app_routes.dart(2 hunks)lib/data/models/dispute.dart(2 hunks)lib/data/models/dispute_chat.dart(1 hunks)lib/data/models/dispute_event.dart(1 hunks)lib/data/repositories/dispute_repository.dart(1 hunks)lib/features/chat/screens/chat_rooms_list.dart(5 hunks)lib/features/chat/widgets/trade_information_tab.dart(1 hunks)lib/features/disputes/data/dispute_mock_data.dart(1 hunks)lib/features/disputes/notifiers/dispute_chat_notifier.dart(1 hunks)lib/features/disputes/providers/dispute_providers.dart(1 hunks)lib/features/disputes/screens/dispute_chat_screen.dart(1 hunks)lib/features/disputes/widgets/dispute_communication_section.dart(1 hunks)lib/features/disputes/widgets/dispute_content.dart(1 hunks)lib/features/disputes/widgets/dispute_description.dart(1 hunks)lib/features/disputes/widgets/dispute_header.dart(1 hunks)lib/features/disputes/widgets/dispute_icon.dart(1 hunks)lib/features/disputes/widgets/dispute_info_card.dart(1 hunks)lib/features/disputes/widgets/dispute_input_section.dart(1 hunks)lib/features/disputes/widgets/dispute_list_item.dart(1 hunks)lib/features/disputes/widgets/dispute_message_bubble.dart(1 hunks)lib/features/disputes/widgets/dispute_message_input.dart(1 hunks)lib/features/disputes/widgets/dispute_messages_list.dart(1 hunks)lib/features/disputes/widgets/dispute_order_id.dart(1 hunks)lib/features/disputes/widgets/dispute_status_badge.dart(1 hunks)lib/features/disputes/widgets/dispute_status_content.dart(1 hunks)lib/features/disputes/widgets/disputes_list.dart(1 hunks)lib/features/order/screens/take_order_screen.dart(1 hunks)lib/l10n/intl_en.arb(3 hunks)lib/l10n/intl_es.arb(4 hunks)lib/l10n/intl_it.arb(4 hunks)lib/services/dispute_service.dart(1 hunks)lib/shared/widgets/order_cards.dart(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/shared/widgets/order_cards.dartlib/features/order/screens/take_order_screen.dartlib/data/repositories/dispute_repository.dartlib/features/chat/widgets/trade_information_tab.dartlib/features/disputes/screens/dispute_chat_screen.dartlib/features/disputes/widgets/dispute_order_id.dartlib/data/models/dispute_event.dartlib/features/disputes/widgets/dispute_description.dartlib/features/disputes/widgets/dispute_status_badge.dartlib/services/dispute_service.dartlib/features/disputes/widgets/dispute_message_bubble.dartlib/features/disputes/widgets/dispute_header.dartlib/features/disputes/widgets/dispute_list_item.dartlib/features/disputes/widgets/dispute_status_content.dartlib/features/disputes/notifiers/dispute_chat_notifier.dartlib/core/app_routes.dartlib/features/disputes/widgets/dispute_info_card.dartlib/features/disputes/widgets/dispute_message_input.dartlib/features/disputes/widgets/dispute_icon.dartlib/data/models/dispute_chat.dartlib/features/disputes/widgets/disputes_list.dartlib/features/disputes/widgets/dispute_messages_list.dartlib/features/disputes/widgets/dispute_input_section.dartlib/features/disputes/widgets/dispute_content.dartlib/features/disputes/providers/dispute_providers.dartlib/features/disputes/widgets/dispute_communication_section.dartlib/features/disputes/data/dispute_mock_data.dartlib/features/chat/screens/chat_rooms_list.dartlib/data/models/dispute.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/shared/widgets/order_cards.dartlib/features/order/screens/take_order_screen.dartlib/data/repositories/dispute_repository.dartlib/features/chat/widgets/trade_information_tab.dartlib/features/disputes/screens/dispute_chat_screen.dartlib/features/disputes/widgets/dispute_order_id.dartlib/data/models/dispute_event.dartlib/features/disputes/widgets/dispute_description.dartlib/features/disputes/widgets/dispute_status_badge.dartlib/services/dispute_service.dartlib/features/disputes/widgets/dispute_message_bubble.dartlib/features/disputes/widgets/dispute_header.dartlib/features/disputes/widgets/dispute_list_item.dartlib/features/disputes/widgets/dispute_status_content.dartlib/features/disputes/notifiers/dispute_chat_notifier.dartlib/core/app_routes.dartlib/features/disputes/widgets/dispute_info_card.dartlib/features/disputes/widgets/dispute_message_input.dartlib/features/disputes/widgets/dispute_icon.dartlib/data/models/dispute_chat.dartlib/features/disputes/widgets/disputes_list.dartlib/features/disputes/widgets/dispute_messages_list.dartlib/features/disputes/widgets/dispute_input_section.dartlib/features/disputes/widgets/dispute_content.dartlib/features/disputes/providers/dispute_providers.dartlib/features/disputes/widgets/dispute_communication_section.dartlib/features/disputes/data/dispute_mock_data.dartlib/features/chat/screens/chat_rooms_list.dartlib/data/models/dispute.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/shared/widgets/order_cards.dartlib/features/order/screens/take_order_screen.dartlib/data/repositories/dispute_repository.dartlib/features/chat/widgets/trade_information_tab.dartlib/features/disputes/screens/dispute_chat_screen.dartlib/features/disputes/widgets/dispute_order_id.dartlib/data/models/dispute_event.dartlib/features/disputes/widgets/dispute_description.dartlib/features/disputes/widgets/dispute_status_badge.dartlib/services/dispute_service.dartlib/features/disputes/widgets/dispute_message_bubble.dartlib/features/disputes/widgets/dispute_header.dartlib/features/disputes/widgets/dispute_list_item.dartlib/features/disputes/widgets/dispute_status_content.dartlib/features/disputes/notifiers/dispute_chat_notifier.dartlib/core/app_routes.dartlib/features/disputes/widgets/dispute_info_card.dartlib/features/disputes/widgets/dispute_message_input.dartlib/features/disputes/widgets/dispute_icon.dartlib/data/models/dispute_chat.dartlib/features/disputes/widgets/disputes_list.dartlib/features/disputes/widgets/dispute_messages_list.dartlib/features/disputes/widgets/dispute_input_section.dartlib/features/disputes/widgets/dispute_content.dartlib/features/disputes/providers/dispute_providers.dartlib/features/disputes/widgets/dispute_communication_section.dartlib/features/disputes/data/dispute_mock_data.dartlib/features/chat/screens/chat_rooms_list.dartlib/data/models/dispute.dart
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_it.arblib/l10n/intl_en.arblib/l10n/intl_es.arb
🧠 Learnings (5)
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Applies to {lib/*.dart,lib/!(generated)/**/*.dart} : Use localized strings; replace hardcoded user-facing text with `S.of(context).keyName`
Applied to files:
lib/features/chat/widgets/trade_information_tab.dart
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories
Applied to files:
lib/features/disputes/notifiers/dispute_chat_notifier.dart
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_it.arblib/l10n/intl_en.arb
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Applies to test/mocks.mocks.dart : Do not manually modify `test/mocks.mocks.dart` (auto-generated by Mockito)
Applied to files:
lib/features/disputes/data/dispute_mock_data.dart
📚 Learning: 2025-08-28T20:32:34.592Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.592Z
Learning: Applies to **/*.mocks.dart : Never manually edit Mockito-generated `*.mocks.dart` files
Applied to files:
lib/features/disputes/data/dispute_mock_data.dart
🪛 RuboCop (1.76.1)
lib/l10n/intl_it.arb
[warning] 760-760: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 965-965: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 976-976: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_en.arb
[warning] 862-862: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 873-873: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_es.arb
[warning] 931-931: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 942-942: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (11)
lib/features/chat/widgets/trade_information_tab.dart (1)
134-140: Null-safety check for currency code.If
order!.fiatCodecan be null/empty,forAmountWithCurrencywill throw or produce odd UI. Consider a safe fallback (e.g., useorder!.fiatCode ?? ''or hide the currency text until loaded).Apply this diff if appropriate:
- Text( - S.of(context)!.forAmountWithCurrency(order!.fiatAmount.toString(), order!.fiatCode), + Text( + S.of(context)!.forAmountWithCurrency( + order!.fiatAmount.toString(), + order!.fiatCode ?? '', + ),lib/core/app_routes.dart (1)
147-157: Route addition LGTM.New
/dispute_details/:disputeIdintegrates cleanly with existing transition wrapper and ShellRoute.lib/features/chat/screens/chat_rooms_list.dart (3)
60-63: Good use of Color.withValues for alphaUsing withValues over deprecated withOpacity aligns with newer Flutter APIs. LGTM.
Also applies to: 88-91
111-111: Nice: real Disputes tab wired inReplacing the placeholder with const DisputesList() completes the UX flow.
157-167: Use non-nullable localized strings for tab descriptions
Replace the?.… ?? '…'pattern withS.of(context).conversationsDescriptionandS.of(context).disputesDescription; both keys exist in everyintl_*.arbfile.lib/features/disputes/widgets/dispute_content.dart (1)
15-23: LGTM: clean composition and spacingGood use of small, focused widgets and const SizedBox spacers. No i18n concerns here.
lib/features/disputes/widgets/dispute_list_item.dart (1)
24-26: Good: uses withValues instead of deprecated withOpacityAlignment with latest Flutter API is correct.
lib/features/disputes/screens/dispute_chat_screen.dart (1)
1-13: Ignore duplicate input widget suggestion
Only DisputeMessageInput is implemented; DisputeInputSection does not exist. No action required.Likely an incorrect or invalid review comment.
lib/features/disputes/widgets/dispute_input_section.dart (1)
65-76: Good: withValues usage and SafeAreaAPI usage and layout considerations are solid.
lib/features/disputes/providers/dispute_providers.dart (1)
31-43: Verify action mapping against product copy.Ensure these action keys match localization and UX expectations for buyer/seller roles; otherwise add a dedicated enum or constants to avoid typos.
lib/l10n/intl_it.arb (1)
712-740: No missing dispute keys in EN/ES ARBs. Verified that all keys added in intl_it.arb appear in intl_en.arb and intl_es.arb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (4)
lib/l10n/intl_en.arb (2)
862-862: Remove duplicate key: "retry" (already defined at Line 215).- "retry": "Retry",
873-873: Remove duplicate key: "orderIdLabel" (already defined at Line 259).- "orderIdLabel": "Order ID",lib/l10n/intl_es.arb (2)
1023-1023: Remove duplicate key: "retry" (already defined at Line 206).- "retry": "Reintentar",
1034-1034: Remove duplicate key: "orderIdLabel" (already defined at Line 600).- "orderIdLabel": "ID de Orden",
🧹 Nitpick comments (5)
lib/l10n/intl_it.arb (1)
1029-1043: Small terminology consistency (optional): use “Disputa” instead of “Controversia”.Multiple entries in this block use “Controversia” while the rest of the file uses “Disputa”. Align for consistency.
lib/features/disputes/data/dispute_mock_data.dart (3)
13-39: Stabilize timestamps to make UI/tests deterministic.DateTime.now() is evaluated on each access to mockDisputes, causing drifting times. Cache a single “now”.
class DisputeMockData { - + static final DateTime _now = DateTime.now(); @@ - createdAt: DateTime.now().subtract(const Duration(minutes: 30)), + createdAt: _now.subtract(const Duration(minutes: 30)), @@ - createdAt: DateTime.now().subtract(const Duration(hours: 6)), + createdAt: _now.subtract(const Duration(hours: 6)), @@ - createdAt: DateTime.now().subtract(const Duration(days: 2)), + createdAt: _now.subtract(const Duration(days: 2)),
60-61: Treat “closed” like “resolved” for mock chats.UI mentions “closed”; include it here to keep behavior consistent.
- if (status == 'resolved') { + if (status == 'resolved' || status == 'closed') {
54-58: Consider using a typed status (enum/union) for mocks.Free-form strings make it easy to mistype and drift from UI logic. Optional.
lib/data/models/dispute.dart (1)
124-144: Optional: accept string/double for createdAt in Nostr events.Robustness improvement; mirror handling you added in fromJson.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (9)
lib/core/app_routes.dart(2 hunks)lib/data/models/dispute.dart(2 hunks)lib/data/models/dispute_chat.dart(1 hunks)lib/data/models/dispute_event.dart(1 hunks)lib/features/disputes/data/dispute_mock_data.dart(1 hunks)lib/features/disputes/widgets/disputes_list.dart(1 hunks)lib/l10n/intl_en.arb(3 hunks)lib/l10n/intl_es.arb(3 hunks)lib/l10n/intl_it.arb(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- lib/core/app_routes.dart
- lib/features/disputes/widgets/disputes_list.dart
- lib/data/models/dispute_chat.dart
- lib/data/models/dispute_event.dart
🧰 Additional context used
📓 Path-based instructions (4)
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/data/models/dispute.dartlib/features/disputes/data/dispute_mock_data.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/data/models/dispute.dartlib/features/disputes/data/dispute_mock_data.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/data/models/dispute.dartlib/features/disputes/data/dispute_mock_data.dart
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_it.arblib/l10n/intl_es.arblib/l10n/intl_en.arb
🧠 Learnings (3)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_it.arb
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to test/mocks.mocks.dart : Do not manually modify `test/mocks.mocks.dart` (auto-generated by Mockito)
Applied to files:
lib/features/disputes/data/dispute_mock_data.dart
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to **/*.mocks.dart : Never manually edit Mockito-generated `*.mocks.dart` files
Applied to files:
lib/features/disputes/data/dispute_mock_data.dart
🪛 RuboCop (1.76.1)
lib/l10n/intl_it.arb
[warning] 760-760: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1057-1057: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1068-1068: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_es.arb
[warning] 1023-1023: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1034-1034: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_en.arb
[warning] 862-862: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 873-873: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
🔇 Additional comments (2)
lib/l10n/intl_en.arb (1)
703-713: LGTM on the new forAmountWithCurrency placeholders.Placeholders look correct and consistent across locales.
lib/l10n/intl_it.arb (1)
762-772: LGTM on forAmountWithCurrency addition.Placeholders align with EN; good parity.
…ect in Italian translations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/l10n/intl_it.arb (1)
620-628: Unify placeholder types forforAmount.amountacross locales: add"type": "Object"(or"String"if you’re passing formatted strings) to theamountplaceholder under@forAmountinintl_en.arbandintl_es.arbso they matchintl_it.arband avoid gen-l10n signature mismatches.
♻️ Duplicate comments (3)
lib/l10n/intl_it.arb (3)
714-721: Add missing dispute status strings to match EN (if present)If EN defines these keys, add their IT counterparts to avoid fallback-to-English.
Proposed additions (only if they exist in EN/ES):
"disputeResolvedTitle": "Disputa risolta", "disputeResolvedMessage": "Questa disputa è stata risolta. Il risolutore ha preso una decisione sulla base delle prove presentate. Controlla il tuo wallet per eventuali rimborsi o pagamenti.", + "disputeInProgress": "Questa disputa è attualmente in corso. Un risolutore sta esaminando il tuo caso.", + "disputeSellerRefunded": "Questa disputa è stata risolta con rimborso al venditore.", + "disputeUnknownStatus": "Lo stato di questa disputa è sconosciuto.",
1053-1056: Duplicate key “retry” (already defined at Line 215) — removeDuplicated JSON key breaks ARB/gen-l10n. Keep the earlier definition.
"disputesWillAppear": "Le dispute appariranno qui quando le apri dai tuoi scambi", "failedLoadDisputes": "Impossibile caricare le dispute", - "retry": "Riprova",
1066-1066: Duplicate key “orderIdLabel” (already defined at Line 641) — removeAvoid ARB duplication errors.
- "orderIdLabel": "ID Ordine",
🧹 Nitpick comments (2)
lib/l10n/intl_it.arb (2)
1030-1031: Terminology consistency: use “disputa” instead of “controversia”Earlier strings use “disputa”; align new ones for a consistent UX.
- "waitingAdminDescription": "La tua controversia è stata inviata. Un amministratore verrà assegnato per aiutare a risolvere questo problema.", + "waitingAdminDescription": "La tua disputa è stata inviata. Un amministratore verrà assegnato per aiutare a risolvere questo problema.", - "adminAssignmentDescription": "Un amministratore verrà assegnato alla tua controversia a breve. Una volta assegnato, potrai comunicare direttamente con lui qui.", + "adminAssignmentDescription": "Un amministratore verrà assegnato alla tua disputa a breve. Una volta assegnato, potrai comunicare direttamente con lui qui.", - "disputesWillAppear": "Le controversie appariranno qui quando le apri dai tuoi scambi", + "disputesWillAppear": "Le dispute appariranno qui quando le apri dai tuoi scambi", - "failedLoadDisputes": "Impossibile caricare le controversie", + "failedLoadDisputes": "Impossibile caricare le dispute", - "disputeWith": "Controversia con {role}: {counterparty}", + "disputeWith": "Disputa con {role}: {counterparty}", - "disputeIdLabel": "ID Controversia", + "disputeIdLabel": "ID Disputa", - "disputeNotFound": "Controversia non trovata", + "disputeNotFound": "Disputa non trovata", - "errorLoadingDispute": "Errore nel caricamento della controversia: {error}", + "errorLoadingDispute": "Errore nel caricamento della disputa: {error}",Also applies to: 1053-1054, 1059-1069, 1072-1074
1037-1037: Prefer “Chiave pubblica” over “Pubkey” in ItalianMatches earlier usage (e.g., “Chiave Pubblica Mostro”).
- "adminPubkey": "Pubkey dell'amministratore", + "adminPubkey": "Chiave pubblica dell'amministratore",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (1)
lib/l10n/intl_it.arb(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_it.arb
🪛 RuboCop (1.76.1)
lib/l10n/intl_it.arb
[warning] 1055-1055: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1066-1066: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (3)
lib/l10n/intl_it.arb (3)
711-740: Dispute lifecycle strings and metadata — LGTMGood coverage of statuses, instructions, and placeholders.
760-770: New key forAmountWithCurrency — LGTMClear separation from
forAmount; placeholders look good.
711-740: Verified EN/ES parity for all new dispute keys and forAmountWithCurrency—no missing keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/l10n/intl_it.arb (1)
620-628: Align placeholder metadata forforAmount.amountacross locales
Inlib/l10n/intl_it.arbthe@forAmount.placeholders.amount.typeis set toObject, while bothintl_en.arbandintl_es.arbomit thetypeproperty. Add or remove the"type"entry so all three ARB files declare the same placeholder metadata to prevent gen-l10n inconsistencies.
♻️ Duplicate comments (2)
lib/l10n/intl_es.arb (2)
1037-1041: Fix duplicate key: "orderIdLabel" defined twice.Earlier at Line 600; remove this one.
Apply:
- "orderIdLabel": "ID de Orden", "disputeIdLabel": "ID de Disputa", "seller": "Vendedor", "buyer": "Comprador",
1023-1027: Fix duplicate key: "retry" defined twice (breaks ARB/JSON).Remove this second occurrence.
Apply:
- "disputesWillAppear": "Las disputas aparecerán aquí cuando las abras desde tus intercambios", - "failedLoadDisputes": "Error al cargar disputas", - "retry": "Reintentar", + "disputesWillAppear": "Las disputas aparecerán aquí cuando las abras desde tus intercambios", + "failedLoadDisputes": "Error al cargar disputas",
🧹 Nitpick comments (2)
lib/l10n/intl_it.arb (1)
711-743: Unify Italian terminology: prefer “disputa” over “controversia”.Minor copy consistency across new dispute strings.
Apply:
- "@_comment_dispute_communication": "Testo Comunicazione Controversie", + "@_comment_dispute_communication": "Testo Comunicazione Dispute", - "waitingAdminDescription": "La tua controversia è stata inviata. Un amministratore verrà assegnato per aiutare a risolvere questo problema.", + "waitingAdminDescription": "La tua disputa è stata inviata. Un amministratore verrà assegnato per aiutare a risolvere questo problema.", - "adminAssignmentDescription": "Un amministratore verrà assegnato alla tua controversia a breve. Una volta assegnato, potrai comunicare direttamente con lui qui.", + "adminAssignmentDescription": "Un amministratore verrà assegnato alla tua disputa a breve. Una volta assegnato, potrai comunicare direttamente con lui qui.", - "disputesWillAppear": "Le controversie appariranno qui quando le apri dai tuoi scambi", + "disputesWillAppear": "Le dispute appariranno qui quando le apri dai tuoi scambi", - "disputeWith": "Controversia con {role}: {counterparty}", + "disputeWith": "Disputa con {role}: {counterparty}", - "disputeIdLabel": "ID Controversia", + "disputeIdLabel": "ID Disputa", - "@_comment_dispute_screen": "Testo Schermata Controversie", + "@_comment_dispute_screen": "Testo Schermata Dispute", - "disputeNotFound": "Controversia non trovata", + "disputaNotFound": "Disputa non trovata", - "errorLoadingDispute": "Errore nel caricamento della controversia: {error}", + "errorLoadingDispute": "Errore nel caricamento della disputa: {error}",Note: Keep the key name "disputeNotFound"; only change its value.
Also applies to: 1056-1079
lib/l10n/intl_es.arb (1)
688-693: Standardize role term: use “administrador” (matches other keys).Replace “mediador” to keep consistency with “admin/administrador”.
Apply:
- "disputeResolvedMessage": "Esta disputa ha sido resuelta. El mediador tomó una decisión basada en la evidencia presentada. Revisa tu billetera para ver reembolsos o pagos.", + "disputeResolvedMessage": "Esta disputa ha sido resuelta. El administrador tomó una decisión basada en la evidencia presentada. Revisa tu billetera para ver reembolsos o pagos.", - "disputeInProgress": "Esta disputa está actualmente en progreso. Un mediador está revisando tu caso.", + "disputeInProgress": "Esta disputa está actualmente en progreso. Un administrador está revisando tu caso.", - "disputeSellerRefunded": "Esta disputa ha sido resuelta con el vendedor siendo reembolsado.", + "disputeSellerRefunded": "Esta disputa se resolvió con reembolso al vendedor.",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
lib/data/models/dispute.dart(2 hunks)lib/l10n/intl_es.arb(3 hunks)lib/l10n/intl_it.arb(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/data/models/dispute.dart
🧰 Additional context used
📓 Path-based instructions (1)
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_es.arblib/l10n/intl_it.arb
🧠 Learnings (1)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_it.arb
🪛 RuboCop (1.76.1)
lib/l10n/intl_es.arb
[warning] 1026-1026: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1037-1037: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
lib/l10n/intl_it.arb (3)
763-773: LGTM: Added forAmountWithCurrency.Key and placeholders look consistent with usage.
1030-1054: LGTM: Dispute communication cluster.Clear labels and statuses; placeholders are correct.
1056-1058: LGTM: Dispute list texts.No duplicate “retry” here; good.
lib/l10n/intl_es.arb (2)
733-743: LGTM: Added forAmountWithCurrency.Key and placeholders are correct.
681-713: Localization parity verified All dispute-related keys, includingdisputesDescriptionthroughdisputeInstruction4andforAmountWithCurrency, are present in intl_en.arb, intl_es.arb, and intl_it.arb.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (6)
lib/features/chat/widgets/chat_tabs.dart (4)
7-13: Avoid prop drilling: read current tab from the provider inside ChatTabsSince this is already a ConsumerWidget, watch the provider internally and drop the currentTab prop.
Apply this diff:
-class ChatTabs extends ConsumerWidget { - final ChatTabType currentTab; +class ChatTabs extends ConsumerWidget { const ChatTabs({ super.key, - required this.currentTab, }); @override - Widget build(BuildContext context, WidgetRef ref) { + Widget build(BuildContext context, WidgetRef ref) { + final currentTab = ref.watch(chatTabProvider);And update the call site (see chat_rooms_list.dart suggestion).
29-31: Avoid null-bang on localized stringsPrefer safe access with fallbacks to prevent crashes if localization isn’t initialized.
Apply this diff:
- _buildTabButton(context, ref, ChatTabType.messages, S.of(context)!.messages, currentTab == ChatTabType.messages), - _buildTabButton(context, ref, ChatTabType.disputes, S.of(context)!.disputes, currentTab == ChatTabType.disputes), + _buildTabButton( + context, + ref, + ChatTabType.messages, + S.of(context)?.messages ?? 'Messages', + currentTab == ChatTabType.messages, + ), + _buildTabButton( + context, + ref, + ChatTabType.disputes, + S.of(context)?.disputes ?? 'Disputes', + currentTab == ChatTabType.disputes, + ),
36-66: Ink ripple won’t render without a Material ancestorWrap InkWell in a transparent Material so ripple/focus highlights display correctly.
Apply this diff:
- return Expanded( - child: InkWell( + return Expanded( + child: Material( + color: Colors.transparent, + child: InkWell( onTap: () { ref.read(chatTabProvider.notifier).state = tabType; }, child: Container( padding: const EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: isActive ? AppTheme.mostroGreen : Colors.transparent, width: 3.0, ), ), ), child: Text( text, textAlign: TextAlign.center, style: TextStyle( color: isActive ? AppTheme.mostroGreen : AppTheme.textInactive, fontWeight: FontWeight.w600, fontSize: 15, letterSpacing: 0.5, ), ), ), - ), + ), + ), );
41-41: Minor: use update for clarityUsing update conveys intent and keeps old/new state transitions uniform.
Apply this diff:
- ref.read(chatTabProvider.notifier).state = tabType; + ref.read(chatTabProvider.notifier).update((_) => tabType);lib/features/chat/screens/chat_rooms_list.dart (2)
80-91: Reduce accidental tab switches on subtle swipesUse a velocity threshold so short drags don’t flip tabs unintentionally.
Apply this diff:
- onHorizontalDragEnd: (details) { - if (details.primaryVelocity != null && - details.primaryVelocity! < 0) { + onHorizontalDragEnd: (details) { + const kThreshold = 300; // px/s + final v = details.primaryVelocity ?? 0; + if (v < -kThreshold) { // Swipe left - go to disputes - ref.read(chatTabProvider.notifier).state = ChatTabType.disputes; - } else if (details.primaryVelocity != null && - details.primaryVelocity! > 0) { + ref.read(chatTabProvider.notifier).state = ChatTabType.disputes; + } else if (v > kThreshold) { // Swipe right - go to messages ref.read(chatTabProvider.notifier).state = ChatTabType.messages; } },
101-103: Bottom padding: avoid hardcoding 80Tie the spacer to the BottomNavBar’s actual height or reuse a shared constant to prevent layout drift if the bar changes.
Example:
- SizedBox( - height: 80 + MediaQuery.of(context).viewPadding.bottom), + SizedBox( + height: BottomNavBar.height + + MediaQuery.of(context).viewPadding.bottom, + ),If BottomNavBar.height isn’t exposed, consider adding a static const there or using SafeArea around scroll content instead of manual padding.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
lib/features/chat/providers/chat_tab_provider.dart(1 hunks)lib/features/chat/screens/chat_rooms_list.dart(5 hunks)lib/features/chat/widgets/chat_tabs.dart(2 hunks)lib/features/disputes/data/dispute_mock_data.dart(1 hunks)lib/features/disputes/widgets/disputes_list.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- lib/features/disputes/widgets/disputes_list.dart
- lib/features/disputes/data/dispute_mock_data.dart
🧰 Additional context used
📓 Path-based instructions (3)
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/features/chat/providers/chat_tab_provider.dartlib/features/chat/widgets/chat_tabs.dartlib/features/chat/screens/chat_rooms_list.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/features/chat/providers/chat_tab_provider.dartlib/features/chat/widgets/chat_tabs.dartlib/features/chat/screens/chat_rooms_list.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/features/chat/providers/chat_tab_provider.dartlib/features/chat/widgets/chat_tabs.dartlib/features/chat/screens/chat_rooms_list.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (3)
lib/features/chat/providers/chat_tab_provider.dart (1)
3-3: Enum addition looks goodClear, descriptive tab types.
lib/features/chat/screens/chat_rooms_list.dart (2)
42-45: Borders with withValues API — nice modernizationGood use of withValues over deprecated withOpacity and consistent divider styling.
Also applies to: 65-68
23-26: Strong typing currentTab (will be inferred once provider is typed)After typing chatTabProvider as StateProvider, currentTab will infer correctly. No action here once that change lands.
Please confirm after applying the provider typing that this line infers ChatTabType without casts:
final currentTab = ref.watch(chatTabProvider);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
lib/features/chat/screens/chat_rooms_list.dart (1)
116-116: Empty-state source-of-truth fix applied—thank you.
Now both the check and the list usesortedChatRoomsProvider.
🧹 Nitpick comments (3)
lib/features/chat/screens/chat_rooms_list.dart (3)
76-95: Prevent accidental tab switches; add a velocity threshold.
Small horizontal drags may flip tabs. Gate on a minimum velocity.Apply:
- onHorizontalDragEnd: (details) { - if (details.primaryVelocity != null && - details.primaryVelocity! < 0) { + onHorizontalDragEnd: (details) { + final v = details.primaryVelocity ?? 0; + const minV = 400; // px/s + if (v < -minV) { // Swipe left - go to disputes ref.read(chatTabProvider.notifier).state = ChatTabType.disputes; - } else if (details.primaryVelocity != null && - details.primaryVelocity! > 0) { + } else if (v > minV) { // Swipe right - go to messages ref.read(chatTabProvider.notifier).state = ChatTabType.messages; } },
121-125: Avoid hardcoded fallback text; rely on i18n keys.
Per guidelines, prefer localized strings only (ensure keys exist).- return EmptyStateView( - message: S.of(context)?.noMessagesAvailable ?? 'No messages available', - ); + return EmptyStateView( + message: S.of(context).noMessagesAvailable, + );
139-149: Remove fallback prose; use strict i18n.
Keep user-facing text in ARB files only.- String _getTabDescription(BuildContext context, ChatTabType currentTab) { - if (currentTab == ChatTabType.messages) { - // Messages tab - return S.of(context)?.conversationsDescription ?? - 'Here you\'ll find your conversations with other users during trades.'; - } else { - // Disputes tab - return S.of(context)?.disputesDescription ?? - 'These are your open disputes and the chats with the admin helping resolve them.'; - } - } + String _getTabDescription(BuildContext context, ChatTabType currentTab) { + return currentTab == ChatTabType.messages + ? S.of(context).conversationsDescription + : S.of(context).disputesDescription; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
lib/features/chat/providers/chat_tab_provider.dart(1 hunks)lib/features/chat/screens/chat_rooms_list.dart(5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/features/chat/providers/chat_tab_provider.dart
🧰 Additional context used
📓 Path-based instructions (3)
{lib/*.dart,lib/!(generated)/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart}: Use localized strings; replace hardcoded user-facing text withS.of(context).keyName
Preferconstconstructors andconstwhere possible
Use latest Flutter/Dart APIs (e.g.,withValues()instead of deprecatedwithOpacity())
Files:
lib/features/chat/screens/chat_rooms_list.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Checkmountedbefore usingBuildContextafterawait(async gaps)
Remove unused imports and dependencies
Files:
lib/features/chat/screens/chat_rooms_list.dart
**/*.dart
📄 CodeRabbit inference engine (CLAUDE.md)
All code comments, variable names, and function names must be in English
Files:
lib/features/chat/screens/chat_rooms_list.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (7)
lib/features/chat/screens/chat_rooms_list.dart (7)
10-11: Imports look correct for the new Disputes tab and tab state provider.
No unused-imports; aligns with the new UI.
18-18: Good refactor to ConsumerWidget.
Simplifies lifecycle; no TabController cleanup needed.
40-42: Nice: useswithValues()instead of deprecatedwithOpacity().
Consistent with guidelines.
55-55: Ensure tab taps update state, not just swipes.
Confirm ChatTabs writes tochatTabProvideron tap; otherwise only the swipe handler will switch tabs.
63-65: Border styling LGTM.
Consistent divider styling withwithValues().
69-69: Dynamic description hook looks good.
Wires tab state to description text cleanly.
22-24: chatTabProvider confirmed as StateProvider;.state = …assignment is valid.
grunch
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
lib/l10n/intl_es.arb (1)
714-717: Duplicate key: createdOn — remove this entry."createdOn" already exists earlier (Line 252). Keep the existing key or reuse createdOnLabel; delete this new one with the colon to avoid JSON/ARB conflicts.
Apply:
- "createdOn": "Creado el:",lib/l10n/intl_en.arb (1)
684-687: Duplicate key: createdOn — remove this new entry."createdOn" already exists above (Line 298). Prefer using the existing createdOnLabel if a label form is needed.
Apply:
- "createdOn": "Created on:",
♻️ Duplicate comments (4)
lib/l10n/intl_es.arb (2)
1039-1043: Duplicate key: orderIdLabel — remove this instance."orderIdLabel" exists earlier (Line 600). Keep the earlier definition.
Apply:
- "orderIdLabel": "ID de Orden",
1023-1029: Duplicate key: retry — remove the second definition here."retry" is already defined earlier (Line 206). Duplicates break ARB codegen.
Apply:
- "retry": "Reintentar",lib/l10n/intl_en.arb (2)
875-878: Duplicate key: orderIdLabel — remove this instance.Already defined earlier (Line 259). Duplicates can cause flakey localization generation.
Apply:
- "orderIdLabel": "Order ID",
859-865: Duplicate key: retry — remove this duplicate."retry" already defined earlier (Line 215). Keep only one.
Apply:
- "retry": "Retry",
🧹 Nitpick comments (3)
lib/l10n/intl_it.arb (1)
624-624: Align placeholder type for amount (Object → String) for consistency.Only IT defines @forAmount.amount.type as Object while EN/ES omit or use String in similar contexts. Recommend switching to String to avoid tooling surprises.
Apply:
- "type": "Object", + "type": "String",lib/l10n/intl_en.arb (2)
232-246: Nit: missing space before {sats} in titles."You are selling{sats}" and "You are buying{sats}" are missing a space before the placeholder.
Apply:
- "youAreSellingTitle": "You are selling{sats} sats", + "youAreSellingTitle": "You are selling {sats} sats", - "youAreBuyingTitle": "You are buying{sats} sats", + "youAreBuyingTitle": "You are buying {sats} sats",
821-833: Housekeeping: leftover blank line.There’s a stray blank line after relay dialog header; safe to keep, but consider removing for consistency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
lib/features/disputes/widgets/disputes_list.dart(1 hunks)lib/l10n/intl_en.arb(3 hunks)lib/l10n/intl_es.arb(3 hunks)lib/l10n/intl_it.arb(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- lib/features/disputes/widgets/disputes_list.dart
🧰 Additional context used
📓 Path-based instructions (1)
lib/l10n/intl_{en,es,it}.arb
📄 CodeRabbit inference engine (CLAUDE.md)
Add new localization keys to all three ARB files (en, es, it)
Files:
lib/l10n/intl_it.arblib/l10n/intl_en.arblib/l10n/intl_es.arb
🧠 Learnings (1)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)
Applied to files:
lib/l10n/intl_it.arblib/l10n/intl_es.arb
🪛 RuboCop (1.76.1)
lib/l10n/intl_en.arb
[warning] 864-864: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 875-875: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
lib/l10n/intl_es.arb
[warning] 1028-1028: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
[warning] 1039-1039: Duplicated key in hash literal.
(Lint/DuplicateHashKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (13)
lib/l10n/intl_it.arb (7)
711-743: Disputes UI strings: parity and placeholders look good.The added dispute keys and metadata match EN/ES, placeholders are correct.
762-773: New forAmountWithCurrency key looks correct.Placeholders and wording align with EN/ES.
1031-1044: Dispute communication block: looks solid.Labels and flow messages are consistent and idiomatic.
1046-1054: Dispute input block: OK.Placeholder for error is correctly declared.
1056-1060: List/info/screen scaffolding: OK.Good coverage for empty/error states.
1062-1073: Dispute info labels: OK.Roles and placeholders are correct.
1075-1081: Dispute screen error block: OK.Error placeholder wired correctly.
lib/l10n/intl_es.arb (2)
681-713: Disputes UI strings added correctly.Parity with EN/IT looks good; placeholders validated.
733-743: forAmountWithCurrency added correctly.Looks consistent with other locales.
lib/l10n/intl_en.arb (4)
651-683: Disputes UI strings: LGTM.Keys and phrasing align with the new UI states; placeholders are correct.
703-713: forAmountWithCurrency: correct addition.Placeholder names/types match other locales.
834-848: Dispute communication block: OK.Wording and flow align with product language.
849-858: Dispute input block: OK.Error placeholder wired correctly.
This PR introduces the complete UI implementation for the Disputes feature, addressing issues #171, #172, and #173.
The implementation includes a fully functional dispute chat interface that replicates the existing chat UI patterns, with message bubbles, admin communications, and proper state management across different dispute statuses (initiated, in-progress, resolved). The UI features proper internationalization support across English, Spanish, and Italian languages, with status-dependent behavior where initiated disputes show a waiting screen without chat input, in-progress disputes display active communication with admins, and resolved disputes show historical messages with resolution notifications.
All hardcoded data has been centralized into a mock data system that can be easily toggled or removed when real dispute integration is implemented. The interface maintains consistency with the existing application design patterns while providing a smooth user experience for dispute resolution workflows.
Summary by CodeRabbit
New Features
Enhancements
Localization