WIP exchange screen state refactor

This commit is contained in:
julian 2023-05-03 14:03:31 -06:00
parent 3564426248
commit 3a97623e5b
19 changed files with 1169 additions and 942 deletions

View file

@ -299,7 +299,8 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()) {
if (Constants.enableExchange) {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
unawaited(ExchangeDataLoadingService.instance.loadAll());
}

View file

@ -0,0 +1,35 @@
import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
class ActivePair extends ChangeNotifier {
AggregateCurrency? _send;
AggregateCurrency? _receive;
AggregateCurrency? get send => _send;
AggregateCurrency? get receive => _receive;
void setSend(
AggregateCurrency? newSend, {
bool notifyListeners = false,
}) {
_send = newSend;
if (notifyListeners) {
this.notifyListeners();
}
}
void setReceive(
AggregateCurrency? newReceive, {
bool notifyListeners = false,
}) {
_receive = newReceive;
if (notifyListeners) {
this.notifyListeners();
}
}
@override
String toString() {
return "ActivePair{ send: $send, receive: $receive }";
}
}

File diff suppressed because it is too large Load diff

View file

@ -9,6 +9,7 @@ import 'package:intl/intl.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:stackwallet/models/isar/models/ethereum/eth_contract.dart';
@ -21,10 +22,13 @@ import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_ste
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
import 'package:stackwallet/services/exchange/trocador/trocador_exchange.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
@ -61,6 +65,12 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
late final Coin? coin;
late final bool walletInitiated;
final exchanges = [
MajesticBankExchange.instance,
ChangeNowExchange.instance,
TrocadorExchange.instance,
];
late final TextEditingController _sendController;
late final TextEditingController _receiveController;
final isDesktop = Util.isDesktop;
@ -105,16 +115,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
Timer? _sendFieldOnChangedTimer;
void sendFieldOnChanged(String value) async {
void sendFieldOnChanged(String value) {
if (_sendFocusNode.hasFocus) {
_sendFieldOnChangedTimer?.cancel();
_sendFieldOnChangedTimer = Timer(_valueCheckInterval, () async {
final newFromAmount = _localizedStringToNum(value);
await ref
.read(exchangeFormStateProvider)
.setSendAmountAndCalculateReceiveAmount(newFromAmount, true);
ref.read(efSendAmountProvider.notifier).state = newFromAmount;
if (!_swapLock && !ref.read(efReversedProvider)) {
unawaited(update());
}
});
}
}
@ -126,9 +137,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
_receiveFieldOnChangedTimer = Timer(_valueCheckInterval, () async {
final newToAmount = _localizedStringToNum(value);
await ref
.read(exchangeFormStateProvider)
.setReceivingAmountAndCalculateSendAmount(newToAmount, true);
ref.read(efReceiveAmountProvider.notifier).state = newToAmount;
if (!_swapLock && ref.read(efReversedProvider)) {
unawaited(update());
}
});
}
@ -147,7 +159,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
Future<AggregateCurrency> _getAggregateCurrency(Currency currency) async {
final rateType = ref.read(exchangeFormStateProvider).exchangeRateType;
final rateType = ref.read(efRateTypeProvider);
final currencies = await ExchangeDataLoadingService.instance.isar.currencies
.filter()
.group((q) => rateType == ExchangeRateType.fixed
@ -178,8 +190,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
void selectSendCurrency() async {
final type = (ref.read(exchangeFormStateProvider).exchangeRateType);
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final type = ref.read(efRateTypeProvider);
final fromTicker = ref.read(efCurrencyPairProvider).send?.ticker ?? "";
if (walletInitiated) {
if (widget.contract != null &&
@ -194,24 +206,26 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
final selectedCurrency = await _showCurrencySelectionSheet(
willChange: ref.read(exchangeFormStateProvider).sendCurrency?.ticker,
willChange: ref.read(efCurrencyPairProvider).send?.ticker,
willChangeIsSend: true,
paired: ref.read(exchangeFormStateProvider).receiveCurrency?.ticker,
paired: ref.read(efCurrencyPairProvider).receive?.ticker,
isFixedRate: type == ExchangeRateType.fixed,
);
if (selectedCurrency != null) {
await showUpdatingExchangeRate(
whileFuture: _getAggregateCurrency(selectedCurrency).then(
(aggregateSelected) => ref
.read(exchangeFormStateProvider)
.updateSendCurrency(aggregateSelected, true)),
(aggregateSelected) => ref.read(efCurrencyPairProvider).setSend(
aggregateSelected,
notifyListeners: true,
),
),
);
}
}
void selectReceiveCurrency() async {
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final toTicker = ref.read(efCurrencyPairProvider).receive?.ticker ?? "";
if (walletInitiated &&
toTicker.toLowerCase() == coin!.ticker.toLowerCase()) {
// do not allow changing away from wallet coin
@ -219,19 +233,20 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
final selectedCurrency = await _showCurrencySelectionSheet(
willChange: ref.read(exchangeFormStateProvider).receiveCurrency?.ticker,
willChange: ref.read(efCurrencyPairProvider).receive?.ticker,
willChangeIsSend: false,
paired: ref.read(exchangeFormStateProvider).sendCurrency?.ticker,
isFixedRate: ref.read(exchangeFormStateProvider).exchangeRateType ==
ExchangeRateType.fixed,
paired: ref.read(efCurrencyPairProvider).send?.ticker,
isFixedRate: ref.read(efRateTypeProvider) == ExchangeRateType.fixed,
);
if (selectedCurrency != null) {
await showUpdatingExchangeRate(
whileFuture: _getAggregateCurrency(selectedCurrency).then(
(aggregateSelected) => ref
.read(exchangeFormStateProvider)
.updateReceivingCurrency(aggregateSelected, true)),
(aggregateSelected) => ref.read(efCurrencyPairProvider).setReceive(
aggregateSelected,
notifyListeners: true,
),
),
);
}
}
@ -241,10 +256,25 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
_sendFocusNode.unfocus();
_receiveFocusNode.unfocus();
await showUpdatingExchangeRate(
whileFuture:
ref.read(exchangeFormStateProvider).swap(shouldNotifyListeners: true),
);
final temp = ref.read(efCurrencyPairProvider).send;
ref.read(efCurrencyPairProvider).setSend(
ref.read(efCurrencyPairProvider).receive,
notifyListeners: true,
);
ref.read(efCurrencyPairProvider).setReceive(
temp,
notifyListeners: true,
);
// final reversed = ref.read(efReversedProvider);
final amount = ref.read(efSendAmountProvider);
ref.read(efSendAmountProvider.notifier).state =
ref.read(efReceiveAmountProvider);
ref.read(efReceiveAmountProvider.notifier).state = amount;
unawaited(update());
_swapLock = false;
}
@ -331,89 +361,20 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
}
void onRateTypeChanged(ExchangeRateType newType) async {
void onRateTypeChanged(ExchangeRateType newType) {
_receiveFocusNode.unfocus();
_sendFocusNode.unfocus();
await showUpdatingExchangeRate(
whileFuture: _onRateTypeChangedFuture(newType),
);
}
Future<void> _onRateTypeChangedFuture(ExchangeRateType newType) async {
ref.read(exchangeFormStateProvider).exchangeRateType = newType;
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "-";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "-";
ref.read(exchangeFormStateProvider).reversed = false;
if (!(toTicker == "-" || fromTicker == "-")) {
// final available = await ExchangeDataLoadingService.instance.isar.pairs
// .where()
// .exchangeNameEqualTo(
// ref.read(currentExchangeNameStateProvider.state).state)
// .filter()
// .fromEqualTo(fromTicker)
// .and()
// .toEqualTo(toTicker)
// .findAll();
await ref.read(exchangeFormStateProvider).refresh();
// if (available.isNotEmpty) {
// final availableCurrencies = await ExchangeDataLoadingService
// .instance.isar.currencies
// .where()
// .exchangeNameEqualTo(
// ref.read(currentExchangeNameStateProvider.state).state)
// .filter()
// .tickerEqualTo(fromTicker)
// .or()
// .tickerEqualTo(toTicker)
// .findAll();
//
// if (availableCurrencies.length > 1) {
// final from =
// availableCurrencies.firstWhere((e) => e.ticker == fromTicker);
// final to =
// availableCurrencies.firstWhere((e) => e.ticker == toTicker);
//
// final newFromAmount = Decimal.tryParse(_sendController.text);
// ref.read(exchangeFormStateProvider).receiveAmount = newFromAmount;
// if (newFromAmount == null) {
// _receiveController.text = "";
// }
//
// await ref
// .read(exchangeFormStateProvider)
// .updateReceivingCurrency(to, false);
// await ref
// .read(exchangeFormStateProvider)
// .updateSendCurrency(from, true);
//
// _receiveController.text =
// ref.read(exchangeFormStateProvider).toAmountString.isEmpty
// ? "-"
// : ref.read(exchangeFormStateProvider).toAmountString;
// if (mounted) {
// Navigator.of(context, rootNavigator: isDesktop).pop();
// }
// return;
// }
// }
}
ref.read(efRateTypeProvider.notifier).state = newType;
update();
}
void onExchangePressed() async {
final rateType = ref.read(exchangeFormStateProvider).exchangeRateType;
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final sendAmount = ref.read(exchangeFormStateProvider).sendAmount!;
final estimate = ref.read(exchangeFormStateProvider).estimates.firstWhere(
(e) =>
e.exchangeProvider ==
ref.read(exchangeFormStateProvider).providerName,
);
final rateType = ref.read(efRateTypeProvider);
final fromTicker = ref.read(efCurrencyPairProvider).send?.ticker ?? "";
final toTicker = ref.read(efCurrencyPairProvider).receive?.ticker ?? "";
final estimate = ref.read(efEstimateProvider)!;
final sendAmount = ref.read(efSendAmountProvider)!;
if (rateType == ExchangeRateType.fixed && toTicker.toUpperCase() == "WOW") {
await showDialog<void>(
@ -430,10 +391,16 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
String rate;
final amountToSend =
estimate.reversed ? estimate.estimatedAmount : sendAmount;
final amountToReceive = estimate.reversed
? ref.read(efReceiveAmountProvider)!
: estimate.estimatedAmount;
switch (rateType) {
case ExchangeRateType.estimated:
rate =
"1 ${fromTicker.toUpperCase()} ~${(estimate.estimatedAmount / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
"1 ${fromTicker.toUpperCase()} ~${(amountToReceive / sendAmount).toDecimal(scaleOnInfinitePrecision: 8).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
break;
case ExchangeRateType.fixed:
bool? shouldCancel;
@ -545,7 +512,9 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return;
}
rate =
"1 ${fromTicker.toUpperCase()} ~${ref.read(exchangeFormStateProvider).rate!.toStringAsFixed(8)} ${toTicker.toUpperCase()}";
"1 ${fromTicker.toUpperCase()} ~${(amountToReceive / amountToSend).toDecimal(
scaleOnInfinitePrecision: 12,
).toStringAsFixed(8)} ${toTicker.toUpperCase()}";
break;
}
@ -553,10 +522,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
sendTicker: fromTicker.toUpperCase(),
receiveTicker: toTicker.toUpperCase(),
rateInfo: rate,
sendAmount: estimate.reversed ? estimate.estimatedAmount : sendAmount,
receiveAmount: estimate.reversed
? ref.read(exchangeFormStateProvider).receiveAmount!
: estimate.estimatedAmount,
sendAmount: amountToSend,
receiveAmount: amountToReceive,
rateType: rateType,
estimate: estimate,
reversed: estimate.reversed,
@ -626,8 +593,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}
String? ticker = isSend
? ref.read(exchangeFormStateProvider).fromTicker
: ref.read(exchangeFormStateProvider).toTicker;
? ref.read(efCurrencyPairProvider).send?.ticker
: ref.read(efCurrencyPairProvider).receive?.ticker;
if (ticker == null) {
return false;
@ -636,6 +603,85 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
return coin.ticker.toUpperCase() == ticker.toUpperCase();
}
Future<void> update() async {
ref.read(efRefreshingProvider.notifier).state = true;
for (final exchange in exchanges) {
ref.read(efEstimatesListProvider(exchange.name).notifier).state = null;
}
final reversed = ref.read(efReversedProvider);
final amount = reversed
? ref.read(efReceiveAmountProvider)
: ref.read(efSendAmountProvider);
if (amount == null || amount <= Decimal.zero) {
ref.read(efRefreshingProvider.notifier).state = false;
return;
}
final rateType = ref.read(efRateTypeProvider);
final pair = ref.read(efCurrencyPairProvider);
for (final exchange in exchanges) {
final sendCurrency = pair.send?.forExchange(exchange.name);
final receiveCurrency = pair.receive?.forExchange(exchange.name);
if (sendCurrency != null && receiveCurrency != null) {
final rangeResponse = await exchange.getRange(
reversed ? receiveCurrency.ticker : sendCurrency.ticker,
reversed ? sendCurrency.ticker : receiveCurrency.ticker,
rateType == ExchangeRateType.fixed,
);
if (rangeResponse.value == null) {
Logging.instance.log(
"Tried to $runtimeType.update Range for:"
" $exchange where response: $rangeResponse",
level: LogLevel.Info,
);
}
final estimateResponse = await exchange.getEstimates(
sendCurrency.ticker,
receiveCurrency.ticker,
amount,
rateType == ExchangeRateType.fixed,
reversed,
);
if (estimateResponse.value == null) {
Logging.instance.log(
"Tried to $runtimeType._fetchEstimateAndRange Estimate for:"
" $exchange where response: $estimateResponse",
level: LogLevel.Info,
);
}
if (estimateResponse.value != null && rangeResponse.value != null) {
ref.read(efEstimatesListProvider(exchange.name).notifier).state =
Tuple2(estimateResponse.value!, rangeResponse.value!);
}
}
}
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(efRefreshingProvider.notifier).state = false;
});
}
void updateSend(Estimate? estimate) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(efSendAmountProvider.notifier).state = estimate?.estimatedAmount;
});
}
void updateReceive(Estimate? estimate) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(efReceiveAmountProvider.notifier).state =
estimate?.estimatedAmount;
});
}
@override
void initState() {
_sendController = TextEditingController();
@ -645,9 +691,32 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
coin = widget.coin;
walletInitiated = walletId != null && coin != null;
_sendFocusNode.addListener(() {
if (_sendFocusNode.hasFocus) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(efReversedProvider.notifier).state = false;
});
}
});
_receiveFocusNode.addListener(() {
if (_receiveFocusNode.hasFocus) {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(efReversedProvider.notifier).state = true;
});
}
});
if (walletInitiated) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
ref.read(exchangeFormStateProvider).reset(shouldNotifyListeners: true);
ref.read(efSendAmountProvider.notifier).state = null;
ref.read(efReceiveAmountProvider.notifier).state = null;
ref.read(efReversedProvider.notifier).state = false;
ref.read(efWarningProvider.notifier).state = "";
ref.read(efRefreshingProvider.notifier).state = false;
ref.read(efCurrencyPairProvider).setSend(null, notifyListeners: true);
ref
.read(efCurrencyPairProvider)
.setReceive(null, notifyListeners: true);
ExchangeDataLoadingService.instance
.getAggregateCurrency(
widget.contract == null ? coin!.ticker : widget.contract!.symbol,
@ -656,17 +725,17 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
)
.then((value) {
if (value != null) {
ref.read(exchangeFormStateProvider).updateSendCurrency(value, true);
ref.read(efCurrencyPairProvider).setSend(
value,
notifyListeners: true,
);
}
});
});
} else {
_sendController.text =
ref.read(exchangeFormStateProvider).fromAmountString;
_receiveController.text =
ref.read(exchangeFormStateProvider).toAmountString;
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
ref.read(exchangeFormStateProvider).refresh();
_sendController.text = ref.read(efSendAmountStringProvider);
_receiveController.text = ref.read(efReceiveAmountStringProvider);
});
}
@ -684,37 +753,42 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType");
final rateType = ref.watch(
exchangeFormStateProvider.select((value) => value.exchangeRateType));
final rateType = ref.watch(efRateTypeProvider);
final isEstimated = rateType == ExchangeRateType.estimated;
ref.listen(
exchangeFormStateProvider.select((value) => value.toAmountString),
(previous, String next) {
ref.listen(efReceiveAmountStringProvider, (previous, String next) {
if (!_receiveFocusNode.hasFocus) {
_receiveController.text = isEstimated && next.isEmpty ? "-" : next;
if (_swapLock) {
_sendController.text =
ref.read(exchangeFormStateProvider).fromAmountString;
}
// if (_swapLock) {
_sendController.text = ref.read(efSendAmountStringProvider);
// }
}
});
ref.listen(
exchangeFormStateProvider.select((value) => value.fromAmountString),
(previous, String next) {
ref.listen(efSendAmountStringProvider, (previous, String next) {
if (!_sendFocusNode.hasFocus) {
_sendController.text = next;
if (_swapLock) {
_receiveController.text = isEstimated
? ref.read(exchangeFormStateProvider).toAmountString.isEmpty
? "-"
: ref.read(exchangeFormStateProvider).toAmountString
: ref.read(exchangeFormStateProvider).toAmountString;
}
// if (_swapLock) {
_receiveController.text =
isEstimated && ref.read(efReceiveAmountStringProvider).isEmpty
? "-"
: ref.read(efReceiveAmountStringProvider);
// }
}
});
ref.listen(efEstimateProvider.notifier, (previous, next) {
if (ref.read(efReversedProvider)) {
updateSend((next as StateController<Estimate?>).state);
} else {
updateReceive((next as StateController<Estimate?>).state);
}
});
ref.listen(efCurrencyPairProvider, (previous, next) {
update();
});
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
@ -729,8 +803,9 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
height: isDesktop ? 10 : 4,
),
ExchangeTextField(
key: Key(
"exchangeTextFieldKeyFor_${Theme.of(context).extension<StackColors>()!.themeType.name}"),
key: Key("exchangeTextFieldKeyFor_"
"${Theme.of(context).extension<StackColors>()!.themeType.name}"
"${ref.watch(efCurrencyPairProvider.select((value) => value.send?.ticker))}"),
controller: _sendController,
focusNode: _sendFocusNode,
textStyle: STextStyles.smallMed14(context).copyWith(
@ -749,8 +824,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: sendFieldOnChanged,
onButtonTap: selectSendCurrency,
isWalletCoin: isWalletCoin(coin, true),
currency: ref.watch(
exchangeFormStateProvider.select((value) => value.sendCurrency)),
currency:
ref.watch(efCurrencyPairProvider.select((value) => value.send)),
),
SizedBox(
height: isDesktop ? 10 : 4,
@ -758,15 +833,10 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
SizedBox(
height: isDesktop ? 10 : 4,
),
if (ref
.watch(
exchangeFormStateProvider.select((value) => value.warning))
.isNotEmpty &&
!ref.watch(
exchangeFormStateProvider.select((value) => value.reversed)))
if (ref.watch(efWarningProvider).isNotEmpty &&
!ref.watch(efReversedProvider))
Text(
ref.watch(
exchangeFormStateProvider.select((value) => value.warning)),
ref.watch(efWarningProvider),
style: STextStyles.errorSmall(context),
),
Row(
@ -830,8 +900,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
background:
Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
onTap: () {
if (!(ref.read(exchangeFormStateProvider).exchangeRateType ==
ExchangeRateType.estimated) &&
if (!(ref.read(efRateTypeProvider) == ExchangeRateType.estimated) &&
_receiveController.text == "-") {
_receiveController.text = "";
}
@ -839,22 +908,16 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: receiveFieldOnChanged,
onButtonTap: selectReceiveCurrency,
isWalletCoin: isWalletCoin(coin, true),
currency: ref.watch(exchangeFormStateProvider
.select((value) => value.receiveCurrency)),
currency: ref
.watch(efCurrencyPairProvider.select((value) => value.receive)),
readOnly: (rateType) == ExchangeRateType.estimated &&
ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)) ==
ref.watch(efExchangeProvider).name ==
ChangeNowExchange.exchangeName,
),
if (ref
.watch(
exchangeFormStateProvider.select((value) => value.warning))
.isNotEmpty &&
ref.watch(
exchangeFormStateProvider.select((value) => value.reversed)))
if (ref.watch(efWarningProvider).isNotEmpty &&
ref.watch(efReversedProvider))
Text(
ref.watch(
exchangeFormStateProvider.select((value) => value.warning)),
ref.watch(efWarningProvider),
style: STextStyles.errorSmall(context),
),
SizedBox(
@ -867,27 +930,28 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: onRateTypeChanged,
),
),
// these reads should be watch
if (ref.watch(exchangeFormStateProvider).sendAmount != null &&
ref.watch(exchangeFormStateProvider).sendAmount != Decimal.zero)
SizedBox(
height: isDesktop ? 20 : 12,
),
// these reads should be watch
if (ref.watch(exchangeFormStateProvider).sendAmount != null &&
ref.watch(exchangeFormStateProvider).sendAmount != Decimal.zero)
ExchangeProviderOptions(
// AnimatedSize(
// duration: const Duration(milliseconds: 250),
// curve: Curves.easeInOutCirc,
// child: ref.watch(efSendAmountProvider).sendAmount != null &&
// ref.watch(exchangeFormStateProvider).sendAmount != Decimal.zero
// ?
Padding(
padding: EdgeInsets.only(top: isDesktop ? 20 : 12),
child: ExchangeProviderOptions(
fixedRate: rateType == ExchangeRateType.fixed,
reversed: ref.watch(
exchangeFormStateProvider.select((value) => value.reversed)),
reversed: ref.watch(efReversedProvider),
),
// : const SizedBox(
// height: 0,
// ),
),
SizedBox(
height: isDesktop ? 20 : 12,
),
PrimaryButton(
buttonHeight: isDesktop ? ButtonHeight.l : null,
enabled: ref.watch(
exchangeFormStateProvider.select((value) => value.canExchange)),
enabled: ref.watch(efCanExchangeProvider),
onPressed: onExchangePressed,
label: "Swap",
)

View file

@ -124,9 +124,8 @@ class _Step2ViewState extends ConsumerState<Step2View> {
@override
Widget build(BuildContext context) {
final supportsRefund = ref.watch(
exchangeFormStateProvider.select((value) => value.exchange.name)) !=
MajesticBankExchange.exchangeName;
final supportsRefund =
ref.watch(efExchangeProvider).name != MajesticBankExchange.exchangeName;
return Background(
child: Scaffold(

View file

@ -52,9 +52,8 @@ class _Step3ViewState extends ConsumerState<Step3View> {
@override
Widget build(BuildContext context) {
final supportsRefund = ref.watch(
exchangeFormStateProvider.select((value) => value.exchange.name)) !=
MajesticBankExchange.exchangeName;
final supportsRefund =
ref.watch(efExchangeProvider).name != MajesticBankExchange.exchangeName;
return Background(
child: Scaffold(
@ -254,8 +253,7 @@ class _Step3ViewState extends ConsumerState<Step3View> {
final ExchangeResponse<Trade> response =
await ref
.read(exchangeFormStateProvider)
.exchange
.read(efExchangeProvider)
.createTrade(
from: model.sendTicker,
to: model.receiveTicker,

View file

@ -70,10 +70,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
}
Future<void> _updateStatus() async {
final statusResponse = await ref
.read(exchangeFormStateProvider)
.exchange
.updateTrade(model.trade!);
final statusResponse =
await ref.read(efExchangeProvider).updateTrade(model.trade!);
String status = "Waiting";
if (statusResponse.value != null) {
status = statusResponse.value!.status;

View file

@ -37,7 +37,8 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;
@ -53,7 +54,8 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;

View file

@ -2,12 +2,10 @@ import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/exceptions/exchange/pair_unavailable_exception.dart';
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
import 'package:stackwallet/providers/exchange/exchange_form_state_provider.dart';
import 'package:stackwallet/providers/global/locale_provider.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/utilities/amount/amount.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
@ -42,138 +40,121 @@ class _ExchangeMultiProviderOptionState extends ConsumerState<ExchangeOption> {
@override
Widget build(BuildContext context) {
final sendCurrency = ref
.watch(exchangeFormStateProvider.select((value) => value.sendCurrency));
final receivingCurrency = ref.watch(
exchangeFormStateProvider.select((value) => value.receiveCurrency));
final fromAmount = ref
.watch(exchangeFormStateProvider.select((value) => value.sendAmount));
final toAmount = ref.watch(
exchangeFormStateProvider.select((value) => value.receiveAmount));
final sendCurrency =
ref.watch(efCurrencyPairProvider.select((value) => value.send));
final receivingCurrency =
ref.watch(efCurrencyPairProvider.select((value) => value.receive));
final reversed = ref.watch(efReversedProvider);
final amount = reversed
? ref.watch(efReceiveAmountProvider)
: ref.watch(efSendAmountProvider);
final estimates = ref.watch(efEstimatesListProvider(widget.exchange.name));
return AnimatedSize(
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOutCubicEmphasized,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (sendCurrency != null &&
child: Builder(
builder: (_) {
if (ref.watch(efRefreshingProvider)) {
// show loading
return _ProviderOption(
exchange: widget.exchange,
estimate: null,
rateString: "",
loadingString: true,
);
} else if (sendCurrency != null &&
receivingCurrency != null &&
toAmount != null &&
toAmount > Decimal.zero &&
fromAmount != null &&
fromAmount > Decimal.zero)
FutureBuilder(
future: widget.exchange.getEstimates(
sendCurrency.ticker,
receivingCurrency.ticker,
widget.reversed ? toAmount : fromAmount,
widget.fixedRate,
widget.reversed,
),
builder: (context,
AsyncSnapshot<ExchangeResponse<List<Estimate>>> snapshot) {
if (snapshot.connectionState == ConnectionState.done &&
snapshot.hasData) {
final estimates = snapshot.data?.value;
amount != null &&
amount > Decimal.zero) {
if (estimates != null && estimates.item1.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
for (int i = 0; i < estimates.item1.length; i++)
Builder(
builder: (context) {
final e = estimates.item1[i];
if (estimates != null && estimates.isNotEmpty) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
for (int i = 0; i < estimates.length; i++)
Builder(
builder: (context) {
final e = estimates[i];
int decimals;
try {
decimals = coinFromTickerCaseInsensitive(
receivingCurrency.ticker)
.decimals;
} catch (_) {
decimals = 8; // some reasonable alternative
}
Amount rate;
if (e.reversed) {
rate = (toAmount / e.estimatedAmount)
.toDecimal(scaleOnInfinitePrecision: 18)
.toAmount(fractionDigits: decimals);
} else {
rate = (e.estimatedAmount / fromAmount)
.toDecimal(scaleOnInfinitePrecision: 18)
.toAmount(fractionDigits: decimals);
}
int decimals;
try {
decimals = coinFromTickerCaseInsensitive(
receivingCurrency.ticker)
.decimals;
} catch (_) {
decimals = 8; // some reasonable alternative
}
Amount rate;
if (e.reversed) {
rate = (amount / e.estimatedAmount)
.toDecimal(scaleOnInfinitePrecision: 18)
.toAmount(fractionDigits: decimals);
} else {
rate = (e.estimatedAmount / amount)
.toDecimal(scaleOnInfinitePrecision: 18)
.toAmount(fractionDigits: decimals);
}
final rateString =
"1 ${sendCurrency.ticker.toUpperCase()} ~ ${rate.localizedStringAsFixed(
locale: ref.watch(
localeServiceChangeNotifierProvider
.select((value) => value.locale),
),
)} ${receivingCurrency.ticker.toUpperCase()}";
return ConditionalParent(
condition: i > 0,
builder: (child) => Column(
mainAxisSize: MainAxisSize.min,
children: [
isDesktop
? Container(
height: 1,
color: Theme.of(context)
.extension<StackColors>()!
.background,
)
: const SizedBox(
height: 16,
),
child,
],
),
child: _ProviderOption(
key: Key(widget.exchange.name +
e.exchangeProvider),
exchange: widget.exchange,
providerName: e.exchangeProvider,
rateString: rateString,
kycRating: e.kycRating,
),
);
},
final rateString =
"1 ${sendCurrency.ticker.toUpperCase()} ~ ${rate.localizedStringAsFixed(
locale: ref.watch(
localeServiceChangeNotifierProvider
.select((value) => value.locale),
),
],
);
} else if (snapshot.data?.exception
is PairUnavailableException) {
return _ProviderOption(
exchange: widget.exchange,
providerName: widget.exchange.name,
rateString: "Unsupported pair",
);
} else {
Logging.instance.log(
"$runtimeType failed to fetch rate for ${widget.exchange.name}: ${snapshot.data}",
level: LogLevel.Warning,
);
)} ${receivingCurrency.ticker.toUpperCase()}";
return _ProviderOption(
exchange: widget.exchange,
providerName: widget.exchange.name,
rateString: "Failed to fetch rate",
);
}
} else {
// show loading
return _ProviderOption(
exchange: widget.exchange,
providerName: widget.exchange.name,
rateString: "",
loadingString: true,
);
}
},
),
],
return ConditionalParent(
condition: i > 0,
builder: (child) => Column(
mainAxisSize: MainAxisSize.min,
children: [
isDesktop
? Container(
height: 1,
color: Theme.of(context)
.extension<StackColors>()!
.background,
)
: const SizedBox(
height: 16,
),
child,
],
),
child: _ProviderOption(
key: Key(widget.exchange.name + e.exchangeProvider),
exchange: widget.exchange,
estimate: e,
rateString: rateString,
kycRating: e.kycRating,
),
);
},
),
],
);
} else {
Logging.instance.log(
"$runtimeType failed to fetch rate for ${widget.exchange.name}: $estimates",
level: LogLevel.Warning,
);
return _ProviderOption(
exchange: widget.exchange,
estimate: null,
rateString: "Failed to fetch rate",
);
}
} else {
// show n/a
return _ProviderOption(
exchange: widget.exchange,
estimate: null,
rateString: "n/a",
);
}
},
),
);
}
@ -183,14 +164,14 @@ class _ProviderOption extends ConsumerStatefulWidget {
const _ProviderOption({
Key? key,
required this.exchange,
required this.providerName,
required this.estimate,
required this.rateString,
this.kycRating,
this.loadingString = false,
}) : super(key: key);
final Exchange exchange;
final String providerName;
final Estimate? estimate;
final String rateString;
final String? kycRating;
final bool loadingString;
@ -206,25 +187,27 @@ class _ProviderOptionState extends ConsumerState<_ProviderOption> {
@override
void initState() {
_id = "${widget.exchange.name} (${widget.providerName})";
_id =
"${widget.exchange.name} (${widget.estimate?.exchangeProvider ?? widget.exchange.name})";
super.initState();
}
@override
Widget build(BuildContext context) {
bool selected = ref.watch(exchangeFormStateProvider
.select((value) => value.combinedExchangeId)) ==
_id;
String groupValue = ref.watch(
exchangeFormStateProvider.select((value) => value.combinedExchangeId));
String groupValue = ref.watch(currentCombinedExchangeIdProvider);
if (ref.watch(
exchangeFormStateProvider.select((value) => value.exchange.name)) ==
widget.providerName) {
selected = true;
if (ref.watch(efExchangeProvider).name ==
(widget.estimate?.exchangeProvider ?? widget.exchange.name)) {
groupValue = _id;
}
bool selected = groupValue == _id;
print("========================================================");
print("gourpValue: $groupValue");
print("_id: $_id");
print("========================================================");
return ConditionalParent(
condition: isDesktop,
builder: (child) => MouseRegion(
@ -233,15 +216,20 @@ class _ProviderOptionState extends ConsumerState<_ProviderOption> {
),
child: GestureDetector(
onTap: () {
if (!selected) {
ref.read(exchangeFormStateProvider).updateExchange(
exchange: widget.exchange,
shouldUpdateData: true,
shouldNotifyListeners: true,
providerName: widget.providerName,
shouldAwait: false,
);
}
ref.read(efExchangeProvider.notifier).state = widget.exchange;
ref.read(efExchangeProviderNameProvider.notifier).state =
widget.estimate?.exchangeProvider ?? widget.exchange.name;
// if (!selected) {
// ref.read(exchangeFormStateProvider).updateExchange(
// exchange: widget.exchange,
// shouldUpdateData: false,
// shouldNotifyListeners: false,
// providerName:
// widget.estimate?.exchangeProvider ?? widget.exchange.name,
// shouldAwait: false,
// );
// }
},
child: Container(
color: Colors.transparent,
@ -263,15 +251,26 @@ class _ProviderOptionState extends ConsumerState<_ProviderOption> {
value: _id,
groupValue: groupValue,
onChanged: (_) {
if (!selected) {
ref.read(exchangeFormStateProvider).updateExchange(
exchange: widget.exchange,
shouldUpdateData: false,
shouldNotifyListeners: true,
providerName: widget.providerName,
shouldAwait: false,
);
}
ref.read(efExchangeProvider.notifier).state =
widget.exchange;
ref
.read(efExchangeProviderNameProvider.notifier)
.state =
widget.estimate?.exchangeProvider ??
widget.exchange.name;
// if (!selected) {
//
//
// ref.read(exchangeFormStateProvider).updateExchange(
// exchange: widget.exchange,
// shouldUpdateData: false,
// shouldNotifyListeners: false,
// providerName:
// widget.estimate?.exchangeProvider ??
// widget.exchange.name,
// shouldAwait: false,
// );
// }
},
),
),
@ -303,7 +302,8 @@ class _ProviderOptionState extends ConsumerState<_ProviderOption> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.providerName,
widget.estimate?.exchangeProvider ??
widget.exchange.name,
style: STextStyles.titleBold12(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!

View file

@ -49,16 +49,10 @@ class _ExchangeProviderOptionsState
@override
Widget build(BuildContext context) {
final sendCurrency = ref.watch(
exchangeFormStateProvider.select(
(value) => value.sendCurrency,
),
);
final receivingCurrency = ref.watch(
exchangeFormStateProvider.select(
(value) => value.receiveCurrency,
),
);
final sendCurrency =
ref.watch(efCurrencyPairProvider.select((value) => value.send));
final receivingCurrency =
ref.watch(efCurrencyPairProvider.select((value) => value.receive));
final showChangeNow = exchangeSupported(
exchangeName: ChangeNowExchange.exchangeName,

View file

@ -29,9 +29,7 @@ class RateTypeToggle extends ConsumerWidget {
onChanged?.call(ExchangeRateType.estimated);
}
},
isOn: ref.watch(exchangeFormStateProvider
.select((value) => value.exchangeRateType)) ==
ExchangeRateType.fixed,
isOn: ref.watch(efRateTypeProvider) == ExchangeRateType.fixed,
onColor: isDesktop
? Theme.of(context)
.extension<StackColors>()!

View file

@ -54,7 +54,8 @@ class _WalletInitiatedExchangeViewState
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;
@ -70,7 +71,8 @@ class _WalletInitiatedExchangeViewState
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/desktop_all_trades_view.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart';
import 'package:stackwallet/providers/exchange/exchange_form_state_provider.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
@ -14,8 +15,6 @@ import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'desktop_all_trades_view.dart';
class DesktopExchangeView extends ConsumerStatefulWidget {
const DesktopExchangeView({Key? key}) : super(key: key);
@ -38,7 +37,8 @@ class _DesktopExchangeViewState extends ConsumerState<DesktopExchangeView> {
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;
@ -54,7 +54,8 @@ class _DesktopExchangeViewState extends ConsumerState<DesktopExchangeView> {
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
await ExchangeDataLoadingService.instance.setCurrenciesIfEmpty(
ref.read(exchangeFormStateProvider),
ref.read(efCurrencyPairProvider),
ref.read(efRateTypeProvider),
);
setState(() {
_initialCachePopulationUnderway = false;

View file

@ -84,8 +84,7 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
);
final ExchangeResponse<Trade> response = await ref
.read(exchangeFormStateProvider)
.exchange
.read(efExchangeProvider)
.createTrade(
from: ref.read(desktopExchangeModelProvider)!.sendTicker,
to: ref.read(desktopExchangeModelProvider)!.receiveTicker,

View file

@ -38,8 +38,7 @@ class DesktopStep1 extends ConsumerWidget {
children: [
DesktopStepItem(
label: "Swap",
value: ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)),
value: ref.watch(efExchangeProviderNameProvider),
),
Container(
height: 1,

View file

@ -36,8 +36,7 @@ class _DesktopStep3State extends ConsumerState<DesktopStep3> {
children: [
DesktopStepItem(
label: "Swap",
value: ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)),
value: ref.watch(efExchangeProviderNameProvider),
),
Container(
height: 1,

View file

@ -46,7 +46,7 @@ class _DesktopStep4State extends ConsumerState<DesktopStep4> {
}
final statusResponse =
await ref.read(exchangeFormStateProvider).exchange.updateTrade(trade);
await ref.read(efExchangeProvider).updateTrade(trade);
String status = "Waiting";
if (statusResponse.value != null) {
status = statusResponse.value!.status;

View file

@ -1,5 +1,116 @@
import 'package:decimal/decimal.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
import 'package:stackwallet/models/exchange/active_pair.dart';
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
import 'package:stackwallet/models/exchange/response_objects/range.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:tuple/tuple.dart';
final exchangeFormStateProvider =
ChangeNotifierProvider<ExchangeFormState>((ref) => ExchangeFormState());
final efEstimatesListProvider =
StateProvider.family<Tuple2<List<Estimate>, Range>?, String>(
(ref, exchangeName) => null);
final efRateTypeProvider =
StateProvider<ExchangeRateType>((ref) => ExchangeRateType.estimated);
final efExchangeProvider =
StateProvider<Exchange>((ref) => Exchange.defaultExchange);
final efExchangeProviderNameProvider =
StateProvider<String>((ref) => Exchange.defaultExchange.name);
final currentCombinedExchangeIdProvider = Provider<String>((ref) {
return "${ref.watch(efExchangeProvider).name}"
" (${ref.watch(efExchangeProviderNameProvider)})";
});
final efSendAmountProvider = StateProvider<Decimal?>((ref) => null);
final efReceiveAmountProvider = StateProvider<Decimal?>((ref) => null);
final efSendAmountStringProvider = StateProvider<String>((ref) {
return ref.watch(efSendAmountProvider)?.toStringAsFixed(8) ?? "";
});
final efReceiveAmountStringProvider = StateProvider<String>((ref) {
return ref.watch(efReceiveAmountProvider)?.toStringAsFixed(8) ?? "";
});
final efReversedProvider = StateProvider<bool>((ref) => false);
final efCurrencyPairProvider = ChangeNotifierProvider<ActivePair>(
(ref) => ActivePair(),
);
final efRangeProvider = StateProvider<Range?>((ref) {
final exchange = ref.watch(efExchangeProvider);
return ref.watch(efEstimatesListProvider(exchange.name))?.item2;
});
final efEstimateProvider = StateProvider<Estimate?>((ref) {
final exchange = ref.watch(efExchangeProvider);
final provider = ref.watch(efExchangeProviderNameProvider);
final reversed = ref.watch(efReversedProvider);
final fixedRate = ref.watch(efRateTypeProvider) == ExchangeRateType.fixed;
final matches =
ref.watch(efEstimatesListProvider(exchange.name))?.item1.where((e) {
return e.exchangeProvider == provider &&
e.fixedRate == fixedRate &&
e.reversed == reversed;
});
Estimate? result;
if (matches != null && matches.isNotEmpty) {
result = matches.first;
} else {
result = null;
}
return result;
});
final efCanExchangeProvider = StateProvider<bool>((ref) {
final Estimate? estimate = ref.watch(efEstimateProvider);
// final Decimal? amount = ref.watch(efReversedProvider)
// ? ref.watch(efSendAmountProvider)
// : ref.watch(efReceiveAmountProvider);
return estimate != null;
});
final efRefreshingProvider = StateProvider<bool>((ref) => false);
final efWarningProvider = StateProvider((ref) {
// if (ref.watch(efReversedProvider)) {
// final _receiveCurrency =
// ref.watch(efCurrencyPairProvider.select((value) => value.receive));
// final _receiveAmount = ref.watch(efReceiveAmountProvider);
// if (_receiveCurrency != null && _receiveAmount != null) {
// final range = ref.watch(efRangeProvider);
// if (range?.min != null &&
// _receiveAmount < range!.min! &&
// _receiveAmount > Decimal.zero) {
// return "Min receive amount ${range.min!.toString()} ${_receiveCurrency.ticker.toUpperCase()}";
// } else if (range?.max != null &&
// _receiveAmount > ref.watch(efRangeProvider)!.max!) {
// return "Max receive amount $range!.max!.toString()} ${_receiveCurrency.ticker.toUpperCase()}";
// }
// }
// } else {
// final _sendCurrency =
// ref.watch(efCurrencyPairProvider.select((value) => value.send));
// final _sendAmount = ref.watch(efSendAmountProvider);
// if (_sendCurrency != null && _sendAmount != null) {
// final range = ref.watch(efRangeProvider);
// if (range?.min != null &&
// _sendAmount < range!.min! &&
// _sendAmount > Decimal.zero) {
// return "Min send amount ${range.min!.toString()} ${_sendCurrency.ticker.toUpperCase()}";
// } else if (range?.max != null && _sendAmount > range!.max!) {
// return "Max send amount ${range.max!.toString()} ${_sendCurrency.ticker.toUpperCase()}";
// }
// }
// }
return "";
});

View file

@ -1,8 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:isar/isar.dart';
import 'package:stackwallet/db/hive/db.dart';
import 'package:stackwallet/models/exchange/active_pair.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
import 'package:stackwallet/models/exchange/exchange_form_state.dart';
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
@ -57,20 +57,29 @@ class ExchangeDataLoadingService {
);
}
Future<void> setCurrenciesIfEmpty(ExchangeFormState state) async {
if (state.sendCurrency == null && state.receiveCurrency == null) {
Future<void> setCurrenciesIfEmpty(
ActivePair? pair,
ExchangeRateType rateType,
) async {
if (pair?.send == null && pair?.receive == null) {
if (await isar.currencies.count() > 0) {
final sendCurrency = await getAggregateCurrency(
"BTC",
state.exchangeRateType,
null,
pair?.setSend(
await getAggregateCurrency(
"BTC",
rateType,
null,
),
notifyListeners: false,
);
final receiveCurrency = await getAggregateCurrency(
"XMR",
state.exchangeRateType,
null,
pair?.setReceive(
await getAggregateCurrency(
"XMR",
rateType,
null,
),
notifyListeners: false,
);
state.setCurrencies(sendCurrency, receiveCurrency);
}
}
}