Skip to content

New add order buttom and new add order screens #103

Merged
chebizarro merged 22 commits into
MostroP2P:mainfrom
AndreaDiazCorreia:feat/buttom-create-orders
May 23, 2025
Merged

New add order buttom and new add order screens #103
chebizarro merged 22 commits into
MostroP2P:mainfrom
AndreaDiazCorreia:feat/buttom-create-orders

Conversation

@AndreaDiazCorreia

@AndreaDiazCorreia AndreaDiazCorreia commented May 21, 2025

Copy link
Copy Markdown
Member

New Order Flow Implementation

This PR implements the new order creation flow and refactors several UI components to improve consistency across the app.

Changes

  • Implemented new Add Order button with animated menu for BUY/SELL options
  • Fixed button positioning to be consistent across different device sizes
  • Created new screens for order creation with proper validation
  • Refactored several UI components for better reusability

Related Issues

Closes #88, #89, #90

Notes

The cancel/submit buttons in the order creation screens don't exactly match the Lovable designs. I opted to reuse existing button components for consistency, but I can update them to match the designs precisely if needed.

image
image
image
image
image

Summary by CodeRabbit

  • New Features

    • Introduced a multi-step order creation form with modular sections for order type, currency, amount, payment methods, price type, premium, and optional lightning address.
    • Added support for selecting multiple payment methods per currency, including a custom option.
    • Implemented an expandable floating action button for quick access to "Buy" and "Sell" order creation.
    • Added a new data source for supported payment methods by currency.
    • Added new UI components for currency selection, amount input with validation, price type toggle, premium slider, and payment methods management.
    • Introduced unified action buttons for order submission and cancellation.
  • Enhancements

    • Refreshed app color palette with updated green and red tones for improved visual clarity.
    • Improved asset management to include all data files in the assets directory.
  • Refactor

    • Simplified and modularized the order creation UI for better usability and maintainability.
    • Repositioned the add order button within the home screen layout for better accessibility.
    • Revised state management in order creation to use local state and providers for cleaner logic and error handling.
    • Updated order model to support multiple payment methods instead of a single method.

@coderabbitai

coderabbitai Bot commented May 21, 2025

Copy link
Copy Markdown
Contributor
## Walkthrough

This update introduces an expandable floating action button for quick BUY/SELL actions, refactors the order creation UI into modular widgets, and adds new providers and data files for payment methods. UI color constants are updated, and asset declarations are broadened. The changes focus on enhancing user interaction and code modularity.

## Changes

| File(s)                                                                                   | Change Summary                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
|-------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| assets/data/payment_methods.json, pubspec.yaml                                            | Added a new JSON data file mapping currencies to payment methods; updated asset declaration to include the whole data directory.                                                                                                                                                                                                                                                                                                                                                                   |
| lib/core/app_theme.dart                                                                  | Updated several color constants for green and red tones to new hex values.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| lib/features/home/screens/home_screen.dart                                               | Repositioned the AddOrderButton from the Scaffold's floatingActionButton to a manually positioned widget inside a Stack.                                                                                                                                                                                                                                                                                                                                                                           |
| lib/features/order/providers/payment_methods_provider.dart                               | Added new Riverpod providers to load, select, and customize payment methods per currency.                                                                                                                                                                                                                                                                                                                                                                                                          |
| lib/features/order/screens/add_order_screen.dart                                         | Major refactor: unified buy/sell order forms, modularized UI into separate widgets, streamlined state management, improved validation, and enhanced order submission logic.                                                                                                                                                                                                                                                                                                                        |
| lib/features/order/widgets/action_buttons.dart                                           | Added new ActionButtons widget with Cancel and Submit buttons, integrating with order state and actions.                                                                                                                                                                                                                                                                                                                                                                                           |
| lib/features/order/widgets/amount_section.dart, .../currency_section.dart, .../form_section.dart, .../lightning_address_section.dart, .../order_type_header.dart, .../payment_methods_section.dart, .../premium_section.dart, .../price_type_section.dart | Added modular widgets for each order form section: amount input, currency selection, form section layout, lightning address input, order type header, payment methods selection, premium slider, and price type toggle.                                                                                                                                                                                                                                   |
| lib/shared/widgets/add_order_button.dart                                                 | Refactored AddOrderButton from a stateless to a stateful widget with animated expandable menu for BUY/SELL, including navigation and appear/disappear animations.                                                                                                                                                                                                                                                                                                                                 |
| lib/shared/providers/exchange_service_provider.dart                                     | Changed selectedFiatCodeProvider to non-nullable with default 'USD' initial value.                                                                                                                                                                                                                                                                                                                                                                                                                 |
| lib/shared/widgets/currency_combo_box.dart                                              | Simplified null checks when accessing currencyCodes with selectedFiatCode.                                                                                                                                                                                                                                                                                                                                                                                                                         |
| lib/data/models/order.dart                                                              | Modified Order model to support a list of payment methods instead of a single string, updated serialization/deserialization, and added copyWith method.                                                                                                                                                                                                                                                                                                                                          |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant AddOrderButton
    participant Navigator

    User->>AddOrderButton: Tap floating action button
    AddOrderButton->>AddOrderButton: Animate menu open/close
    User->>AddOrderButton: Tap BUY or SELL button
    AddOrderButton->>Navigator: Navigate to /add_order with order type
sequenceDiagram
    participant User
    participant AddOrderScreen
    participant Providers
    participant OrderNotifier

    User->>AddOrderScreen: Fill out order form sections
    AddOrderScreen->>Providers: Fetch currencies, payment methods, etc.
    User->>AddOrderScreen: Tap Submit
    AddOrderScreen->>OrderNotifier: Validate and submit order
    OrderNotifier-->>AddOrderScreen: Success or error response
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement fixed buttons for quick buy/sell (#88)
Add appear/disappear animations (#88)
Connect with navigation to go to the order creation screen (#88)
Ensure buttons are correctly positioned on all screens (#88)

Poem

A button now floats with a magical spin,
Tap it and watch—BUY or SELL can begin!
With colors refreshed and forms made anew,
Payment methods for every currency too.
Quick actions for bunnies who trade on the fly—
Hop, hop, hooray! Give this update a try!
🐇✨


<!-- walkthrough_end -->

<!-- announcements_start -->

> [!NOTE]
> <details>
> <summary>⚡️ AI Code Reviews for VS Code, Cursor, Windsurf</summary>
> 
> CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
> Learn more [here](http://coderabbit.ai/ide).
> 
> </details>

---

> [!NOTE]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 30th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=MostroP2P/mobile&utm_content=103):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@AndreaDiazCorreia

Copy link
Copy Markdown
Member Author

@grunch @Catrya Try it out when you can, there are a couple of things regarding the design, but I'm making the changes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 12

🧹 Nitpick comments (17)
assets/data/payment_methods.json (1)

1-20: Well-structured payment methods data

The JSON structure provides a comprehensive mapping of currency codes to their respective payment methods, with a sensible default fallback. This organization allows for easy extensibility and maintenance.

Consider adding comments in the JSON to document when this data was last updated and potentially where to find canonical sources for payment methods by region, which could help with future maintenance.

lib/features/order/widgets/order_type_header.dart (1)

4-36: Clean, reusable header component

The OrderTypeHeader widget is well-implemented with appropriate styling and text conditionally based on the order type. The use of a dedicated widget improves reusability and code organization.

Consider extracting the color value Color(0xFF1E2230) to a constant in your theme file for better maintainability and consistency.

- color: Color(0xFF1E2230),
+ color: AppTheme.headerBackgroundDark, // Define this in your theme
lib/features/order/widgets/lightning_address_section.dart (1)

4-29: Well-structured form section component

The LightningAddressSection widget is well-implemented with clear separation of concerns and appropriate reuse of the FormSection widget. The optional nature of the field is clearly communicated to users.

Consider adding validation for Lightning addresses to ensure they follow the correct format (usually in the form of user@domain.com).

 child: TextField(
   controller: controller,
   style: const TextStyle(color: Colors.white),
+  onChanged: (value) {
+    // Basic Lightning address validation
+    final isValid = value.isEmpty || value.contains('@');
+    // Update validation state if needed
+  },
   decoration: const InputDecoration(
     border: InputBorder.none,
     hintText: 'Enter lightning address',
     hintStyle: TextStyle(color: Colors.grey),
   ),
 ),
lib/features/home/screens/home_screen.dart (1)

80-84: Consider device adaptability for button positioning

The fixed positioning may not adapt well to different screen sizes or when the keyboard is shown. Consider using MediaQuery to adjust positioning based on screen dimensions.

 Positioned(
-  bottom: 100,
+  bottom: MediaQuery.of(context).size.height > 700 ? 100 : 80,
   right: 16,
   child: const AddOrderButton(),
 ),
lib/features/order/widgets/form_section.dart (1)

1-68: Good job creating this reusable FormSection widget!

The widget provides a consistent UI container for form sections with a title, icon, and child content. This will help maintain visual consistency across the order creation screens.

A few suggestions to improve:

  1. Consider extracting hardcoded colors like Color(0xFF1E2230) and Colors.white.withOpacity(0.7) to theme constants for better maintainability
  2. Add documentation comments to explain the purpose and parameters of this widget
 import 'package:flutter/material.dart';
+import 'package:mostro_mobile/core/app_theme.dart'; // Assuming this is where theme colors are defined

+/// A reusable section container for form elements.
+/// 
+/// Displays a styled container with a title, icon in a colored circle,
+/// main content, and optional extra content below.
 class FormSection extends StatelessWidget {
   final String title;
   final Widget icon;
   final Color iconBackgroundColor;
   final Widget child;
   final Widget? extraContent;

   const FormSection({
     super.key,
     required this.title,
     required this.icon,
     required this.iconBackgroundColor,
     required this.child,
     this.extraContent,
   });

   @override
   Widget build(BuildContext context) {
     return Container(
       decoration: BoxDecoration(
-        color: const Color(0xFF1E2230),
+        color: Theme.of(context).colorScheme.surface, // Or appropriate theme color
         borderRadius: BorderRadius.circular(8),
       ),
       child: Column(
         crossAxisAlignment: CrossAxisAlignment.start,
         children: [
           Padding(
             padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
             child: Text(
               title,
               style: TextStyle(
-                color: Colors.white.withOpacity(0.7),
+                color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
                 fontSize: 14,
               ),
             ),
           ),
lib/features/order/widgets/action_buttons.dart (2)

5-15: Review the currentRequestId parameter necessity

The currentRequestId parameter is marked as nullable (int?) but is required in the constructor. If it's truly optional, consider making it optional in the constructor as well.

 class ActionButtons extends StatelessWidget {
   final VoidCallback onCancel;
   final VoidCallback onSubmit;
-  final int? currentRequestId;
+  final int? currentRequestId; // ID to track button state

   const ActionButtons({
     super.key,
     required this.onCancel,
     required this.onSubmit,
-    required this.currentRequestId,
+    this.currentRequestId,
   });

1-55: Extract hardcoded colors to theme constants

Consider using theme colors or defined constants instead of hardcoded hex values for better maintainability and consistency.

 import 'package:flutter/material.dart';
 import 'package:mostro_mobile/data/models/enums/action.dart' as nostr_action;
 import 'package:mostro_mobile/shared/widgets/mostro_reactive_button.dart';
+import 'package:mostro_mobile/core/app_theme.dart'; // Assuming this is where theme colors are defined

+/// A widget that displays Cancel and Submit buttons for order creation.
 class ActionButtons extends StatelessWidget {
   // ... existing code

   @override
   Widget build(BuildContext context) {
+    final theme = Theme.of(context);
+    
     return Row(
       mainAxisAlignment: MainAxisAlignment.spaceBetween,
       children: [
         Expanded(
           child: ElevatedButton(
             onPressed: onCancel,
             style: ElevatedButton.styleFrom(
-              backgroundColor: const Color(0xFF1E2230),
+              backgroundColor: theme.colorScheme.surface, // Or appropriate theme color
               foregroundColor: Colors.white,
               padding: const EdgeInsets.symmetric(vertical: 12),
               shape: RoundedRectangleBorder(
                 borderRadius: BorderRadius.circular(24),
               ),
             ),
             child: const Text('Cancel'),
           ),
         ),
         // ... rest of the code

               timeout: const Duration(seconds: 5),
               showSuccessIndicator: true,
-              backgroundColor: const Color(0xFF7856AF),
+              backgroundColor: theme.colorScheme.primary, // Or appropriate theme color
             ),
lib/features/order/widgets/premium_section.dart (1)

78-79: Consider fewer slider divisions for smoother interaction

Using 200 divisions for a range of -10 to 10 results in increments of 0.1, which might be unnecessarily precise for premium percentages and could make the slider less smooth. Consider reducing the number of divisions.

                   child: Slider(
                     value: value,
                     min: -10,
                     max: 10,
-                    divisions: 200,
+                    divisions: 40, // Increments of 0.5% are likely sufficient
                     onChanged: onChanged,
                   ),
lib/features/order/widgets/price_type_section.dart (1)

52-68: Improve Switch and Label arrangement

The current arrangement has the "Market" label before the switch, which might be confusing. Consider placing the label after the switch or using a more descriptive approach to clearly indicate what each state represents.

                 Row(
                   children: [
+                    Switch(
+                      value: isMarketRate,
+                      activeColor: const Color(0xFF764BA2),
+                      onChanged: onToggle,
+                    ),
                     Text(
-                      'Market',
+                      isMarketRate ? 'Market' : 'Custom',
                       style: TextStyle(
                         color: isMarketRate
                             ? const Color(0xFF8CC63F)
                             : Colors.grey,
                         fontSize: 14,
                       ),
                     ),
-                    Switch(
-                      value: isMarketRate,
-                      activeColor: const Color(0xFF764BA2),
-                      onChanged: onToggle,
-                    ),
                   ],
                 ),
lib/shared/widgets/add_order_button.dart (3)

55-57: Hard-coded size limits flexibility on tablets & landscape

SizedBox(height: 130, width: 200) forces a fixed footprint that may clip or float awkwardly on large or very small screens.
Prefer IntrinsicHeight, IntrinsicWidth, or ConstrainedBox with max constraints (or remove the wrapper and rely on Align / Padding) so the widget adapts naturally to its surroundings.


64-70: Minor layout nit – residual gap when the menu is closed

margin: const EdgeInsets.only(bottom: 10) is applied even when the menu height is 0, leaving a visible 10 px gap beneath the collapsed FAB. Consider animating the margin together with the height:

-            margin: const EdgeInsets.only(bottom: 10),
+            margin: EdgeInsets.only(bottom: _isMenuOpen ? 10 : 0),

120-130: Accessibility: expose a semantic label for the FAB

Screen-reader users cannot know what the FAB does because no semantics are provided. Wrap the FloatingActionButton in a Semantics widget or set tooltip on the FAB so assistive technologies announce “Add order menu”.

   FloatingActionButton(
     onPressed: _toggleMenu,
+    tooltip: 'Create order',
lib/features/order/widgets/currency_section.dart (1)

16-18: Minor: defaulting silently to USD can hide configuration errors

If selectedFiatCodeProvider unexpectedly returns null, the widget silently falls back to "USD", masking the underlying state problem.
Consider asserting or logging a warning so the issue surfaces during development.

lib/features/order/widgets/amount_section.dart (1)

33-34: Keyboard type: number improves UX

TextInputType.text shows the full keyboard, yet only digits (and an optional dash) are expected.
Using TextInputType.numberWithOptions(signed: true) keeps the numeric keypad while still allowing “-” on iOS.

-        keyboardType: TextInputType.text,
+        keyboardType: const TextInputType.numberWithOptions(signed: true),
lib/core/app_theme.dart (1)

7-16: Duplicate colour constants make maintenance harder

mostroGreen, buyColor, activeColor, and statusActive all carry the same hex value (0xFF9CD651).
Keeping multiple aliases for the exact same colour increases the chance that future tweaks forget to update all of them.

Consider picking a single source-of-truth constant (e.g. mostroGreen) and alias the others:

static const Color buyColor    = mostroGreen;
static const Color activeColor = mostroGreen;
static const Color statusActive = mostroGreen;

That way, a palette change only needs to be performed in one place.

lib/features/order/widgets/payment_methods_section.dart (1)

101-112: Minor: nested StatefulBuilder is unnecessary

The outer StatefulBuilder already gives you setDialogState.
Embedding a second StatefulBuilder for the custom text field adds complexity without benefit.

You can safely remove the inner builder and call setDialogState from the outer scope if needed.

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

245-251: Duplicate “Other” token in the concatenated payment methods

When the user selects “Other” and provides a custom value, the final string becomes
"Bank Transfer, Other, MyCustomMethod".

Consider dropping "Other" if a concrete custom method is supplied:

 List<String> paymentMethods = List<String>.from(_selectedPaymentMethods);
 if (_showCustomPaymentMethod &&
     _customPaymentMethodController.text.isNotEmpty) {
-  paymentMethods.add(_customPaymentMethodController.text);
+  paymentMethods
+    ..remove('Other')
+    ..add(_customPaymentMethodController.text);
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5563241 and 5d1c0a1.

📒 Files selected for processing (16)
  • assets/data/payment_methods.json (1 hunks)
  • lib/core/app_theme.dart (2 hunks)
  • lib/features/home/screens/home_screen.dart (1 hunks)
  • lib/features/order/providers/payment_methods_provider.dart (1 hunks)
  • lib/features/order/screens/add_order_screen.dart (2 hunks)
  • lib/features/order/widgets/action_buttons.dart (1 hunks)
  • lib/features/order/widgets/amount_section.dart (1 hunks)
  • lib/features/order/widgets/currency_section.dart (1 hunks)
  • lib/features/order/widgets/form_section.dart (1 hunks)
  • lib/features/order/widgets/lightning_address_section.dart (1 hunks)
  • lib/features/order/widgets/order_type_header.dart (1 hunks)
  • lib/features/order/widgets/payment_methods_section.dart (1 hunks)
  • lib/features/order/widgets/premium_section.dart (1 hunks)
  • lib/features/order/widgets/price_type_section.dart (1 hunks)
  • lib/shared/widgets/add_order_button.dart (1 hunks)
  • pubspec.yaml (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (2)
pubspec.yaml (1)

116-116: Asset declaration improvement

The asset declaration has been broadened to include the entire assets/data/ directory rather than listing individual files. This is a good practice that simplifies the addition of new data files without requiring pubspec.yaml modifications each time.

lib/features/home/screens/home_screen.dart (1)

24-86: Improved button positioning for enhanced UI interactions

The floating action button has been repositioned using a Stack and Positioned widget instead of the Scaffold's floatingActionButton property. This change supports the new expandable menu behavior and provides precise control over button placement.

Comment thread lib/features/home/screens/home_screen.dart Outdated
Comment thread lib/features/order/widgets/action_buttons.dart
Comment thread lib/features/order/widgets/premium_section.dart
Comment thread lib/features/order/widgets/price_type_section.dart
Comment thread lib/shared/widgets/add_order_button.dart
Comment thread lib/features/order/widgets/amount_section.dart
Comment thread lib/features/order/providers/payment_methods_provider.dart Outdated
Comment thread lib/features/order/widgets/payment_methods_section.dart
Comment thread lib/features/order/widgets/payment_methods_section.dart Outdated
Comment thread lib/features/order/screens/add_order_screen.dart
@grunch grunch requested review from Catrya, chebizarro and grunch May 21, 2025 12:30

@grunch grunch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Great work @AndreaDiazCorreia I would like to change some things like, when the user mark Other in payment method, the payment method doesn't include the word Other, but I think we can merge this and fix it later.

This is a tACK !

@grunch

grunch commented May 21, 2025

Copy link
Copy Markdown
Member

Another issue I found on this implementation is that when you create an order USD is the default fiat currency apparently selected but if you want to use USD and just leave that dropdown and keep filling the other elements of the form when submit the app will tell you that you didn't select a fiat currency.

Also we need to add a filter to select a currency, we have 137 fiat currencies to show and we can't filter as we can do with the current version of the app.

@AndreaDiazCorreia Can you fix this before merge please?

@Catrya Catrya left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hola @AndreaDiazCorreia, buen trabajo!

  • El botón de Market/Fixed no funciona, ese es importante. Por defecto está Market pero si el usuario lo desactiva y pasa a Fixed, se debe cambiar la barra del Premium % por la de "Enter the Sats amount you want to Sell" como está en lovable

  • En los métodos de pago de USD no debe estar Cash, LA meetup, eso fue solo un ejemplo que puse en lovable para que se viera que un usuario podía poner lo que quisiera en una orden

  • Faltan los textos de los botones de info, creo que si no se van a poner ahora entonces se debería quitar el icono de info, pero lo idel es que sí esté todo eso.

  • Para seleccionar el fiat debería dejarse además de la lista, que arriba el usuario pudiera escribirla para no scrolear mucho, como está actualmente en la app. (disculpa que en lovable no estuviera exactamente así)

@grunch

grunch commented May 21, 2025

Copy link
Copy Markdown
Member

Something that I just realize, it is really nice that the app allows to the user to select payment methods, but if the user select various methods we should follow NIP-69 which is an standard attempt

For an event with three methods lemon, belo, mp and a custom like pepita coin, we send the event with the pm tag like this

    ["pm", "lemon", "belo", "mp", "pepita coin"],

You can read the NIP 69 for a better understanding and a complete example

https://github.com/nostr-protocol/nips/blob/master/69.md

return jsonDecode(response) as Map<String, dynamic>;
});

// Proveedor para obtener los métodos de pago basados en la moneda seleccionada

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi @AndreaDiazCorreia remember always write comments in english please

@Catrya

Catrya commented May 22, 2025

Copy link
Copy Markdown
Member

Hola @AndreaDiazCorreia esto no tiene prioridad alta, no es imprescindible para mergear este PR, pero si te da tiempo hacerlo estaría genial, si no, no hay problema y se deja para luego:

  • En los botones de Buy y Sell poner las flechas del mismo color del texto (hora están un poco más claras que el texto)
  • En la barra del % de prima o descuento, dejar solo números enteros cuando el usuario desliza, no fraccionarios como ahora

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
lib/features/order/screens/add_order_screen.dart (1)

233-244: False “no currency selected” error when the user keeps the default

As discussed above, selectedFiatCodeProvider may still hold null even though USD is visibly selected by default, causing this guard to block form submission.

Once the provider default is fixed (see CurrencySection.dart review), remove this defensive branch or change the condition to:

-      if (selectedFiatCode == null || selectedFiatCode.isEmpty) {
+      if (selectedFiatCode.trim().isEmpty) {
lib/features/order/providers/payment_methods_provider.dart (1)

38-44: Initial empty list instance is now recreated per notifier – previous concern resolved

SelectedPaymentMethodsNotifier constructs a new list in its constructor, so the shared-mutable-list problem highlighted earlier no longer applies. 👍

🧹 Nitpick comments (5)
lib/features/order/widgets/currency_section.dart (1)

20-24: Inconsistent capitalisation (“Fiat” vs “fiat”)

Minor, but user-facing strings should be consistent to avoid looking like typos.

Suggestion: keep “fiat” lower-case in both sentences.

lib/shared/widgets/add_order_button.dart (2)

60-66: Code comments are in Spanish – stick to project language (English)

Maintain consistency so every contributor can understand inline documentation.

-      height: 130, // Altura suficiente para mostrar ambos elementos
-      width: 200, // Ancho suficiente para los botones
+      height: 130, // Enough height to display both menu items
+      width: 200,  // Enough width for the buttons

60-71: Hard-coded size may clip on very small or tablet devices

Pinning the FAB container to height: 130, width: 200 risks overflow or an odd amount of empty space depending on text scale and layout.

Consider using IntrinsicHeight/IntrinsicWidth or SizedBox.shrink() together with AnimatedSize so the widget adapts to its content:

-    return SizedBox(
-      height: 130,
-      width: 200,
+    return AnimatedSize(
+      duration: const Duration(milliseconds: 200),
+      child: ConstrainedBox(
+        constraints: const BoxConstraints(minWidth: 56, minHeight: 56),
lib/features/order/screens/add_order_screen.dart (1)

170-193: Numeric validation is too lax for sats amount

int.tryParse silently converts “-1”, “0”, or huge values; the validator only checks presence.

Enhance validation:

validator: (value) {
  if (!_marketRate) {
-   if (value == null || value.isEmpty) {
-     return 'Please enter sats amount';
-   }
+   final parsed = int.tryParse(value ?? '');
+   if (parsed == null || parsed <= 0) {
+     return 'Enter a positive integer amount';
+   }
  }
  return null;
},

Also guard against huge numbers (> 2.1e15) to avoid int overflow on 32-bit platforms.

lib/features/order/providers/payment_methods_provider.dart (1)

18-26: Provider returns a mutable list – callers can accidentally tamper with shared state

Although you clone the JSON array (List.from(...)), you then add('Other'), returning a growable list that widgets might mutate in-place.

To keep data immutable:

-        final methods = List<String>.from(data[currencyCode]);
-        if (!methods.contains('Other')) {
-          methods.add('Other');
-        }
-        return methods;
+        final raw = List<String>.from(data[currencyCode]);
+        final withOther = raw.contains('Other') ? raw : [...raw, 'Other'];
+        return List.unmodifiable(withOther);

Same applies to the default branch.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b762ef3 and a2b4c9e.

⛔ Files ignored due to path filters (1)
  • lib/generated/l10n.dart is excluded by !**/generated/**
📒 Files selected for processing (8)
  • lib/features/order/providers/payment_methods_provider.dart (1 hunks)
  • lib/features/order/screens/add_order_screen.dart (2 hunks)
  • lib/features/order/widgets/amount_section.dart (1 hunks)
  • lib/features/order/widgets/currency_section.dart (1 hunks)
  • lib/features/order/widgets/payment_methods_section.dart (1 hunks)
  • lib/features/order/widgets/premium_section.dart (1 hunks)
  • lib/features/order/widgets/price_type_section.dart (1 hunks)
  • lib/shared/widgets/add_order_button.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • lib/features/order/widgets/price_type_section.dart
  • lib/features/order/widgets/premium_section.dart
  • lib/features/order/widgets/amount_section.dart
  • lib/features/order/widgets/payment_methods_section.dart
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release

Comment thread lib/features/order/widgets/currency_section.dart
Comment thread lib/features/order/widgets/currency_section.dart Outdated
Comment thread lib/features/order/screens/add_order_screen.dart

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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/order/screens/add_order_screen.dart (1)

274-282: ⚠️ Potential issue

Fix payment methods encoding for NIP-69 compliance.

The current implementation joins payment methods into a single comma-separated string, which doesn't comply with the NIP-69 standard mentioned by reviewer @grunch. According to NIP-69, payment methods should be encoded as separate tags.

-final paymentMethod = paymentMethods.join(', ');
-
-final order = Order(
-  kind: _orderType,
-  fiatCode: selectedFiatCode,
-  fiatAmount: fiatAmount!,
-  minAmount: minAmount,
-  maxAmount: maxAmount,
-  paymentMethod: paymentMethod,
+// Store payment methods as a list for proper NIP-69 encoding
+
+final order = Order(
+  kind: _orderType,
+  fiatCode: selectedFiatCode,
+  fiatAmount: fiatAmount!,
+  minAmount: minAmount,
+  maxAmount: maxAmount,
+  paymentMethods: paymentMethods, // Order model needs to be updated to accept List<String>

This will require updating the Order model to accept a List<String> for payment methods, and ensuring the event creation logic properly encodes them according to NIP-69.

🧹 Nitpick comments (2)
lib/features/order/screens/add_order_screen.dart (2)

160-169: Restrict premium slider to integer values only.

According to reviewer @Catrya's suggestion, the percentage slider for premium or discount should restrict input to integer values only, avoiding fractional numbers when the user slides.

The PremiumSection widget should be modified to ensure only integer values are accepted. This is a non-blocking UI refinement.


235-243: Remove redundant empty check for selectedFiatCode.

Since selectedFiatCodeProvider now defaults to 'USD' and is non-nullable, this check for an empty string is redundant and can be removed.

-if (selectedFiatCode.isEmpty) {
-  ScaffoldMessenger.of(context).showSnackBar(
-    const SnackBar(
-      content: Text('Please select a currency'),
-      duration: Duration(seconds: 2),
-    ),
-  );
-  return;
-}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a2b4c9e and bb3fff3.

📒 Files selected for processing (5)
  • lib/features/order/screens/add_order_screen.dart (2 hunks)
  • lib/features/order/widgets/currency_section.dart (1 hunks)
  • lib/features/order/widgets/payment_methods_section.dart (1 hunks)
  • lib/shared/providers/exchange_service_provider.dart (1 hunks)
  • lib/shared/widgets/currency_combo_box.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/order/widgets/currency_section.dart
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (6)
lib/shared/providers/exchange_service_provider.dart (1)

30-30: LGTM: Default fiat code implemented correctly.

The change from nullable StateProvider<String?> to non-nullable StateProvider<String> with a default value of 'USD' addresses the currency selection issue mentioned in PR comments. This ensures a currency is always selected.

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

71-73: Null check simplification is appropriate.

The removal of the null check for selectedFiatCode aligns with the provider change making it non-nullable. This simplification improves code readability while maintaining the same functionality.

lib/features/order/widgets/payment_methods_section.dart (3)

84-89: LGTM: Overflow property is correctly placed.

The Text widget correctly uses overflow property. This addresses the previously identified issue mentioned in the past review comments.


158-174: LGTM: Controller usage is correct.

The TextField now directly uses the existing controller that's passed from the parent, avoiding memory leaks and cursor position issues that were flagged in previous reviews.


50-66:

Details

❓ Verification inconclusive

Add filtering for fiat currencies dropdown.

The reviewer @grunch pointed out that a filtering mechanism for the currency selection dropdown is needed, as the app currently lists 137 fiat currencies without any filter. This component doesn't appear to implement that filtering functionality.


🏁 Script executed:

#!/bin/bash
# Check if there's a separate currency filtering implementation elsewhere
rg "currency.*filter" --type dart

Length of output: 35


Ensure filtering for the fiat‐currency dropdown

I wasn’t able to find any existing search or filter logic for the fiat currency selector—users currently have to scroll through all 137 currencies. Please add a text‐based filter (or searchable dropdown) so users can quickly narrow the list.

• Location to update:

  • lib/features/order/widgets/payment_methods_section.dart (around the DropdownButton/currency selector that sets selectedFiatCode)

• Suggested approach:

  • Wrap the currency list in a List<String> and apply .where(...) based on a search field.
  • Consider using a package like dropdown_search or a custom TextField + ListView combo.
lib/features/order/screens/add_order_screen.dart (1)

177-192: LGTM: Fixed sats amount controller now properly connected.

The _satsAmountController is now correctly attached to a TextFormField with proper validation, resolving the previous issue where it was declared but never used.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
lib/features/order/widgets/currency_section.dart (1)

32-39: ⚠️ Potential issue

UI shows USD by default but provider may be null

The code shows 'USD' as default in the UI even when selectedFiatCode is null, which creates inconsistency between what the user sees and what the system stores. To fix this, initialize the provider with 'USD' or set it when building this widget.

-    final selectedFiatCode = ref.watch(selectedFiatCodeProvider);
+    final selectedFiatCodeNotifier = ref.read(selectedFiatCodeProvider.notifier);
+    final selectedFiatCode = ref.watch(selectedFiatCodeProvider) ?? 'USD';
+    
+    // Initialize with default if null
+    if (selectedFiatCodeNotifier.state == null) {
+      selectedFiatCodeNotifier.state = 'USD';
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb3fff3 and d3b45ec.

📒 Files selected for processing (3)
  • lib/data/models/order.dart (11 hunks)
  • lib/features/order/screens/add_order_screen.dart (2 hunks)
  • lib/features/order/widgets/currency_section.dart (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (15)
lib/data/models/order.dart (9)

16-16: Changed the paymentMethod field to a list of strings

The change from a single string to a List for payment methods aligns with the requirement to support multiple payment methods selection. This modification follows good practices by properly updating all related methods and maintaining backward compatibility.


37-48: Constructor updated to handle payment methods list

The constructor now properly accepts and defensively copies the payment methods list, which is good practice. This ensures that modifications to the original list won't affect the Order instance.


61-61: JSON serialization updated for payment methods list

The toJson method now correctly serializes the payment methods as a list rather than a single string.


93-94: Updated validation for required fields

The validation list now includes 'payment_methods' instead of 'payment_method', which is consistent with the model changes.


96-107: Robust backward compatibility for payment methods

The implementation effectively handles multiple formats for payment methods:

  • List of strings
  • Single comma-separated string
  • Legacy 'payment_method' field

This ensures smooth transitions from older app versions and prevents data loss.


140-140: Updated fromEvent factory to use payment methods list

The factory constructor now correctly uses the event's payment methods list property.


157-157: Updated toMap to handle payment methods list

The toMap method now properly includes the payment methods list, maintaining consistency across all serialization methods.


171-182: Consistent deserialization in fromMap method

The fromMap method applies the same robust backward compatibility logic as fromJson, handling various formats of payment methods data. This ensures consistency across all deserialization paths.


208-230: Updated copyWith method to handle payment methods list

The copyWith method now properly includes the payment methods list, ensuring all model properties are maintained during partial updates.

lib/features/order/widgets/currency_section.dart (3)

67-70: Currency search implemented correctly

The search functionality for currencies has been properly implemented with a text field that dynamically filters the currency list, addressing @grunch's concern about navigating through 137 currencies.


179-185: Currency selection callback executed correctly

The onCurrencySelected callback is now executed after updating the provider state and before closing the dialog, ensuring that listeners receive the new selection. This addresses the issue mentioned in previous reviews.


16-17:

Details

❌ Incorrect review comment

Currency selection issue may persist

Although the UI shows 'USD' as default, the provider may still be null initially. If a user leaves the dropdown unchanged, this could cause the validation failure mentioned by @grunch in the PR comments.


🏁 Script executed:

#!/bin/bash
# Check how selectedFiatCodeProvider is defined in the provider file
rg "selectedFiatCodeProvider" lib/shared/providers/exchange_service_provider.dart

Length of output: 153


selectedFiatCodeProvider always initialized to ‘USD’
The StateProvider<String> for selectedFiatCodeProvider is defined with an initial value of 'USD', so ref.watch(selectedFiatCodeProvider) can never be null. The previous concern about a null provider can be disregarded.

Likely an incorrect or invalid review comment.

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

31-32: Sats amount controller now properly connected

The _satsAmountController is now correctly wired to a TextFormField (lines 177-192) that appears when fixed price is selected. This resolves the issue from the previous review.


177-193: Fixed price sats amount input implemented correctly

The TextFormField for entering sats amount when using fixed price is properly implemented with validation that ensures a value is entered only when market rate is disabled.


290-300: Order creation with multiple payment methods

The Order constructor is now called with the payment methods list directly, which is consistent with the updated Order model. This ensures that multiple payment methods are properly stored and can be encoded according to NIP-69 later.

Comment on lines +274 to +284
// Preparar la lista de métodos de pago para cumplir con NIP-69
List<String> paymentMethods =
List<String>.from(_selectedPaymentMethods);
if (_showCustomPaymentMethod &&
_customPaymentMethodController.text.isNotEmpty) {
paymentMethods.add(_customPaymentMethodController.text);
}

// Cada método de pago se mantiene como un elemento separado en la lista
// en lugar de concatenarlos en una cadena

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

NIP-69 compliance for payment methods

The code now properly maintains payment methods as a list of separate items rather than concatenating them into a string. This is the first step toward NIP-69 compliance, which requires each payment method to be emitted as a separate ["pm", "<method>"] tag.


🏁 Script executed:

#!/bin/bash
# Check if event creation code properly handles NIP-69 tagging
rg -A 10 "createEvent|pm" lib/ --glob "**event**"

Length of output: 947


Update NIP-69 payment method tagging in both parsing and creation

To achieve full NIP-69 compliance you need to:

  • lib/data/models/nostr_event.dart
    • Replace the comma-based getter

    List<String> get paymentMethods =>
      _getTagValue('pm')?.split(',') ?? [];

    with a multi-tag reader, e.g.:

    List<String> get paymentMethods => _getTagValues('pm') ?? [];

    (ensure you implement or expose a _getTagValues('pm') that returns all “pm” tag values.)

  • Your event builder (wherever you call createEvent or assemble the tags list)
    • Emit each payment method as its own tag instead of joining them:

    tags: [
      ..._selectedPaymentMethods.map((m) => ['pm', m]),
      if (_showCustomPaymentMethod && _customPaymentMethodController.text.isNotEmpty)
        ['pm', _customPaymentMethodController.text],
      // …other tags
    ],

Remove any logic that concatenates payment methods into a single comma-separated string.

🤖 Prompt for AI Agents
In lib/features/order/screens/add_order_screen.dart around lines 274 to 284,
update the event creation code to emit each payment method as a separate ['pm',
method] tag instead of concatenating them into a single string. Replace any
logic that joins payment methods with commas by mapping each selected payment
method to its own tag array, and include the custom payment method similarly if
present. Also, ensure the event model's getter for payment methods uses a
multi-tag reader like _getTagValues('pm') to retrieve all 'pm' tags
individually.

Comment on lines +231 to +243
void _submitOrder() {
if (_formKey.currentState?.validate() ?? false) {
final selectedFiatCode = ref.read(selectedFiatCodeProvider);

// 1) Currency dropdown always enabled
CurrencyComboBox(
key: const Key('fiatCodeDropdown'),
label: 'Fiat code',
onSelected: (String fiatCode) {
setState(() {
_isEnabled = true;
});
},
if (selectedFiatCode.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select a currency'),
duration: Duration(seconds: 2),
),
);
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Currency selection validation still has an issue

The validation checks if selectedFiatCode is empty but doesn't initialize it with a default value. This likely causes the bug reported by @grunch where users are prompted about missing currency selection even though USD appears selected in the UI.

-  final selectedFiatCode = ref.read(selectedFiatCodeProvider);
+  // Ensure we have a selected currency, defaulting to USD if none is set
+  final selectedFiatCodeNotifier = ref.read(selectedFiatCodeProvider.notifier);
+  if (selectedFiatCodeNotifier.state == null || selectedFiatCodeNotifier.state!.isEmpty) {
+    selectedFiatCodeNotifier.state = 'USD';
+  }
+  final selectedFiatCode = selectedFiatCodeNotifier.state!;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
void _submitOrder() {
if (_formKey.currentState?.validate() ?? false) {
final selectedFiatCode = ref.read(selectedFiatCodeProvider);
// 1) Currency dropdown always enabled
CurrencyComboBox(
key: const Key('fiatCodeDropdown'),
label: 'Fiat code',
onSelected: (String fiatCode) {
setState(() {
_isEnabled = true;
});
},
if (selectedFiatCode.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select a currency'),
duration: Duration(seconds: 2),
),
);
return;
}
void _submitOrder() {
if (_formKey.currentState?.validate() ?? false) {
// Ensure we have a selected currency, defaulting to USD if none is set
final selectedFiatCodeNotifier = ref.read(selectedFiatCodeProvider.notifier);
if (selectedFiatCodeNotifier.state == null || selectedFiatCodeNotifier.state!.isEmpty) {
selectedFiatCodeNotifier.state = 'USD';
}
final selectedFiatCode = selectedFiatCodeNotifier.state!;
if (selectedFiatCode.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Please select a currency'),
duration: Duration(seconds: 2),
),
);
return;
}
// …rest of _submitOrder()
}
}
🤖 Prompt for AI Agents
In lib/features/order/screens/add_order_screen.dart around lines 231 to 243, the
validation checks if selectedFiatCode is empty but does not ensure it has a
default value. To fix this, initialize selectedFiatCodeProvider with a default
currency code such as 'USD' so that the validation reflects the actual UI state
and prevents incorrect prompts about missing currency selection.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
lib/features/order/notfiers/abstract_mostro_notifier.dart (1)

146-146: Consider adding null check for consistency.

While there's a null check for order at line 138 that breaks out of the switch statement, for consistency with the implementation at lines 172-174, consider adding an explicit null check here as well.

-          'payment_method': _formatPaymentMethods(order.paymentMethods),
+          'payment_method': order != null
+              ? _formatPaymentMethods(order.paymentMethods)
+              : 'No payment method',
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3b45ec and 4d60673.

📒 Files selected for processing (11)
  • assets/data/payment_methods.json (1 hunks)
  • lib/core/app_theme.dart (2 hunks)
  • lib/features/order/notfiers/abstract_mostro_notifier.dart (3 hunks)
  • lib/features/order/screens/add_order_screen.dart (2 hunks)
  • lib/features/order/widgets/action_buttons.dart (1 hunks)
  • lib/features/order/widgets/amount_section.dart (1 hunks)
  • lib/features/order/widgets/form_section.dart (1 hunks)
  • lib/features/order/widgets/premium_section.dart (1 hunks)
  • lib/features/order/widgets/price_type_section.dart (1 hunks)
  • lib/features/trades/screens/trade_detail_screen.dart (4 hunks)
  • lib/features/trades/widgets/mostro_message_detail_widget.dart (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • assets/data/payment_methods.json
  • lib/features/order/widgets/form_section.dart
  • lib/features/order/widgets/premium_section.dart
  • lib/features/order/widgets/action_buttons.dart
  • lib/features/order/widgets/price_type_section.dart
  • lib/features/order/widgets/amount_section.dart
  • lib/core/app_theme.dart
  • lib/features/order/screens/add_order_screen.dart
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (7)
lib/features/trades/screens/trade_detail_screen.dart (2)

104-109: Multiple payment methods support is implemented correctly.

The code now properly handles a list of payment methods, joining them with commas for display, and provides a fallback message when the list is empty.


140-140: Label updated for multiple payment methods.

Label has been correctly updated from singular "Payment method" to plural "Payment methods" to reflect the support for multiple payment methods.

lib/features/trades/widgets/mostro_message_detail_widget.dart (3)

21-34: Good implementation of payment methods formatting helper.

The helper method properly handles different scenarios:

  • Returns a clear message for empty lists
  • Returns just the method name for single payment methods
  • Returns a concise format for multiple methods showing count

This approach aligns with NIP-69 requirements mentioned in the PR comments for handling multiple payment methods.


141-144: Proper null checking for payment methods formatting.

The code correctly handles potential null values for orderPayload when formatting payment methods.


152-155: Consistent implementation of payment methods formatting.

This change correctly applies the same pattern for payment methods formatting and null checking as used elsewhere.

lib/features/order/notfiers/abstract_mostro_notifier.dart (2)

37-50: Well-implemented payment methods formatting helper.

The helper method properly handles different scenarios for payment methods formatting in notifications, consistent with the implementation in other files.


172-175: Proper null handling for payment methods in notifications.

The code correctly handles potential null values for the order object when formatting payment methods for notifications.

@chebizarro chebizarro merged commit 1313159 into MostroP2P:main May 23, 2025
1 of 2 checks passed
@Catrya

Catrya commented May 23, 2025

Copy link
Copy Markdown
Member

This shouldn't be merged, creating an order doesn't work, this is the log on my Mostro:

2025-05-23T07:07:58.736533Z ERROR mostrod::app: Failed to parse message, inner message, and signature from rumor content: missing field `payment_method` at line 1 column 338

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.

Implement Quick BUY/SELL Action Buttons

4 participants