Skip to content

Commit

Permalink
Addresses @Catrya comments
Browse files Browse the repository at this point in the history
  • Loading branch information
chebizarro committed Nov 26, 2024
1 parent 64721c5 commit ee67611
Show file tree
Hide file tree
Showing 10 changed files with 210 additions and 241 deletions.
43 changes: 19 additions & 24 deletions lib/core/utils/nostr_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -282,28 +282,23 @@ class NostrUtils {
}
}

static Future<String> _encryptNIP44(
String content, String privkey, String pubkey) async {
if (content.isEmpty) throw ArgumentError('Content cannot be empty');
if (privkey.length != 64) throw ArgumentError('Invalid private key length');
if (!pubkey.startsWith('02')) throw ArgumentError('Invalid public key format');
try {
return await Nip44.encryptMessage(content, privkey, pubkey);
} catch (e) {
// Handle encryption error appropriately
throw Exception('Encryption failed: $e');
}
}

static Future<String> _decryptNIP44(
String encryptedContent, String privkey, String pubkey) async {
if (encryptedContent.isEmpty) throw ArgumentError('Encrypted content cannot be empty');
if (privkey.length != 64) throw ArgumentError('Invalid private key length');
if (!pubkey.startsWith('02')) throw ArgumentError('Invalid public key format');
try {
return await Nip44.decryptMessage(encryptedContent, privkey, pubkey);
} catch (e) {
// Handle encryption error appropriately
throw Exception('Decryption failed: $e');
}
static Future<String> _encryptNIP44(
String content, String privkey, String pubkey) async {
try {
return await Nip44.encryptMessage(content, privkey, pubkey);
} catch (e) {
// Handle encryption error appropriately
throw Exception('Encryption failed: $e');
}
}

static Future<String> _decryptNIP44(
String encryptedContent, String privkey, String pubkey) async {
try {
return await Nip44.decryptMessage(encryptedContent, privkey, pubkey);
} catch (e) {
// Handle encryption error appropriately
throw Exception('Decryption failed: $e');
}
}
}
39 changes: 39 additions & 0 deletions lib/data/models/amount.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
class Amount {
final int minimum;
final int? maximum;

Amount(this.minimum, this.maximum);

factory Amount.fromList(List<String> fa) {
if (fa.length < 2) {
throw ArgumentError(
'List must have at least two elements: a label and a minimum value.');
}

final min = int.tryParse(fa[1]);
if (min == null) {
throw ArgumentError(
'Second element must be a valid integer representing the minimum value.');
}

int? max;
if (fa.length > 2) {
max = int.tryParse(fa[2]);
}

return Amount(min, max);
}

factory Amount.empty() {
return Amount(0, null);
}

@override
String toString() {
if (maximum != null) {
return '$minimum - $maximum';
} else {
return '$minimum';
}
}
}
2 changes: 1 addition & 1 deletion lib/data/models/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ abstract class Content {
String get type;
Map<String, dynamic> toJson();

factory Content.fromJson(Map<String, dynamic> json) {fromJson
factory Content.fromJson(Map<String, dynamic> json) {
if (json.containsKey('order')) {
return Order.fromJson(json['order']);
} else if (json.containsKey('payment_request')) {
Expand Down
12 changes: 10 additions & 2 deletions lib/data/models/nostr_event.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:convert';
import 'package:mostro_mobile/data/models/amount.dart';
import 'package:mostro_mobile/data/models/enums/order_type.dart';
import 'package:mostro_mobile/data/models/rating.dart';
import 'package:timeago/timeago.dart' as timeago;
Expand All @@ -9,11 +10,13 @@ extension NostrEventExtensions on NostrEvent {
// Getters para acceder fácilmente a los tags específicos
String? get recipient => _getTagValue('p');
String? get orderId => _getTagValue('d');
OrderType? get orderType => _getTagValue('k') != null ? OrderType.fromString(_getTagValue('k')!) : null;
OrderType? get orderType => _getTagValue('k') != null
? OrderType.fromString(_getTagValue('k')!)
: null;
String? get currency => _getTagValue('f');
String? get status => _getTagValue('s');
String? get amount => _getTagValue('amt');
String? get fiatAmount => _getTagValue('fa');
Amount get fiatAmount => _getAmount('fa');
List<String> get paymentMethods => _getTagValue('pm')?.split(',') ?? [];
String? get premium => _getTagValue('premium');
String? get source => _getTagValue('source');
Expand All @@ -40,6 +43,11 @@ extension NostrEventExtensions on NostrEvent {
return (tag != null && tag.length > 1) ? tag[1] : null;
}

Amount _getAmount(String key) {
final tag = tags?.firstWhere((t) => t[0] == key, orElse: () => []);
return (tag != null && tag.length> 1) ? Amount.fromList(tag) : Amount.empty();
}

String _timeAgo(String? ts) {
if (ts == null) return "invalid date";
final timestamp = int.tryParse(ts);
Expand Down
2 changes: 1 addition & 1 deletion lib/data/models/order.dart
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class Order implements Content {
status: Status.fromString(event.status!),
amount: event.amount as int,
fiatCode: event.currency!,
fiatAmount: int.parse(event.fiatAmount!),
fiatAmount: event.fiatAmount.minimum,
paymentMethod: event.paymentMethods.join(','),
premium: event.premium as int,
createdAt: event.createdAt as int,
Expand Down
79 changes: 35 additions & 44 deletions lib/data/models/rating.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,67 +7,58 @@ class Rating {
final int maxRate;
final int minRate;

Rating(
{required this.totalReviews,
required this.totalRating,
required this.lastRating,
required this.maxRate,
required this.minRate});
const Rating({
required this.totalReviews,
required this.totalRating,
required this.lastRating,
required this.maxRate,
required this.minRate,
});

factory Rating.deserialized(String data) {
if (data.isEmpty) {
throw FormatException('Empty data string provided');
}

if (data == 'none') {
return Rating(
totalReviews: 0,
totalRating: 0.0,
lastRating: 0,
maxRate: 0,
minRate: 0);
return Rating.empty();
}

try {
final json = jsonDecode(data) as Map<String, dynamic>;
final rating = json['rating'] as Map<String, dynamic>?;

if (rating == null) {
throw FormatException('Missing rating object in JSON');
}

return Rating(
totalReviews: _parseIntField(rating, 'total_reviews'),
totalRating: _parseDoubleField(rating, 'total_rating'),
lastRating: _parseIntField(rating, 'last_rating'),
maxRate: _parseIntField(rating, 'max_rate'),
minRate: _parseIntField(rating, 'min_rate'),
totalReviews: _parseInt(json, 'total_reviews'),
totalRating: _parseDouble(json, 'total_rating'),
lastRating: _parseInt(json, 'last_rating'),
maxRate: _parseInt(json, 'max_rate'),
minRate: _parseInt(json, 'min_rate'),
);
} on FormatException {
rethrow;
} catch (e) {
throw FormatException('Failed to parse rating data: $e');
}
}
static int _parseIntField(Map<String, dynamic> json, String field) {

static int _parseInt(Map<String, dynamic> json, String field) {
final value = json[field];
if (value == null) {
throw FormatException('Missing required field: $field');
}
if (value is! num) {
throw FormatException(
'Invalid type for $field: expected number, got ${value.runtimeType}');
}
return value.toInt();
if (value is int) return value;
if (value is double) return value.toInt();
throw FormatException('Invalid value for $field: $value');
}

static double _parseDoubleField(Map<String, dynamic> json, String field) {
static double _parseDouble(Map<String, dynamic> json, String field) {
final value = json[field];
if (value == null) {
throw FormatException('Missing required field: $field');
}
if (value is! num) {
throw FormatException(
'Invalid type for $field: expected number, got ${value.runtimeType}');
}
return value.toDouble();
if (value is double) return value;
if (value is int) return value.toDouble();
throw FormatException('Invalid value for $field: $value');
}

static Rating empty() {
return const Rating(
totalReviews: 0,
totalRating: 0.0,
lastRating: 0,
maxRate: 0,
minRate: 0,
);
}
}
}
5 changes: 3 additions & 2 deletions lib/presentation/order/screens/order_details_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ class OrderDetailsScreen extends ConsumerWidget {
Widget _buildContent(BuildContext context, WidgetRef ref, NostrEvent order) {
return Scaffold(
backgroundColor: AppTheme.dark1,
appBar: _buildAppBar('${order.orderType?.value.toUpperCase()} BITCOIN', context),
appBar: _buildAppBar(
'${order.orderType?.value.toUpperCase()} BITCOIN', context),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
Expand Down Expand Up @@ -291,7 +292,7 @@ class OrderDetailsScreen extends ConsumerWidget {
Expanded(
child: ElevatedButton(
onPressed: () {
context.read<OrderDetailsBloc>().add(CancelOrder());
Navigator.of(context).pop();
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
Expand Down
53 changes: 0 additions & 53 deletions lib/presentation/widgets/group_box.dart

This file was deleted.

52 changes: 15 additions & 37 deletions lib/presentation/widgets/order_filter.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:heroicons/heroicons.dart';
import 'package:mostro_mobile/core/theme/app_theme.dart';
import 'package:mostro_mobile/presentation/widgets/group_box.dart';

class OrderFilter extends StatelessWidget {
const OrderFilter({super.key});
Expand Down Expand Up @@ -51,55 +50,34 @@ class OrderFilter extends StatelessWidget {
],
),
SizedBox(height: 20),
buildDropdownSection(context, 'Fiat currencies', ''),
buildDropdownSection(context, 'Payment methods', ''),
buildDropdownSection(context, 'Countries', ''),
buildDropdownSection(context, 'Rating', ''),
buildDropdownSection(context, 'Fiat currencies', []),
buildDropdownSection(context, 'Payment methods', []),
buildDropdownSection(context, 'Countries', []),
buildDropdownSection(context, 'Rating', []),
],
),
);
}

Widget buildDropdownSection(
BuildContext context, String title, String value) {
BuildContext context, String title, List<DropdownMenuItem<String>> items) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(height: 4),
Container(
padding: EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppTheme.grey),
DropdownButtonFormField<String>(
decoration: InputDecoration(
border: InputBorder.none,
labelText: title,
labelStyle: const TextStyle(color: AppTheme.mostroGreen),
),
child: GroupBox(
title: title,
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
value: value,
onChanged: (String? newValue) {},
items: <String>[value]
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
style: TextStyle(
color: AppTheme.dark1,
fontSize: 14,
),
),
);
}).toList(),
icon: Icon(
Icons.arrow_drop_down,
color: AppTheme.dark1,
),
),
)),
dropdownColor: AppTheme.dark1,
style: TextStyle(color: AppTheme.cream1),
items: items,
value: '', onChanged: (String? value) { },
),
SizedBox(height: 4),
],
),
);
Expand Down
Loading

0 comments on commit ee67611

Please sign in to comment.