Skip to content

Conversation

@AndreaDiazCorreia
Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia commented Sep 15, 2025

This PR implements dispute listing functionality by connecting real data from Mostro dispute DMs to the existing UI components. When users create disputes, they now appear automatically in the debug-only "Disputes" tab with actual order information instead of mock data. Key improvements include: proper dispute-to-order association via orderId, enhanced DisputeData creation with OrderState context for displaying real order IDs and statuses, and improved provider logic to match disputes with their corresponding sessions. The dispute list is currently visible only in debug mode to prevent exposure to end users until the complete dispute resolution system is ready.

Summary by CodeRabbit

  • New Features

    • Disputes now load from your real sessions/orders and appear linked to the correct order.
    • Added a “Waiting for admin assignment” status for newly opened disputes.
  • UI/UX

    • Disputes list supports loading, empty, and error states with a retry action.
    • Messages screen simplified in production; extra debug tabs available only in debug builds.
  • Localization

    • Added dispute-related translations (EN/ES/IT).
  • Bug Fixes

    • Improved fallback linking and more accurate default dispute statuses.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 15, 2025

Walkthrough

Replaces mock dispute flows with session/order-backed retrieval and UI view models; adds DisputeDescriptionKey.initiatedPendingAdmin and i18n keys; gates disputes UI to debug builds; attaches orderId on dispute initiation; updates repository, providers, widgets, notifier, and localization; minor service delay increase.

Changes

Cohort / File(s) Summary
Dispute model updates
lib/data/models/dispute.dart
Added enum member initiatedPendingAdmin; DisputeData.fromDispute falls back to orderState.order.id for orderId, defaults status to initiated, maps initiated+unknown creator → initiatedPendingAdmin, and description returns "Waiting for admin assignment".
Repository: real data flow
lib/data/repositories/dispute_repository.dart
Replaced mock getUserDisputes with session- and order-aware collection using sessionNotifierProvider and orderNotifierProvider(orderId); added per-session try/catch and logging; getDispute now queries getUserDisputes.
Providers: real data + UI view models
lib/features/disputes/providers/dispute_providers.dart
Removed mock-data helpers; disputeDetailsProvider/userDisputesProvider use repository; added public userDisputeDataProvider (FutureProvider<List>) that correlates disputes with sessions/orders to build UI view models.
Disputes list widget (async, Riverpod)
lib/features/disputes/widgets/disputes_list.dart
Converted DisputesList to ConsumerWidget; consumes userDisputeDataProvider with AsyncValue.when (loading, error+retry, empty, list); removed kDebugMode mock rendering and hard-coded data.
Dispute status text
lib/features/disputes/widgets/dispute_status_content.dart
Added handling for DisputeDescriptionKey.initiatedPendingAdmin → localized disputeWaitingForAdmin.
Chat rooms UI gating
lib/features/chat/screens/chat_rooms_list.dart
Added kDebugMode gating: debug builds show ChatTabs and swipe/disputes tab; release builds show a non-debug Messages header (_buildMessagesTabHeader) and always render messages body (no disputes/swipe).
Notifier: attach orderId on initiation
lib/features/order/notfiers/abstract_mostro_notifier.dart
On Action.disputeInitiatedByYou/...ByPeer, creates disputeWithOrderId (copy with orderId), updates state with it prior to sending notification; includes eventId in notification call.
i18n additions / removals
lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_it.arb
Added keys: disputeWaitingForAdmin, disputeYouOpened, disputeOpenedAgainstUser, disputeResolved (en/es/it); added disputeInstruction4 (en); removed/renamed orderIdLabelorderId (en, es removed).
Service mock timing
lib/services/dispute_service.dart
sendDisputeMessage adds an extra mock delay (total ~400ms) — purely additive simulated delay.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant UI as DisputesList (UI)
  participant Prov as userDisputeDataProvider
  participant Repo as DisputeRepository
  participant Sess as sessionNotifierProvider
  participant Ord as orderNotifierProvider(orderId)

  User->>UI: Open Disputes screen
  UI->>Prov: ref.watch(userDisputeDataProvider)
  Prov->>Repo: getUserDisputes()
  Repo->>Sess: read sessions
  loop per session with orderId
    Repo->>Ord: read order state
    Ord-->>Repo: orderState (may include dispute)
    Repo-->>Repo: collect dispute if present
  end
  Repo-->>Prov: List<Dispute>
  Prov->>Sess: read sessions
  loop per dispute
    Prov->>Ord: find matching order state
    Ord-->>Prov: orderState | null
    Prov-->>Prov: build DisputeData (include order context if found)
  end
  Prov-->>UI: AsyncValue<List<DisputeData>>
  UI-->>User: Render loading / error / empty / list
Loading
sequenceDiagram
  autonumber
  participant Notifier as AbstractMostroNotifier
  participant State as OrderState
  participant Bus as NotificationBus

  Note over Notifier,State: On dispute initiation actions
  Notifier->>Notifier: disputeWithOrderId = dispute.copy(orderId: currentOrderId)
  Notifier->>State: state = state.copyWith(dispute: disputeWithOrderId)
  State-->>Notifier: updated state
  Notifier->>Bus: sendNotification(eventId, payload with dispute_id)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • grunch
  • Catrya
  • chebizarro

Poem

I nibble bytes in moonlit code,
From mocks to sessions I now strode.
Disputes wait soft, a patient plan—
"Awaiting admin" — hop with me, clan! 🥕🐇

Pre-merge checks and finishing touches

✅ 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 "Dispute Listing" is concise and directly related to the primary change in this PR—implementing dispute listing and connecting real dispute/order data to the UI—so it accurately summarizes the main change for a quick scan. It is a clear, single-phrase summary suitable for commit history even though it does not include debug-only or data-source specifics.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/dispute-listing

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4867c4d and f917ba8.

📒 Files selected for processing (4)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (2 hunks)
  • lib/l10n/intl_en.arb (1 hunks)
  • lib/l10n/intl_es.arb (1 hunks)
  • lib/l10n/intl_it.arb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/l10n/intl_it.arb
🧰 Additional context used
📓 Path-based instructions (2)
lib/l10n/intl_{en,es,it}.arb

📄 CodeRabbit inference engine (CLAUDE.md)

When adding a localization key, add it to all three ARB files: intl_en.arb, intl_es.arb, intl_it.arb

Files:

  • lib/l10n/intl_es.arb
  • lib/l10n/intl_en.arb
lib/l10n/*.arb

📄 CodeRabbit inference engine (CLAUDE.md)

After modifying ARB files, regenerate localization (e.g., dart run build_runner build -d or flutter gen-l10n)

Files:

  • lib/l10n/intl_es.arb
  • lib/l10n/intl_en.arb
🧠 Learnings (1)
📚 Learning: 2025-09-18T17:17:38.944Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-18T17:17:38.944Z
Learning: Applies to lib/l10n/intl_{en,es,it}.arb : When adding a localization key, add it to all three ARB files: intl_en.arb, intl_es.arb, intl_it.arb

Applied to files:

  • lib/l10n/intl_es.arb
⏰ 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 (4)
lib/l10n/intl_en.arb (2)

709-712: New dispute status keys OK — regenerate l10n before merging

Keys exist in lib/l10n/intl_en.arb, lib/l10n/intl_es.arb, lib/l10n/intl_it.arb (around lines 709–712 / 715–718 / 769–772); flutter gen-l10n / dart build_runner could not run here (flutter/dart not installed). Run gen-l10n locally or ensure CI runs it prior to merge.


283-283: Keep both keys — they're distinct and in use

  • lib/l10n/intl_en.arb: line 283 "orderIdLabel": "Order ID", line 722 "orderId": "Order ID:".
  • Both keys are referenced in code (e.g. S.of(context)!.orderIdLabel in lib/shared/widgets/order_cards.dart and lib/features/disputes/widgets/dispute_info_card.dart; S.of(context)!.orderId in lib/features/chat/widgets/trade_information_tab.dart).

Likely an incorrect or invalid review comment.

lib/l10n/intl_es.arb (2)

600-600: Do not remove orderIdLabel — it's referenced; unify callers before changing the ARB

S.of(context)!.orderIdLabel is referenced in lib/shared/widgets/order_cards.dart:207 and lib/features/disputes/widgets/dispute_info_card.dart:56; many other files use S.of(context)!.orderId. Pick a single key (recommend "orderId" with trailing colon), update all callers to that key, then remove the unused ARB entry.

Likely an incorrect or invalid review comment.


715-718: New dispute status keys present — regenerate l10n before merge

Found in lib/l10n/intl_en.arb (lines 709–712), lib/l10n/intl_es.arb (715–718), lib/l10n/intl_it.arb (769–772).
Generation failed in sandbox: 'flutter'/'dart' not found — run flutter gen-l10n or dart run build_runner build -d locally or via CI and confirm the generated Dart localization classes include these messages.

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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: 9

🧹 Nitpick comments (3)
lib/services/dispute_service.dart (1)

52-54: Remove duplicate delay in mock implementation

The method now has two identical 200ms delays (lines 52 and 54), effectively making the total delay 400ms. This appears to be unintentional duplication.

   Future<void> sendDisputeMessage(String disputeId, String message) async {
     // Mock implementation
     await Future.delayed(const Duration(milliseconds: 200));
-    // Mock implementation
-    await Future.delayed(const Duration(milliseconds: 200));
   }
lib/features/disputes/widgets/disputes_list.dart (1)

17-17: Consider adding const to CircularProgressIndicator.

-      loading: () => const Center(child: CircularProgressIndicator()),
+      loading: () => const Center(child: const CircularProgressIndicator()),
lib/features/disputes/providers/dispute_providers.dart (1)

41-78: Log caught errors in userDisputeDataProvider instead of silently swallowing.

rg output shows this catch in lib/features/disputes/providers/dispute_providers.dart is the only similar catch; swallowing errors hides failures—add debug-only logging.

File: lib/features/disputes/providers/dispute_providers.dart (lines 41–78)

         } catch (e) {
           // Continue checking other sessions
+          // Consider logging for debugging in development
+          // if (kDebugMode) {
+          //   debugPrint('Failed to read order state: $e');
+          // }
           continue;
         }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9994149 and 01b4b02.

📒 Files selected for processing (11)
  • lib/data/models/dispute.dart (4 hunks)
  • lib/data/repositories/dispute_repository.dart (2 hunks)
  • lib/features/chat/screens/chat_rooms_list.dart (4 hunks)
  • lib/features/disputes/providers/dispute_providers.dart (3 hunks)
  • lib/features/disputes/widgets/dispute_status_content.dart (1 hunks)
  • lib/features/disputes/widgets/disputes_list.dart (1 hunks)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (2 hunks)
  • lib/l10n/intl_en.arb (2 hunks)
  • lib/l10n/intl_es.arb (2 hunks)
  • lib/l10n/intl_it.arb (2 hunks)
  • lib/services/dispute_service.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 with S.of(context).keyName
Prefer const constructors and const where possible
Use latest Flutter/Dart APIs (e.g., withValues() instead of deprecated withOpacity())

Files:

  • lib/services/dispute_service.dart
  • lib/features/disputes/widgets/dispute_status_content.dart
  • lib/features/disputes/widgets/disputes_list.dart
  • lib/data/repositories/dispute_repository.dart
  • lib/features/chat/screens/chat_rooms_list.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/data/models/dispute.dart
  • lib/features/disputes/providers/dispute_providers.dart
{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}

📄 CodeRabbit inference engine (CLAUDE.md)

{lib/*.dart,lib/!(generated)/**/*.dart,test/**/*.dart}: Check mounted before using BuildContext after await (async gaps)
Remove unused imports and dependencies

Files:

  • lib/services/dispute_service.dart
  • lib/features/disputes/widgets/dispute_status_content.dart
  • lib/features/disputes/widgets/disputes_list.dart
  • lib/data/repositories/dispute_repository.dart
  • lib/features/chat/screens/chat_rooms_list.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/data/models/dispute.dart
  • lib/features/disputes/providers/dispute_providers.dart
**/*.dart

📄 CodeRabbit inference engine (CLAUDE.md)

All code comments, variable names, and function names must be in English

Files:

  • lib/services/dispute_service.dart
  • lib/features/disputes/widgets/dispute_status_content.dart
  • lib/features/disputes/widgets/disputes_list.dart
  • lib/data/repositories/dispute_repository.dart
  • lib/features/chat/screens/chat_rooms_list.dart
  • lib/features/order/notfiers/abstract_mostro_notifier.dart
  • lib/data/models/dispute.dart
  • lib/features/disputes/providers/dispute_providers.dart
lib/l10n/intl_{en,es,it}.arb

📄 CodeRabbit inference engine (CLAUDE.md)

Add new localization keys to all three ARB files (en, es, it)

Files:

  • lib/l10n/intl_es.arb
  • lib/l10n/intl_it.arb
  • lib/l10n/intl_en.arb
🧠 Learnings (5)
📚 Learning: 2025-08-28T20:32:34.625Z
Learnt from: CR
PR: MostroP2P/mobile#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-28T20:32:34.625Z
Learning: Applies to test/mocks.mocks.dart : Do not manually modify `test/mocks.mocks.dart` (auto-generated by Mockito)

Applied to files:

  • lib/services/dispute_service.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 lib/l10n/intl_{en,es,it}.arb : Add new localization keys to all three ARB files (en, es, it)

Applied to files:

  • lib/l10n/intl_es.arb
  • lib/l10n/intl_it.arb
  • lib/l10n/intl_en.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: Use Riverpod for state management with Notifiers encapsulating business logic; access data only through repositories

Applied to files:

  • lib/data/repositories/dispute_repository.dart
  • lib/features/disputes/providers/dispute_providers.dart
📚 Learning: 2025-05-06T15:49:26.443Z
Learnt from: chebizarro
PR: MostroP2P/mobile#74
File: lib/services/mostro_service.dart:70-76
Timestamp: 2025-05-06T15:49:26.443Z
Learning: In the Mostro Mobile codebase, Riverpod code generation is used with `Riverpod` annotations. Providers like `eventStorageProvider` are generated in `.g.dart` files from annotated functions in the main provider files. These providers are accessible by importing the main provider file (e.g., `mostro_service_provider.dart`), not by importing a separate provider file.

Applied to files:

  • lib/features/chat/screens/chat_rooms_list.dart
📚 Learning: 2025-06-26T15:03:23.529Z
Learnt from: chebizarro
PR: MostroP2P/mobile#127
File: lib/features/order/notfiers/abstract_mostro_notifier.dart:45-54
Timestamp: 2025-06-26T15:03:23.529Z
Learning: In AbstractMostroNotifier, state updates occur for all messages regardless of timestamp to hydrate the OrderNotifier from MostroStorage during sync, while handleEvent is only called for recent messages (within 60 seconds) to prevent re-triggering side effects like notifications and navigation for previously handled messages. This design prevents displaying stale notifications when the app is reopened or brought to the foreground.

Applied to files:

  • lib/features/order/notfiers/abstract_mostro_notifier.dart
🪛 RuboCop (1.76.1)
lib/l10n/intl_es.arb

[warning] 613-613: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 719-719: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 721-721: Duplicated key in hash literal.

(Lint/DuplicateHashKey)

lib/l10n/intl_it.arb

[warning] 678-678: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 773-773: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 775-775: Duplicated key in hash literal.

(Lint/DuplicateHashKey)

lib/l10n/intl_en.arb

[warning] 296-296: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 713-713: Duplicated key in hash literal.

(Lint/DuplicateHashKey)


[warning] 715-715: 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 (18)
lib/features/order/notfiers/abstract_mostro_notifier.dart (2)

275-291: Good implementation of dispute-order association

The logic correctly creates a copy of the dispute with the orderId before updating the state, ensuring disputes are properly linked to their corresponding orders for the listing feature.


293-309: Consistent implementation for peer-initiated disputes

The same pattern is correctly applied for peer-initiated disputes, maintaining consistency with the disputeInitiatedByYou case.

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

127-128: Good implementation of pending admin state

The new case correctly handles the initiatedPendingAdmin state, providing appropriate user feedback when a dispute is waiting for admin assignment.

lib/data/models/dispute.dart (3)

9-9: Well-structured enum addition for pending admin state

The new initiatedPendingAdmin enum value appropriately represents the dispute state when waiting for admin assignment, fitting well within the existing dispute lifecycle states.


379-380: Good defensive programming with fallback orderId

The implementation properly handles null orderId by falling back to the order ID from orderState, ensuring disputes maintain their order association even when the orderId field is missing.


431-436: Logical state transition for pending admin disputes

The switch case correctly returns initiatedPendingAdmin when the creator status is unknown (null), which appropriately represents disputes awaiting admin assignment where the initiator hasn't been determined yet.

lib/features/chat/screens/chat_rooms_list.dart (3)

3-3: LGTM! Appropriate use of foundation for debug mode checks.

The import is correctly added to support kDebugMode checks for debug-only UI features.


105-107: Good implementation of environment-specific text.

The conditional text display correctly shows tab-specific descriptions in debug mode while falling back to a safe, user-friendly message in release mode.


116-139: Swipe gesture implementation looks good.

The horizontal swipe detection for tab switching is properly gated to debug mode only, preventing end users from accessing the disputes tab in production.

lib/data/repositories/dispute_repository.dart (1)

9-9: LGTM! Necessary import for order state access.

The import is correctly added to support reading order states for dispute retrieval.

lib/features/disputes/providers/dispute_providers.dart (3)

3-10: LGTM! Imports properly organized for real data flow.

The imports correctly bring in the necessary models and providers to support the transition from mock to real dispute data.


21-25: Provider correctly uses repository for real data.

The implementation properly fetches dispute details from the repository instead of using mock data.


71-76: Good fallback handling for DisputeData creation.

The code properly handles both cases - when matching order state is found and when it's not, ensuring DisputeData is always created.

lib/features/disputes/widgets/disputes_list.dart (5)

2-6: LGTM! Widget properly migrated to ConsumerWidget.

The migration from StatelessWidget to ConsumerWidget is correctly implemented to support Riverpod state management.


14-15: Excellent use of AsyncValue pattern.

The implementation properly watches the userDisputeDataProvider and handles all async states (loading, error, data).


36-39: Good implementation of retry functionality.

The error state properly includes a retry button that refreshes the provider, giving users a way to recover from transient failures.


43-74: Well-designed empty state UI.

The empty state properly differentiates between "no disputes" and provides helpful context with localized messages.


76-89: ListView implementation looks correct.

The ListView properly renders DisputeListItem widgets with navigation to dispute details.

@AndreaDiazCorreia AndreaDiazCorreia changed the title Feat/dispute listing Dispute Listing Sep 17, 2025
@grunch grunch merged commit 0ee0717 into main Sep 19, 2025
2 checks passed
@grunch grunch deleted the feat/dispute-listing branch September 19, 2025 12:00
@coderabbitai coderabbitai bot mentioned this pull request Oct 12, 2025
3 tasks
@coderabbitai coderabbitai bot mentioned this pull request Nov 10, 2025
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.

3 participants