mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2025-03-22 15:19:11 +00:00
only show exchanges supported by selected aggregate currency pair based on exchange flow type
This commit is contained in:
parent
b1c8a56ba6
commit
4630d616cd
5 changed files with 543 additions and 432 deletions
|
@ -19,8 +19,22 @@ class AggregateCurrency {
|
||||||
}
|
}
|
||||||
|
|
||||||
String get ticker => _map.values.first!.ticker;
|
String get ticker => _map.values.first!.ticker;
|
||||||
|
|
||||||
String get name => _map.values.first!.name;
|
String get name => _map.values.first!.name;
|
||||||
|
|
||||||
String get image => _map.values.first!.image;
|
String get image => _map.values.first!.image;
|
||||||
|
|
||||||
SupportedRateType get rateType => _map.values.first!.rateType;
|
SupportedRateType get rateType => _map.values.first!.rateType;
|
||||||
|
|
||||||
bool get isStackCoin => _map.values.first!.isStackCoin;
|
bool get isStackCoin => _map.values.first!.isStackCoin;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
String str = "AggregateCurrency: {";
|
||||||
|
for (final key in _map.keys) {
|
||||||
|
str += " $key: ${_map[key]},";
|
||||||
|
}
|
||||||
|
str += " }";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,9 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
|
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
|
||||||
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
||||||
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
|
||||||
|
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
||||||
import 'package:stackwallet/services/exchange/exchange.dart';
|
import 'package:stackwallet/services/exchange/exchange.dart';
|
||||||
|
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
|
||||||
import 'package:stackwallet/utilities/logger.dart';
|
import 'package:stackwallet/utilities/logger.dart';
|
||||||
|
|
||||||
class ExchangeFormState extends ChangeNotifier {
|
class ExchangeFormState extends ChangeNotifier {
|
||||||
|
@ -323,6 +325,29 @@ class ExchangeFormState extends ChangeNotifier {
|
||||||
required bool shouldNotifyListeners,
|
required bool shouldNotifyListeners,
|
||||||
}) async {
|
}) async {
|
||||||
try {
|
try {
|
||||||
|
switch (exchange.name) {
|
||||||
|
case ChangeNowExchange.exchangeName:
|
||||||
|
if (!_exchangeSupported(
|
||||||
|
exchangeName: exchange.name,
|
||||||
|
sendCurrency: sendCurrency,
|
||||||
|
receiveCurrency: receiveCurrency,
|
||||||
|
exchangeRateType: exchangeRateType,
|
||||||
|
)) {
|
||||||
|
_exchange = MajesticBankExchange.instance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MajesticBankExchange.exchangeName:
|
||||||
|
if (!_exchangeSupported(
|
||||||
|
exchangeName: exchange.name,
|
||||||
|
sendCurrency: sendCurrency,
|
||||||
|
receiveCurrency: receiveCurrency,
|
||||||
|
exchangeRateType: exchangeRateType,
|
||||||
|
)) {
|
||||||
|
_exchange = ChangeNowExchange.instance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
await _updateRanges(shouldNotifyListeners: false);
|
await _updateRanges(shouldNotifyListeners: false);
|
||||||
await _updateEstimate(shouldNotifyListeners: false);
|
await _updateEstimate(shouldNotifyListeners: false);
|
||||||
if (shouldNotifyListeners) {
|
if (shouldNotifyListeners) {
|
||||||
|
@ -452,6 +477,25 @@ class ExchangeFormState extends ChangeNotifier {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _exchangeSupported({
|
||||||
|
required String exchangeName,
|
||||||
|
required AggregateCurrency? sendCurrency,
|
||||||
|
required AggregateCurrency? receiveCurrency,
|
||||||
|
required ExchangeRateType exchangeRateType,
|
||||||
|
}) {
|
||||||
|
final send = sendCurrency?.forExchange(exchangeName);
|
||||||
|
if (send == null) return false;
|
||||||
|
|
||||||
|
final rcv = receiveCurrency?.forExchange(exchangeName);
|
||||||
|
if (rcv == null) return false;
|
||||||
|
|
||||||
|
if (exchangeRateType == ExchangeRateType.fixed) {
|
||||||
|
return send.supportsFixedRate && rcv.supportsFixedRate;
|
||||||
|
} else {
|
||||||
|
return send.supportsEstimatedRate && rcv.supportsEstimatedRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return "{"
|
return "{"
|
||||||
|
|
|
@ -44,6 +44,12 @@ class Currency {
|
||||||
@Index()
|
@Index()
|
||||||
final bool isStackCoin;
|
final bool isStackCoin;
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
bool get supportsFixedRate => rateType == SupportedRateType.fixed || rateType == SupportedRateType.both;
|
||||||
|
|
||||||
|
@ignore
|
||||||
|
bool get supportsEstimatedRate => rateType == SupportedRateType.estimated || rateType == SupportedRateType.both;
|
||||||
|
|
||||||
Currency({
|
Currency({
|
||||||
required this.exchangeName,
|
required this.exchangeName,
|
||||||
required this.ticker,
|
required this.ticker,
|
||||||
|
|
|
@ -862,10 +862,6 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
|
||||||
if (ref.watch(exchangeFormStateProvider).sendAmount != null &&
|
if (ref.watch(exchangeFormStateProvider).sendAmount != null &&
|
||||||
ref.watch(exchangeFormStateProvider).sendAmount != Decimal.zero)
|
ref.watch(exchangeFormStateProvider).sendAmount != Decimal.zero)
|
||||||
ExchangeProviderOptions(
|
ExchangeProviderOptions(
|
||||||
from: ref.watch(exchangeFormStateProvider).fromTicker,
|
|
||||||
to: ref.watch(exchangeFormStateProvider).toTicker,
|
|
||||||
fromAmount: ref.watch(exchangeFormStateProvider).sendAmount,
|
|
||||||
toAmount: ref.watch(exchangeFormStateProvider).receiveAmount,
|
|
||||||
fixedRate: rateType == ExchangeRateType.fixed,
|
fixedRate: rateType == ExchangeRateType.fixed,
|
||||||
reversed: ref.watch(
|
reversed: ref.watch(
|
||||||
exchangeFormStateProvider.select((value) => value.reversed)),
|
exchangeFormStateProvider.select((value) => value.reversed)),
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:stackwallet/exceptions/exchange/pair_unavailable_exception.dart';
|
import 'package:stackwallet/exceptions/exchange/pair_unavailable_exception.dart';
|
||||||
|
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
|
||||||
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
import 'package:stackwallet/models/exchange/response_objects/estimate.dart';
|
||||||
import 'package:stackwallet/providers/providers.dart';
|
import 'package:stackwallet/providers/providers.dart';
|
||||||
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
|
||||||
|
@ -20,27 +21,62 @@ import 'package:stackwallet/widgets/animated_text.dart';
|
||||||
import 'package:stackwallet/widgets/conditional_parent.dart';
|
import 'package:stackwallet/widgets/conditional_parent.dart';
|
||||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||||
|
|
||||||
class ExchangeProviderOptions extends ConsumerWidget {
|
class ExchangeProviderOptions extends ConsumerStatefulWidget {
|
||||||
const ExchangeProviderOptions({
|
const ExchangeProviderOptions({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.from,
|
|
||||||
required this.to,
|
|
||||||
required this.fromAmount,
|
|
||||||
required this.toAmount,
|
|
||||||
required this.fixedRate,
|
required this.fixedRate,
|
||||||
required this.reversed,
|
required this.reversed,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final String? from;
|
|
||||||
final String? to;
|
|
||||||
final Decimal? fromAmount;
|
|
||||||
final Decimal? toAmount;
|
|
||||||
final bool fixedRate;
|
final bool fixedRate;
|
||||||
final bool reversed;
|
final bool reversed;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
ConsumerState<ExchangeProviderOptions> createState() =>
|
||||||
final isDesktop = Util.isDesktop;
|
_ExchangeProviderOptionsState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ExchangeProviderOptionsState
|
||||||
|
extends ConsumerState<ExchangeProviderOptions> {
|
||||||
|
final isDesktop = Util.isDesktop;
|
||||||
|
|
||||||
|
bool exchangeSupported({
|
||||||
|
required String exchangeName,
|
||||||
|
required AggregateCurrency? sendCurrency,
|
||||||
|
required AggregateCurrency? receiveCurrency,
|
||||||
|
}) {
|
||||||
|
final send = sendCurrency?.forExchange(exchangeName);
|
||||||
|
if (send == null) return false;
|
||||||
|
|
||||||
|
final rcv = receiveCurrency?.forExchange(exchangeName);
|
||||||
|
if (rcv == null) return false;
|
||||||
|
|
||||||
|
if (widget.fixedRate) {
|
||||||
|
return send.supportsFixedRate && rcv.supportsFixedRate;
|
||||||
|
} else {
|
||||||
|
return send.supportsEstimatedRate && rcv.supportsEstimatedRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final sendCurrency = ref.watch(exchangeFormStateProvider).sendCurrency;
|
||||||
|
final receivingCurrency =
|
||||||
|
ref.watch(exchangeFormStateProvider).receiveCurrency;
|
||||||
|
final fromAmount = ref.watch(exchangeFormStateProvider).sendAmount;
|
||||||
|
final toAmount = ref.watch(exchangeFormStateProvider).receiveAmount;
|
||||||
|
|
||||||
|
final showChangeNow = exchangeSupported(
|
||||||
|
exchangeName: ChangeNowExchange.exchangeName,
|
||||||
|
sendCurrency: sendCurrency,
|
||||||
|
receiveCurrency: receivingCurrency,
|
||||||
|
);
|
||||||
|
final showMajesticBank = exchangeSupported(
|
||||||
|
exchangeName: MajesticBankExchange.exchangeName,
|
||||||
|
sendCurrency: sendCurrency,
|
||||||
|
receiveCurrency: receivingCurrency,
|
||||||
|
);
|
||||||
|
|
||||||
return RoundedWhiteContainer(
|
return RoundedWhiteContainer(
|
||||||
padding: isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(12),
|
padding: isDesktop ? const EdgeInsets.all(0) : const EdgeInsets.all(12),
|
||||||
borderColor: isDesktop
|
borderColor: isDesktop
|
||||||
|
@ -48,181 +84,203 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
: null,
|
: null,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
ConditionalParent(
|
if (showChangeNow)
|
||||||
condition: isDesktop,
|
ConditionalParent(
|
||||||
builder: (child) => MouseRegion(
|
condition: isDesktop,
|
||||||
cursor: SystemMouseCursors.click,
|
builder: (child) => MouseRegion(
|
||||||
child: child,
|
cursor: SystemMouseCursors.click,
|
||||||
),
|
child: child,
|
||||||
child: GestureDetector(
|
),
|
||||||
onTap: () {
|
child: GestureDetector(
|
||||||
if (ref.read(currentExchangeNameStateProvider.state).state !=
|
onTap: () {
|
||||||
ChangeNowExchange.exchangeName) {
|
if (ref.read(currentExchangeNameStateProvider.state).state !=
|
||||||
ref.read(currentExchangeNameStateProvider.state).state =
|
ChangeNowExchange.exchangeName) {
|
||||||
ChangeNowExchange.exchangeName;
|
ref.read(currentExchangeNameStateProvider.state).state =
|
||||||
ref.read(exchangeFormStateProvider).updateExchange(
|
ChangeNowExchange.exchangeName;
|
||||||
exchange: ref.read(exchangeProvider),
|
ref.read(exchangeFormStateProvider).updateExchange(
|
||||||
shouldUpdateData: true,
|
exchange: ref.read(exchangeProvider),
|
||||||
shouldNotifyListeners: true,
|
shouldUpdateData: true,
|
||||||
);
|
shouldNotifyListeners: true,
|
||||||
}
|
);
|
||||||
},
|
}
|
||||||
child: Container(
|
},
|
||||||
color: Colors.transparent,
|
child: Container(
|
||||||
child: Padding(
|
color: Colors.transparent,
|
||||||
padding: isDesktop
|
child: Padding(
|
||||||
? const EdgeInsets.all(16)
|
padding: isDesktop
|
||||||
: const EdgeInsets.all(0),
|
? const EdgeInsets.all(16)
|
||||||
child: Row(
|
: const EdgeInsets.all(0),
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
child: Row(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
SizedBox(
|
children: [
|
||||||
width: 20,
|
SizedBox(
|
||||||
height: 20,
|
width: 20,
|
||||||
child: Padding(
|
height: 20,
|
||||||
padding:
|
child: Padding(
|
||||||
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
|
padding:
|
||||||
child: Radio(
|
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
|
||||||
activeColor: Theme.of(context)
|
child: Radio(
|
||||||
.extension<StackColors>()!
|
activeColor: Theme.of(context)
|
||||||
.radioButtonIconEnabled,
|
.extension<StackColors>()!
|
||||||
value: ChangeNowExchange.exchangeName,
|
.radioButtonIconEnabled,
|
||||||
groupValue: ref
|
value: ChangeNowExchange.exchangeName,
|
||||||
.watch(currentExchangeNameStateProvider.state)
|
groupValue: ref
|
||||||
.state,
|
.watch(currentExchangeNameStateProvider.state)
|
||||||
onChanged: (_) {
|
.state,
|
||||||
// if (value is String) {
|
onChanged: (_) {
|
||||||
// ref
|
if (ref
|
||||||
// .read(
|
.read(currentExchangeNameStateProvider
|
||||||
// currentExchangeNameStateProvider.state)
|
.state)
|
||||||
// .state = value;
|
.state !=
|
||||||
// ref
|
ChangeNowExchange.exchangeName) {
|
||||||
// .read(exchangeFormStateProvider(ref
|
ref
|
||||||
// .read(prefsChangeNotifierProvider)
|
.read(currentExchangeNameStateProvider
|
||||||
// .exchangeRateType))
|
.state)
|
||||||
// .exchange =
|
.state = ChangeNowExchange.exchangeName;
|
||||||
// Exchange.fromName(ref
|
ref
|
||||||
// .read(currentExchangeNameStateProvider
|
.read(exchangeFormStateProvider)
|
||||||
// .state)
|
.updateExchange(
|
||||||
// .state);
|
exchange: ref.read(exchangeProvider),
|
||||||
// }
|
shouldUpdateData: true,
|
||||||
},
|
shouldNotifyListeners: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
width: 14,
|
||||||
width: 14,
|
),
|
||||||
),
|
Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.only(top: 5.0),
|
||||||
padding: const EdgeInsets.only(top: 5.0),
|
child: SizedBox(
|
||||||
child: SizedBox(
|
|
||||||
width: isDesktop ? 32 : 24,
|
|
||||||
height: isDesktop ? 32 : 24,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.exchange.changeNow,
|
|
||||||
width: isDesktop ? 32 : 24,
|
width: isDesktop ? 32 : 24,
|
||||||
height: isDesktop ? 32 : 24,
|
height: isDesktop ? 32 : 24,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.exchange.changeNow,
|
||||||
|
width: isDesktop ? 32 : 24,
|
||||||
|
height: isDesktop ? 32 : 24,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
width: 10,
|
||||||
width: 10,
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
ChangeNowExchange.exchangeName,
|
||||||
ChangeNowExchange.exchangeName,
|
style:
|
||||||
style: STextStyles.titleBold12(context).copyWith(
|
STextStyles.titleBold12(context).copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.textDark2,
|
.textDark2,
|
||||||
),
|
|
||||||
),
|
|
||||||
if (from != null &&
|
|
||||||
to != null &&
|
|
||||||
toAmount != null &&
|
|
||||||
toAmount! > Decimal.zero &&
|
|
||||||
fromAmount != null &&
|
|
||||||
fromAmount! > Decimal.zero)
|
|
||||||
FutureBuilder(
|
|
||||||
future: ChangeNowExchange.instance.getEstimate(
|
|
||||||
from!,
|
|
||||||
to!,
|
|
||||||
reversed ? toAmount! : fromAmount!,
|
|
||||||
fixedRate,
|
|
||||||
reversed,
|
|
||||||
),
|
),
|
||||||
builder: (context,
|
),
|
||||||
AsyncSnapshot<ExchangeResponse<Estimate>>
|
if (sendCurrency != null &&
|
||||||
snapshot) {
|
receivingCurrency != null &&
|
||||||
if (snapshot.connectionState ==
|
toAmount != null &&
|
||||||
ConnectionState.done &&
|
toAmount > Decimal.zero &&
|
||||||
snapshot.hasData) {
|
fromAmount != null &&
|
||||||
final estimate = snapshot.data?.value;
|
fromAmount > Decimal.zero)
|
||||||
if (estimate != null) {
|
FutureBuilder(
|
||||||
Decimal rate;
|
future:
|
||||||
if (estimate.reversed) {
|
ChangeNowExchange.instance.getEstimate(
|
||||||
rate = (toAmount! /
|
sendCurrency.ticker,
|
||||||
estimate.estimatedAmount)
|
receivingCurrency.ticker,
|
||||||
.toDecimal(
|
widget.reversed ? toAmount : fromAmount,
|
||||||
scaleOnInfinitePrecision: 12);
|
widget.fixedRate,
|
||||||
} else {
|
widget.reversed,
|
||||||
rate = (estimate.estimatedAmount /
|
),
|
||||||
fromAmount!)
|
builder: (context,
|
||||||
.toDecimal(
|
AsyncSnapshot<ExchangeResponse<Estimate>>
|
||||||
scaleOnInfinitePrecision: 12);
|
snapshot) {
|
||||||
}
|
if (snapshot.connectionState ==
|
||||||
Coin coin;
|
ConnectionState.done &&
|
||||||
try {
|
snapshot.hasData) {
|
||||||
coin =
|
final estimate = snapshot.data?.value;
|
||||||
coinFromTickerCaseInsensitive(to!);
|
if (estimate != null) {
|
||||||
} catch (_) {
|
Decimal rate;
|
||||||
coin = Coin.bitcoin;
|
if (estimate.reversed) {
|
||||||
}
|
rate = (toAmount /
|
||||||
|
estimate.estimatedAmount)
|
||||||
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: 12);
|
||||||
|
} else {
|
||||||
|
rate = (estimate.estimatedAmount /
|
||||||
|
fromAmount)
|
||||||
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: 12);
|
||||||
|
}
|
||||||
|
Coin coin;
|
||||||
|
try {
|
||||||
|
coin = coinFromTickerCaseInsensitive(
|
||||||
|
receivingCurrency.ticker);
|
||||||
|
} catch (_) {
|
||||||
|
coin = Coin.bitcoin;
|
||||||
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
"1 ${sendCurrency.ticker.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
||||||
value: rate,
|
value: rate,
|
||||||
locale: ref.watch(
|
locale: ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale),
|
(value) => value.locale),
|
||||||
|
),
|
||||||
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin),
|
||||||
|
)} ${receivingCurrency.ticker.toUpperCase()}",
|
||||||
|
style: STextStyles.itemSubtitle12(
|
||||||
|
context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
),
|
),
|
||||||
decimalPlaces:
|
);
|
||||||
Constants.decimalPlacesForCoin(
|
} else if (snapshot.data?.exception
|
||||||
coin),
|
is PairUnavailableException) {
|
||||||
)} ${to!.toUpperCase()}",
|
return Text(
|
||||||
style:
|
"Unsupported pair",
|
||||||
STextStyles.itemSubtitle12(context)
|
style: STextStyles.itemSubtitle12(
|
||||||
.copyWith(
|
context)
|
||||||
color: Theme.of(context)
|
.copyWith(
|
||||||
.extension<StackColors>()!
|
color: Theme.of(context)
|
||||||
.textSubtitle1,
|
.extension<StackColors>()!
|
||||||
),
|
.textSubtitle1,
|
||||||
);
|
),
|
||||||
} else if (snapshot.data?.exception
|
);
|
||||||
is PairUnavailableException) {
|
} else {
|
||||||
return Text(
|
Logging.instance.log(
|
||||||
"Unsupported pair",
|
"$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
|
||||||
style:
|
level: LogLevel.Warning,
|
||||||
STextStyles.itemSubtitle12(context)
|
);
|
||||||
.copyWith(
|
return Text(
|
||||||
color: Theme.of(context)
|
"Failed to fetch rate",
|
||||||
.extension<StackColors>()!
|
style: STextStyles.itemSubtitle12(
|
||||||
.textSubtitle1,
|
context)
|
||||||
),
|
.copyWith(
|
||||||
);
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logging.instance.log(
|
return AnimatedText(
|
||||||
"$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
|
stringsToLoopThrough: const [
|
||||||
level: LogLevel.Warning,
|
"Loading",
|
||||||
);
|
"Loading.",
|
||||||
return Text(
|
"Loading..",
|
||||||
"Failed to fetch rate",
|
"Loading...",
|
||||||
|
],
|
||||||
style:
|
style:
|
||||||
STextStyles.itemSubtitle12(context)
|
STextStyles.itemSubtitle12(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
|
@ -232,233 +290,242 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
return AnimatedText(
|
|
||||||
stringsToLoopThrough: const [
|
|
||||||
"Loading",
|
|
||||||
"Loading.",
|
|
||||||
"Loading..",
|
|
||||||
"Loading...",
|
|
||||||
],
|
|
||||||
style: STextStyles.itemSubtitle12(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (!(from != null &&
|
|
||||||
to != null &&
|
|
||||||
toAmount != null &&
|
|
||||||
toAmount! > Decimal.zero &&
|
|
||||||
fromAmount != null &&
|
|
||||||
fromAmount! > Decimal.zero))
|
|
||||||
Text(
|
|
||||||
"n/a",
|
|
||||||
style: STextStyles.itemSubtitle12(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
),
|
||||||
),
|
if (!(sendCurrency != null &&
|
||||||
],
|
receivingCurrency != null &&
|
||||||
|
toAmount != null &&
|
||||||
|
toAmount > Decimal.zero &&
|
||||||
|
fromAmount != null &&
|
||||||
|
fromAmount > Decimal.zero))
|
||||||
|
Text(
|
||||||
|
"n/a",
|
||||||
|
style: STextStyles.itemSubtitle12(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
if (isDesktop)
|
if (showChangeNow && showMajesticBank)
|
||||||
Container(
|
isDesktop
|
||||||
height: 1,
|
? Container(
|
||||||
color: Theme.of(context).extension<StackColors>()!.background,
|
height: 1,
|
||||||
),
|
color:
|
||||||
if (!isDesktop)
|
Theme.of(context).extension<StackColors>()!.background,
|
||||||
const SizedBox(
|
)
|
||||||
height: 16,
|
: const SizedBox(
|
||||||
),
|
height: 16,
|
||||||
ConditionalParent(
|
),
|
||||||
condition: isDesktop,
|
|
||||||
builder: (child) => MouseRegion(
|
if (showMajesticBank)
|
||||||
cursor: SystemMouseCursors.click,
|
ConditionalParent(
|
||||||
child: child,
|
condition: isDesktop,
|
||||||
),
|
builder: (child) => MouseRegion(
|
||||||
child: GestureDetector(
|
cursor: SystemMouseCursors.click,
|
||||||
onTap: () {
|
child: child,
|
||||||
if (ref.read(currentExchangeNameStateProvider.state).state !=
|
),
|
||||||
MajesticBankExchange.exchangeName) {
|
child: GestureDetector(
|
||||||
ref.read(currentExchangeNameStateProvider.state).state =
|
onTap: () {
|
||||||
MajesticBankExchange.exchangeName;
|
if (ref.read(currentExchangeNameStateProvider.state).state !=
|
||||||
ref.read(exchangeFormStateProvider).updateExchange(
|
MajesticBankExchange.exchangeName) {
|
||||||
exchange: ref.read(exchangeProvider),
|
ref.read(currentExchangeNameStateProvider.state).state =
|
||||||
shouldUpdateData: true,
|
MajesticBankExchange.exchangeName;
|
||||||
shouldNotifyListeners: true,
|
ref.read(exchangeFormStateProvider).updateExchange(
|
||||||
);
|
exchange: ref.read(exchangeProvider),
|
||||||
}
|
shouldUpdateData: true,
|
||||||
},
|
shouldNotifyListeners: true,
|
||||||
child: Container(
|
);
|
||||||
color: Colors.transparent,
|
}
|
||||||
child: Padding(
|
},
|
||||||
padding: isDesktop
|
child: Container(
|
||||||
? const EdgeInsets.all(16)
|
color: Colors.transparent,
|
||||||
: const EdgeInsets.all(0),
|
child: Padding(
|
||||||
child: Row(
|
padding: isDesktop
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
? const EdgeInsets.all(16)
|
||||||
children: [
|
: const EdgeInsets.all(0),
|
||||||
SizedBox(
|
child: Row(
|
||||||
width: 20,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
height: 20,
|
children: [
|
||||||
child: Padding(
|
SizedBox(
|
||||||
padding:
|
width: 20,
|
||||||
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
|
height: 20,
|
||||||
child: Radio(
|
child: Padding(
|
||||||
activeColor: Theme.of(context)
|
padding:
|
||||||
.extension<StackColors>()!
|
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
|
||||||
.radioButtonIconEnabled,
|
child: Radio(
|
||||||
value: MajesticBankExchange.exchangeName,
|
activeColor: Theme.of(context)
|
||||||
groupValue: ref
|
.extension<StackColors>()!
|
||||||
.watch(currentExchangeNameStateProvider.state)
|
.radioButtonIconEnabled,
|
||||||
.state,
|
value: MajesticBankExchange.exchangeName,
|
||||||
onChanged: (_) {
|
groupValue: ref
|
||||||
// if (value is String) {
|
.watch(currentExchangeNameStateProvider.state)
|
||||||
// ref
|
.state,
|
||||||
// .read(
|
onChanged: (_) {
|
||||||
// currentExchangeNameStateProvider.state)
|
if (ref
|
||||||
// .state = value;
|
.read(currentExchangeNameStateProvider
|
||||||
// ref
|
.state)
|
||||||
// .read(exchangeFormStateProvider(ref
|
.state !=
|
||||||
// .read(prefsChangeNotifierProvider)
|
MajesticBankExchange.exchangeName) {
|
||||||
// .exchangeRateType))
|
ref
|
||||||
// .exchange =
|
.read(currentExchangeNameStateProvider
|
||||||
// Exchange.fromName(ref
|
.state)
|
||||||
// .read(currentExchangeNameStateProvider
|
.state =
|
||||||
// .state)
|
MajesticBankExchange.exchangeName;
|
||||||
// .state);
|
ref
|
||||||
// }
|
.read(exchangeFormStateProvider)
|
||||||
},
|
.updateExchange(
|
||||||
|
exchange: ref.read(exchangeProvider),
|
||||||
|
shouldUpdateData: true,
|
||||||
|
shouldNotifyListeners: true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
width: 14,
|
||||||
width: 14,
|
),
|
||||||
),
|
Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.only(top: 5.0),
|
||||||
padding: const EdgeInsets.only(top: 5.0),
|
child: SizedBox(
|
||||||
child: SizedBox(
|
|
||||||
width: isDesktop ? 32 : 24,
|
|
||||||
height: isDesktop ? 32 : 24,
|
|
||||||
child: SvgPicture.asset(
|
|
||||||
Assets.exchange.majesticBankBlue,
|
|
||||||
width: isDesktop ? 32 : 24,
|
width: isDesktop ? 32 : 24,
|
||||||
height: isDesktop ? 32 : 24,
|
height: isDesktop ? 32 : 24,
|
||||||
|
child: SvgPicture.asset(
|
||||||
|
Assets.exchange.majesticBankBlue,
|
||||||
|
width: isDesktop ? 32 : 24,
|
||||||
|
height: isDesktop ? 32 : 24,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
width: 10,
|
||||||
width: 10,
|
),
|
||||||
),
|
Expanded(
|
||||||
Expanded(
|
child: Column(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisSize: MainAxisSize.min,
|
||||||
mainAxisSize: MainAxisSize.min,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
MajesticBankExchange.exchangeName,
|
||||||
MajesticBankExchange.exchangeName,
|
style:
|
||||||
style: STextStyles.titleBold12(context).copyWith(
|
STextStyles.titleBold12(context).copyWith(
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.extension<StackColors>()!
|
.extension<StackColors>()!
|
||||||
.textDark2,
|
.textDark2,
|
||||||
),
|
|
||||||
),
|
|
||||||
if (from != null &&
|
|
||||||
to != null &&
|
|
||||||
toAmount != null &&
|
|
||||||
toAmount! > Decimal.zero &&
|
|
||||||
fromAmount != null &&
|
|
||||||
fromAmount! > Decimal.zero)
|
|
||||||
FutureBuilder(
|
|
||||||
future:
|
|
||||||
MajesticBankExchange.instance.getEstimate(
|
|
||||||
from!,
|
|
||||||
to!,
|
|
||||||
reversed ? toAmount! : fromAmount!,
|
|
||||||
fixedRate,
|
|
||||||
reversed,
|
|
||||||
),
|
),
|
||||||
builder: (context,
|
),
|
||||||
AsyncSnapshot<ExchangeResponse<Estimate>>
|
if (sendCurrency != null &&
|
||||||
snapshot) {
|
receivingCurrency != null &&
|
||||||
if (snapshot.connectionState ==
|
toAmount != null &&
|
||||||
ConnectionState.done &&
|
toAmount > Decimal.zero &&
|
||||||
snapshot.hasData) {
|
fromAmount != null &&
|
||||||
final estimate = snapshot.data?.value;
|
fromAmount > Decimal.zero)
|
||||||
if (estimate != null) {
|
FutureBuilder(
|
||||||
Decimal rate;
|
future:
|
||||||
if (estimate.reversed) {
|
MajesticBankExchange.instance.getEstimate(
|
||||||
rate = (toAmount! /
|
sendCurrency.ticker,
|
||||||
estimate.estimatedAmount)
|
receivingCurrency.ticker,
|
||||||
.toDecimal(
|
widget.reversed ? toAmount : fromAmount,
|
||||||
scaleOnInfinitePrecision: 12);
|
widget.fixedRate,
|
||||||
} else {
|
widget.reversed,
|
||||||
rate = (estimate.estimatedAmount /
|
),
|
||||||
fromAmount!)
|
builder: (context,
|
||||||
.toDecimal(
|
AsyncSnapshot<ExchangeResponse<Estimate>>
|
||||||
scaleOnInfinitePrecision: 12);
|
snapshot) {
|
||||||
}
|
if (snapshot.connectionState ==
|
||||||
Coin coin;
|
ConnectionState.done &&
|
||||||
try {
|
snapshot.hasData) {
|
||||||
coin =
|
final estimate = snapshot.data?.value;
|
||||||
coinFromTickerCaseInsensitive(to!);
|
if (estimate != null) {
|
||||||
} catch (_) {
|
Decimal rate;
|
||||||
coin = Coin.bitcoin;
|
if (estimate.reversed) {
|
||||||
}
|
rate = (toAmount /
|
||||||
|
estimate.estimatedAmount)
|
||||||
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: 12);
|
||||||
|
} else {
|
||||||
|
rate = (estimate.estimatedAmount /
|
||||||
|
fromAmount)
|
||||||
|
.toDecimal(
|
||||||
|
scaleOnInfinitePrecision: 12);
|
||||||
|
}
|
||||||
|
Coin coin;
|
||||||
|
try {
|
||||||
|
coin = coinFromTickerCaseInsensitive(
|
||||||
|
receivingCurrency.ticker);
|
||||||
|
} catch (_) {
|
||||||
|
coin = Coin.bitcoin;
|
||||||
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
"1 ${from!.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
"1 ${sendCurrency.ticker.toUpperCase()} ~ ${Format.localizedStringAsFixed(
|
||||||
value: rate,
|
value: rate,
|
||||||
locale: ref.watch(
|
locale: ref.watch(
|
||||||
localeServiceChangeNotifierProvider
|
localeServiceChangeNotifierProvider
|
||||||
.select(
|
.select(
|
||||||
(value) => value.locale),
|
(value) => value.locale),
|
||||||
|
),
|
||||||
|
decimalPlaces:
|
||||||
|
Constants.decimalPlacesForCoin(
|
||||||
|
coin),
|
||||||
|
)} ${receivingCurrency.ticker.toUpperCase()}",
|
||||||
|
style: STextStyles.itemSubtitle12(
|
||||||
|
context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
),
|
),
|
||||||
decimalPlaces:
|
);
|
||||||
Constants.decimalPlacesForCoin(
|
} else if (snapshot.data?.exception
|
||||||
coin),
|
is PairUnavailableException) {
|
||||||
)} ${to!.toUpperCase()}",
|
return Text(
|
||||||
style:
|
"Unsupported pair",
|
||||||
STextStyles.itemSubtitle12(context)
|
style: STextStyles.itemSubtitle12(
|
||||||
.copyWith(
|
context)
|
||||||
color: Theme.of(context)
|
.copyWith(
|
||||||
.extension<StackColors>()!
|
color: Theme.of(context)
|
||||||
.textSubtitle1,
|
.extension<StackColors>()!
|
||||||
),
|
.textSubtitle1,
|
||||||
);
|
),
|
||||||
} else if (snapshot.data?.exception
|
);
|
||||||
is PairUnavailableException) {
|
} else {
|
||||||
return Text(
|
Logging.instance.log(
|
||||||
"Unsupported pair",
|
"$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
|
||||||
style:
|
level: LogLevel.Warning,
|
||||||
STextStyles.itemSubtitle12(context)
|
);
|
||||||
.copyWith(
|
return Text(
|
||||||
color: Theme.of(context)
|
"Failed to fetch rate",
|
||||||
.extension<StackColors>()!
|
style: STextStyles.itemSubtitle12(
|
||||||
.textSubtitle1,
|
context)
|
||||||
),
|
.copyWith(
|
||||||
);
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Logging.instance.log(
|
return AnimatedText(
|
||||||
"$runtimeType failed to fetch rate for ChangeNOW: ${snapshot.data}",
|
stringsToLoopThrough: const [
|
||||||
level: LogLevel.Warning,
|
"Loading",
|
||||||
);
|
"Loading.",
|
||||||
return Text(
|
"Loading..",
|
||||||
"Failed to fetch rate",
|
"Loading...",
|
||||||
|
],
|
||||||
style:
|
style:
|
||||||
STextStyles.itemSubtitle12(context)
|
STextStyles.itemSubtitle12(context)
|
||||||
.copyWith(
|
.copyWith(
|
||||||
|
@ -468,53 +535,37 @@ class ExchangeProviderOptions extends ConsumerWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
return AnimatedText(
|
|
||||||
stringsToLoopThrough: const [
|
|
||||||
"Loading",
|
|
||||||
"Loading.",
|
|
||||||
"Loading..",
|
|
||||||
"Loading...",
|
|
||||||
],
|
|
||||||
style: STextStyles.itemSubtitle12(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (!(from != null &&
|
|
||||||
to != null &&
|
|
||||||
toAmount != null &&
|
|
||||||
toAmount! > Decimal.zero &&
|
|
||||||
fromAmount != null &&
|
|
||||||
fromAmount! > Decimal.zero))
|
|
||||||
Text(
|
|
||||||
"n/a",
|
|
||||||
style: STextStyles.itemSubtitle12(context)
|
|
||||||
.copyWith(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<StackColors>()!
|
|
||||||
.textSubtitle1,
|
|
||||||
),
|
),
|
||||||
),
|
if (!(sendCurrency != null &&
|
||||||
],
|
receivingCurrency != null &&
|
||||||
|
toAmount != null &&
|
||||||
|
toAmount > Decimal.zero &&
|
||||||
|
fromAmount != null &&
|
||||||
|
fromAmount > Decimal.zero))
|
||||||
|
Text(
|
||||||
|
"n/a",
|
||||||
|
style: STextStyles.itemSubtitle12(context)
|
||||||
|
.copyWith(
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<StackColors>()!
|
||||||
|
.textSubtitle1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
// if (isDesktop)
|
||||||
if (isDesktop)
|
// Container(
|
||||||
Container(
|
// height: 1,
|
||||||
height: 1,
|
// color: Theme.of(context).extension<StackColors>()!.background,
|
||||||
color: Theme.of(context).extension<StackColors>()!.background,
|
// ),
|
||||||
),
|
|
||||||
// if (!isDesktop)
|
// if (!isDesktop)
|
||||||
// const SizedBox(
|
// const SizedBox(
|
||||||
// height: 16,
|
// height: 16,
|
||||||
|
|
Loading…
Reference in a new issue