fix: various amount unit issues

This commit is contained in:
julian 2023-05-30 09:02:09 -06:00
parent cb8e02a3ac
commit 388c60d016
7 changed files with 138 additions and 58 deletions

View file

@ -30,6 +30,7 @@ import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
import 'package:stackwallet/utilities/amount/amount_unit.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
@ -115,14 +116,25 @@ class _SendViewState extends ConsumerState<SendView> {
void _cryptoAmountChanged() async {
if (!_cryptoAmountChangeLock) {
final String cryptoAmount = cryptoAmountController.text;
String cryptoAmount = cryptoAmountController.text;
if (cryptoAmount.isNotEmpty &&
cryptoAmount != "." &&
cryptoAmount != ",") {
if (cryptoAmount.startsWith("~")) {
cryptoAmount = cryptoAmount.substring(1);
}
if (cryptoAmount.contains(" ")) {
cryptoAmount = cryptoAmount.split(" ").first;
}
final shift = ref.read(pAmountUnit(coin)).shift;
_amountToSend = cryptoAmount.contains(",")
? Decimal.parse(cryptoAmount.replaceFirst(",", "."))
.shift(0 - shift)
.toAmount(fractionDigits: coin.decimals)
: Decimal.parse(cryptoAmount)
.shift(0 - shift)
.toAmount(fractionDigits: coin.decimals);
if (_cachedAmountToSend != null &&
_cachedAmountToSend == _amountToSend) {
@ -189,6 +201,15 @@ class _SendViewState extends ConsumerState<SendView> {
late Amount _currentFee;
void _setCurrentFee(String fee, bool shouldSetState) {
fee = fee.trim();
if (fee.startsWith("~")) {
fee = fee.substring(1);
}
if (fee.contains(" ")) {
fee = fee.split(" ").first;
}
final value = fee.contains(",")
? Decimal.parse(fee.replaceFirst(",", "."))
.toAmount(fractionDigits: coin.decimals)
@ -269,7 +290,6 @@ class _SendViewState extends ConsumerState<SendView> {
break;
}
final String locale = ref.read(localeServiceChangeNotifierProvider).locale;
Amount fee;
if (coin == Coin.monero) {
MoneroTransactionPriority specialMoneroId;
@ -288,7 +308,8 @@ class _SendViewState extends ConsumerState<SendView> {
fee = await manager.estimateFeeFor(amount, specialMoneroId.raw!);
cachedFees[amount] = ref.read(pAmountFormatter(coin)).format(
fee,
withUnitName: false,
withUnitName: true,
indicatePrecisionLoss: false,
);
return cachedFees[amount]!;
@ -299,7 +320,8 @@ class _SendViewState extends ConsumerState<SendView> {
cachedFiroPrivateFees[amount] = ref.read(pAmountFormatter(coin)).format(
fee,
withUnitName: false,
withUnitName: true,
indicatePrecisionLoss: false,
);
return cachedFiroPrivateFees[amount]!;
@ -309,7 +331,8 @@ class _SendViewState extends ConsumerState<SendView> {
cachedFiroPublicFees[amount] = ref.read(pAmountFormatter(coin)).format(
fee,
withUnitName: false,
withUnitName: true,
indicatePrecisionLoss: false,
);
return cachedFiroPublicFees[amount]!;
@ -318,7 +341,8 @@ class _SendViewState extends ConsumerState<SendView> {
fee = await manager.estimateFeeFor(amount, feeRate);
cachedFees[amount] = ref.read(pAmountFormatter(coin)).format(
fee,
withUnitName: false,
withUnitName: true,
indicatePrecisionLoss: false,
);
return cachedFees[amount]!;
@ -340,7 +364,6 @@ class _SendViewState extends ConsumerState<SendView> {
return ref.read(pAmountFormatter(coin)).format(
balance,
withUnitName: false,
);
}
@ -599,7 +622,15 @@ class _SendViewState extends ConsumerState<SendView> {
if (_data != null) {
if (_data!.amount != null) {
cryptoAmountController.text = _data!.amount!.toString();
final amount = Amount.fromDecimal(
_data!.amount!,
fractionDigits: coin.decimals,
);
cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format(
amount,
withUnitName: false,
);
}
sendToController.text = _data!.contactLabel;
_address = _data!.address.trim();
@ -1360,7 +1391,7 @@ class _SendViewState extends ConsumerState<SendView> {
_privateBalanceString !=
null) {
return Text(
"$_privateBalanceString ${coin.ticker}",
"$_privateBalanceString",
style: STextStyles
.itemSubtitle(context),
);
@ -1373,7 +1404,7 @@ class _SendViewState extends ConsumerState<SendView> {
_publicBalanceString !=
null) {
return Text(
"$_publicBalanceString ${coin.ticker}",
"$_publicBalanceString",
style: STextStyles
.itemSubtitle(context),
);
@ -1511,7 +1542,9 @@ class _SendViewState extends ConsumerState<SendView> {
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
coin.ticker,
ref
.watch(pAmountUnit(coin))
.unitForCoin(coin),
style: STextStyles.smallMed14(context)
.copyWith(
color: Theme.of(context)
@ -1833,6 +1866,8 @@ class _SendViewState extends ConsumerState<SendView> {
amount: (Decimal.tryParse(
cryptoAmountController
.text) ??
_amountToSend
?.decimal ??
Decimal.zero)
.toAmount(
fractionDigits: coin.decimals,
@ -1872,7 +1907,7 @@ class _SendViewState extends ConsumerState<SendView> {
false,
);
return Text(
"~${snapshot.data! as String} ${coin.ticker}",
"~${snapshot.data! as String}",
style: STextStyles
.itemSubtitle(
context),
@ -1929,7 +1964,7 @@ class _SendViewState extends ConsumerState<SendView> {
false,
);
return Text(
"~${snapshot.data! as String} ${coin.ticker}",
"~${snapshot.data! as String}",
style: STextStyles
.itemSubtitle(
context),

View file

@ -1,5 +1,4 @@
import 'package:cw_core/monero_transaction_priority.dart';
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/paymint/fee_object_model.dart';
@ -10,6 +9,7 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/fee_rate_type_enum.dart';
@ -325,20 +325,21 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.fast,
amount: amount,
),
// future: manager.estimateFeeFor(
// Format.decimalAmountToSatoshis(
// amount),
// feeObject!.fast),
builder: (_,
AsyncSnapshot<Amount> snapshot) {
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
return Text(
"(~${snapshot.data!.decimal.toStringAsFixed(
manager.coin.decimals,
)}"
" ${manager.coin.ticker})",
"(~${ref.watch(
pAmountFormatter(
manager.coin,
),
).format(
snapshot.data!,
indicatePrecisionLoss:
false,
)})",
style: STextStyles.itemSubtitle(
context),
textAlign: TextAlign.left,
@ -461,18 +462,21 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.medium,
amount: amount,
),
// future: manager.estimateFeeFor(
// Format.decimalAmountToSatoshis(
// amount),
// feeObject!.fast),
builder: (_,
AsyncSnapshot<Amount> snapshot) {
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
return Text(
"(~${snapshot.data!.decimal.toStringAsFixed(manager.coin.decimals)}"
" ${manager.coin.ticker})",
"(~${ref.watch(
pAmountFormatter(
manager.coin,
),
).format(
snapshot.data!,
indicatePrecisionLoss:
false,
)})",
style: STextStyles.itemSubtitle(
context),
textAlign: TextAlign.left,
@ -596,17 +600,21 @@ class _TransactionFeeSelectionSheetState
feeRate: feeObject!.slow,
amount: amount,
),
// future: manager.estimateFeeFor(
// Format.decimalAmountToSatoshis(
// amount),
// feeObject!.fast),
builder: (_,
AsyncSnapshot<Amount> snapshot) {
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
return Text(
"(~${snapshot.data!.decimal.toStringAsFixed(manager.coin.decimals)} ${manager.coin.ticker})",
"(~${ref.watch(
pAmountFormatter(
manager.coin,
),
).format(
snapshot.data!,
indicatePrecisionLoss:
false,
)})",
style: STextStyles.itemSubtitle(
context),
textAlign: TextAlign.left,
@ -669,25 +677,31 @@ class _TransactionFeeSelectionSheetState
switch (feeRateType) {
case FeeRateType.fast:
if (ref.read(feeSheetSessionCacheProvider).fast[amount] != null) {
return (ref.read(feeSheetSessionCacheProvider).fast[amount]
as Decimal)
.toStringAsFixed(coin.decimals);
return ref.read(pAmountFormatter(coin)).format(
ref.read(feeSheetSessionCacheProvider).fast[amount]!,
indicatePrecisionLoss: false,
withUnitName: false,
);
}
return null;
case FeeRateType.average:
if (ref.read(feeSheetSessionCacheProvider).average[amount] != null) {
return (ref.read(feeSheetSessionCacheProvider).average[amount]
as Decimal)
.toStringAsFixed(coin.decimals);
return ref.read(pAmountFormatter(coin)).format(
ref.read(feeSheetSessionCacheProvider).average[amount]!,
indicatePrecisionLoss: false,
withUnitName: false,
);
}
return null;
case FeeRateType.slow:
if (ref.read(feeSheetSessionCacheProvider).slow[amount] != null) {
return (ref.read(feeSheetSessionCacheProvider).slow[amount]
as Decimal)
.toStringAsFixed(coin.decimals);
return ref.read(pAmountFormatter(coin)).format(
ref.read(feeSheetSessionCacheProvider).slow[amount]!,
indicatePrecisionLoss: false,
withUnitName: false,
);
}
return null;
}

View file

@ -170,6 +170,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format(
amount,
withUnitName: false,
indicatePrecisionLoss: false,
);
_amountToSend = amount;
}
@ -261,10 +262,17 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
void _cryptoAmountChanged() async {
if (!_cryptoAmountChangeLock) {
final String cryptoAmount = cryptoAmountController.text;
String cryptoAmount = cryptoAmountController.text;
if (cryptoAmount.isNotEmpty &&
cryptoAmount != "." &&
cryptoAmount != ",") {
if (cryptoAmount.startsWith("~")) {
cryptoAmount = cryptoAmount.substring(1);
}
if (cryptoAmount.contains(" ")) {
cryptoAmount = cryptoAmount.split(" ").first;
}
_amountToSend = Amount.fromDecimal(
cryptoAmount.contains(",")
? Decimal.parse(cryptoAmount.replaceFirst(",", "."))
@ -361,7 +369,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
final Amount fee = wallet.estimateFeeFor(feeRate);
cachedFees = ref.read(pAmountFormatter(coin)).format(
fee,
withUnitName: false,
withUnitName: true,
indicatePrecisionLoss: false,
);
return cachedFees;
@ -684,7 +693,9 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
.read(tokenServiceProvider)!
.balance
.spendable,
ethContract: tokenContract,
withUnitName: false,
indicatePrecisionLoss: true,
);
},
child: Container(
@ -1164,7 +1175,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
ConnectionState.done &&
snapshot.hasData) {
return Text(
"~${snapshot.data! as String} ${coin.ticker}",
"~${snapshot.data! as String}",
style:
STextStyles.itemSubtitle(
context),

View file

@ -12,6 +12,7 @@ import 'package:stackwallet/providers/wallet/public_private_balance_state_provid
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -360,10 +361,10 @@ class FeeDropDownChild extends ConsumerWidget {
children: [
Text(
"${feeRateType.prettyName} "
"(~${snapshot.data!.decimal.toStringAsFixed(
manager.coin.decimals,
)} "
"${manager.coin.ticker})",
"(~${ref.watch(pAmountFormatter(manager.coin)).format(
snapshot.data!,
indicatePrecisionLoss: false,
)})",
style:
STextStyles.desktopTextExtraExtraSmall(context).copyWith(
color: Theme.of(context)

View file

@ -28,6 +28,7 @@ import 'package:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/utilities/address_utils.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/amount/amount_formatter.dart';
import 'package:stackwallet/utilities/amount/amount_unit.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/barcode_scanner_interface.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart';
@ -430,14 +431,25 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
void _cryptoAmountChanged() async {
if (!_cryptoAmountChangeLock) {
final String cryptoAmount = cryptoAmountController.text;
String cryptoAmount = cryptoAmountController.text;
if (cryptoAmount.isNotEmpty &&
cryptoAmount != "." &&
cryptoAmount != ",") {
if (cryptoAmount.startsWith("~")) {
cryptoAmount = cryptoAmount.substring(1);
}
if (cryptoAmount.contains(" ")) {
cryptoAmount = cryptoAmount.split(" ").first;
}
final shift = ref.read(pAmountUnit(coin)).shift;
_amountToSend = cryptoAmount.contains(",")
? Decimal.parse(cryptoAmount.replaceFirst(",", "."))
.shift(0 - shift)
.toAmount(fractionDigits: coin.decimals)
: Decimal.parse(cryptoAmount)
.shift(0 - shift)
.toAmount(fractionDigits: coin.decimals);
if (_cachedAmountToSend != null &&
_cachedAmountToSend == _amountToSend) {
@ -527,12 +539,12 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
}
if (private && _privateBalanceString != null) {
return Text(
"$_privateBalanceString ${coin.ticker}",
"$_privateBalanceString",
style: STextStyles.itemSubtitle(context),
);
} else if (!private && _publicBalanceString != null) {
return Text(
"$_publicBalanceString ${coin.ticker}",
"$_publicBalanceString",
style: STextStyles.itemSubtitle(context),
);
} else {
@ -1043,7 +1055,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
coin.ticker,
ref.watch(pAmountUnit(coin)).unitForCoin(coin),
style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!

View file

@ -50,6 +50,7 @@ class AmountFormatter {
String? overrideUnit,
EthContract? ethContract,
bool withUnitName = true,
bool indicatePrecisionLoss = true,
}) {
return unit.displayAmount(
amount: amount,
@ -57,6 +58,7 @@ class AmountFormatter {
coin: coin,
maxDecimalPlaces: maxDecimals,
withUnitName: withUnitName,
indicatePrecisionLoss: indicatePrecisionLoss,
overrideUnit: overrideUnit,
tokenContract: ethContract,
);

View file

@ -114,6 +114,7 @@ extension AmountUnitExt on AmountUnit {
required Coin coin,
required int maxDecimalPlaces,
bool withUnitName = true,
bool indicatePrecisionLoss = true,
String? overrideUnit,
EthContract? tokenContract,
}) {
@ -192,7 +193,15 @@ extension AmountUnitExt on AmountUnit {
returnValue += "$separator$remainder";
}
if (!withUnitName) {
if (!withUnitName && !indicatePrecisionLoss) {
return returnValue;
}
if (didLosePrecision && indicatePrecisionLoss) {
returnValue = "~$returnValue";
}
if (!withUnitName && indicatePrecisionLoss) {
return returnValue;
}
@ -201,10 +210,6 @@ extension AmountUnitExt on AmountUnit {
overrideUnit = unitForContract(tokenContract);
}
if (didLosePrecision) {
returnValue = "~$returnValue";
}
return "$returnValue ${overrideUnit ?? unitForCoin(coin)}";
}
}