-
Notifications
You must be signed in to change notification settings - Fork 16
Feat/tabs and orders #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat/tabs and orders #98
Conversation
|
""" WalkthroughThe 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 Changes
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
Poem
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit 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. Note ⚡️ Faster reviews with cachingCodeRabbit 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 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 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
⛔ Files ignored due to path filters (1)
pubspec.lockis 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.
| child: Text( | ||
| '6', | ||
| style: TextStyle( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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| onPressed: () { | ||
| // Action for notifications | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 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 dartLength 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.dartImplement 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
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK
Home screen is really beautiful 🏩
Catrya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
|
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
lib/data/models/rating.dart (2)
62-86: Consolidate duplicated helpers to improve maintainability
_parseIntvs._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
📒 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 castingdouble→int
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:
- Validate the value is actually an integer (
value % 1 == 0) before casting.- 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.
| 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, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ 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.
| 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.
Catrya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK, great job @AndreaDiazCorreia


Summary of Changes
This PR introduces several UI updates as part of Issue #85:
Notes
app_themestill needs to be adjusted to integrate these changes properly.Summary by CodeRabbit