CW-1155: Mask fiat amounts to be more readable (#2420)

* feat: Mask fiat amounts to be more readable, with comma formating for large numbers * fix: Add fiat masking to buy and sell

David Adegoke committed Jul 31, 2025 at 17:46 UTC a41c23952fbd6420b5c2353e2fb6bd5a354d2e3f
4 files changed +31 -9
lib/buy/buy_quote.dart
+2 -1
@@ -1,6 +1,7 @@
1 import 'package:cake_wallet/buy/buy_provider.dart';
2 import 'package:cake_wallet/buy/payment_method.dart';
3 import 'package:cake_wallet/core/selectable_option.dart';
4 +import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
5 import 'package:cake_wallet/entities/fiat_currency.dart';
6 import 'package:cake_wallet/entities/provider_types.dart';
7 import 'package:cake_wallet/exchange/limits.dart';
@@ -96,7 +97,7 @@ class Quote extends SelectableOption {
97
98 @override
99 String get topLeftSubTitle =>
99 - this.rate > 0 ? '1 $cryptoName = ${rate.toStringAsFixed(2)} $fiatName' : '';
100 + this.rate > 0 ? '1 $cryptoName = ${formatWithCommas(rate.toStringAsFixed(2))} $fiatName' : '';
101
102 @override
103 String get bottomLeftSubTitle {
lib/entities/calculate_fiat_amount.dart
+21 -4
@@ -4,7 +4,7 @@ String calculateFiatAmount({double? price, String? cryptoAmount}) {
4 }
5
6 cryptoAmount = cryptoAmount.replaceAll(',', '.');
7 -
7 +
8 final _amount = double.parse(cryptoAmount);
9 final _result = price * _amount;
10 final result = _result < 0 ? _result * -1 : _result;
@@ -15,14 +15,31 @@ String calculateFiatAmount({double? price, String? cryptoAmount}) {
15
16 var formatted = '';
17 final parts = result.toString().split('.');
18 -
18 +
19 if (parts.length >= 2) {
20 if (parts[1].length > 2) {
21 - formatted = parts[0] + '.' + parts[1].substring(0, 2);
21 + formatted = formatWithCommas(parts[0] + '.' + parts[1].substring(0, 2));
22 } else {
23 - formatted = parts[0] + '.' + parts[1];
23 + formatted = formatWithCommas(parts[0] + '.' + parts[1]);
24 }
25 + } else {
26 + formatted = formatWithCommas(parts[0]);
27 }
28
29 return result > 0.01 ? formatted : '< 0.01';
30 }
31 +
32 +String formatWithCommas(String number) {
33 + if (number.isEmpty) return number;
34 +
35 + final parts = number.split('.');
36 + final integerPart = parts[0];
37 + final decimalPart = parts.length > 1 ? parts[1] : '';
38 +
39 + final formattedInteger = integerPart.replaceAllMapped(
40 + RegExp(r'\B(?=(\d{3})+(?!\d))'),
41 + (Match match) => ',',
42 + );
43 +
44 + return decimalPart.isNotEmpty ? '$formattedInteger.$decimalPart' : formattedInteger;
45 +}
lib/entities/calculate_fiat_amount_raw.dart
+3 -1
@@ -1,3 +1,5 @@
1 +import 'calculate_fiat_amount.dart';
2 +
3 String calculateFiatAmountRaw({required double cryptoAmount, double? price}) {
4 if (price == null) {
5 return '0.00';
@@ -9,5 +11,5 @@ String calculateFiatAmountRaw({required double cryptoAmount, double? price}) {
11 return '0.00';
12 }
13
12 - return result > 0.01 ? result.toStringAsFixed(2) : '< 0.01';
14 + return result > 0.01 ? formatWithCommas(result.toStringAsFixed(2)) : '< 0.01';
15 }
\ No newline at end of file
lib/entities/format_amount.dart
+5 -3
@@ -1,8 +1,10 @@
1 +import 'calculate_fiat_amount.dart';
2 +
3 String formatAmount(String amount) {
4 if ((!amount.contains('.'))&&(!amount.contains(','))) {
3 - return amount + '.00';
5 + return formatWithCommas(amount + '.00');
6 } else if ((amount.endsWith('.'))||(amount.endsWith(','))) {
5 - return amount + '00';
7 + return formatWithCommas(amount + '00');
8 }
7 - return amount;
9 + return formatWithCommas(amount);
10 }
\ No newline at end of file