Skip to content

Conversation

@AndreaDiazCorreia
Copy link
Member

@AndreaDiazCorreia AndreaDiazCorreia commented May 13, 2025

Summary of Changes

This PR introduces several UI updates as part of Issue #85:

  • Updated the top navigation bar.
  • Added a notifications button (currently hardcoded).
  • Redesigned the Buy BTC / Sell BTC tabs.
  • Updated the filter component design (functionality remains unchanged).
  • Updated the order item card design.
  • Modified the "Add Order" button (work in progress for a separate issue).
  • Redesigned the bottom navigation bar.

Notes

  • Consider using a lighter background color to make order cards stand out more. I attempted to match the brightness level used in the Lovable version, but wasn't able to achieve the same result using Flutter. The current appearance is acceptable, but a lighter background might enhance visibility.
  • The app_theme still needs to be adjusted to integrate these changes properly.

image

Summary by CodeRabbit

  • New Features
    • Introduced a floating action button for adding orders.
    • Added a new filter button with enhanced styling and dynamic filtered offer count.
    • Redesigned empty state with icon and explanatory text for filtered orders.
  • UI Improvements
    • Refreshed Home screen with a custom app bar, dark theme, and improved layout.
    • Modernized order list items with richer visuals, clearer labels, and enhanced rating display.
    • Updated bottom navigation bar with new icons, adaptive layout, and improved notification badges.
    • Enhanced MostroAppBar with notification badge and streamlined actions.
  • Chores
    • Added LucideIcons dependency for updated iconography.
    • Extended app theme with new color constants and reusable shadow styles.
    • Improved data model parsing and error handling for ratings, including support for a new JSON format and added "days" field.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 13, 2025

"""

Walkthrough

The changes introduce a comprehensive UI redesign for the home screen and related widgets, focusing on a consistent dark theme, enhanced visual hierarchy, and improved navigation. Key updates include a custom app bar, a floating action button for adding orders, revamped tab and filter controls, a modernized order list item, and a refactored bottom navigation bar with new iconography and styling. A new dependency for Lucide icons was added. The Rating model was extended to support a new JSON format and include a days field with improved parsing robustness. The app theme was expanded with new colors and shadow styles.

Changes

File(s) Change Summary
lib/features/home/screens/home_screen.dart Refactored HomeScreen UI: replaced MostroAppBar with a custom app bar, added a floating AddOrderButton, updated background color, modularized tab buttons, redesigned filter button, improved empty state, and streamlined layout for clarity and consistency. Added two new private methods for app bar and tab button construction.
lib/features/home/widgets/order_list_item.dart Overhauled OrderListItem: replaced GestureDetector/CustomCard with Material/InkWell for ripple effects, enhanced styling with shadows and backgrounds, improved order type and rating display, updated payment method presentation, and removed several helper methods. No changes to public interface.
lib/shared/widgets/add_order_button.dart Added new AddOrderButton widget: a floating action button with custom color, icon, and navigation to /add_order.
lib/shared/widgets/bottom_nav_bar.dart Refactored bottom navigation bar: switched to LucideIcons, used Google Fonts, updated layout to full-width dark background with adaptive height, improved icon and label styling, repositioned notification badges, and updated method signatures to use IconData and label strings.
lib/shared/widgets/mostro_app_bar.dart Modified MostroAppBar: adjusted leading icon padding and size, set leadingWidth, replaced action buttons with a single notification bell icon and badge, removed previous plus and bolt icons. No changes to public interface.
lib/core/app_theme.dart Extended AppTheme with new categorized color constants for backgrounds, text, actions, and status; updated scaffold background color; added reusable shadow styles for cards and buttons; reformatted text theme for clarity.
lib/data/models/rating.dart Extended Rating model: added required days field, enhanced deserialized factory to support new JSON format with nested list/map structure, improved parsing robustness with helper methods avoiding exceptions, updated empty factory to include days.
pubspec.yaml Added lucide_icons dependency version ^0.257.0.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant HomeScreen
    participant AddOrderButton
    participant Router

    User->>HomeScreen: Opens Home Screen
    HomeScreen->>User: Displays custom AppBar, tabs, filter, order list, AddOrderButton, bottom nav
    User->>AddOrderButton: Taps floating action button
    AddOrderButton->>Router: context.push('/add_order')
    Router-->>User: Navigates to Add Order screen
Loading

Poem

In the moonlit night, the UI took flight,
With tabs and buttons shining bright.
A floating green, a bell with six,
New icons join the rabbit’s tricks.
Shadows, fonts, and colors blend—
A stylish hop from end to end!
🐇✨
"""

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

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.


Note

⚡️ Faster reviews with caching

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 16th. 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.


📜 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 080ab21 and 35efc39.

📒 Files selected for processing (1)
  • lib/features/home/screens/home_screen.dart (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/home/screens/home_screen.dart
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • 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 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 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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (3)
pubspec.yaml (1)

67-67: Fix trailing space in dependency declaration.

There's a trailing space after the version constraint that should be removed to comply with YAML style guidelines.

-  lucide_icons: ^0.257.0 
+  lucide_icons: ^0.257.0
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 67-67: trailing spaces

(trailing-spaces)

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

32-72: Consider parameterizing the notification count.

The notification count "6" is currently hardcoded. Consider making this a parameter to allow dynamic updates based on actual notification count.

-                    '6',
+                    '$notificationCount',

You might want to add a parameter to the MostroAppBar constructor:

const MostroAppBar({super.key, this.notificationCount = 0});
final int notificationCount;
lib/features/home/widgets/order_list_item.dart (1)

207-210: Consider making the payment method emoji dynamic.

The payment method section uses a hardcoded emoji ('💳') which doesn't reflect the actual payment method type.

-    const Text(
-      '💳 ', // Default emoji
-      style: TextStyle(fontSize: 16),
-    ),
+    Text(
+      _getPaymentMethodEmoji(order.paymentMethods.isNotEmpty ? order.paymentMethods[0] : 'tm'),
+      style: const TextStyle(fontSize: 16),
+    ),

Add this helper method:

String _getPaymentMethodEmoji(String paymentMethod) {
  // Map payment methods to appropriate emojis
  switch(paymentMethod.toLowerCase()) {
    case 'bank': return '🏦 ';
    case 'cash': return '💵 ';
    // Add more cases as needed
    default: 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 7ac001c and 7323087.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • lib/features/home/screens/home_screen.dart (2 hunks)
  • lib/features/home/widgets/order_list_item.dart (1 hunks)
  • lib/shared/widgets/add_order_button.dart (1 hunks)
  • lib/shared/widgets/bottom_nav_bar.dart (3 hunks)
  • lib/shared/widgets/mostro_app_bar.dart (2 hunks)
  • pubspec.yaml (1 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
pubspec.yaml

[error] 67-67: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (13)
lib/shared/widgets/add_order_button.dart (1)

1-22: LGTM - Clean implementation of the floating action button.

The implementation is well-structured and follows Flutter best practices. The custom styling with Mostro green color and black icon creates a good visual hierarchy.

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

16-31: Well-structured leading menu icon implementation.

The custom padding and explicit size create a consistent appearance. The leadingWidth of 70 provides adequate space for the icon and its touch target.

lib/shared/widgets/bottom_nav_bar.dart (3)

4-6: LGTM - Appropriate package dependencies.

The addition of lucide_icons and google_fonts packages supports the UI modernization and consistent styling across the app.


21-67: Good adaptive container implementation.

The removal of fixed height and use of SafeArea improves adaptability across different devices and screen sizes. The subtle top border creates a nice visual separation.


79-124: Well-structured navigation item layout.

The Expanded widget with InkWell provides good touch feedback and ensures equal spacing. The Column layout with Icon and Text creates a clear visual hierarchy.

lib/features/home/widgets/order_list_item.dart (3)

20-30: Great implementation of dynamic premium value color calculation.

The code elegantly determines the color and formatting of premium values based on whether they're positive or negative, enhancing visual feedback for users.


32-59: Well-crafted container styling with visual depth.

The design implementation with layered shadows and subtle border creates an excellent visual hierarchy. The specific color values and shadow configurations provide a polished, modern dark theme appearance.


60-72: Good use of Material and InkWell for proper touch feedback.

The implementation correctly uses Material and InkWell to provide appropriate ripple effects and tactile feedback, which improves the user experience.

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

25-28: Nicely positioned floating action button.

Good implementation of the floating action button with appropriate padding to position it above the navbar, which improves usability.


43-67: Improved empty state with visual cues.

The enhanced empty state UI with an icon and descriptive text greatly improves user understanding when no orders are available.


87-160: Well-structured app bar implementation.

The custom app bar provides a consistent look and feel with the rest of the UI redesign. The drawer toggle and notification badge are well-positioned.


198-234: Excellent tab button implementation.

The reusable tab button implementation reduces code duplication and provides consistent styling with clear active/inactive states.


258-307: Well-designed filter button with visual feedback.

The filter button design with count indicator provides users with clear visual feedback about the current filter state.

Comment on lines +145 to +147
child: Text(
'6',
style: TextStyle(
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Hardcoded notification count needs to be dynamic.

The notification badge shows a fixed count of '6', which should be replaced with a dynamic value from a provider or service.

- '6',
+ '${notificationCount ?? 0}',

Add a provider to track notifications:

// Add this import
import 'package:flutter_riverpod/flutter_riverpod.dart';

// Add this provider
final notificationCountProvider = StateProvider<int>((ref) => 0);

// Then in the build method, add:
final notificationCount = ref.watch(notificationCountProvider);

// Use in the notification badge

Comment on lines +129 to +131
onPressed: () {
// Action for notifications
},
Copy link
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

Empty notification button handler.

The notification button has an empty onPressed handler, which indicates incomplete functionality.


🏁 Script executed:

#!/bin/bash
# Check if there's a notifications screen implementation
echo "Searching for notification-related files and routes..."
rg -l "notification|Notification" --type dart

# Check if there are any route definitions for notifications
echo "Checking for notification routes in router configuration..."
rg "\/notification|route.*notification" --type dart

Length of output: 1270


#!/bin/bash
# Retry searching for notification route definitions in app_routes.dart
echo "Searching for 'notification' in router configuration (lib/core/app_routes.dart)..."
rg -n "notification" lib/core/app_routes.dart

Implement Notification Button Handler
The notifications icon in HomeScreen currently has an empty onPressed callback, indicating unimplemented behavior. Please wire it up to your notifications UI or service.

• lib/features/home/screens/home_screen.dart (lines 129–131):

                onPressed: () {
-                  // Action for notifications
+                  Navigator.pushNamed(context, AppRoutes.notifications);
                },

• lib/core/app_routes.dart: ensure you have a route defined, for example:

static const notifications = '/notifications';
// …
routes: {
  AppRoutes.notifications: (ctx) => NotificationsScreen(),
  // …
},

• If you don’t yet have a NotificationsScreen, create one under lib/features/notifications/screens/notifications_screen.dart and connect it to your existing NotificationService.

@grunch grunch requested review from Catrya, chebizarro and grunch May 13, 2025 19:16
Copy link
Member

@grunch grunch left a comment

Choose a reason for hiding this comment

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

tACK

Home screen is really beautiful 🏩

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

@AndreaDiazCorreia se ve muy bien!
Estoy de acuerdo en que quizás un fondo un poco más claro haría que se destaquen más las tarjetas con las órdenes, o quizás el borde un poco más grueso, pero para empezar me parece bien así, si tienes alguna sugerencia de qué color puede quedar mejor avisanos a @grunch y a mí para verlo.

En las órdenes no salen correctamente ni la cantidad de días ni la cantidad de trades, salen fijos en 50 días y 0 trades. Eso sería bueno tenerlo listo para que no cree confusión si se saca una nueva versión y están fijos esos números.

@grunch
Copy link
Member

grunch commented May 15, 2025

Align the icons to the center (vertically)

imagen

@Catrya
Copy link
Member

Catrya commented May 15, 2025

Hola @AndreaDiazCorreia No me había dado cuenta antes, pero en vez de decir Trades (el número de trades que salen en las órdenes) debería decir Reviews, que es como está en los eventos de nostr y es lo que realmente significa, porque puede que alguien tenga 20 trades pero solo 15 reviews, y esto último es lo que se publica. Voy a arreglarlo en lovable de todas formas

@grunch grunch self-requested a review May 16, 2025 19:47
@grunch
Copy link
Member

grunch commented May 16, 2025

Como comentó catrya, los valores de las reviews y los dias están hardcodeados, porfa pon los valores reales

imagen

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/data/models/rating.dart (2)

62-86: Consolidate duplicated helpers to improve maintainability

_parseInt vs. _parseIntFromNestedJson (and the double counterparts) contain identical logic—the only difference is the method name. This duplication:

  • Inflates the code surface and cognitive load.
  • Increases the chance that future fixes land in one helper but not the other.

A single generic helper with an optional default value covers both use cases:

-static int _parseInt(Map<String, dynamic> json, String field,
-    {int defaultValue = 0}) { … }
-
-static int _parseIntFromNestedJson(Map<String, dynamic> json, String field,
-    {int defaultValue = 0}) { … }
+static int _parseIntSafe(
+  Map<String, dynamic> json,
+  String field, {
+  int defaultValue = 0,
+}) { … }

Do the same for _parseDoubleSafe. Then call the shared helpers everywhere.
This shrinks ~40 lines, aligns behaviour, and makes future changes a one-liner.

Also applies to: 88-113


20-27: Normalise special string tokens before comparison

data == 'none' fails if the server returns "None", " NONE ", etc.
Trim and lowercase the string first:

-    if (data == 'none') {
+    if (data.trim().toLowerCase() == 'none') {

This makes the parser a bit more defensive against minor API changes.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8cb5f and 080ab21.

📒 Files selected for processing (2)
  • lib/data/models/rating.dart (2 hunks)
  • lib/features/home/widgets/order_list_item.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • lib/features/home/widgets/order_list_item.dart
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build & Release
🔇 Additional comments (1)
lib/data/models/rating.dart (1)

65-68: Beware of silent truncation when casting doubleint

value.toInt() floors the number (e.g. 4.9 → 4). If fractional values are possible in the data feed this silently loses precision. Two safer alternatives:

  1. Validate the value is actually an integer (value % 1 == 0) before casting.
  2. Round instead of floor (value.round()).

Confirm the backend never sends fractional ints, or adopt one of the above to prevent subtle off-by-one errors in statistics.

Comment on lines +32 to +44
if (json is List &&
json.length > 1 &&
json[0] == 'rating' &&
json[1] is Map) {
final Map<String, dynamic> ratingData = json[1] as Map<String, dynamic>;
return Rating(
totalReviews: _parseIntFromNestedJson(ratingData, 'total_reviews'),
totalRating: _parseDoubleFromNestedJson(ratingData, 'total_rating'),
days: _parseIntFromNestedJson(ratingData, 'days'),
lastRating: 0,
maxRate: 5,
minRate: 1,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Parse all available fields in the list-based JSON to avoid silent data loss

In the "rating" list format you parse only totalReviews, totalRating, and days while hard-coding lastRating, maxRate, and minRate.
If those keys are present in the payload they are ignored, causing the app to under-represent the seller’s reputation information.

-          days: _parseIntFromNestedJson(ratingData, 'days'),
-          lastRating: 0,
-          maxRate: 5,
-          minRate: 1,
+          days: _parseIntFromNestedJson(ratingData, 'days'),
+          lastRating: _parseIntFromNestedJson(
+            ratingData,
+            'last_rating',
+            defaultValue: 0,
+          ),
+          maxRate: _parseIntFromNestedJson(
+            ratingData,
+            'max_rate',
+            defaultValue: 5,
+          ),
+          minRate: _parseIntFromNestedJson(
+            ratingData,
+            'min_rate',
+            defaultValue: 1,
+          ),

This keeps the two code paths feature-parity and prevents accidental regressions if the server starts sending these fields.

📝 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
if (json is List &&
json.length > 1 &&
json[0] == 'rating' &&
json[1] is Map) {
final Map<String, dynamic> ratingData = json[1] as Map<String, dynamic>;
return Rating(
totalReviews: _parseIntFromNestedJson(ratingData, 'total_reviews'),
totalRating: _parseDoubleFromNestedJson(ratingData, 'total_rating'),
days: _parseIntFromNestedJson(ratingData, 'days'),
lastRating: 0,
maxRate: 5,
minRate: 1,
);
if (json is List &&
json.length > 1 &&
json[0] == 'rating' &&
json[1] is Map) {
final Map<String, dynamic> ratingData = json[1] as Map<String, dynamic>;
return Rating(
totalReviews: _parseIntFromNestedJson(ratingData, 'total_reviews'),
totalRating: _parseDoubleFromNestedJson(ratingData, 'total_rating'),
days: _parseIntFromNestedJson(ratingData, 'days'),
lastRating: _parseIntFromNestedJson(
ratingData,
'last_rating',
defaultValue: 0,
),
maxRate: _parseIntFromNestedJson(
ratingData,
'max_rate',
defaultValue: 5,
),
minRate: _parseIntFromNestedJson(
ratingData,
'min_rate',
defaultValue: 1,
),
);
}
🤖 Prompt for AI Agents
In lib/data/models/rating.dart between lines 32 and 44, the code parses only
totalReviews, totalRating, and days from the list-based JSON while hardcoding
lastRating, maxRate, and minRate. To fix this, update the parsing logic to
extract lastRating, maxRate, and minRate from the ratingData map if they exist,
using the appropriate parsing functions, instead of hardcoding their values.
This ensures all available fields are captured and prevents data loss or
under-representation of the seller's reputation.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

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

tACK, great job @AndreaDiazCorreia

@chebizarro chebizarro merged commit 5563241 into MostroP2P:main May 17, 2025
1 of 2 checks passed
@AndreaDiazCorreia AndreaDiazCorreia mentioned this pull request May 17, 2025
7 tasks
@AndreaDiazCorreia AndreaDiazCorreia deleted the feat/tabs-and-orders branch May 28, 2025 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants