Merge branch 'staging' into ui-fixes

This commit is contained in:
sneurlax 2023-02-10 13:55:58 -06:00
commit 44074428a9
81 changed files with 3579 additions and 3028 deletions

View file

@ -17,6 +17,7 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart'; import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'; import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart';
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'; import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart';
@ -66,8 +67,6 @@ import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:window_size/window_size.dart'; import 'package:window_size/window_size.dart';
import 'db/main_db.dart';
final openedFromSWBFileStringStateProvider = final openedFromSWBFileStringStateProvider =
StateProvider<String?>((ref) => null); StateProvider<String?>((ref) => null);
@ -291,10 +290,6 @@ class _MaterialAppWithThemeState extends ConsumerState<MaterialAppWithTheme>
// TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet // TODO: this should probably run unawaited. Keep commented out for now as proper community nodes ui hasn't been implemented yet
// unawaited(_nodeService.updateCommunityNodes()); // unawaited(_nodeService.updateCommunityNodes());
print("================================================");
print("${ref.read(prefsChangeNotifierProvider).externalCalls}");
print("${await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()}");
print("================================================");
// run without awaiting // run without awaiting
if (ref.read(prefsChangeNotifierProvider).externalCalls && if (ref.read(prefsChangeNotifierProvider).externalCalls &&
await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()) { await ref.read(prefsChangeNotifierProvider).isExternalCallsSet()) {

View file

@ -0,0 +1,40 @@
import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:tuple/tuple.dart';
class AggregateCurrency {
final Map<String, Currency?> _map = {};
AggregateCurrency(
{required List<Tuple2<String, Currency>> exchangeCurrencyPairs}) {
assert(exchangeCurrencyPairs.isNotEmpty);
for (final item in exchangeCurrencyPairs) {
_map[item.item1] = item.item2;
}
}
Currency? forExchange(String exchangeName) {
return _map[exchangeName];
}
String get ticker => _map.values.first!.ticker;
String get name => _map.values.first!.name;
String get image => _map.values.first!.image;
SupportedRateType get rateType => _map.values.first!.rateType;
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;
}
}

View file

@ -1,14 +1,11 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:isar/isar.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/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.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/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/exchange_data_loading_service.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/logger.dart';
class ExchangeFormState extends ChangeNotifier { class ExchangeFormState extends ChangeNotifier {
@ -53,15 +50,15 @@ class ExchangeFormState extends ChangeNotifier {
// //
} }
Currency? _sendCurrency; AggregateCurrency? _sendCurrency;
Currency? get sendCurrency => _sendCurrency; AggregateCurrency? get sendCurrency => _sendCurrency;
// set sendCurrency(Currency? sendCurrency) { // set sendCurrency(Currency? sendCurrency) {
// _sendCurrency = sendCurrency; // _sendCurrency = sendCurrency;
// // // //
// } // }
Currency? _receiveCurrency; AggregateCurrency? _receiveCurrency;
Currency? get receiveCurrency => _receiveCurrency; AggregateCurrency? get receiveCurrency => _receiveCurrency;
// set receiveCurrency(Currency? receiveCurrency) { // set receiveCurrency(Currency? receiveCurrency) {
// _receiveCurrency = receiveCurrency; // _receiveCurrency = receiveCurrency;
// // // //
@ -113,8 +110,8 @@ class ExchangeFormState extends ChangeNotifier {
receiveAmount != null && receiveAmount != null &&
rate != null && rate != null &&
rate! >= Decimal.zero && rate! >= Decimal.zero &&
exchange.name == sendCurrency!.exchangeName && sendCurrency!.forExchange(exchange.name) != null &&
exchange.name == receiveCurrency!.exchangeName && receiveCurrency!.forExchange(exchange.name) != null &&
warning.isEmpty; warning.isEmpty;
} }
@ -156,73 +153,6 @@ class ExchangeFormState extends ChangeNotifier {
}) async { }) async {
_exchange = exchange; _exchange = exchange;
if (shouldUpdateData) { if (shouldUpdateData) {
if (_sendCurrency != null) {
_sendCurrency = await ExchangeDataLoadingService
.instance.isar.currencies
.where()
.exchangeNameEqualTo(exchange.name)
.filter()
.tickerEqualTo(_sendCurrency!.ticker)
.and()
.group((q) => exchangeRateType == ExchangeRateType.fixed
? q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.fixed)
: q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.estimated))
.findFirst();
}
if (_sendCurrency == null) {
switch (exchange.name) {
case ChangeNowExchange.exchangeName:
_sendCurrency = _cachedSendCN;
break;
case MajesticBankExchange.exchangeName:
_sendCurrency = _cachedSendMB;
break;
}
}
if (_receiveCurrency != null) {
_receiveCurrency = await ExchangeDataLoadingService
.instance.isar.currencies
.where()
.exchangeNameEqualTo(exchange.name)
.filter()
.tickerEqualTo(_receiveCurrency!.ticker)
.and()
.group((q) => exchangeRateType == ExchangeRateType.fixed
? q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.fixed)
: q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.estimated))
.findFirst();
}
if (_receiveCurrency == null) {
switch (exchange.name) {
case ChangeNowExchange.exchangeName:
_receiveCurrency = _cachedReceivingCN;
break;
case MajesticBankExchange.exchangeName:
_receiveCurrency = _cachedReceivingMB;
break;
}
}
_updateCachedCurrencies(
exchangeName: exchange.name,
send: _sendCurrency,
receiving: _receiveCurrency,
);
await _updateRangesAndEstimate( await _updateRangesAndEstimate(
shouldNotifyListeners: false, shouldNotifyListeners: false,
); );
@ -233,14 +163,9 @@ class ExchangeFormState extends ChangeNotifier {
} }
} }
void setCurrencies(Currency from, Currency to) { void setCurrencies(AggregateCurrency from, AggregateCurrency to) {
_sendCurrency = from; _sendCurrency = from;
_receiveCurrency = to; _receiveCurrency = to;
_updateCachedCurrencies(
exchangeName: exchange.name,
send: _sendCurrency,
receiving: _receiveCurrency,
);
} }
void reset({ void reset({
@ -316,7 +241,7 @@ class ExchangeFormState extends ChangeNotifier {
} }
Future<void> updateSendCurrency( Future<void> updateSendCurrency(
Currency sendCurrency, AggregateCurrency sendCurrency,
bool shouldNotifyListeners, bool shouldNotifyListeners,
) async { ) async {
try { try {
@ -324,12 +249,6 @@ class ExchangeFormState extends ChangeNotifier {
_minSendAmount = null; _minSendAmount = null;
_maxSendAmount = null; _maxSendAmount = null;
_updateCachedCurrencies(
exchangeName: exchange.name,
send: _sendCurrency,
receiving: _receiveCurrency,
);
if (_receiveCurrency == null) { if (_receiveCurrency == null) {
_rate = null; _rate = null;
} else { } else {
@ -346,7 +265,7 @@ class ExchangeFormState extends ChangeNotifier {
} }
Future<void> updateReceivingCurrency( Future<void> updateReceivingCurrency(
Currency receiveCurrency, AggregateCurrency receiveCurrency,
bool shouldNotifyListeners, bool shouldNotifyListeners,
) async { ) async {
try { try {
@ -354,12 +273,6 @@ class ExchangeFormState extends ChangeNotifier {
_minReceiveAmount = null; _minReceiveAmount = null;
_maxReceiveAmount = null; _maxReceiveAmount = null;
_updateCachedCurrencies(
exchangeName: exchange.name,
send: _sendCurrency,
receiving: _receiveCurrency,
);
if (_sendCurrency == null) { if (_sendCurrency == null) {
_rate = null; _rate = null;
} else { } else {
@ -387,16 +300,10 @@ class ExchangeFormState extends ChangeNotifier {
_minReceiveAmount = null; _minReceiveAmount = null;
_maxReceiveAmount = null; _maxReceiveAmount = null;
final Currency? tmp = sendCurrency; final AggregateCurrency? tmp = sendCurrency;
_sendCurrency = receiveCurrency; _sendCurrency = receiveCurrency;
_receiveCurrency = tmp; _receiveCurrency = tmp;
_updateCachedCurrencies(
exchangeName: exchange.name,
send: _sendCurrency,
receiving: _receiveCurrency,
);
await _updateRangesAndEstimate( await _updateRangesAndEstimate(
shouldNotifyListeners: false, shouldNotifyListeners: false,
); );
@ -418,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) {
@ -542,33 +472,30 @@ class ExchangeFormState extends ChangeNotifier {
//============================================================================ //============================================================================
Currency? _cachedReceivingMB;
Currency? _cachedSendMB;
Currency? _cachedReceivingCN;
Currency? _cachedSendCN;
void _updateCachedCurrencies({
required String exchangeName,
required Currency? send,
required Currency? receiving,
}) {
switch (exchangeName) {
case ChangeNowExchange.exchangeName:
_cachedSendCN = send ?? _cachedSendCN;
_cachedReceivingCN = receiving ?? _cachedReceivingCN;
break;
case MajesticBankExchange.exchangeName:
_cachedSendMB = send ?? _cachedSendMB;
_cachedReceivingMB = receiving ?? _cachedReceivingMB;
break;
}
}
void _notify() { void _notify() {
debugPrint("ExFState NOTIFY: ${toString()}"); debugPrint("ExFState NOTIFY: ${toString()}");
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 "{"

View file

@ -1,7 +1,7 @@
import 'package:decimal/decimal.dart'; import 'package:decimal/decimal.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart'; import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
class IncompleteExchangeModel extends ChangeNotifier { class IncompleteExchangeModel extends ChangeNotifier {
final String sendTicker; final String sendTicker;
@ -15,6 +15,7 @@ class IncompleteExchangeModel extends ChangeNotifier {
final ExchangeRateType rateType; final ExchangeRateType rateType;
final bool reversed; final bool reversed;
final bool walletInitiated;
String? _recipientAddress; String? _recipientAddress;
@ -68,6 +69,7 @@ class IncompleteExchangeModel extends ChangeNotifier {
required this.receiveAmount, required this.receiveAmount,
required this.rateType, required this.rateType,
required this.reversed, required this.reversed,
required this.walletInitiated,
String? rateId, String? rateId,
}) : _rateId = rateId; }) : _rateId = rateId;
} }

View file

@ -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,

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stackwallet/exceptions/address/address_exception.dart'; import 'package:stackwallet/exceptions/address/address_exception.dart';
import 'package:stackwallet/models/isar/models/blockchain_data/crypto_currency_address.dart'; import 'package:stackwallet/models/isar/models/blockchain_data/crypto_currency_address.dart';
@ -71,6 +73,45 @@ class Address extends CryptoCurrencyAddress {
"derivationPath: $derivationPath, " "derivationPath: $derivationPath, "
"otherData: $otherData, " "otherData: $otherData, "
"}"; "}";
String toJsonString() {
final Map<String, dynamic> result = {
"walletId": walletId,
"value": value,
"publicKey": publicKey,
"derivationIndex": derivationIndex,
"type": type.name,
"subType": subType.name,
"derivationPath": derivationPath?.value,
"otherData": otherData,
};
return jsonEncode(result);
}
static Address fromJsonString(
String jsonString, {
String? overrideWalletId,
}) {
final json = jsonDecode(jsonString);
final derivationPathString = json["derivationPath"] as String?;
final DerivationPath? derivationPath =
derivationPathString == null ? null : DerivationPath();
if (derivationPath != null) {
derivationPath.value = derivationPathString!;
}
return Address(
walletId: overrideWalletId ?? json["walletId"] as String,
value: json["value"] as String,
publicKey: List<int>.from(json["publicKey"] as List),
derivationIndex: json["derivationIndex"] as int,
derivationPath: derivationPath,
type: AddressType.values.byName(json["type"] as String),
subType: AddressSubType.values.byName(json["subType"] as String),
otherData: json["otherData"] as String?,
);
}
} }
// do not modify // do not modify

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
part 'input.g.dart'; part 'input.g.dart';
@ -30,4 +32,32 @@ class Input {
late final int? sequence; late final int? sequence;
late final String? innerRedeemScriptAsm; late final String? innerRedeemScriptAsm;
String toJsonString() {
final Map<String, dynamic> result = {
"txid": txid,
"vout": vout,
"scriptSig": scriptSig,
"scriptSigAsm": scriptSigAsm,
"witness": witness,
"isCoinbase": isCoinbase,
"sequence": sequence,
"innerRedeemScriptAsm": innerRedeemScriptAsm,
};
return jsonEncode(result);
}
static Input fromJsonString(String jsonString) {
final json = jsonDecode(jsonString);
return Input(
txid: json["txid"] as String,
vout: json["vout"] as int,
scriptSig: json["scriptSig"] as String?,
scriptSigAsm: json["scriptSigAsm"] as String?,
witness: json["witness"] as String?,
isCoinbase: json["isCoinbase"] as bool?,
sequence: json["sequence"] as int?,
innerRedeemScriptAsm: json["innerRedeemScriptAsm"] as String?,
);
}
} }

View file

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
part 'output.g.dart'; part 'output.g.dart';
@ -21,4 +23,26 @@ class Output {
late final String scriptPubKeyAddress; late final String scriptPubKeyAddress;
late final int value; late final int value;
String toJsonString() {
final Map<String, dynamic> result = {
"scriptPubKey": scriptPubKey,
"scriptPubKeyAsm": scriptPubKeyAsm,
"scriptPubKeyType": scriptPubKeyType,
"scriptPubKeyAddress": scriptPubKeyAddress,
"value": value,
};
return jsonEncode(result);
}
static Output fromJsonString(String jsonString) {
final json = jsonDecode(jsonString);
return Output(
scriptPubKey: json["scriptPubKey"] as String?,
scriptPubKeyAsm: json["scriptPubKeyAsm"] as String?,
scriptPubKeyType: json["scriptPubKeyType"] as String?,
scriptPubKeyAddress: json["scriptPubKeyAddress"] as String,
value: json["value"] as int,
);
}
} }

View file

@ -1,3 +1,4 @@
import 'dart:convert';
import 'dart:math'; import 'dart:math';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
@ -133,6 +134,60 @@ class Transaction {
"inputsLength: ${inputs.length}, " "inputsLength: ${inputs.length}, "
"outputsLength: ${outputs.length}, " "outputsLength: ${outputs.length}, "
"}"; "}";
String toJsonString() {
final Map<String, dynamic> result = {
"walletId": walletId,
"txid": txid,
"timestamp": timestamp,
"type": type.name,
"subType": subType.name,
"amount": amount,
"fee": fee,
"height": height,
"isCancelled": isCancelled,
"isLelantus": isLelantus,
"slateId": slateId,
"otherData": otherData,
"address": address.value?.toJsonString(),
"inputs": inputs.map((e) => e.toJsonString()).toList(),
"outputs": outputs.map((e) => e.toJsonString()).toList(),
};
return jsonEncode(result);
}
static Tuple2<Transaction, Address?> fromJsonString(
String jsonString, {
String? overrideWalletId,
}) {
final json = jsonDecode(jsonString);
final transaction = Transaction(
walletId: overrideWalletId ?? json["walletId"] as String,
txid: json["txid"] as String,
timestamp: json["timestamp"] as int,
type: TransactionType.values.byName(json["type"] as String),
subType: TransactionSubType.values.byName(json["subType"] as String),
amount: json["amount"] as int,
fee: json["fee"] as int,
height: json["height"] as int?,
isCancelled: json["isCancelled"] as bool,
isLelantus: json["isLelantus"] as bool?,
slateId: json["slateId"] as String?,
otherData: json["otherData"] as String?,
inputs: List<String>.from(json["inputs"] as List)
.map((e) => Input.fromJsonString(e))
.toList(),
outputs: List<String>.from(json["outputs"] as List)
.map((e) => Output.fromJsonString(e))
.toList(),
);
if (json["address"] == null) {
return Tuple2(transaction, null);
} else {
final address = Address.fromJsonString(json["address"] as String);
return Tuple2(transaction, address);
}
}
} }
// Used in Isar db and stored there as int indexes so adding/removing values // Used in Isar db and stored there as int indexes so adding/removing values

View file

@ -20,10 +20,13 @@ import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/expandable.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
class RestoreOptionsView extends ConsumerStatefulWidget { class RestoreOptionsView extends ConsumerStatefulWidget {
@ -49,10 +52,17 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
late TextEditingController _dateController; late TextEditingController _dateController;
late FocusNode textFieldFocusNode; late FocusNode textFieldFocusNode;
late final FocusNode passwordFocusNode;
late final TextEditingController passwordController;
final bool _nextEnabled = true; final bool _nextEnabled = true;
DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0); DateTime _restoreFromDate = DateTime.fromMillisecondsSinceEpoch(0);
late final Color baseColor; late final Color baseColor;
bool hidePassword = true;
bool _expandedAdavnced = false;
bool get supportsMnemonicPassphrase =>
!(coin == Coin.monero || coin == Coin.wownero || coin == Coin.epicCash);
@override @override
void initState() { void initState() {
@ -63,6 +73,8 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
_dateController = TextEditingController(); _dateController = TextEditingController();
textFieldFocusNode = FocusNode(); textFieldFocusNode = FocusNode();
passwordController = TextEditingController();
passwordFocusNode = FocusNode();
super.initState(); super.initState();
} }
@ -71,6 +83,8 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
void dispose() { void dispose() {
_dateController.dispose(); _dateController.dispose();
textFieldFocusNode.dispose(); textFieldFocusNode.dispose();
passwordController.dispose();
passwordFocusNode.dispose();
super.dispose(); super.dispose();
} }
@ -132,11 +146,12 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
if (mounted) { if (mounted) {
await Navigator.of(context).pushNamed( await Navigator.of(context).pushNamed(
RestoreWalletView.routeName, RestoreWalletView.routeName,
arguments: Tuple4( arguments: Tuple5(
walletName, walletName,
coin, coin,
ref.read(mnemonicWordCountStateProvider.state).state, ref.read(mnemonicWordCountStateProvider.state).state,
_restoreFromDate, _restoreFromDate,
passwordController.text,
), ),
); );
} }
@ -186,8 +201,6 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
await Future<void>.delayed(const Duration(milliseconds: 125)); await Future<void>.delayed(const Duration(milliseconds: 125));
} }
final now = DateTime.now();
final date = await showRoundedDatePicker( final date = await showRoundedDatePicker(
context: context, context: context,
initialDate: DateTime.now(), initialDate: DateTime.now(),
@ -441,6 +454,120 @@ class _RestoreOptionsViewState extends ConsumerState<RestoreOptionsView> {
MobileMnemonicLengthSelector( MobileMnemonicLengthSelector(
chooseMnemonicLength: chooseMnemonicLength, chooseMnemonicLength: chooseMnemonicLength,
), ),
if (supportsMnemonicPassphrase)
SizedBox(
height: isDesktop ? 24 : 16,
),
if (supportsMnemonicPassphrase)
Expandable(
onExpandChanged: (state) {
setState(() {
_expandedAdavnced = state == ExpandableState.expanded;
});
},
header: Container(
color: Colors.transparent,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 8.0,
horizontal: 16,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Advanced",
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(
context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
)
: STextStyles.smallMed12(context),
textAlign: TextAlign.left,
),
SvgPicture.asset(
_expandedAdavnced
? Assets.svg.chevronUp
: Assets.svg.chevronDown,
width: 12,
height: 6,
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveSearchIconRight,
),
],
),
),
),
body: Container(
color: Colors.transparent,
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
key: const Key("mnemonicPassphraseFieldKey1"),
focusNode: passwordFocusNode,
controller: passwordController,
style: isDesktop
? STextStyles.desktopTextMedium(context).copyWith(
height: 2,
)
: STextStyles.field(context),
obscureText: hidePassword,
enableSuggestions: false,
autocorrect: false,
decoration: standardInputDecoration(
"Recovery phrase password",
passwordFocusNode,
context,
).copyWith(
suffixIcon: UnconstrainedBox(
child: ConditionalParent(
condition: isDesktop,
builder: (child) => SizedBox(
height: 70,
child: child,
),
child: Row(
children: [
SizedBox(
width: isDesktop ? 24 : 16,
),
GestureDetector(
key: const Key(
"mnemonicPassphraseFieldShowPasswordButtonKey"),
onTap: () async {
setState(() {
hidePassword = !hidePassword;
});
},
child: SvgPicture.asset(
hidePassword
? Assets.svg.eye
: Assets.svg.eyeSlash,
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
width: isDesktop ? 24 : 16,
height: isDesktop ? 24 : 16,
),
),
const SizedBox(
width: 12,
),
],
),
),
),
),
),
),
),
),
if (!isDesktop) if (!isDesktop)
const Spacer( const Spacer(
flex: 3, flex: 3,

View file

@ -54,6 +54,7 @@ class RestoreWalletView extends ConsumerStatefulWidget {
required this.walletName, required this.walletName,
required this.coin, required this.coin,
required this.seedWordsLength, required this.seedWordsLength,
required this.mnemonicPassphrase,
required this.restoreFromDate, required this.restoreFromDate,
this.barcodeScanner = const BarcodeScannerWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(),
this.clipboard = const ClipboardWrapper(), this.clipboard = const ClipboardWrapper(),
@ -63,6 +64,7 @@ class RestoreWalletView extends ConsumerStatefulWidget {
final String walletName; final String walletName;
final Coin coin; final Coin coin;
final String mnemonicPassphrase;
final int seedWordsLength; final int seedWordsLength;
final DateTime restoreFromDate; final DateTime restoreFromDate;
@ -290,7 +292,7 @@ class _RestoreWalletViewState extends ConsumerState<RestoreWalletView> {
// without using them // without using them
await manager.recoverFromMnemonic( await manager.recoverFromMnemonic(
mnemonic: mnemonic, mnemonic: mnemonic,
mnemonicPassphrase: "", // TODO add ui for certain coins mnemonicPassphrase: widget.mnemonicPassphrase,
maxUnusedAddressGap: widget.coin == Coin.firo ? 50 : 20, maxUnusedAddressGap: widget.coin == Coin.firo ? 50 : 20,
maxNumberOfIndexesToCheck: 1000, maxNumberOfIndexesToCheck: 1000,
height: height, height: height,

View file

@ -26,16 +26,14 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
class ExchangeCurrencySelectionView extends StatefulWidget { class ExchangeCurrencySelectionView extends StatefulWidget {
const ExchangeCurrencySelectionView({ const ExchangeCurrencySelectionView({
Key? key, Key? key,
required this.exchangeName, required this.willChangeTicker,
required this.willChange, required this.pairedTicker,
required this.paired,
required this.isFixedRate, required this.isFixedRate,
required this.willChangeIsSend, required this.willChangeIsSend,
}) : super(key: key); }) : super(key: key);
final String exchangeName; final String? willChangeTicker;
final Currency? willChange; final String? pairedTicker;
final Currency? paired;
final bool isFixedRate; final bool isFixedRate;
final bool willChangeIsSend; final bool willChangeIsSend;
@ -89,7 +87,7 @@ class _ExchangeCurrencySelectionViewState
} }
Future<List<Currency>> _loadCurrencies() async { Future<List<Currency>> _loadCurrencies() async {
if (widget.paired == null) { if (widget.pairedTicker == null) {
return await _getCurrencies(); return await _getCurrencies();
} }
@ -109,7 +107,6 @@ class _ExchangeCurrencySelectionViewState
Future<Currency?> _getCurrency(String ticker) { Future<Currency?> _getCurrency(String ticker) {
return ExchangeDataLoadingService.instance.isar.currencies return ExchangeDataLoadingService.instance.isar.currencies
.where() .where()
.exchangeNameEqualTo(widget.exchangeName)
.filter() .filter()
.tickerEqualTo(ticker, caseSensitive: false) .tickerEqualTo(ticker, caseSensitive: false)
.group((q) => widget.isFixedRate .group((q) => widget.isFixedRate
@ -127,7 +124,6 @@ class _ExchangeCurrencySelectionViewState
Future<List<Pair>> _loadAvailablePairs() { Future<List<Pair>> _loadAvailablePairs() {
final query = ExchangeDataLoadingService.instance.isar.pairs final query = ExchangeDataLoadingService.instance.isar.pairs
.where() .where()
.exchangeNameEqualTo(widget.exchangeName)
.filter() .filter()
.group((q) => widget.isFixedRate .group((q) => widget.isFixedRate
? q ? q
@ -140,8 +136,8 @@ class _ExchangeCurrencySelectionViewState
.rateTypeEqualTo(SupportedRateType.estimated)) .rateTypeEqualTo(SupportedRateType.estimated))
.and() .and()
.group((q) => widget.willChangeIsSend .group((q) => widget.willChangeIsSend
? q.toEqualTo(widget.paired!.ticker, caseSensitive: false) ? q.toEqualTo(widget.pairedTicker!, caseSensitive: false)
: q.fromEqualTo(widget.paired!.ticker, caseSensitive: false)); : q.fromEqualTo(widget.pairedTicker!, caseSensitive: false));
if (widget.willChangeIsSend) { if (widget.willChangeIsSend) {
return query.sortByFrom().findAll(); return query.sortByFrom().findAll();
@ -153,7 +149,6 @@ class _ExchangeCurrencySelectionViewState
Future<List<Currency>> _getCurrencies() async { Future<List<Currency>> _getCurrencies() async {
return ExchangeDataLoadingService.instance.isar.currencies return ExchangeDataLoadingService.instance.isar.currencies
.where() .where()
.exchangeNameEqualTo(widget.exchangeName)
.filter() .filter()
.group((q) => widget.isFixedRate .group((q) => widget.isFixedRate
? q ? q
@ -166,6 +161,7 @@ class _ExchangeCurrencySelectionViewState
.rateTypeEqualTo(SupportedRateType.estimated)) .rateTypeEqualTo(SupportedRateType.estimated))
.sortByIsStackCoin() .sortByIsStackCoin()
.thenByName() .thenByName()
.distinctByTicker(caseSensitive: false)
.findAll(); .findAll();
} }
@ -174,7 +170,7 @@ class _ExchangeCurrencySelectionViewState
return _currencies; return _currencies;
} }
if (widget.paired == null) { if (widget.pairedTicker == null) {
return _currencies return _currencies
.where((e) => .where((e) =>
e.name.toLowerCase().contains(text.toLowerCase()) || e.name.toLowerCase().contains(text.toLowerCase()) ||
@ -183,7 +179,7 @@ class _ExchangeCurrencySelectionViewState
} else { } else {
return _currencies return _currencies
.where((e) => .where((e) =>
e.ticker.toLowerCase() != widget.paired!.ticker.toLowerCase() && e.ticker.toLowerCase() != widget.pairedTicker!.toLowerCase() &&
(e.name.toLowerCase().contains(text.toLowerCase()) || (e.name.toLowerCase().contains(text.toLowerCase()) ||
e.ticker.toLowerCase().contains(text.toLowerCase()))) e.ticker.toLowerCase().contains(text.toLowerCase())))
.toList(growable: false); .toList(growable: false);
@ -322,8 +318,7 @@ class _ExchangeCurrencySelectionViewState
Flexible( Flexible(
child: Builder(builder: (context) { child: Builder(builder: (context) {
final coins = Coin.values.where((e) => final coins = Coin.values.where((e) =>
e.ticker.toLowerCase() != e.ticker.toLowerCase() != widget.pairedTicker?.toLowerCase());
widget.paired?.ticker.toLowerCase());
final items = filter(_searchString) final items = filter(_searchString)
.where((e) => coins .where((e) => coins

View file

@ -6,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:isar/isar.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/incomplete_exchange.dart';
import 'package:stackwallet/models/isar/exchange_cache/currency.dart'; import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart'; import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
@ -13,7 +14,6 @@ import 'package:stackwallet/pages/exchange_view/exchange_coin_selection/exchange
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_1_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_1_view.dart';
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_provider_options.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_provider_options.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/rate_type_toggle.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
@ -22,6 +22,7 @@ import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
@ -128,8 +129,37 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
}); });
} }
Future<AggregateCurrency> _getAggregateCurrency(Currency currency) async {
final rateType = ref.read(exchangeFormStateProvider).exchangeRateType;
final currencies = await ExchangeDataLoadingService.instance.isar.currencies
.filter()
.group((q) => rateType == ExchangeRateType.fixed
? q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.fixed)
: q
.rateTypeEqualTo(SupportedRateType.both)
.or()
.rateTypeEqualTo(SupportedRateType.estimated))
.and()
.tickerEqualTo(
currency.ticker,
caseSensitive: false,
)
.findAll();
final items = [Tuple2(currency.exchangeName, currency)];
for (final currency in currencies) {
items.add(Tuple2(currency.exchangeName, currency));
}
return AggregateCurrency(exchangeCurrencyPairs: items);
}
void selectSendCurrency() async { void selectSendCurrency() async {
final type = (ref.read(prefsChangeNotifierProvider).exchangeRateType); final type = (ref.read(exchangeFormStateProvider).exchangeRateType);
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? ""; final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
if (walletInitiated && if (walletInitiated &&
@ -139,17 +169,18 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
} }
final selectedCurrency = await _showCurrencySelectionSheet( final selectedCurrency = await _showCurrencySelectionSheet(
willChange: ref.read(exchangeFormStateProvider).sendCurrency, willChange: ref.read(exchangeFormStateProvider).sendCurrency?.ticker,
willChangeIsSend: true, willChangeIsSend: true,
paired: ref.read(exchangeFormStateProvider).receiveCurrency, paired: ref.read(exchangeFormStateProvider).receiveCurrency?.ticker,
isFixedRate: type == ExchangeRateType.fixed, isFixedRate: type == ExchangeRateType.fixed,
); );
if (selectedCurrency != null) { if (selectedCurrency != null) {
await showUpdatingExchangeRate( await showUpdatingExchangeRate(
whileFuture: ref whileFuture: _getAggregateCurrency(selectedCurrency).then(
.read(exchangeFormStateProvider) (aggregateSelected) => ref
.updateSendCurrency(selectedCurrency, true), .read(exchangeFormStateProvider)
.updateSendCurrency(aggregateSelected, true)),
); );
} }
} }
@ -163,18 +194,19 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
} }
final selectedCurrency = await _showCurrencySelectionSheet( final selectedCurrency = await _showCurrencySelectionSheet(
willChange: ref.read(exchangeFormStateProvider).receiveCurrency, willChange: ref.read(exchangeFormStateProvider).receiveCurrency?.ticker,
willChangeIsSend: false, willChangeIsSend: false,
paired: ref.read(exchangeFormStateProvider).sendCurrency, paired: ref.read(exchangeFormStateProvider).sendCurrency?.ticker,
isFixedRate: ref.read(prefsChangeNotifierProvider).exchangeRateType == isFixedRate: ref.read(exchangeFormStateProvider).exchangeRateType ==
ExchangeRateType.fixed, ExchangeRateType.fixed,
); );
if (selectedCurrency != null) { if (selectedCurrency != null) {
await showUpdatingExchangeRate( await showUpdatingExchangeRate(
whileFuture: ref whileFuture: _getAggregateCurrency(selectedCurrency).then(
.read(exchangeFormStateProvider) (aggregateSelected) => ref
.updateReceivingCurrency(selectedCurrency, true), .read(exchangeFormStateProvider)
.updateReceivingCurrency(aggregateSelected, true)),
); );
} }
} }
@ -193,8 +225,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
} }
Future<Currency?> _showCurrencySelectionSheet({ Future<Currency?> _showCurrencySelectionSheet({
required Currency? willChange, required String? willChange,
required Currency? paired, required String? paired,
required bool isFixedRate, required bool isFixedRate,
required bool willChangeIsSend, required bool willChangeIsSend,
}) async { }) async {
@ -241,12 +273,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
.extension<StackColors>()! .extension<StackColors>()!
.background, .background,
child: ExchangeCurrencySelectionView( child: ExchangeCurrencySelectionView(
exchangeName: ref willChangeTicker: willChange,
.read(currentExchangeNameStateProvider pairedTicker: paired,
.state)
.state,
willChange: willChange,
paired: paired,
isFixedRate: isFixedRate, isFixedRate: isFixedRate,
willChangeIsSend: willChangeIsSend, willChangeIsSend: willChangeIsSend,
), ),
@ -263,10 +291,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
: await Navigator.of(context).push( : await Navigator.of(context).push(
MaterialPageRoute<dynamic>( MaterialPageRoute<dynamic>(
builder: (_) => ExchangeCurrencySelectionView( builder: (_) => ExchangeCurrencySelectionView(
exchangeName: willChangeTicker: willChange,
ref.read(currentExchangeNameStateProvider.state).state, pairedTicker: paired,
willChange: willChange,
paired: paired,
isFixedRate: isFixedRate, isFixedRate: isFixedRate,
willChangeIsSend: willChangeIsSend, willChangeIsSend: willChangeIsSend,
), ),
@ -298,68 +324,69 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
ref.read(exchangeFormStateProvider).reversed = false; ref.read(exchangeFormStateProvider).reversed = false;
if (!(toTicker == "-" || fromTicker == "-")) { if (!(toTicker == "-" || fromTicker == "-")) {
final available = await ExchangeDataLoadingService.instance.isar.pairs // final available = await ExchangeDataLoadingService.instance.isar.pairs
.where() // .where()
.exchangeNameEqualTo( // .exchangeNameEqualTo(
ref.read(currentExchangeNameStateProvider.state).state) // ref.read(currentExchangeNameStateProvider.state).state)
.filter() // .filter()
.fromEqualTo(fromTicker) // .fromEqualTo(fromTicker)
.and() // .and()
.toEqualTo(toTicker) // .toEqualTo(toTicker)
.findAll(); // .findAll();
await ref.read(exchangeFormStateProvider).refresh();
if (available.isNotEmpty) { // if (available.isNotEmpty) {
final availableCurrencies = await ExchangeDataLoadingService // final availableCurrencies = await ExchangeDataLoadingService
.instance.isar.currencies // .instance.isar.currencies
.where() // .where()
.exchangeNameEqualTo( // .exchangeNameEqualTo(
ref.read(currentExchangeNameStateProvider.state).state) // ref.read(currentExchangeNameStateProvider.state).state)
.filter() // .filter()
.tickerEqualTo(fromTicker) // .tickerEqualTo(fromTicker)
.or() // .or()
.tickerEqualTo(toTicker) // .tickerEqualTo(toTicker)
.findAll(); // .findAll();
//
if (availableCurrencies.length > 1) { // if (availableCurrencies.length > 1) {
final from = // final from =
availableCurrencies.firstWhere((e) => e.ticker == fromTicker); // availableCurrencies.firstWhere((e) => e.ticker == fromTicker);
final to = // final to =
availableCurrencies.firstWhere((e) => e.ticker == toTicker); // availableCurrencies.firstWhere((e) => e.ticker == toTicker);
//
final newFromAmount = Decimal.tryParse(_sendController.text); // final newFromAmount = Decimal.tryParse(_sendController.text);
ref.read(exchangeFormStateProvider).receiveAmount = newFromAmount; // ref.read(exchangeFormStateProvider).receiveAmount = newFromAmount;
if (newFromAmount == null) { // if (newFromAmount == null) {
_receiveController.text = ""; // _receiveController.text = "";
} // }
//
await ref // await ref
.read(exchangeFormStateProvider) // .read(exchangeFormStateProvider)
.updateReceivingCurrency(to, false); // .updateReceivingCurrency(to, false);
await ref // await ref
.read(exchangeFormStateProvider) // .read(exchangeFormStateProvider)
.updateSendCurrency(from, true); // .updateSendCurrency(from, true);
//
_receiveController.text = // _receiveController.text =
ref.read(exchangeFormStateProvider).toAmountString.isEmpty // ref.read(exchangeFormStateProvider).toAmountString.isEmpty
? "-" // ? "-"
: ref.read(exchangeFormStateProvider).toAmountString; // : ref.read(exchangeFormStateProvider).toAmountString;
if (mounted) { // if (mounted) {
Navigator.of(context, rootNavigator: isDesktop).pop(); // Navigator.of(context, rootNavigator: isDesktop).pop();
} // }
return; // return;
} // }
} // }
} }
} }
void onExchangePressed() async { void onExchangePressed() async {
final rateType = ref.read(prefsChangeNotifierProvider).exchangeRateType; final rateType = ref.read(exchangeFormStateProvider).exchangeRateType;
final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? ""; final fromTicker = ref.read(exchangeFormStateProvider).fromTicker ?? "";
final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? ""; final toTicker = ref.read(exchangeFormStateProvider).toTicker ?? "";
final sendAmount = ref.read(exchangeFormStateProvider).sendAmount!; final sendAmount = ref.read(exchangeFormStateProvider).sendAmount!;
final estimate = ref.read(exchangeFormStateProvider).estimate!; final estimate = ref.read(exchangeFormStateProvider).estimate!;
final exchangeName = ref.read(currentExchangeNameStateProvider.state).state; final exchangeName = ref.read(exchangeFormStateProvider).exchange.name;
String rate; String rate;
@ -531,6 +558,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
rateType: rateType, rateType: rateType,
rateId: estimate.rateId, rateId: estimate.rateId,
reversed: estimate.reversed, reversed: estimate.reversed,
walletInitiated: walletInitiated,
); );
if (mounted) { if (mounted) {
@ -644,7 +672,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final rateType = ref.watch( final rateType = ref.watch(
prefsChangeNotifierProvider.select((value) => value.exchangeRateType)); exchangeFormStateProvider.select((value) => value.exchangeRateType));
final isEstimated = rateType == ExchangeRateType.estimated; final isEstimated = rateType == ExchangeRateType.estimated;
@ -708,10 +736,8 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: sendFieldOnChanged, onChanged: sendFieldOnChanged,
onButtonTap: selectSendCurrency, onButtonTap: selectSendCurrency,
isWalletCoin: isWalletCoin(coin, true), isWalletCoin: isWalletCoin(coin, true),
image: ref.watch(exchangeFormStateProvider currency: ref.watch(
.select((value) => value.sendCurrency?.image)), exchangeFormStateProvider.select((value) => value.sendCurrency)),
ticker: ref.watch(
exchangeFormStateProvider.select((value) => value.fromTicker)),
), ),
SizedBox( SizedBox(
height: isDesktop ? 10 : 4, height: isDesktop ? 10 : 4,
@ -791,7 +817,7 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
background: background:
Theme.of(context).extension<StackColors>()!.textFieldDefaultBG, Theme.of(context).extension<StackColors>()!.textFieldDefaultBG,
onTap: () { onTap: () {
if (!(ref.read(prefsChangeNotifierProvider).exchangeRateType == if (!(ref.read(exchangeFormStateProvider).exchangeRateType ==
ExchangeRateType.estimated) && ExchangeRateType.estimated) &&
_receiveController.text == "-") { _receiveController.text == "-") {
_receiveController.text = ""; _receiveController.text = "";
@ -800,13 +826,11 @@ class _ExchangeFormState extends ConsumerState<ExchangeForm> {
onChanged: receiveFieldOnChanged, onChanged: receiveFieldOnChanged,
onButtonTap: selectReceiveCurrency, onButtonTap: selectReceiveCurrency,
isWalletCoin: isWalletCoin(coin, true), isWalletCoin: isWalletCoin(coin, true),
image: ref.watch(exchangeFormStateProvider currency: ref.watch(exchangeFormStateProvider
.select((value) => value.receiveCurrency?.image)) ?? .select((value) => value.receiveCurrency)),
"",
ticker: ref.watch(
exchangeFormStateProvider.select((value) => value.toTicker)),
readOnly: (rateType) == ExchangeRateType.estimated && readOnly: (rateType) == ExchangeRateType.estimated &&
ref.watch(exchangeProvider).name == ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)) ==
ChangeNowExchange.exchangeName, ChangeNowExchange.exchangeName,
), ),
if (ref if (ref
@ -840,10 +864,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)),

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_2_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/background.dart';

View file

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

View file

@ -5,16 +5,15 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_4_view.dart'; import 'package:stackwallet/pages/exchange_view/exchange_step_views/step_4_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart';
import 'package:stackwallet/providers/exchange/exchange_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart'; import 'package:stackwallet/services/exchange/majestic_bank/majestic_bank_exchange.dart';
import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/services/notifications_api.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/background.dart';
@ -53,9 +52,9 @@ class _Step3ViewState extends ConsumerState<Step3View> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final supportsRefund = final supportsRefund = ref.watch(
ref.watch(currentExchangeNameStateProvider.state).state != exchangeFormStateProvider.select((value) => value.exchange.name)) !=
MajesticBankExchange.exchangeName; MajesticBankExchange.exchangeName;
return Background( return Background(
child: Scaffold( child: Scaffold(
@ -255,7 +254,8 @@ class _Step3ViewState extends ConsumerState<Step3View> {
final ExchangeResponse<Trade> response = final ExchangeResponse<Trade> response =
await ref await ref
.read(exchangeProvider) .read(exchangeFormStateProvider)
.exchange
.createTrade( .createTrade(
from: model.sendTicker, from: model.sendTicker,
to: model.receiveTicker, to: model.receiveTicker,

File diff suppressed because it is too large Load diff

View file

@ -8,9 +8,12 @@ import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
import 'package:stackwallet/pages/exchange_view/trade_details_view.dart'; import 'package:stackwallet/pages/exchange_view/trade_details_view.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/trade_card.dart'; import 'package:stackwallet/widgets/trade_card.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -24,8 +27,38 @@ class ExchangeView extends ConsumerStatefulWidget {
} }
class _ExchangeViewState extends ConsumerState<ExchangeView> { class _ExchangeViewState extends ConsumerState<ExchangeView> {
bool _initialCachePopulationUnderway = false;
@override @override
void initState() { void initState() {
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
if (ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
ExchangeDataLoadingService.instance
.init()
.then((_) => ExchangeDataLoadingService.instance.loadAll());
} else if (ExchangeDataLoadingService.instance.isLoading &&
ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
super.initState(); super.initState();
} }
@ -38,154 +71,176 @@ class _ExchangeViewState extends ConsumerState<ExchangeView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
return SafeArea( return ConditionalParent(
child: NestedScrollView( condition: _initialCachePopulationUnderway,
floatHeaderSlivers: true, builder: (child) {
headerSliverBuilder: (context, innerBoxIsScrolled) { return Stack(
return [ children: [
SliverOverlapAbsorber( child,
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), Material(
sliver: const SliverToBoxAdapter( color: Theme.of(context)
child: Padding( .extension<StackColors>()!
padding: EdgeInsets.only( .overlay
left: 16, .withOpacity(0.6),
right: 16, child: const CustomLoadingOverlay(
top: 16, message: "Updating exchange data",
), subMessage: "This could take a few minutes",
child: ExchangeForm(), eventBus: null,
),
), ),
) )
]; ],
}, );
body: Builder( },
builder: (buildContext) { child: SafeArea(
final trades = ref child: NestedScrollView(
.watch(tradesServiceProvider.select((value) => value.trades)); floatHeaderSlivers: true,
final tradeCount = trades.length; headerSliverBuilder: (context, innerBoxIsScrolled) {
final hasHistory = tradeCount > 0; return [
SliverOverlapAbsorber(
return Padding( handle:
padding: const EdgeInsets.symmetric(horizontal: 12), NestedScrollView.sliverOverlapAbsorberHandleFor(context),
child: CustomScrollView( sliver: const SliverToBoxAdapter(
slivers: [ child: Padding(
SliverOverlapInjector( padding: EdgeInsets.only(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor( left: 16,
buildContext, right: 16,
top: 16,
), ),
child: ExchangeForm(),
), ),
SliverToBoxAdapter( ),
child: Padding( )
padding: const EdgeInsets.symmetric(horizontal: 4), ];
child: Column( },
crossAxisAlignment: CrossAxisAlignment.stretch, body: Builder(
children: [ builder: (buildContext) {
const SizedBox( final trades = ref
height: 12, .watch(tradesServiceProvider.select((value) => value.trades));
), final tradeCount = trades.length;
Text( final hasHistory = tradeCount > 0;
"Trades",
style: STextStyles.itemSubtitle(context).copyWith( return Padding(
color: Theme.of(context) padding: const EdgeInsets.symmetric(horizontal: 12),
.extension<StackColors>()! child: CustomScrollView(
.textDark3, slivers: [
), SliverOverlapInjector(
), handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
const SizedBox( buildContext,
height: 12,
),
],
), ),
), ),
),
if (hasHistory)
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Padding(
padding: const EdgeInsets.all(4),
child: TradeCard(
key: Key("tradeCard_${trades[index].uuid}"),
trade: trades[index],
onTap: () async {
final String tradeId = trades[index].tradeId;
final lookup = ref
.read(tradeSentFromStackLookupProvider)
.all;
//todo: check if print needed
// debugPrint("ALL: $lookup");
final String? txid = ref
.read(tradeSentFromStackLookupProvider)
.getTxidForTradeId(tradeId);
final List<String>? walletIds = ref
.read(tradeSentFromStackLookupProvider)
.getWalletIdsForTradeId(tradeId);
if (txid != null &&
walletIds != null &&
walletIds.isNotEmpty) {
final manager = ref
.read(walletsChangeNotifierProvider)
.getManager(walletIds.first);
//todo: check if print needed
// debugPrint("name: ${manager.walletName}");
final tx = await MainDB.instance
.getTransactions(walletIds.first)
.filter()
.txidEqualTo(txid)
.findFirst();
if (mounted) {
unawaited(Navigator.of(context).pushNamed(
TradeDetailsView.routeName,
arguments: Tuple4(tradeId, tx,
walletIds.first, manager.walletName),
));
}
} else {
unawaited(Navigator.of(context).pushNamed(
TradeDetailsView.routeName,
arguments: Tuple4(
tradeId, null, walletIds?.first, null),
));
}
},
),
);
}, childCount: tradeCount),
),
if (!hasHistory)
SliverToBoxAdapter( SliverToBoxAdapter(
child: Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4), padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container( child: Column(
decoration: BoxDecoration( crossAxisAlignment: CrossAxisAlignment.stretch,
color: Theme.of(context) children: [
.extension<StackColors>()! const SizedBox(
.popupBG, height: 12,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
), ),
), Text(
child: Padding( "Trades",
padding: const EdgeInsets.all(12), style: STextStyles.itemSubtitle(context).copyWith(
child: Text( color: Theme.of(context)
"Trades will appear here", .extension<StackColors>()!
textAlign: TextAlign.center, .textDark3,
style: STextStyles.itemSubtitle(context), ),
),
const SizedBox(
height: 12,
),
],
),
),
),
if (hasHistory)
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return Padding(
padding: const EdgeInsets.all(4),
child: TradeCard(
key: Key("tradeCard_${trades[index].uuid}"),
trade: trades[index],
onTap: () async {
final String tradeId = trades[index].tradeId;
final lookup = ref
.read(tradeSentFromStackLookupProvider)
.all;
//todo: check if print needed
// debugPrint("ALL: $lookup");
final String? txid = ref
.read(tradeSentFromStackLookupProvider)
.getTxidForTradeId(tradeId);
final List<String>? walletIds = ref
.read(tradeSentFromStackLookupProvider)
.getWalletIdsForTradeId(tradeId);
if (txid != null &&
walletIds != null &&
walletIds.isNotEmpty) {
final manager = ref
.read(walletsChangeNotifierProvider)
.getManager(walletIds.first);
//todo: check if print needed
// debugPrint("name: ${manager.walletName}");
final tx = await MainDB.instance
.getTransactions(walletIds.first)
.filter()
.txidEqualTo(txid)
.findFirst();
if (mounted) {
unawaited(Navigator.of(context).pushNamed(
TradeDetailsView.routeName,
arguments: Tuple4(tradeId, tx,
walletIds.first, manager.walletName),
));
}
} else {
unawaited(Navigator.of(context).pushNamed(
TradeDetailsView.routeName,
arguments: Tuple4(
tradeId, null, walletIds?.first, null),
));
}
},
),
);
}, childCount: tradeCount),
),
if (!hasHistory)
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Container(
decoration: BoxDecoration(
color: Theme.of(context)
.extension<StackColors>()!
.popupBG,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
child: Padding(
padding: const EdgeInsets.all(12),
child: Text(
"Trades will appear here",
textAlign: TextAlign.center,
style: STextStyles.itemSubtitle(context),
),
), ),
), ),
), ),
), ),
), ],
], ),
), );
); },
}, ),
), ),
), ),
); );

View file

@ -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,196 @@ 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(exchangeFormStateProvider).exchange.name !=
ref.read(currentExchangeNameStateProvider.state).state = ChangeNowExchange.exchangeName) {
ChangeNowExchange.exchangeName; ref.read(exchangeFormStateProvider).updateExchange(
ref.read(exchangeFormStateProvider).updateExchange( exchange: ChangeNowExchange.instance,
exchange: ref.read(exchangeProvider), shouldUpdateData: true,
shouldUpdateData: true, shouldNotifyListeners: true,
shouldNotifyListeners: true, );
); }
} },
}, child: Container(
child: Container( color: Colors.transparent,
color: Colors.transparent, child: Padding(
child: Padding( padding: isDesktop
padding: isDesktop ? const EdgeInsets.all(16)
? const EdgeInsets.all(16) : const EdgeInsets.all(0),
: const EdgeInsets.all(0), child: Row(
child: Row( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ SizedBox(
SizedBox( width: 20,
width: 20, height: 20,
height: 20, child: Padding(
child: Padding( padding:
padding: EdgeInsets.only(top: isDesktop ? 20.0 : 15.0),
EdgeInsets.only(top: isDesktop ? 20.0 : 15.0), child: Radio(
child: Radio( activeColor: Theme.of(context)
activeColor: Theme.of(context) .extension<StackColors>()!
.extension<StackColors>()! .radioButtonIconEnabled,
.radioButtonIconEnabled, value: ChangeNowExchange.exchangeName,
value: ChangeNowExchange.exchangeName, groupValue: ref.watch(exchangeFormStateProvider
groupValue: ref .select((value) => value.exchange.name)),
.watch(currentExchangeNameStateProvider.state) onChanged: (_) {
.state, if (ref
onChanged: (_) { .read(exchangeFormStateProvider)
// if (value is String) { .exchange
// ref .name !=
// .read( ChangeNowExchange.exchangeName) {
// currentExchangeNameStateProvider.state) ref
// .state = value; .read(exchangeFormStateProvider)
// ref .updateExchange(
// .read(exchangeFormStateProvider(ref exchange: ChangeNowExchange.instance,
// .read(prefsChangeNotifierProvider) shouldUpdateData: true,
// .exchangeRateType)) shouldNotifyListeners: true,
// .exchange = );
// Exchange.fromName(ref }
// .read(currentExchangeNameStateProvider },
// .state) ),
// .state);
// }
},
), ),
), ),
), 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 +283,234 @@ 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(exchangeFormStateProvider).exchange.name !=
ref.read(exchangeFormStateProvider).updateExchange( MajesticBankExchange.exchangeName) {
exchange: ref.read(exchangeProvider), ref.read(exchangeFormStateProvider).updateExchange(
shouldUpdateData: true, exchange: MajesticBankExchange.instance,
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: MajesticBankExchange.exchangeName, .radioButtonIconEnabled,
groupValue: ref value: MajesticBankExchange.exchangeName,
.watch(currentExchangeNameStateProvider.state) groupValue: ref.watch(exchangeFormStateProvider
.state, .select((value) => value.exchange.name)),
onChanged: (_) { onChanged: (_) {
// if (value is String) { if (ref
// ref .read(exchangeFormStateProvider)
// .read( .exchange
// currentExchangeNameStateProvider.state) .name !=
// .state = value; MajesticBankExchange.exchangeName) {
// ref ref
// .read(exchangeFormStateProvider(ref .read(exchangeFormStateProvider)
// .read(prefsChangeNotifierProvider) .updateExchange(
// .exchangeRateType)) exchange: MajesticBankExchange.instance,
// .exchange = shouldUpdateData: true,
// Exchange.fromName(ref shouldNotifyListeners: true,
// .read(currentExchangeNameStateProvider );
// .state) }
// .state); },
// } ),
},
), ),
), ),
), 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 +520,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,

View file

@ -1,210 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
enum ExchangeRateType { estimated, fixed }
class ExchangeRateSheet extends ConsumerWidget {
const ExchangeRateSheet({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).extension<StackColors>()!.popupBG,
borderRadius: const BorderRadius.vertical(
top: Radius.circular(20),
),
),
child: Padding(
padding: const EdgeInsets.only(
left: 24,
right: 24,
top: 10,
bottom: 0,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Container(
decoration: BoxDecoration(
color:
Theme.of(context).extension<StackColors>()!.textSubtitle4,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
),
width: 60,
height: 4,
),
),
const SizedBox(
height: 36,
),
Text(
"Exchange rate",
style: STextStyles.pageTitleH2(context),
textAlign: TextAlign.left,
),
const SizedBox(
height: 16,
),
GestureDetector(
onTap: () {
final state =
ref.read(prefsChangeNotifierProvider).exchangeRateType;
if (state != ExchangeRateType.estimated) {
ref.read(prefsChangeNotifierProvider).exchangeRateType =
ExchangeRateType.estimated;
}
Navigator.of(context).pop(ExchangeRateType.estimated);
},
child: Container(
color: Colors.transparent,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
SizedBox(
width: 20,
height: 20,
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ExchangeRateType.estimated,
groupValue: ref.watch(prefsChangeNotifierProvider
.select((value) => value.exchangeRateType)),
onChanged: (x) {
//todo: check if print needed
// debugPrint(x.toString());
ref
.read(prefsChangeNotifierProvider)
.exchangeRateType =
ExchangeRateType.estimated;
Navigator.of(context)
.pop(ExchangeRateType.estimated);
},
),
)
],
),
const SizedBox(
width: 12,
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Estimated rate",
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
const SizedBox(
height: 2,
),
Text(
"ChangeNOW will pick the best rate for you during the moment of the exchange.",
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
textAlign: TextAlign.left,
),
],
),
)
],
),
),
),
const SizedBox(
height: 16,
),
GestureDetector(
onTap: () {
final state =
ref.read(prefsChangeNotifierProvider).exchangeRateType;
if (state != ExchangeRateType.fixed) {
ref.read(prefsChangeNotifierProvider).exchangeRateType =
ExchangeRateType.fixed;
}
Navigator.of(context).pop(ExchangeRateType.fixed);
},
child: Container(
color: Colors.transparent,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: [
SizedBox(
width: 20,
height: 20,
child: Radio(
activeColor: Theme.of(context)
.extension<StackColors>()!
.radioButtonIconEnabled,
value: ExchangeRateType.fixed,
groupValue: ref.watch(prefsChangeNotifierProvider
.select((value) => value.exchangeRateType)),
onChanged: (x) {
ref
.read(prefsChangeNotifierProvider)
.exchangeRateType = ExchangeRateType.fixed;
Navigator.of(context).pop(ExchangeRateType.fixed);
},
),
),
],
),
const SizedBox(
width: 12,
),
Flexible(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Fixed rate",
style: STextStyles.titleBold12(context),
textAlign: TextAlign.left,
),
const SizedBox(
height: 2,
),
Text(
"You will get the exact exchange amount displayed - ChangeNOW takes all the rate risks.",
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textSubtitle1,
),
textAlign: TextAlign.left,
)
],
),
),
],
),
),
),
const SizedBox(
height: 24,
),
],
),
),
);
}
}

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart'; import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/toggle.dart'; import 'package:stackwallet/widgets/toggle.dart';
@ -24,16 +24,12 @@ class RateTypeToggle extends ConsumerWidget {
return Toggle( return Toggle(
onValueChanged: (value) { onValueChanged: (value) {
if (value) { if (value) {
ref.read(prefsChangeNotifierProvider).exchangeRateType =
ExchangeRateType.fixed;
onChanged?.call(ExchangeRateType.fixed); onChanged?.call(ExchangeRateType.fixed);
} else { } else {
ref.read(prefsChangeNotifierProvider).exchangeRateType =
ExchangeRateType.estimated;
onChanged?.call(ExchangeRateType.estimated); onChanged?.call(ExchangeRateType.estimated);
} }
}, },
isOn: ref.watch(prefsChangeNotifierProvider isOn: ref.watch(exchangeFormStateProvider
.select((value) => value.exchangeRateType)) == .select((value) => value.exchangeRateType)) ==
ExchangeRateType.fixed, ExchangeRateType.fixed,
onColor: isDesktop onColor: isDesktop

View file

@ -18,6 +18,7 @@ import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.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/services/exchange/simpleswap/simpleswap_exchange.dart'; import 'package:stackwallet/services/exchange/simpleswap/simpleswap_exchange.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/clipboard_interface.dart'; import 'package:stackwallet/utilities/clipboard_interface.dart';
@ -1128,6 +1129,10 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
url = url =
"https://simpleswap.io/exchange?id=${trade.tradeId}"; "https://simpleswap.io/exchange?id=${trade.tradeId}";
break; break;
case MajesticBankExchange.exchangeName:
url =
"https://majesticbank.sc/track?trx=${trade.tradeId}";
break;
} }
return ConditionalParent( return ConditionalParent(
condition: isDesktop, condition: isDesktop,

View file

@ -4,11 +4,15 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/exchange_view/exchange_form.dart'; import 'package:stackwallet/pages/exchange_view/exchange_form.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart'; import 'package:stackwallet/pages/exchange_view/sub_widgets/step_row.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
class WalletInitiatedExchangeView extends ConsumerStatefulWidget { class WalletInitiatedExchangeView extends ConsumerStatefulWidget {
const WalletInitiatedExchangeView({ const WalletInitiatedExchangeView({
@ -32,10 +36,41 @@ class _WalletInitiatedExchangeViewState
late final String walletId; late final String walletId;
late final Coin coin; late final Coin coin;
bool _initialCachePopulationUnderway = false;
@override @override
void initState() { void initState() {
walletId = widget.walletId; walletId = widget.walletId;
coin = widget.coin; coin = widget.coin;
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
if (ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
ExchangeDataLoadingService.instance
.init()
.then((_) => ExchangeDataLoadingService.instance.loadAll());
} else if (ExchangeDataLoadingService.instance.isLoading &&
ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
super.initState(); super.initState();
} }
@ -48,76 +83,98 @@ class _WalletInitiatedExchangeViewState
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
return Background( return ConditionalParent(
child: Scaffold( condition: _initialCachePopulationUnderway,
backgroundColor: Theme.of(context).extension<StackColors>()!.background, builder: (child) {
appBar: AppBar( return Stack(
leading: AppBarBackButton( children: [
onPressed: () async { child,
if (FocusScope.of(context).hasFocus) { Material(
FocusScope.of(context).unfocus(); color: Theme.of(context)
await Future<void>.delayed(const Duration(milliseconds: 75)); .extension<StackColors>()!
} .overlay
if (mounted) { .withOpacity(0.6),
Navigator.of(context).pop(); child: const CustomLoadingOverlay(
} message: "Updating exchange data",
}, subMessage: "This could take a few minutes",
eventBus: null,
),
)
],
);
},
child: Background(
child: Scaffold(
backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () async {
if (FocusScope.of(context).hasFocus) {
FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 75));
}
if (mounted) {
Navigator.of(context).pop();
}
},
),
title: Text(
"Exchange",
style: STextStyles.navBarTitle(context),
),
), ),
title: Text( body: LayoutBuilder(
"Exchange", builder: (context, constraints) {
style: STextStyles.navBarTitle(context), final width = MediaQuery.of(context).size.width - 32;
), return Padding(
), padding: const EdgeInsets.all(12),
body: LayoutBuilder( child: SingleChildScrollView(
builder: (context, constraints) { child: ConstrainedBox(
final width = MediaQuery.of(context).size.width - 32; constraints: BoxConstraints(
return Padding( minHeight: constraints.maxHeight - 24,
padding: const EdgeInsets.all(12), ),
child: SingleChildScrollView( child: IntrinsicHeight(
child: ConstrainedBox( child: Padding(
constraints: BoxConstraints( padding: const EdgeInsets.all(4),
minHeight: constraints.maxHeight - 24, child: Column(
), crossAxisAlignment: CrossAxisAlignment.stretch,
child: IntrinsicHeight( children: [
child: Padding( StepRow(
padding: const EdgeInsets.all(4), count: 4,
child: Column( current: 0,
crossAxisAlignment: CrossAxisAlignment.stretch, width: width,
children: [ ),
StepRow( const SizedBox(
count: 4, height: 14,
current: 0, ),
width: width, Text(
), "Exchange amount",
const SizedBox( style: STextStyles.pageTitleH1(context),
height: 14, ),
), const SizedBox(
Text( height: 8,
"Exchange amount", ),
style: STextStyles.pageTitleH1(context), Text(
), "Network fees and other exchange charges are included in the rate.",
const SizedBox( style: STextStyles.itemSubtitle(context),
height: 8, ),
), const SizedBox(
Text( height: 24,
"Network fees and other exchange charges are included in the rate.", ),
style: STextStyles.itemSubtitle(context), ExchangeForm(
), walletId: walletId,
const SizedBox( coin: coin,
height: 24, ),
), ],
ExchangeForm( ),
walletId: walletId,
coin: coin,
),
],
), ),
), ),
), ),
), ),
), );
); },
}, ),
), ),
), ),
); );

View file

@ -13,7 +13,6 @@ import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/models/stack_restoring_ui_state.dart'; import 'package:stackwallet/models/stack_restoring_ui_state.dart';
import 'package:stackwallet/models/trade_wallet_lookup.dart'; import 'package:stackwallet/models/trade_wallet_lookup.dart';
import 'package:stackwallet/models/wallet_restore_state.dart'; import 'package:stackwallet/models/wallet_restore_state.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/services/address_book_service.dart'; import 'package:stackwallet/services/address_book_service.dart';
import 'package:stackwallet/services/coins/coin_service.dart'; import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/manager.dart'; import 'package:stackwallet/services/coins/manager.dart';
@ -246,7 +245,6 @@ abstract class SWB {
final _prefs = Prefs.instance; final _prefs = Prefs.instance;
await _prefs.init(); await _prefs.init();
prefs['currency'] = _prefs.currency; prefs['currency'] = _prefs.currency;
prefs['exchangeRateType'] = _prefs.exchangeRateType.name;
prefs['useBiometrics'] = _prefs.useBiometrics; prefs['useBiometrics'] = _prefs.useBiometrics;
prefs['hasPin'] = _prefs.hasPin; prefs['hasPin'] = _prefs.hasPin;
prefs['language'] = _prefs.language; prefs['language'] = _prefs.language;
@ -992,9 +990,6 @@ abstract class SWB {
final _prefs = Prefs.instance; final _prefs = Prefs.instance;
await _prefs.init(); await _prefs.init();
_prefs.currency = prefs['currency'] as String; _prefs.currency = prefs['currency'] as String;
_prefs.exchangeRateType = prefs['exchangeRateType'] == "estimated"
? ExchangeRateType.estimated
: ExchangeRateType.fixed;
// _prefs.useBiometrics = prefs['useBiometrics'] as bool; // _prefs.useBiometrics = prefs['useBiometrics'] as bool;
// _prefs.hasPin = prefs['hasPin'] as bool; // _prefs.hasPin = prefs['hasPin'] as bool;
_prefs.language = prefs['language'] as String; _prefs.language = prefs['language'] as String;

View file

@ -29,7 +29,6 @@ import 'package:stackwallet/services/coins/manager.dart';
import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/node_connection_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart'; import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_changed_event.dart';
import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
@ -38,6 +37,7 @@ import 'package:stackwallet/utilities/enums/wallet_balance_toggle_state.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart'; import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart'; import 'package:stackwallet/widgets/custom_buttons/blue_text_button.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart';
@ -77,6 +77,8 @@ class _WalletViewState extends ConsumerState<WalletView> {
late StreamSubscription<dynamic> _syncStatusSubscription; late StreamSubscription<dynamic> _syncStatusSubscription;
late StreamSubscription<dynamic> _nodeStatusSubscription; late StreamSubscription<dynamic> _nodeStatusSubscription;
bool _rescanningOnOpen = false;
@override @override
void initState() { void initState() {
walletId = widget.walletId; walletId = widget.walletId;
@ -91,7 +93,18 @@ class _WalletViewState extends ConsumerState<WalletView> {
_shouldDisableAutoSyncOnLogOut = false; _shouldDisableAutoSyncOnLogOut = false;
} }
ref.read(managerProvider).refresh(); if (ref.read(managerProvider).rescanOnOpenVersion == Constants.rescanV1) {
_rescanningOnOpen = true;
ref.read(managerProvider).fullRescan(20, 1000).then(
(_) => ref.read(managerProvider).resetRescanOnOpen().then(
(_) => WidgetsBinding.instance.addPostFrameCallback(
(_) => setState(() => _rescanningOnOpen = false),
),
),
);
} else {
ref.read(managerProvider).refresh();
}
if (ref.read(managerProvider).isRefreshing) { if (ref.read(managerProvider).isRefreshing) {
_currentSyncStatus = WalletSyncStatus.syncing; _currentSyncStatus = WalletSyncStatus.syncing;
@ -278,10 +291,9 @@ class _WalletViewState extends ConsumerState<WalletView> {
unawaited( unawaited(
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
WalletInitiatedExchangeView.routeName, WalletInitiatedExchangeView.routeName,
arguments: Tuple3( arguments: Tuple2(
walletId, walletId,
coin, coin,
_loadCNData,
), ),
), ),
); );
@ -355,435 +367,454 @@ class _WalletViewState extends ConsumerState<WalletView> {
} }
} }
void _loadCNData() {
// unawaited future
// if (ref.read(prefsChangeNotifierProvider).externalCalls) {
ExchangeDataLoadingService.instance.loadAll();
// .loadAll(ref, coin: ref.read(managerProvider).coin);
// } else {
// Logging.instance.log("User does not want to use external calls",
// level: LogLevel.Info);
// }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final coin = ref.watch(managerProvider.select((value) => value.coin)); final coin = ref.watch(managerProvider.select((value) => value.coin));
return WillPopScope( return ConditionalParent(
onWillPop: _onWillPop, condition: _rescanningOnOpen,
child: Background( builder: (child) {
child: Scaffold( return WillPopScope(
backgroundColor: onWillPop: () async => !_rescanningOnOpen,
Theme.of(context).extension<StackColors>()!.background, child: Stack(
appBar: AppBar( children: [
leading: AppBarBackButton( child,
onPressed: () { Background(
_logout(); child: CustomLoadingOverlay(
Navigator.of(context).pop(); message:
}, "Migration in progress\nThis could take a while\nPlease don't leave this screen",
), subMessage: "This only needs to run once per wallet",
titleSpacing: 0, eventBus: null,
title: Row( textColor:
children: [ Theme.of(context).extension<StackColors>()!.textDark,
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
// color: Theme.of(context).extension<StackColors>()!.accentColorDark
width: 24,
height: 24,
), ),
const SizedBox( )
width: 16,
),
Expanded(
child: Text(
ref.watch(
managerProvider.select((value) => value.walletName)),
style: STextStyles.navBarTitle(context),
overflow: TextOverflow.ellipsis,
),
)
],
),
actions: [
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewRadioButton"),
size: 36,
shadows: const [],
color:
Theme.of(context).extension<StackColors>()!.background,
icon: _buildNetworkIcon(_currentSyncStatus),
onPressed: () {
Navigator.of(context).pushNamed(
WalletNetworkSettingsView.routeName,
arguments: Tuple3(
walletId,
_currentSyncStatus,
_currentNodeStatus,
),
);
},
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewAlertsButton"),
size: 36,
shadows: const [],
color:
Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
ref.watch(notificationsProvider.select((value) =>
value.hasUnreadNotificationsFor(walletId)))
? Assets.svg.bellNew(context)
: Assets.svg.bell,
width: 20,
height: 20,
color: ref.watch(notificationsProvider.select((value) =>
value.hasUnreadNotificationsFor(walletId)))
? null
: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: () {
// reset unread state
ref.refresh(unreadNotificationsStateProvider);
Navigator.of(context)
.pushNamed(
NotificationsView.routeName,
arguments: walletId,
)
.then((_) {
final Set<int> unreadNotificationIds = ref
.read(unreadNotificationsStateProvider.state)
.state;
if (unreadNotificationIds.isEmpty) return;
List<Future<dynamic>> futures = [];
for (int i = 0;
i < unreadNotificationIds.length - 1;
i++) {
futures.add(ref
.read(notificationsProvider)
.markAsRead(
unreadNotificationIds.elementAt(i), false));
}
// wait for multiple to update if any
Future.wait(futures).then((_) {
// only notify listeners once
ref
.read(notificationsProvider)
.markAsRead(unreadNotificationIds.last, true);
});
});
},
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewSettingsButton"),
size: 36,
shadows: const [],
color:
Theme.of(context).extension<StackColors>()!.background,
icon: SvgPicture.asset(
Assets.svg.bars,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 20,
height: 20,
),
onPressed: () {
//todo: check if print needed
// debugPrint("wallet view settings tapped");
Navigator.of(context).pushNamed(
WalletSettingsView.routeName,
arguments: Tuple4(
walletId,
ref.read(managerProvider).coin,
_currentSyncStatus,
_currentNodeStatus,
),
);
},
),
),
),
], ],
), ),
body: SafeArea( );
child: Container( },
color: Theme.of(context).extension<StackColors>()!.background, child: WillPopScope(
child: Column( onWillPop: _onWillPop,
child: Background(
child: Scaffold(
backgroundColor:
Theme.of(context).extension<StackColors>()!.background,
appBar: AppBar(
leading: AppBarBackButton(
onPressed: () {
_logout();
Navigator.of(context).pop();
},
),
titleSpacing: 0,
title: Row(
children: [ children: [
const SizedBox( SvgPicture.asset(
height: 10, Assets.svg.iconFor(coin: coin),
// color: Theme.of(context).extension<StackColors>()!.accentColorDark
width: 24,
height: 24,
), ),
Center( const SizedBox(
child: Padding( width: 16,
padding: const EdgeInsets.symmetric(horizontal: 16), ),
child: WalletSummary( Expanded(
walletId: walletId, child: Text(
managerProvider: managerProvider, ref.watch(
initialSyncStatus: ref.watch(managerProvider managerProvider.select((value) => value.walletName)),
.select((value) => value.isRefreshing)) style: STextStyles.navBarTitle(context),
? WalletSyncStatus.syncing overflow: TextOverflow.ellipsis,
: WalletSyncStatus.synced, ),
), )
],
),
actions: [
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewRadioButton"),
size: 36,
shadows: const [],
color: Theme.of(context)
.extension<StackColors>()!
.background,
icon: _buildNetworkIcon(_currentSyncStatus),
onPressed: () {
Navigator.of(context).pushNamed(
WalletNetworkSettingsView.routeName,
arguments: Tuple3(
walletId,
_currentSyncStatus,
_currentNodeStatus,
),
);
},
), ),
), ),
if (coin == Coin.firo) ),
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewAlertsButton"),
size: 36,
shadows: const [],
color: Theme.of(context)
.extension<StackColors>()!
.background,
icon: SvgPicture.asset(
ref.watch(notificationsProvider.select((value) =>
value.hasUnreadNotificationsFor(walletId)))
? Assets.svg.bellNew(context)
: Assets.svg.bell,
width: 20,
height: 20,
color: ref.watch(notificationsProvider.select((value) =>
value.hasUnreadNotificationsFor(walletId)))
? null
: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: () {
// reset unread state
ref.refresh(unreadNotificationsStateProvider);
Navigator.of(context)
.pushNamed(
NotificationsView.routeName,
arguments: walletId,
)
.then((_) {
final Set<int> unreadNotificationIds = ref
.read(unreadNotificationsStateProvider.state)
.state;
if (unreadNotificationIds.isEmpty) return;
List<Future<dynamic>> futures = [];
for (int i = 0;
i < unreadNotificationIds.length - 1;
i++) {
futures.add(ref
.read(notificationsProvider)
.markAsRead(
unreadNotificationIds.elementAt(i), false));
}
// wait for multiple to update if any
Future.wait(futures).then((_) {
// only notify listeners once
ref
.read(notificationsProvider)
.markAsRead(unreadNotificationIds.last, true);
});
});
},
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 10,
right: 10,
),
child: AspectRatio(
aspectRatio: 1,
child: AppBarIconButton(
key: const Key("walletViewSettingsButton"),
size: 36,
shadows: const [],
color: Theme.of(context)
.extension<StackColors>()!
.background,
icon: SvgPicture.asset(
Assets.svg.bars,
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
width: 20,
height: 20,
),
onPressed: () {
//todo: check if print needed
// debugPrint("wallet view settings tapped");
Navigator.of(context).pushNamed(
WalletSettingsView.routeName,
arguments: Tuple4(
walletId,
ref.read(managerProvider).coin,
_currentSyncStatus,
_currentNodeStatus,
),
);
},
),
),
),
],
),
body: SafeArea(
child: Container(
color: Theme.of(context).extension<StackColors>()!.background,
child: Column(
children: [
const SizedBox( const SizedBox(
height: 10, height: 10,
), ),
if (coin == Coin.firo) Center(
Padding( child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row( child: WalletSummary(
children: [ walletId: walletId,
Expanded( managerProvider: managerProvider,
child: TextButton( initialSyncStatus: ref.watch(managerProvider
style: Theme.of(context) .select((value) => value.isRefreshing))
.extension<StackColors>()! ? WalletSyncStatus.syncing
.getSecondaryEnabledButtonStyle(context), : WalletSyncStatus.synced,
onPressed: () async { ),
await showDialog<void>( ),
context: context, ),
builder: (context) => StackDialog( if (coin == Coin.firo)
title: "Attention!", const SizedBox(
message: height: 10,
"You're about to anonymize all of your public funds.", ),
leftButton: TextButton( if (coin == Coin.firo)
onPressed: () { Padding(
Navigator.of(context).pop(); padding: const EdgeInsets.symmetric(horizontal: 16),
}, child: Row(
child: Text( children: [
"Cancel", Expanded(
style: STextStyles.button(context) child: TextButton(
.copyWith( style: Theme.of(context)
color: Theme.of(context) .extension<StackColors>()!
.extension<StackColors>()! .getSecondaryEnabledButtonStyle(context),
.accentColorDark, onPressed: () async {
await showDialog<void>(
context: context,
builder: (context) => StackDialog(
title: "Attention!",
message:
"You're about to anonymize all of your public funds.",
leftButton: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
"Cancel",
style: STextStyles.button(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorDark,
),
),
),
rightButton: TextButton(
onPressed: () async {
Navigator.of(context).pop();
unawaited(attemptAnonymize());
},
style: Theme.of(context)
.extension<StackColors>()!
.getPrimaryEnabledButtonStyle(
context),
child: Text(
"Continue",
style: STextStyles.button(context),
), ),
), ),
), ),
rightButton: TextButton( );
onPressed: () async { },
Navigator.of(context).pop(); child: Text(
"Anonymize funds",
unawaited(attemptAnonymize()); style: STextStyles.button(context).copyWith(
}, color: Theme.of(context)
style: Theme.of(context) .extension<StackColors>()!
.extension<StackColors>()! .buttonTextSecondary,
.getPrimaryEnabledButtonStyle(
context),
child: Text(
"Continue",
style: STextStyles.button(context),
),
),
), ),
);
},
child: Text(
"Anonymize funds",
style: STextStyles.button(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
), ),
), ),
), ),
],
),
),
const SizedBox(
height: 20,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Transactions",
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
CustomTextButton(
text: "See all",
onTap: () {
Navigator.of(context).pushNamed(
AllTransactionsView.routeName,
arguments: walletId,
);
},
), ),
], ],
), ),
), ),
const SizedBox( const SizedBox(
height: 20, height: 12,
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Transactions",
style: STextStyles.itemSubtitle(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark3,
),
),
CustomTextButton(
text: "See all",
onTap: () {
Navigator.of(context).pushNamed(
AllTransactionsView.routeName,
arguments: walletId,
);
},
),
],
), ),
), Expanded(
const SizedBox( child: Stack(
height: 12, children: [
), Padding(
Expanded( padding: const EdgeInsets.symmetric(horizontal: 16),
child: Stack( child: Padding(
children: [ padding: const EdgeInsets.only(bottom: 14),
Padding( child: ClipRRect(
padding: const EdgeInsets.symmetric(horizontal: 16), borderRadius: BorderRadius.vertical(
child: Padding( top: Radius.circular(
padding: const EdgeInsets.only(bottom: 14), Constants.size.circularBorderRadius,
child: ClipRRect( ),
borderRadius: BorderRadius.vertical( bottom: Radius.circular(
top: Radius.circular( // WalletView.navBarHeight / 2.0,
Constants.size.circularBorderRadius,
),
bottom: Radius.circular(
// WalletView.navBarHeight / 2.0,
Constants.size.circularBorderRadius,
),
),
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius, Constants.size.circularBorderRadius,
), ),
), ),
child: Column( child: Container(
crossAxisAlignment: decoration: BoxDecoration(
CrossAxisAlignment.stretch, color: Colors.transparent,
children: [ borderRadius: BorderRadius.circular(
Expanded( Constants.size.circularBorderRadius,
child: TransactionsList(
managerProvider: managerProvider,
walletId: walletId,
),
), ),
], ),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch,
children: [
Expanded(
child: TransactionsList(
managerProvider: managerProvider,
walletId: walletId,
),
),
],
),
), ),
), ),
), ),
), ),
), Column(
Column( mainAxisAlignment: MainAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.end, children: [
children: [ Row(
Row( mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, children: [
children: [ Padding(
Padding( padding: const EdgeInsets.only(
padding: const EdgeInsets.only( bottom: 14,
bottom: 14, left: 16,
left: 16, right: 16,
right: 16, ),
), child: WalletNavigationBar(
child: WalletNavigationBar( walletId: widget.walletId,
walletId: widget.walletId, coin: ref.watch(managerProvider
coin: ref.watch(managerProvider .select((value) => value.coin)),
.select((value) => value.coin)), enableExchange:
enableExchange: Constants.enableExchange && Constants.enableExchange &&
ref.watch(managerProvider.select( ref.watch(managerProvider.select(
(value) => value.coin)) != (value) => value.coin)) !=
Coin.epicCash, Coin.epicCash,
height: WalletView.navBarHeight, height: WalletView.navBarHeight,
onExchangePressed: () => onExchangePressed: () =>
_onExchangePressed(context), _onExchangePressed(context),
onReceivePressed: () async { onReceivePressed: () async {
final coin = final coin =
ref.read(managerProvider).coin; ref.read(managerProvider).coin;
if (mounted) { if (mounted) {
unawaited( unawaited(
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
ReceiveView.routeName, ReceiveView.routeName,
arguments: Tuple2(
walletId,
coin,
),
));
}
},
onSendPressed: () {
final walletId =
ref.read(managerProvider).walletId;
final coin =
ref.read(managerProvider).coin;
switch (ref
.read(
walletBalanceToggleStateProvider
.state)
.state) {
case WalletBalanceToggleState.full:
ref
.read(
publicPrivateBalanceStateProvider
.state)
.state = "Public";
break;
case WalletBalanceToggleState
.available:
ref
.read(
publicPrivateBalanceStateProvider
.state)
.state = "Private";
break;
}
Navigator.of(context).pushNamed(
SendView.routeName,
arguments: Tuple2( arguments: Tuple2(
walletId, walletId,
coin, coin,
), ),
);
},
onBuyPressed: () {
unawaited(
Navigator.of(context).pushNamed(
BuyInWalletView.routeName,
arguments: coin,
)); ));
} },
}, ),
onSendPressed: () {
final walletId =
ref.read(managerProvider).walletId;
final coin =
ref.read(managerProvider).coin;
switch (ref
.read(walletBalanceToggleStateProvider
.state)
.state) {
case WalletBalanceToggleState.full:
ref
.read(
publicPrivateBalanceStateProvider
.state)
.state = "Public";
break;
case WalletBalanceToggleState.available:
ref
.read(
publicPrivateBalanceStateProvider
.state)
.state = "Private";
break;
}
Navigator.of(context).pushNamed(
SendView.routeName,
arguments: Tuple2(
walletId,
coin,
),
);
},
onBuyPressed: () {
unawaited(Navigator.of(context).pushNamed(
BuyInWalletView.routeName,
arguments: coin,
));
},
), ),
), ],
], ),
), ],
], )
) ],
], ),
), ),
), ],
], ),
), ),
), ),
), ),

View file

@ -1,79 +1,142 @@
import 'package:flutter/material.dart'; 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/exchange_view/exchange_form.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_trade_history.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/services/exchange/exchange_data_loading_service.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart'; import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
class DesktopExchangeView extends StatefulWidget { class DesktopExchangeView extends ConsumerStatefulWidget {
const DesktopExchangeView({Key? key}) : super(key: key); const DesktopExchangeView({Key? key}) : super(key: key);
static const String routeName = "/desktopExchange"; static const String routeName = "/desktopExchange";
@override @override
State<DesktopExchangeView> createState() => _DesktopExchangeViewState(); ConsumerState<DesktopExchangeView> createState() =>
_DesktopExchangeViewState();
} }
class _DesktopExchangeViewState extends State<DesktopExchangeView> { class _DesktopExchangeViewState extends ConsumerState<DesktopExchangeView> {
bool _initialCachePopulationUnderway = false;
@override
void initState() {
if (!ref.read(prefsChangeNotifierProvider).externalCalls) {
if (ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
ExchangeDataLoadingService.instance
.init()
.then((_) => ExchangeDataLoadingService.instance.loadAll());
} else if (ExchangeDataLoadingService.instance.isLoading &&
ExchangeDataLoadingService.currentCacheVersion <
ExchangeDataLoadingService.cacheVersion) {
_initialCachePopulationUnderway = true;
ExchangeDataLoadingService.instance.onLoadingComplete = () {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
_initialCachePopulationUnderway = false;
});
});
};
}
super.initState();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return DesktopScaffold( return ConditionalParent(
appBar: DesktopAppBar( condition: _initialCachePopulationUnderway,
isCompactHeight: true, builder: (child) {
leading: Padding( return Stack(
children: [
child,
Material(
color: Theme.of(context)
.extension<StackColors>()!
.overlay
.withOpacity(0.6),
child: const CustomLoadingOverlay(
message: "Updating exchange data",
subMessage: "This could take a few minutes",
eventBus: null,
),
)
],
);
},
child: DesktopScaffold(
appBar: DesktopAppBar(
isCompactHeight: true,
leading: Padding(
padding: const EdgeInsets.only(
left: 24,
),
child: Text(
"Exchange",
style: STextStyles.desktopH3(context),
),
),
),
body: Padding(
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
left: 24, left: 24,
right: 24,
bottom: 24,
), ),
child: Text( child: Row(
"Exchange", crossAxisAlignment: CrossAxisAlignment.start,
style: STextStyles.desktopH3(context), children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Exchange details",
style: STextStyles.desktopTextExtraExtraSmall(context),
),
const SizedBox(
height: 16,
),
const RoundedWhiteContainer(
padding: EdgeInsets.all(24),
child: ExchangeForm(),
),
],
),
),
const SizedBox(
width: 16,
),
Expanded(
child: Row(
children: const [
Expanded(
child: DesktopTradeHistory(),
),
],
),
),
],
), ),
), ),
), ),
body: Padding(
padding: const EdgeInsets.only(
left: 24,
right: 24,
bottom: 24,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Exchange details",
style: STextStyles.desktopTextExtraExtraSmall(context),
),
const SizedBox(
height: 16,
),
const RoundedWhiteContainer(
padding: EdgeInsets.all(24),
child: ExchangeForm(),
),
],
),
),
const SizedBox(
width: 16,
),
Expanded(
child: Row(
children: const [
Expanded(
child: DesktopTradeHistory(),
),
],
),
),
],
),
),
); );
} }
} }

View file

@ -7,19 +7,19 @@ import 'package:qr_flutter/qr_flutter.dart';
import 'package:stackwallet/models/exchange/incomplete_exchange.dart'; import 'package:stackwallet/models/exchange/incomplete_exchange.dart';
import 'package:stackwallet/models/exchange/response_objects/trade.dart'; import 'package:stackwallet/models/exchange/response_objects/trade.dart';
import 'package:stackwallet/pages/exchange_view/send_from_view.dart'; import 'package:stackwallet/pages/exchange_view/send_from_view.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_1.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_2.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_3.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_4.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/subwidgets/desktop_exchange_steps_indicator.dart';
import 'package:stackwallet/providers/exchange/exchange_provider.dart'; import 'package:stackwallet/providers/exchange/exchange_form_state_provider.dart';
import 'package:stackwallet/providers/global/trades_service_provider.dart'; import 'package:stackwallet/providers/global/trades_service_provider.dart';
import 'package:stackwallet/route_generator.dart'; import 'package:stackwallet/route_generator.dart';
import 'package:stackwallet/services/exchange/exchange_response.dart'; import 'package:stackwallet/services/exchange/exchange_response.dart';
import 'package:stackwallet/services/notifications_api.dart'; import 'package:stackwallet/services/notifications_api.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
@ -83,7 +83,8 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
); );
final ExchangeResponse<Trade> response = await ref final ExchangeResponse<Trade> response = await ref
.read(exchangeProvider) .read(exchangeFormStateProvider)
.exchange
.createTrade( .createTrade(
from: ref.read(desktopExchangeModelProvider)!.sendTicker, from: ref.read(desktopExchangeModelProvider)!.sendTicker,
to: ref.read(desktopExchangeModelProvider)!.receiveTicker, to: ref.read(desktopExchangeModelProvider)!.receiveTicker,

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
import 'package:stackwallet/providers/providers.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -38,7 +38,8 @@ class DesktopStep1 extends ConsumerWidget {
children: [ children: [
DesktopStepItem( DesktopStepItem(
label: "Exchange", label: "Exchange",
value: ref.watch(currentExchangeNameStateProvider.state).state, value: ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)),
), ),
Container( Container(
height: 1, height: 1,

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/step_scaffold.dart';
import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart'; import 'package:stackwallet/pages_desktop_specific/desktop_exchange/exchange_steps/subwidgets/desktop_step_item.dart';
import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart'; import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/utilities/enums/exchange_rate_type_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart'; import 'package:stackwallet/widgets/rounded_white_container.dart';
@ -36,7 +36,8 @@ class _DesktopStep3State extends ConsumerState<DesktopStep3> {
children: [ children: [
DesktopStepItem( DesktopStepItem(
label: "Exchange", label: "Exchange",
value: ref.watch(currentExchangeNameStateProvider.state).state, value: ref.watch(exchangeFormStateProvider
.select((value) => value.exchange.name)),
), ),
Container( Container(
height: 1, height: 1,

View file

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

View file

@ -24,12 +24,15 @@ import 'package:stackwallet/services/event_bus/events/global/wallet_sync_status_
import 'package:stackwallet/services/event_bus/global_event_bus.dart'; import 'package:stackwallet/services/event_bus/global_event_bus.dart';
import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart'; import 'package:stackwallet/services/mixins/paynym_wallet_interface.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart'; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart';
import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart'; import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/background.dart';
import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart'; import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
import 'package:stackwallet/widgets/custom_loading_overlay.dart'; import 'package:stackwallet/widgets/custom_loading_overlay.dart';
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart'; import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
@ -63,6 +66,7 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
late final EventBus eventBus; late final EventBus eventBus;
late final bool _shouldDisableAutoSyncOnLogOut; late final bool _shouldDisableAutoSyncOnLogOut;
bool _rescanningOnOpen = false;
Future<void> onBackPressed() async { Future<void> onBackPressed() async {
await _logout(); await _logout();
@ -265,7 +269,18 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
_shouldDisableAutoSyncOnLogOut = false; _shouldDisableAutoSyncOnLogOut = false;
} }
ref.read(managerProvider).refresh(); if (ref.read(managerProvider).rescanOnOpenVersion == Constants.rescanV1) {
_rescanningOnOpen = true;
ref.read(managerProvider).fullRescan(20, 1000).then(
(_) => ref.read(managerProvider).resetRescanOnOpen().then(
(_) => WidgetsBinding.instance.addPostFrameCallback(
(_) => setState(() => _rescanningOnOpen = false),
),
),
);
} else {
ref.read(managerProvider).refresh();
}
super.initState(); super.initState();
} }
@ -284,241 +299,263 @@ class _DesktopWalletViewState extends ConsumerState<DesktopWalletView> {
final managerProvider = ref.watch(walletsChangeNotifierProvider final managerProvider = ref.watch(walletsChangeNotifierProvider
.select((value) => value.getManagerProvider(widget.walletId))); .select((value) => value.getManagerProvider(widget.walletId)));
return DesktopScaffold( return ConditionalParent(
appBar: DesktopAppBar( condition: _rescanningOnOpen,
background: Theme.of(context).extension<StackColors>()!.popupBG, builder: (child) {
leading: Expanded( return Stack(
child: Row( children: [
children: [ child,
const SizedBox( Background(
width: 32, child: CustomLoadingOverlay(
message:
"Migration in progress\nThis could take a while\nPlease don't leave this screen",
subMessage: "This only needs to run once per wallet",
eventBus: null,
textColor: Theme.of(context).extension<StackColors>()!.textDark,
), ),
AppBarIconButton( )
size: 32, ],
color: Theme.of(context) );
.extension<StackColors>()! },
.textFieldDefaultBG, child: DesktopScaffold(
shadows: const [], appBar: DesktopAppBar(
icon: SvgPicture.asset( background: Theme.of(context).extension<StackColors>()!.popupBG,
Assets.svg.arrowLeft, leading: Expanded(
width: 18, child: Row(
height: 18, children: [
const SizedBox(
width: 32,
),
AppBarIconButton(
size: 32,
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.topNavIconPrimary, .textFieldDefaultBG,
shadows: const [],
icon: SvgPicture.asset(
Assets.svg.arrowLeft,
width: 18,
height: 18,
color: Theme.of(context)
.extension<StackColors>()!
.topNavIconPrimary,
),
onPressed: onBackPressed,
),
const SizedBox(
width: 15,
),
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
width: 32,
height: 32,
),
const SizedBox(
width: 12,
),
ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 48,
),
child: IntrinsicWidth(
child: DesktopWalletNameField(
walletId: widget.walletId,
),
),
),
const Spacer(),
Row(
children: [
NetworkInfoButton(
walletId: widget.walletId,
eventBus: eventBus,
),
const SizedBox(
width: 2,
),
WalletKeysButton(
walletId: widget.walletId,
),
const SizedBox(
width: 2,
),
DeleteWalletButton(
walletId: widget.walletId,
),
const SizedBox(
width: 12,
),
],
),
],
),
),
useSpacers: false,
isCompactHeight: true,
),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
RoundedWhiteContainer(
padding: const EdgeInsets.all(20),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
width: 40,
height: 40,
),
const SizedBox(
width: 10,
),
DesktopWalletSummary(
walletId: widget.walletId,
managerProvider: managerProvider,
initialSyncStatus: ref.watch(managerProvider
.select((value) => value.isRefreshing))
? WalletSyncStatus.syncing
: WalletSyncStatus.synced,
),
const Spacer(),
if (coin == Coin.firo) const SizedBox(width: 10),
if (coin == Coin.firo)
SecondaryButton(
width: 180,
buttonHeight: ButtonHeight.l,
label: "Anonymize funds",
onPressed: () async {
await showDialog<void>(
context: context,
barrierDismissible: false,
builder: (context) => DesktopDialog(
maxWidth: 500,
maxHeight: 210,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32, vertical: 20),
child: Column(
children: [
Text(
"Attention!",
style: STextStyles.desktopH2(context),
),
const SizedBox(height: 16),
Text(
"You're about to anonymize all of your public funds.",
style:
STextStyles.desktopTextSmall(context),
),
const SizedBox(height: 32),
Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
SecondaryButton(
width: 200,
buttonHeight: ButtonHeight.l,
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
const SizedBox(width: 20),
PrimaryButton(
width: 200,
buttonHeight: ButtonHeight.l,
label: "Continue",
onPressed: () {
Navigator.of(context).pop();
unawaited(attemptAnonymize());
},
)
],
),
],
),
),
),
);
},
),
if (ref.watch(walletsChangeNotifierProvider.select(
(value) => value
.getManager(widget.walletId)
.hasPaynymSupport)))
SecondaryButton(
label: "PayNym",
width: 160,
buttonHeight: ButtonHeight.l,
icon: SvgPicture.asset(
Assets.svg.user,
height: 20,
width: 20,
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
onPressed: onPaynymButtonPressed,
),
// if (coin == Coin.firo) const SizedBox(width: 16),
// SecondaryButton(
// width: 180,
// buttonHeight: ButtonHeight.l,
// onPressed: () {
// _onExchangePressed(context);
// },
// label: "Exchange",
// icon: Container(
// width: 24,
// height: 24,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(24),
// color: Theme.of(context)
// .extension<StackColors>()!
// .buttonBackPrimary
// .withOpacity(0.2),
// ),
// child: Center(
// child: SvgPicture.asset(
// Assets.svg.arrowRotate2,
// width: 14,
// height: 14,
// color: Theme.of(context)
// .extension<StackColors>()!
// .buttonTextSecondary,
// ),
// ),
// ),
// ),
],
), ),
onPressed: onBackPressed,
), ),
const SizedBox( const SizedBox(
width: 15, height: 24,
), ),
SvgPicture.asset( Expanded(
Assets.svg.iconFor(coin: coin), child: Row(
width: 32, children: [
height: 32, SizedBox(
), width: 450,
const SizedBox( child: MyWallet(
width: 12, walletId: widget.walletId,
), ),
ConstrainedBox( ),
constraints: const BoxConstraints( const SizedBox(
minWidth: 48, width: 16,
),
Expanded(
child: RecentDesktopTransactions(
walletId: widget.walletId,
),
),
],
), ),
child: IntrinsicWidth(
child: DesktopWalletNameField(
walletId: widget.walletId,
),
),
),
const Spacer(),
Row(
children: [
NetworkInfoButton(
walletId: widget.walletId,
eventBus: eventBus,
),
const SizedBox(
width: 2,
),
WalletKeysButton(
walletId: widget.walletId,
),
const SizedBox(
width: 2,
),
DeleteWalletButton(
walletId: widget.walletId,
),
const SizedBox(
width: 12,
),
],
), ),
], ],
), ),
), ),
useSpacers: false,
isCompactHeight: true,
),
body: Padding(
padding: const EdgeInsets.all(24),
child: Column(
children: [
RoundedWhiteContainer(
padding: const EdgeInsets.all(20),
child: Row(
children: [
SvgPicture.asset(
Assets.svg.iconFor(coin: coin),
width: 40,
height: 40,
),
const SizedBox(
width: 10,
),
DesktopWalletSummary(
walletId: widget.walletId,
managerProvider: managerProvider,
initialSyncStatus: ref.watch(managerProvider
.select((value) => value.isRefreshing))
? WalletSyncStatus.syncing
: WalletSyncStatus.synced,
),
const Spacer(),
if (coin == Coin.firo) const SizedBox(width: 10),
if (coin == Coin.firo)
SecondaryButton(
width: 180,
buttonHeight: ButtonHeight.l,
label: "Anonymize funds",
onPressed: () async {
await showDialog<void>(
context: context,
barrierDismissible: false,
builder: (context) => DesktopDialog(
maxWidth: 500,
maxHeight: 210,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32, vertical: 20),
child: Column(
children: [
Text(
"Attention!",
style: STextStyles.desktopH2(context),
),
const SizedBox(height: 16),
Text(
"You're about to anonymize all of your public funds.",
style:
STextStyles.desktopTextSmall(context),
),
const SizedBox(height: 32),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SecondaryButton(
width: 200,
buttonHeight: ButtonHeight.l,
label: "Cancel",
onPressed: () {
Navigator.of(context).pop();
},
),
const SizedBox(width: 20),
PrimaryButton(
width: 200,
buttonHeight: ButtonHeight.l,
label: "Continue",
onPressed: () {
Navigator.of(context).pop();
unawaited(attemptAnonymize());
},
)
],
),
],
),
),
),
);
},
),
if (ref.watch(walletsChangeNotifierProvider.select((value) =>
value.getManager(widget.walletId).hasPaynymSupport)))
SecondaryButton(
label: "PayNym",
width: 160,
buttonHeight: ButtonHeight.l,
icon: SvgPicture.asset(
Assets.svg.user,
height: 20,
width: 20,
color: Theme.of(context)
.extension<StackColors>()!
.buttonTextSecondary,
),
onPressed: onPaynymButtonPressed,
),
// if (coin == Coin.firo) const SizedBox(width: 16),
// SecondaryButton(
// width: 180,
// buttonHeight: ButtonHeight.l,
// onPressed: () {
// _onExchangePressed(context);
// },
// label: "Exchange",
// icon: Container(
// width: 24,
// height: 24,
// decoration: BoxDecoration(
// borderRadius: BorderRadius.circular(24),
// color: Theme.of(context)
// .extension<StackColors>()!
// .buttonBackPrimary
// .withOpacity(0.2),
// ),
// child: Center(
// child: SvgPicture.asset(
// Assets.svg.arrowRotate2,
// width: 14,
// height: 14,
// color: Theme.of(context)
// .extension<StackColors>()!
// .buttonTextSecondary,
// ),
// ),
// ),
// ),
],
),
),
const SizedBox(
height: 24,
),
Expanded(
child: Row(
children: [
SizedBox(
width: 450,
child: MyWallet(
walletId: widget.walletId,
),
),
const SizedBox(
width: 16,
),
Expanded(
child: RecentDesktopTransactions(
walletId: widget.walletId,
),
),
],
),
),
],
),
), ),
); );
} }

View file

@ -1,6 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
final currentExchangeNameStateProvider = StateProvider<String>(
(ref) => Exchange.defaultExchange.name,
);

View file

@ -1,9 +0,0 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/providers/exchange/current_exchange_name_state_provider.dart';
import 'package:stackwallet/services/exchange/exchange.dart';
final exchangeProvider = Provider<Exchange>(
(ref) => Exchange.fromName(
ref.watch(currentExchangeNameStateProvider.state).state,
),
);

View file

@ -2,10 +2,8 @@ export './buy/buy_form_state_provider.dart';
export './buy/simplex_initial_load_status.dart'; export './buy/simplex_initial_load_status.dart';
export './buy/simplex_provider.dart'; export './buy/simplex_provider.dart';
export './exchange/changenow_initial_load_status.dart'; export './exchange/changenow_initial_load_status.dart';
export './exchange/current_exchange_name_state_provider.dart';
export './exchange/exchange_flow_is_active_state_provider.dart'; export './exchange/exchange_flow_is_active_state_provider.dart';
export './exchange/exchange_form_state_provider.dart'; export './exchange/exchange_form_state_provider.dart';
export './exchange/exchange_provider.dart';
export './exchange/exchange_send_from_wallet_id_provider.dart'; export './exchange/exchange_send_from_wallet_id_provider.dart';
export './exchange/trade_note_service_provider.dart'; export './exchange/trade_note_service_provider.dart';
export './exchange/trade_sent_from_stack_lookup_provider.dart'; export './exchange/trade_sent_from_stack_lookup_provider.dart';

View file

@ -711,15 +711,15 @@ class RouteGenerator {
return _routeError("${settings.name} invalid args: ${args.toString()}"); return _routeError("${settings.name} invalid args: ${args.toString()}");
case RestoreWalletView.routeName: case RestoreWalletView.routeName:
if (args is Tuple4<String, Coin, int, DateTime>) { if (args is Tuple5<String, Coin, int, DateTime, String>) {
return getRoute( return getRoute(
shouldUseMaterialRoute: useMaterialPageRoute, shouldUseMaterialRoute: useMaterialPageRoute,
builder: (_) => RestoreWalletView( builder: (_) => RestoreWalletView(
walletName: args.item1, walletName: args.item1,
coin: args.item2, coin: args.item2,
seedWordsLength: args.item3, seedWordsLength: args.item3,
restoreFromDate: args.item4, restoreFromDate: args.item4,
), mnemonicPassphrase: args.item5),
settings: RouteSettings( settings: RouteSettings(
name: settings.name, name: settings.name,
), ),

View file

@ -871,7 +871,7 @@ class EpicCashWallet extends CoinServiceAPI
publicKey: [], // ?? publicKey: [], // ??
); );
await db.putAddress(address); await db.updateOrPutAddresses([address]);
} }
return address; return address;
@ -2094,12 +2094,14 @@ class EpicCashWallet extends CoinServiceAPI
height = null; height = null;
} }
final isIncoming = (tx["tx_type"] == "TxReceived" ||
tx["tx_type"] == "TxReceivedCancelled");
final txn = isar_models.Transaction( final txn = isar_models.Transaction(
walletId: walletId, walletId: walletId,
txid: commitId ?? tx["id"].toString(), txid: commitId ?? tx["id"].toString(),
timestamp: (dt.millisecondsSinceEpoch ~/ 1000), timestamp: (dt.millisecondsSinceEpoch ~/ 1000),
type: (tx["tx_type"] == "TxReceived" || type: isIncoming
tx["tx_type"] == "TxReceivedCancelled")
? isar_models.TransactionType.incoming ? isar_models.TransactionType.incoming
: isar_models.TransactionType.outgoing, : isar_models.TransactionType.outgoing,
subType: isar_models.TransactionSubType.none, subType: isar_models.TransactionSubType.none,
@ -2122,6 +2124,38 @@ class EpicCashWallet extends CoinServiceAPI
.filter() .filter()
.valueEqualTo(address) .valueEqualTo(address)
.findFirst(); .findFirst();
if (transactionAddress == null) {
if (isIncoming) {
transactionAddress = isar_models.Address(
walletId: walletId,
value: address,
publicKey: [],
derivationIndex: 0,
derivationPath: null,
type: isar_models.AddressType.mimbleWimble,
subType: isar_models.AddressSubType.receiving,
);
} else {
final myRcvAddr = await currentReceivingAddress;
final isSentToSelf = myRcvAddr == address;
transactionAddress = isar_models.Address(
walletId: walletId,
value: address,
publicKey: [],
derivationIndex: isSentToSelf ? 0 : -1,
derivationPath: null,
type: isSentToSelf
? isar_models.AddressType.mimbleWimble
: isar_models.AddressType.nonWallet,
subType: isSentToSelf
? isar_models.AddressSubType.receiving
: isar_models.AddressSubType.nonWallet,
);
}
}
// //
// midSortedTx["inputSize"] = tx["num_inputs"]; // midSortedTx["inputSize"] = tx["num_inputs"];
// midSortedTx["outputSize"] = tx["num_outputs"]; // midSortedTx["outputSize"] = tx["num_outputs"];

View file

@ -2,6 +2,7 @@ import 'dart:async';
import 'package:event_bus/event_bus.dart'; import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/balance.dart'; import 'package:stackwallet/models/balance.dart';
import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models; import 'package:stackwallet/models/isar/models/isar_models.dart' as isar_models;
import 'package:stackwallet/models/models.dart'; import 'package:stackwallet/models/models.dart';
@ -227,4 +228,18 @@ class Manager with ChangeNotifier {
int get currentHeight => _currentWallet.storedChainHeight; int get currentHeight => _currentWallet.storedChainHeight;
bool get hasPaynymSupport => _currentWallet is PaynymWalletInterface; bool get hasPaynymSupport => _currentWallet is PaynymWalletInterface;
int get rescanOnOpenVersion =>
DB.instance.get<dynamic>(
boxName: DB.boxNameDBInfo,
key: "rescan_on_open_$walletId",
) as int? ??
0;
Future<void> resetRescanOnOpen() async {
await DB.instance.delete<dynamic>(
key: "rescan_on_open_$walletId",
boxName: DB.boxNameDBInfo,
);
}
} }

View file

@ -434,8 +434,27 @@ class ChangeNowAPI {
final json = await _makeGetRequest(uri); final json = await _makeGetRequest(uri);
try { try {
final value = EstimatedExchangeAmount.fromJson( final map = Map<String, dynamic>.from(json as Map);
Map<String, dynamic>.from(json as Map));
if (map["error"] != null) {
if (map["error"] == "not_valid_fixed_rate_pair") {
return ExchangeResponse(
exception: PairUnavailableException(
map["message"] as String? ?? "Unsupported fixed rate pair",
ExchangeExceptionType.generic,
),
);
} else {
return ExchangeResponse(
exception: ExchangeException(
map["message"] as String? ?? map["error"].toString(),
ExchangeExceptionType.generic,
),
);
}
}
final value = EstimatedExchangeAmount.fromJson(map);
return ExchangeResponse( return ExchangeResponse(
value: Estimate( value: Estimate(
estimatedAmount: value.estimatedAmount, estimatedAmount: value.estimatedAmount,

View file

@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/models/isar/exchange_cache/currency.dart'; import 'package:stackwallet/models/isar/exchange_cache/currency.dart';
import 'package:stackwallet/models/isar/exchange_cache/pair.dart'; import 'package:stackwallet/models/isar/exchange_cache/pair.dart';
import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart'; import 'package:stackwallet/services/exchange/change_now/change_now_exchange.dart';
@ -16,6 +17,25 @@ class ExchangeDataLoadingService {
Isar? _isar; Isar? _isar;
Isar get isar => _isar!; Isar get isar => _isar!;
VoidCallback? onLoadingError;
VoidCallback? onLoadingComplete;
static const int cacheVersion = 1;
static int get currentCacheVersion =>
DB.instance.get<dynamic>(
boxName: DB.boxNameDBInfo,
key: "exchange_data_cache_version") as int? ??
0;
Future<void> _updateCurrentCacheVersion(int version) async {
await DB.instance.put<dynamic>(
boxName: DB.boxNameDBInfo,
key: "exchange_data_cache_version",
value: version,
);
}
Future<void> init() async { Future<void> init() async {
if (_isar != null && isar.isOpen) return; if (_isar != null && isar.isOpen) return;
_isar = await Isar.open( _isar = await Isar.open(
@ -25,18 +45,23 @@ class ExchangeDataLoadingService {
], ],
directory: (await StackFileSystem.applicationIsarDirectory()).path, directory: (await StackFileSystem.applicationIsarDirectory()).path,
inspector: kDebugMode, inspector: kDebugMode,
// inspector: false,
name: "exchange_cache", name: "exchange_cache",
); );
} }
bool get isLoading => _locked;
bool _locked = false; bool _locked = false;
Future<void> loadAll() async { Future<void> loadAll() async {
print("LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG: LOCKED=$_locked");
if (!_locked) { if (!_locked) {
_locked = true; _locked = true;
print("LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"); Logging.instance.log(
final time = DateTime.now(); "ExchangeDataLoadingService.loadAll starting...",
level: LogLevel.Info,
);
final start = DateTime.now();
try { try {
await Future.wait([ await Future.wait([
_loadChangeNowCurrencies(), _loadChangeNowCurrencies(),
@ -46,13 +71,18 @@ class ExchangeDataLoadingService {
// loadSimpleswapFloatingRateCurrencies(ref), // loadSimpleswapFloatingRateCurrencies(ref),
loadMajesticBankCurrencies(), loadMajesticBankCurrencies(),
]); ]);
Logging.instance.log(
print( "ExchangeDataLoadingService.loadAll finished in ${DateTime.now().difference(start).inSeconds} seconds",
"LOADINGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG done in ${DateTime.now().difference(time).inSeconds} seconds"); level: LogLevel.Info,
);
onLoadingComplete?.call();
await _updateCurrentCacheVersion(cacheVersion);
} catch (e, s) { } catch (e, s) {
Logging.instance.log( Logging.instance.log(
"ExchangeDataLoadingService.loadAll failed: $e\n$s", "ExchangeDataLoadingService.loadAll failed after ${DateTime.now().difference(start).inSeconds} seconds: $e\n$s",
level: LogLevel.Error); level: LogLevel.Error,
);
onLoadingError?.call();
} }
_locked = false; _locked = false;
} }
@ -82,7 +112,7 @@ class ExchangeDataLoadingService {
Future<void> _loadChangeNowFixedRatePairs() async { Future<void> _loadChangeNowFixedRatePairs() async {
final exchange = ChangeNowExchange.instance; final exchange = ChangeNowExchange.instance;
final responsePairs = await exchange.getAllPairs(true); final responsePairs = await compute(exchange.getAllPairs, true);
if (responsePairs.value != null) { if (responsePairs.value != null) {
await isar.writeTxn(() async { await isar.writeTxn(() async {
@ -107,7 +137,7 @@ class ExchangeDataLoadingService {
Future<void> _loadChangeNowEstimatedRatePairs() async { Future<void> _loadChangeNowEstimatedRatePairs() async {
final exchange = ChangeNowExchange.instance; final exchange = ChangeNowExchange.instance;
final responsePairs = await exchange.getAllPairs(false); final responsePairs = await compute(exchange.getAllPairs, false);
if (responsePairs.value != null) { if (responsePairs.value != null) {
await isar.writeTxn(() async { await isar.writeTxn(() async {

View file

@ -21,7 +21,8 @@ abstract class Constants {
} }
static bool enableExchange = Util.isDesktop || !Platform.isIOS; static bool enableExchange = Util.isDesktop || !Platform.isIOS;
static bool enableBuy = true; // true for development, TODO change to "Util.isDesktop || !Platform.isIOS;" as above or even just = enableExchange static bool enableBuy =
true; // true for development, TODO change to "Util.isDesktop || !Platform.isIOS;" as above or even just = enableExchange
//TODO: correct for monero? //TODO: correct for monero?
static const int _satsPerCoinMonero = 1000000000000; static const int _satsPerCoinMonero = 1000000000000;
@ -41,6 +42,8 @@ abstract class Constants {
static const int currentHiveDbVersion = 5; static const int currentHiveDbVersion = 5;
static const int rescanV1 = 1;
static int satsPerCoin(Coin coin) { static int satsPerCoin(Coin coin) {
switch (coin) { switch (coin) {
case Coin.bitcoin: case Coin.bitcoin:

View file

@ -1,5 +1,3 @@
import 'dart:convert';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:stackwallet/db/main_db.dart'; import 'package:stackwallet/db/main_db.dart';
import 'package:stackwallet/electrumx_rpc/electrumx.dart'; import 'package:stackwallet/electrumx_rpc/electrumx.dart';
@ -12,10 +10,10 @@ import 'package:stackwallet/models/node_model.dart';
import 'package:stackwallet/services/mixins/wallet_db.dart'; import 'package:stackwallet/services/mixins/wallet_db.dart';
import 'package:stackwallet/services/node_service.dart'; import 'package:stackwallet/services/node_service.dart';
import 'package:stackwallet/services/wallets_service.dart'; import 'package:stackwallet/services/wallets_service.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/default_nodes.dart'; import 'package:stackwallet/utilities/default_nodes.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart'; import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'; import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart';
import 'package:stackwallet/utilities/format.dart';
import 'package:stackwallet/utilities/logger.dart'; import 'package:stackwallet/utilities/logger.dart';
import 'package:stackwallet/utilities/prefs.dart'; import 'package:stackwallet/utilities/prefs.dart';
import 'package:tuple/tuple.dart'; import 'package:tuple/tuple.dart';
@ -200,6 +198,7 @@ class DbVersionMigrator with WalletDB {
final prefs = Prefs.instance; final prefs = Prefs.instance;
final walletInfoList = await walletsService.walletNames; final walletInfoList = await walletsService.walletNames;
await prefs.init(); await prefs.init();
await MainDB.instance.initMainDB();
for (final walletId in walletInfoList.keys) { for (final walletId in walletInfoList.keys) {
final info = walletInfoList[walletId]!; final info = walletInfoList[walletId]!;
@ -207,206 +206,67 @@ class DbVersionMigrator with WalletDB {
final walletBox = await Hive.openBox<dynamic>(info.walletId); final walletBox = await Hive.openBox<dynamic>(info.walletId);
final receiveDerivePrefix = "${walletId}_receiveDerivations";
final changeDerivePrefix = "${walletId}_changeDerivations";
const receiveAddressesPrefix = "receivingAddresses"; const receiveAddressesPrefix = "receivingAddresses";
const changeAddressesPrefix = "changeAddresses"; const changeAddressesPrefix = "changeAddresses";
final p2pkhRcvDerivations = // we need to manually migrate epic cash transactions as they are not
(await secureStore.read(key: receiveDerivePrefix)) ?? // stored on the epic cash blockchain
(await secureStore.read(key: "${receiveDerivePrefix}P2PKH")); if (info.coin == Coin.epicCash) {
final p2shRcvDerivations = final txnData = walletBox.get("latest_tx_model") as TransactionData?;
await secureStore.read(key: "${receiveDerivePrefix}P2SH");
final p2wpkhRcvDerivations =
await secureStore.read(key: "${receiveDerivePrefix}P2WPKH");
final p2pkhCngDerivations = // we ever only used index 0 in the past
(await secureStore.read(key: changeDerivePrefix)) ?? const rcvIndex = 0;
(await secureStore.read(key: "${changeDerivePrefix}P2PKH"));
final p2shCngDerivations =
await secureStore.read(key: "${changeDerivePrefix}P2SH");
final p2wpkhCngDerivations =
await secureStore.read(key: "${changeDerivePrefix}P2WPKH");
// useless? final List<Tuple2<isar_models.Transaction, isar_models.Address?>>
// const receiveIndexPrefix = "receivingIndex"; transactionsData = [];
// const changeIndexPrefix = "changeIndex"; if (txnData != null) {
// final p2pkhRcvIndex = walletBox.get(receiveIndexPrefix) as int? ?? final txns = txnData.getAllTransactions();
// walletBox.get("${receiveIndexPrefix}P2PKH") as int?;
// final p2shRcvIndex =
// walletBox.get("${receiveIndexPrefix}P2SH") as int?;
// final p2wpkhRcvIndex =
// walletBox.get("${receiveIndexPrefix}P2WPKH") as int?;
//
// final p2pkhCngIndex = walletBox.get(changeIndexPrefix) as int? ??
// walletBox.get("${changeIndexPrefix}P2PKH") as int?;
// final p2shCngIndex =
// walletBox.get("${changeIndexPrefix}P2SH") as int?;
// final p2wpkhCngIndex =
// walletBox.get("${changeIndexPrefix}P2WPKH") as int?;
final List<isar_models.Address> newAddresses = []; for (final tx in txns.values) {
bool isIncoming = tx.txType == "Received";
if (p2pkhRcvDerivations != null) { final iTx = isar_models.Transaction(
newAddresses.addAll( walletId: walletId,
_v4GetAddressesFromDerivationString( txid: tx.txid,
p2pkhRcvDerivations, timestamp: tx.timestamp,
isar_models.AddressType.p2pkh, type: isIncoming
isar_models.AddressSubType.receiving, ? isar_models.TransactionType.incoming
walletId, : isar_models.TransactionType.outgoing,
), subType: isar_models.TransactionSubType.none,
); amount: tx.amount,
} fee: tx.fees,
height: tx.height,
isCancelled: tx.isCancelled,
isLelantus: false,
slateId: tx.slateId,
otherData: tx.otherData,
inputs: [],
outputs: [],
);
if (p2shRcvDerivations != null) { if (tx.address.isEmpty) {
newAddresses.addAll( transactionsData.add(Tuple2(iTx, null));
_v4GetAddressesFromDerivationString( } else {
p2shRcvDerivations, final address = isar_models.Address(
isar_models.AddressType.p2sh, walletId: walletId,
isar_models.AddressSubType.receiving, value: tx.address,
walletId, publicKey: [],
), derivationIndex: isIncoming ? rcvIndex : -1,
); derivationPath: null,
} type: isIncoming
? isar_models.AddressType.mimbleWimble
if (p2wpkhRcvDerivations != null) { : isar_models.AddressType.unknown,
newAddresses.addAll( subType: isIncoming
_v4GetAddressesFromDerivationString( ? isar_models.AddressSubType.receiving
p2wpkhRcvDerivations, : isar_models.AddressSubType.unknown,
isar_models.AddressType.p2wpkh, );
isar_models.AddressSubType.receiving, transactionsData.add(Tuple2(iTx, address));
walletId, }
), }
);
}
if (p2pkhCngDerivations != null) {
newAddresses.addAll(
_v4GetAddressesFromDerivationString(
p2pkhCngDerivations,
isar_models.AddressType.p2pkh,
isar_models.AddressSubType.change,
walletId,
),
);
}
if (p2shCngDerivations != null) {
newAddresses.addAll(
_v4GetAddressesFromDerivationString(
p2shCngDerivations,
isar_models.AddressType.p2sh,
isar_models.AddressSubType.change,
walletId,
),
);
}
if (p2wpkhCngDerivations != null) {
newAddresses.addAll(
_v4GetAddressesFromDerivationString(
p2wpkhCngDerivations,
isar_models.AddressType.p2wpkh,
isar_models.AddressSubType.change,
walletId,
),
);
}
final currentNewSet = newAddresses.map((e) => e.value).toSet();
final p2pkhRcvAddresses = _v4GetAddressesFromList(
_getList(walletBox.get(receiveAddressesPrefix) ??
walletBox.get("${receiveAddressesPrefix}P2PKH")),
isar_models.AddressType.p2pkh,
isar_models.AddressSubType.receiving,
walletId);
for (final address in p2pkhRcvAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
} }
await MainDB.instance.addNewTransactionData(transactionsData, walletId);
} }
final p2shRcvAddresses = _v4GetAddressesFromList(
_getList(walletBox.get("${receiveAddressesPrefix}P2SH")),
isar_models.AddressType.p2sh,
isar_models.AddressSubType.receiving,
walletId);
for (final address in p2shRcvAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
}
}
final p2wpkhRcvAddresses = _v4GetAddressesFromList(
_getList(walletBox.get("${receiveAddressesPrefix}P2WPKH")),
isar_models.AddressType.p2wpkh,
isar_models.AddressSubType.receiving,
walletId);
for (final address in p2wpkhRcvAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
}
}
final p2pkhCngAddresses = _v4GetAddressesFromList(
_getList(walletBox.get(changeAddressesPrefix) ??
walletBox.get("${changeAddressesPrefix}P2PKH")),
isar_models.AddressType.p2wpkh,
isar_models.AddressSubType.change,
walletId);
for (final address in p2pkhCngAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
}
}
final p2shCngAddresses = _v4GetAddressesFromList(
_getList(walletBox.get("${changeAddressesPrefix}P2SH")),
isar_models.AddressType.p2wpkh,
isar_models.AddressSubType.change,
walletId);
for (final address in p2shCngAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
}
}
final p2wpkhCngAddresses = _v4GetAddressesFromList(
_getList(walletBox.get("${changeAddressesPrefix}P2WPKH")),
isar_models.AddressType.p2wpkh,
isar_models.AddressSubType.change,
walletId);
for (final address in p2wpkhCngAddresses) {
if (!currentNewSet.contains(address.value)) {
newAddresses.add(address);
}
}
// transactions
final txnData = walletBox.get("latest_tx_model") as TransactionData?;
final txns = txnData?.getAllTransactions().values ?? [];
final txnDataLelantus =
walletBox.get("latest_lelantus_tx_model") as TransactionData?;
final txnsLelantus = txnDataLelantus?.getAllTransactions().values ?? [];
final List<Tuple2<isar_models.Transaction, isar_models.Address?>>
newTransactions = [];
newTransactions
.addAll(_parseTransactions(txns, walletId, false, newAddresses));
newTransactions.addAll(
_parseTransactions(txnsLelantus, walletId, true, newAddresses));
// store newly parsed data in isar
await MainDB.instance.initMainDB();
initWalletDB();
await db.isar.writeTxn(() async {
await db.isar.addresses.putAll(newAddresses);
});
await db.addNewTransactionData(newTransactions, walletId);
// delete data from hive // delete data from hive
await walletBox.delete(receiveAddressesPrefix); await walletBox.delete(receiveAddressesPrefix);
await walletBox.delete("${receiveAddressesPrefix}P2PKH"); await walletBox.delete("${receiveAddressesPrefix}P2PKH");
@ -418,154 +278,24 @@ class DbVersionMigrator with WalletDB {
await walletBox.delete("${changeAddressesPrefix}P2WPKH"); await walletBox.delete("${changeAddressesPrefix}P2WPKH");
await walletBox.delete("latest_tx_model"); await walletBox.delete("latest_tx_model");
await walletBox.delete("latest_lelantus_tx_model"); await walletBox.delete("latest_lelantus_tx_model");
}
}
List<Tuple2<isar_models.Transaction, isar_models.Address?>> // set empty mnemonic passphrase as we used that by default before
_parseTransactions( if ((await secureStore.read(key: '${walletId}_mnemonicPassphrase')) ==
Iterable<Transaction> txns, null) {
String walletId, await secureStore.write(
bool isLelantus, key: '${walletId}_mnemonicPassphrase', value: "");
List<isar_models.Address> parsedAddresses, }
) {
List<Tuple2<isar_models.Transaction, isar_models.Address?>> transactions =
[];
for (final tx in txns) {
final type = tx.txType.toLowerCase() == "received"
? isar_models.TransactionType.incoming
: isar_models.TransactionType.outgoing;
final subType = tx.subType.toLowerCase() == "mint"
? isar_models.TransactionSubType.mint
: tx.subType.toLowerCase() == "join"
? isar_models.TransactionSubType.join
: isar_models.TransactionSubType.none;
final List<isar_models.Input> inputs = []; // doing this for epic cash will delete transaction history as it is not
final List<isar_models.Output> outputs = []; // stored on the epic cash blockchain
if (info.coin != Coin.epicCash) {
for (final inp in tx.inputs) { // set flag to initiate full rescan on opening wallet
final input = isar_models.Input( await DB.instance.put<dynamic>(
txid: inp.txid, boxName: DB.boxNameDBInfo,
vout: inp.vout, key: "rescan_on_open_$walletId",
scriptSig: inp.scriptsig, value: Constants.rescanV1,
scriptSigAsm: inp.scriptsigAsm,
isCoinbase: inp.isCoinbase,
sequence: inp.sequence,
innerRedeemScriptAsm: inp.innerRedeemscriptAsm,
); );
inputs.add(input);
} }
for (final out in tx.outputs) {
final output = isar_models.Output(
scriptPubKey: out.scriptpubkey,
scriptPubKeyAsm: out.scriptpubkeyAsm,
scriptPubKeyType: out.scriptpubkeyType,
scriptPubKeyAddress: out.scriptpubkeyAddress,
value: out.value,
);
outputs.add(output);
}
final transaction = isar_models.Transaction(
walletId: walletId,
txid: tx.txid,
timestamp: tx.timestamp,
type: type,
subType: subType,
amount: tx.amount,
fee: tx.fees,
height: tx.height,
isCancelled: tx.isCancelled,
isLelantus: false,
slateId: tx.slateId,
otherData: tx.otherData,
inputs: inputs,
outputs: outputs,
);
isar_models.Address? address;
if (tx.address.isNotEmpty) {
final addresses = parsedAddresses.where((e) => e.value == tx.address);
if (addresses.isNotEmpty) {
address = addresses.first;
} else {
address = isar_models.Address(
walletId: walletId,
value: tx.address,
publicKey: [],
derivationIndex: -1,
derivationPath: null,
type: isar_models.AddressType.unknown,
subType: type == isar_models.TransactionType.incoming
? isar_models.AddressSubType.receiving
: isar_models.AddressSubType.unknown,
);
}
}
transactions.add(Tuple2(transaction, address));
} }
return transactions;
}
List<isar_models.Address> _v4GetAddressesFromDerivationString(
String derivationsString,
isar_models.AddressType type,
isar_models.AddressSubType subType,
String walletId,
) {
final List<isar_models.Address> addresses = [];
final derivations =
Map<String, dynamic>.from(jsonDecode(derivationsString) as Map);
for (final entry in derivations.entries) {
final addr = entry.value["address"] as String? ?? entry.key;
final pubKey = entry.value["pubKey"] as String? ??
entry.value["publicKey"] as String;
final index = int.tryParse(entry.key) ?? -1;
final address = isar_models.Address(
walletId: walletId,
value: addr,
publicKey: Format.stringToUint8List(pubKey),
derivationIndex: index,
derivationPath: null, // we have no idea what the full path is
type: type,
subType: subType,
);
addresses.add(address);
}
return addresses;
}
List<isar_models.Address> _v4GetAddressesFromList(
List<String> addressStrings,
isar_models.AddressType type,
isar_models.AddressSubType subType,
String walletId,
) {
final List<isar_models.Address> addresses = [];
for (final addr in addressStrings) {
final address = isar_models.Address(
walletId: walletId,
value: addr,
publicKey: [],
derivationIndex: -1,
derivationPath: null, // index unknown
type: type,
subType: subType,
);
addresses.add(address);
}
return addresses;
}
List<String> _getList(dynamic list) {
if (list == null) return [];
return List<String>.from(list as List);
} }
} }

View file

@ -0,0 +1 @@
enum ExchangeRateType { estimated, fixed }

View file

@ -1,6 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:stackwallet/hive/db.dart'; import 'package:stackwallet/hive/db.dart';
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart';
import 'package:stackwallet/utilities/constants.dart'; import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart'; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart';
import 'package:stackwallet/utilities/enums/languages_enum.dart'; import 'package:stackwallet/utilities/enums/languages_enum.dart';
@ -18,7 +17,7 @@ class Prefs extends ChangeNotifier {
Future<void> init() async { Future<void> init() async {
if (!_initialized) { if (!_initialized) {
_currency = await _getPreferredCurrency(); _currency = await _getPreferredCurrency();
_exchangeRateType = await _getExchangeRateType(); // _exchangeRateType = await _getExchangeRateType();
_useBiometrics = await _getUseBiometrics(); _useBiometrics = await _getUseBiometrics();
_hasPin = await _getHasPin(); _hasPin = await _getHasPin();
_language = await _getPreferredLanguage(); _language = await _getPreferredLanguage();
@ -251,44 +250,44 @@ class Prefs extends ChangeNotifier {
// exchange rate type // exchange rate type
ExchangeRateType _exchangeRateType = ExchangeRateType.estimated; // ExchangeRateType _exchangeRateType = ExchangeRateType.estimated;
//
ExchangeRateType get exchangeRateType => _exchangeRateType; // ExchangeRateType get exchangeRateType => _exchangeRateType;
//
set exchangeRateType(ExchangeRateType exchangeRateType) { // set exchangeRateType(ExchangeRateType exchangeRateType) {
if (_exchangeRateType != exchangeRateType) { // if (_exchangeRateType != exchangeRateType) {
switch (exchangeRateType) { // switch (exchangeRateType) {
case ExchangeRateType.estimated: // case ExchangeRateType.estimated:
DB.instance.put<dynamic>( // DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs, // boxName: DB.boxNamePrefs,
key: "exchangeRateType", // key: "exchangeRateType",
value: "estimated"); // value: "estimated");
break; // break;
case ExchangeRateType.fixed: // case ExchangeRateType.fixed:
DB.instance.put<dynamic>( // DB.instance.put<dynamic>(
boxName: DB.boxNamePrefs, // boxName: DB.boxNamePrefs,
key: "exchangeRateType", // key: "exchangeRateType",
value: "fixed"); // value: "fixed");
break; // break;
} // }
_exchangeRateType = exchangeRateType; // _exchangeRateType = exchangeRateType;
notifyListeners(); // notifyListeners();
} // }
} // }
//
Future<ExchangeRateType> _getExchangeRateType() async { // Future<ExchangeRateType> _getExchangeRateType() async {
String? rate = await DB.instance.get<dynamic>( // String? rate = await DB.instance.get<dynamic>(
boxName: DB.boxNamePrefs, key: "exchangeRateType") as String?; // boxName: DB.boxNamePrefs, key: "exchangeRateType") as String?;
rate ??= "estimated"; // rate ??= "estimated";
switch (rate) { // switch (rate) {
case "estimated": // case "estimated":
return ExchangeRateType.estimated; // return ExchangeRateType.estimated;
case "fixed": // case "fixed":
return ExchangeRateType.fixed; // return ExchangeRateType.fixed;
default: // default:
throw Exception("Invalid exchange rate type found in prefs!"); // throw Exception("Invalid exchange rate type found in prefs!");
} // }
} // }
// use biometrics // use biometrics

View file

@ -11,11 +11,15 @@ class CustomLoadingOverlay extends ConsumerStatefulWidget {
const CustomLoadingOverlay({ const CustomLoadingOverlay({
Key? key, Key? key,
required this.message, required this.message,
this.subMessage,
required this.eventBus, required this.eventBus,
this.textColor,
}) : super(key: key); }) : super(key: key);
final String message; final String message;
final String? subMessage;
final EventBus? eventBus; final EventBus? eventBus;
final Color? textColor;
@override @override
ConsumerState<CustomLoadingOverlay> createState() => ConsumerState<CustomLoadingOverlay> createState() =>
@ -56,10 +60,12 @@ class _CustomLoadingOverlayState extends ConsumerState<CustomLoadingOverlay> {
children: [ children: [
Text( Text(
widget.message, widget.message,
textAlign: TextAlign.center,
style: STextStyles.pageTitleH2(context).copyWith( style: STextStyles.pageTitleH2(context).copyWith(
color: Theme.of(context) color: widget.textColor ??
.extension<StackColors>()! Theme.of(context)
.loadingOverlayTextColor, .extension<StackColors>()!
.loadingOverlayTextColor,
), ),
), ),
if (widget.eventBus != null) if (widget.eventBus != null)
@ -70,11 +76,28 @@ class _CustomLoadingOverlayState extends ConsumerState<CustomLoadingOverlay> {
Text( Text(
"${(_percent * 100).toStringAsFixed(2)}%", "${(_percent * 100).toStringAsFixed(2)}%",
style: STextStyles.pageTitleH2(context).copyWith( style: STextStyles.pageTitleH2(context).copyWith(
color: Theme.of(context) color: widget.textColor ??
.extension<StackColors>()! Theme.of(context)
.loadingOverlayTextColor, .extension<StackColors>()!
.loadingOverlayTextColor,
), ),
), ),
if (widget.subMessage != null)
const SizedBox(
height: 10,
),
if (widget.subMessage != null)
Text(
widget.subMessage!,
textAlign: TextAlign.center,
style: STextStyles.pageTitleH2(context).copyWith(
fontSize: 14,
color: widget.textColor ??
Theme.of(context)
.extension<StackColors>()!
.loadingOverlayTextColor,
),
)
], ],
), ),
), ),

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/models/exchange/aggregate_currency.dart';
import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart'; import 'package:stackwallet/pages/buy_view/sub_widgets/crypto_selection_view.dart';
import 'package:stackwallet/utilities/assets.dart'; import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart'; import 'package:stackwallet/utilities/text_styles.dart';
@ -23,8 +24,7 @@ class ExchangeTextField extends StatefulWidget {
this.onSubmitted, this.onSubmitted,
this.onTap, this.onTap,
required this.isWalletCoin, required this.isWalletCoin,
this.image, this.currency,
this.ticker,
this.readOnly = false, this.readOnly = false,
}) : super(key: key); }) : super(key: key);
@ -42,8 +42,7 @@ class ExchangeTextField extends StatefulWidget {
final bool isWalletCoin; final bool isWalletCoin;
final bool readOnly; final bool readOnly;
final String? image; final AggregateCurrency? currency;
final String? ticker;
@override @override
State<ExchangeTextField> createState() => _ExchangeTextFieldState(); State<ExchangeTextField> createState() => _ExchangeTextFieldState();
@ -115,7 +114,7 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
top: 12, top: 12,
left: 12, left: 12,
), ),
hintText: "0", hintText: widget.currency == null ? "select currency" : "0",
hintStyle: STextStyles.fieldLabel(context).copyWith( hintStyle: STextStyles.fieldLabel(context).copyWith(
fontSize: 14, fontSize: 14,
), ),
@ -157,18 +156,18 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
), ),
child: Builder( child: Builder(
builder: (context) { builder: (context) {
if (isStackCoin(widget.ticker)) { if (isStackCoin(widget.currency?.ticker)) {
return Center( return Center(
child: getIconForTicker( child: getIconForTicker(
widget.ticker!, widget.currency!.ticker,
size: 18, size: 18,
), ),
); );
} else if (widget.image != null && } else if (widget.currency != null &&
widget.image!.isNotEmpty) { widget.currency!.image.isNotEmpty) {
return Center( return Center(
child: SvgPicture.network( child: SvgPicture.network(
widget.image!, widget.currency!.image,
height: 18, height: 18,
placeholderBuilder: (_) => Container( placeholderBuilder: (_) => Container(
width: 18, width: 18,
@ -215,7 +214,7 @@ class _ExchangeTextFieldState extends State<ExchangeTextField> {
width: 6, width: 6,
), ),
Text( Text(
widget.ticker?.toUpperCase() ?? "-", widget.currency?.ticker.toUpperCase() ?? "n/a",
style: STextStyles.smallMed14(context).copyWith( style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!

View file

@ -11,7 +11,7 @@ description: Stack Wallet
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.5.37+122 version: 1.5.37+123
environment: environment:
sdk: ">=2.17.0 <3.0.0" sdk: ">=2.17.0 <3.0.0"

View file

@ -4,14 +4,12 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i4; import 'dart:async' as _i4;
import 'dart:ui' as _i9; import 'dart:ui' as _i8;
import 'package:decimal/decimal.dart' as _i2; import 'package:decimal/decimal.dart' as _i2;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3; import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i3;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart' import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i7;
as _i7;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i8;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i6; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i6;
import 'package:stackwallet/utilities/prefs.dart' as _i5; import 'package:stackwallet/utilities/prefs.dart' as _i5;
@ -511,20 +509,6 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i7.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i7.ExchangeRateType.estimated,
) as _i7.ExchangeRateType);
@override
set exchangeRateType(_i7.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -598,12 +582,12 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i8.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i7.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i8.BackupFrequencyType.everyTenMinutes, returnValue: _i7.BackupFrequencyType.everyTenMinutes,
) as _i8.BackupFrequencyType); ) as _i7.BackupFrequencyType);
@override @override
set backupFrequencyType(_i8.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i7.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -717,7 +701,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs {
returnValueForMissingStub: _i4.Future<void>.value(), returnValueForMissingStub: _i4.Future<void>.value(),
) as _i4.Future<void>); ) as _i4.Future<void>);
@override @override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
[listener], [listener],
@ -725,7 +709,7 @@ class MockPrefs extends _i1.Mock implements _i5.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
void removeListener(_i9.VoidCallback? listener) => super.noSuchMethod( void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#removeListener, #removeListener,
[listener], [listener],

View file

@ -4,13 +4,11 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i3; import 'dart:async' as _i3;
import 'dart:ui' as _i8; import 'dart:ui' as _i7;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/electrumx_rpc/rpc.dart' as _i2; import 'package:stackwallet/electrumx_rpc/rpc.dart' as _i2;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart' import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i6;
as _i6;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i7;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i5; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i5;
import 'package:stackwallet/utilities/prefs.dart' as _i4; import 'package:stackwallet/utilities/prefs.dart' as _i4;
@ -232,20 +230,6 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i6.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i6.ExchangeRateType.estimated,
) as _i6.ExchangeRateType);
@override
set exchangeRateType(_i6.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -319,12 +303,12 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i7.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i6.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i7.BackupFrequencyType.everyTenMinutes, returnValue: _i6.BackupFrequencyType.everyTenMinutes,
) as _i7.BackupFrequencyType); ) as _i6.BackupFrequencyType);
@override @override
set backupFrequencyType(_i7.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i6.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -438,7 +422,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs {
returnValueForMissingStub: _i3.Future<void>.value(), returnValueForMissingStub: _i3.Future<void>.value(),
) as _i3.Future<void>); ) as _i3.Future<void>);
@override @override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
[listener], [listener],
@ -446,7 +430,7 @@ class MockPrefs extends _i1.Mock implements _i4.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod( void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#removeListener, #removeListener,
[listener], [listener],

View file

@ -19,8 +19,6 @@ import 'package:stackwallet/models/balance.dart' as _i12;
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i16; import 'package:stackwallet/models/isar/models/isar_models.dart' as _i16;
import 'package:stackwallet/models/node_model.dart' as _i24; import 'package:stackwallet/models/node_model.dart' as _i24;
import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i9; import 'package:stackwallet/models/paymint/fee_object_model.dart' as _i9;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart'
as _i30;
import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i25; import 'package:stackwallet/services/coins/bitcoin/bitcoin_wallet.dart' as _i25;
import 'package:stackwallet/services/coins/coin_service.dart' as _i18; import 'package:stackwallet/services/coins/coin_service.dart' as _i18;
import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/coins/manager.dart' as _i6;
@ -30,7 +28,7 @@ import 'package:stackwallet/services/transaction_notification_tracker.dart'
as _i8; as _i8;
import 'package:stackwallet/services/wallets.dart' as _i19; import 'package:stackwallet/services/wallets.dart' as _i19;
import 'package:stackwallet/services/wallets_service.dart' as _i2; import 'package:stackwallet/services/wallets_service.dart' as _i2;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i31; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i30;
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i20; import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i20;
import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i26; import 'package:stackwallet/utilities/enums/derive_path_type_enum.dart' as _i26;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i29; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i29;
@ -2307,20 +2305,6 @@ class MockPrefs extends _i1.Mock implements _i22.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i30.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i30.ExchangeRateType.estimated,
) as _i30.ExchangeRateType);
@override
set exchangeRateType(_i30.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -2394,12 +2378,12 @@ class MockPrefs extends _i1.Mock implements _i22.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i31.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i30.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i31.BackupFrequencyType.everyTenMinutes, returnValue: _i30.BackupFrequencyType.everyTenMinutes,
) as _i31.BackupFrequencyType); ) as _i30.BackupFrequencyType);
@override @override
set backupFrequencyType(_i31.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i30.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -2693,6 +2677,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -2858,6 +2847,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i21.Future<bool>.value(false), returnValue: _i21.Future<bool>.value(false),
) as _i21.Future<bool>); ) as _i21.Future<bool>);
@override @override
_i21.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i21.Future<void>.value(),
returnValueForMissingStub: _i21.Future<void>.value(),
) as _i21.Future<void>);
@override
void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( void addListener(_i23.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -373,6 +373,11 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -538,6 +543,15 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: _i8.Future<bool>.value(false), returnValue: _i8.Future<bool>.value(false),
) as _i8.Future<bool>); ) as _i8.Future<bool>);
@override @override
_i8.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
@override
void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( void addListener(_i10.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -334,6 +334,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -499,6 +504,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -332,6 +332,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -497,6 +502,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -3,36 +3,33 @@
// Do not manually edit this file. // Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes // ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i7; import 'dart:async' as _i6;
import 'dart:ui' as _i8; import 'dart:ui' as _i7;
import 'package:decimal/decimal.dart' as _i15; import 'package:decimal/decimal.dart' as _i14;
import 'package:http/http.dart' as _i13; import 'package:http/http.dart' as _i12;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart' import 'package:stackwallet/models/exchange/change_now/cn_exchange_estimate.dart'
as _i18;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'
as _i20;
import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'
as _i21;
import 'package:stackwallet/models/exchange/response_objects/estimate.dart'
as _i17; as _i17;
import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction.dart'
as _i19; as _i19;
import 'package:stackwallet/models/exchange/response_objects/range.dart' import 'package:stackwallet/models/exchange/change_now/exchange_transaction_status.dart'
as _i20;
import 'package:stackwallet/models/exchange/response_objects/estimate.dart'
as _i16; as _i16;
import 'package:stackwallet/models/exchange/response_objects/trade.dart' import 'package:stackwallet/models/exchange/response_objects/fixed_rate_market.dart'
as _i10; as _i18;
import 'package:stackwallet/models/isar/exchange_cache/currency.dart' as _i14; import 'package:stackwallet/models/exchange/response_objects/range.dart'
import 'package:stackwallet/models/isar/exchange_cache/pair.dart' as _i22; as _i15;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart' import 'package:stackwallet/models/exchange/response_objects/trade.dart' as _i9;
as _i5; import 'package:stackwallet/models/isar/exchange_cache/currency.dart' as _i13;
import 'package:stackwallet/models/isar/exchange_cache/pair.dart' as _i21;
import 'package:stackwallet/services/exchange/change_now/change_now_api.dart' import 'package:stackwallet/services/exchange/change_now/change_now_api.dart'
as _i12; as _i11;
import 'package:stackwallet/services/exchange/exchange_response.dart' as _i2; import 'package:stackwallet/services/exchange/exchange_response.dart' as _i2;
import 'package:stackwallet/services/trade_notes_service.dart' as _i11; import 'package:stackwallet/services/trade_notes_service.dart' as _i10;
import 'package:stackwallet/services/trade_service.dart' as _i9; import 'package:stackwallet/services/trade_service.dart' as _i8;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i6; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i5;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i4; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i4;
import 'package:stackwallet/utilities/prefs.dart' as _i3; import 'package:stackwallet/utilities/prefs.dart' as _i3;
@ -182,20 +179,6 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i5.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i5.ExchangeRateType.estimated,
) as _i5.ExchangeRateType);
@override
set exchangeRateType(_i5.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -269,12 +252,12 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i6.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i5.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i6.BackupFrequencyType.everyTenMinutes, returnValue: _i5.BackupFrequencyType.everyTenMinutes,
) as _i6.BackupFrequencyType); ) as _i5.BackupFrequencyType);
@override @override
set backupFrequencyType(_i6.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i5.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -344,51 +327,51 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
_i7.Future<void> init() => (super.noSuchMethod( _i6.Future<void> init() => (super.noSuchMethod(
Invocation.method( Invocation.method(
#init, #init,
[], [],
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod( _i6.Future<void> incrementCurrentNotificationIndex() => (super.noSuchMethod(
Invocation.method( Invocation.method(
#incrementCurrentNotificationIndex, #incrementCurrentNotificationIndex,
[], [],
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<bool> isExternalCallsSet() => (super.noSuchMethod( _i6.Future<bool> isExternalCallsSet() => (super.noSuchMethod(
Invocation.method( Invocation.method(
#isExternalCallsSet, #isExternalCallsSet,
[], [],
), ),
returnValue: _i7.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i7.Future<void> saveUserID(String? userId) => (super.noSuchMethod( _i6.Future<void> saveUserID(String? userId) => (super.noSuchMethod(
Invocation.method( Invocation.method(
#saveUserID, #saveUserID,
[userId], [userId],
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod( _i6.Future<void> saveSignupEpoch(int? signupEpoch) => (super.noSuchMethod(
Invocation.method( Invocation.method(
#saveSignupEpoch, #saveSignupEpoch,
[signupEpoch], [signupEpoch],
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
[listener], [listener],
@ -396,7 +379,7 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod( void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#removeListener, #removeListener,
[listener], [listener],
@ -424,29 +407,29 @@ class MockPrefs extends _i1.Mock implements _i3.Prefs {
/// A class which mocks [TradesService]. /// A class which mocks [TradesService].
/// ///
/// See the documentation for Mockito's code generation for more information. /// See the documentation for Mockito's code generation for more information.
class MockTradesService extends _i1.Mock implements _i9.TradesService { class MockTradesService extends _i1.Mock implements _i8.TradesService {
MockTradesService() { MockTradesService() {
_i1.throwOnMissingStub(this); _i1.throwOnMissingStub(this);
} }
@override @override
List<_i10.Trade> get trades => (super.noSuchMethod( List<_i9.Trade> get trades => (super.noSuchMethod(
Invocation.getter(#trades), Invocation.getter(#trades),
returnValue: <_i10.Trade>[], returnValue: <_i9.Trade>[],
) as List<_i10.Trade>); ) as List<_i9.Trade>);
@override @override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
_i10.Trade? get(String? tradeId) => (super.noSuchMethod(Invocation.method( _i9.Trade? get(String? tradeId) => (super.noSuchMethod(Invocation.method(
#get, #get,
[tradeId], [tradeId],
)) as _i10.Trade?); )) as _i9.Trade?);
@override @override
_i7.Future<void> add({ _i6.Future<void> add({
required _i10.Trade? trade, required _i9.Trade? trade,
required bool? shouldNotifyListeners, required bool? shouldNotifyListeners,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -458,12 +441,12 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
#shouldNotifyListeners: shouldNotifyListeners, #shouldNotifyListeners: shouldNotifyListeners,
}, },
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> edit({ _i6.Future<void> edit({
required _i10.Trade? trade, required _i9.Trade? trade,
required bool? shouldNotifyListeners, required bool? shouldNotifyListeners,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -475,12 +458,12 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
#shouldNotifyListeners: shouldNotifyListeners, #shouldNotifyListeners: shouldNotifyListeners,
}, },
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> delete({ _i6.Future<void> delete({
required _i10.Trade? trade, required _i9.Trade? trade,
required bool? shouldNotifyListeners, required bool? shouldNotifyListeners,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -492,11 +475,11 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
#shouldNotifyListeners: shouldNotifyListeners, #shouldNotifyListeners: shouldNotifyListeners,
}, },
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> deleteByUuid({ _i6.Future<void> deleteByUuid({
required String? uuid, required String? uuid,
required bool? shouldNotifyListeners, required bool? shouldNotifyListeners,
}) => }) =>
@ -509,11 +492,11 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
#shouldNotifyListeners: shouldNotifyListeners, #shouldNotifyListeners: shouldNotifyListeners,
}, },
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
[listener], [listener],
@ -521,7 +504,7 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod( void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#removeListener, #removeListener,
[listener], [listener],
@ -549,7 +532,7 @@ class MockTradesService extends _i1.Mock implements _i9.TradesService {
/// A class which mocks [TradeNotesService]. /// A class which mocks [TradeNotesService].
/// ///
/// See the documentation for Mockito's code generation for more information. /// See the documentation for Mockito's code generation for more information.
class MockTradeNotesService extends _i1.Mock implements _i11.TradeNotesService { class MockTradeNotesService extends _i1.Mock implements _i10.TradeNotesService {
MockTradeNotesService() { MockTradeNotesService() {
_i1.throwOnMissingStub(this); _i1.throwOnMissingStub(this);
} }
@ -574,7 +557,7 @@ class MockTradeNotesService extends _i1.Mock implements _i11.TradeNotesService {
returnValue: '', returnValue: '',
) as String); ) as String);
@override @override
_i7.Future<void> set({ _i6.Future<void> set({
required String? tradeId, required String? tradeId,
required String? note, required String? note,
}) => }) =>
@ -587,21 +570,21 @@ class MockTradeNotesService extends _i1.Mock implements _i11.TradeNotesService {
#note: note, #note: note,
}, },
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
_i7.Future<void> delete({required String? tradeId}) => (super.noSuchMethod( _i6.Future<void> delete({required String? tradeId}) => (super.noSuchMethod(
Invocation.method( Invocation.method(
#delete, #delete,
[], [],
{#tradeId: tradeId}, {#tradeId: tradeId},
), ),
returnValue: _i7.Future<void>.value(), returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(), returnValueForMissingStub: _i6.Future<void>.value(),
) as _i7.Future<void>); ) as _i6.Future<void>);
@override @override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
[listener], [listener],
@ -609,7 +592,7 @@ class MockTradeNotesService extends _i1.Mock implements _i11.TradeNotesService {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
void removeListener(_i8.VoidCallback? listener) => super.noSuchMethod( void removeListener(_i7.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#removeListener, #removeListener,
[listener], [listener],
@ -637,13 +620,13 @@ class MockTradeNotesService extends _i1.Mock implements _i11.TradeNotesService {
/// A class which mocks [ChangeNowAPI]. /// A class which mocks [ChangeNowAPI].
/// ///
/// See the documentation for Mockito's code generation for more information. /// See the documentation for Mockito's code generation for more information.
class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI { class MockChangeNowAPI extends _i1.Mock implements _i11.ChangeNowAPI {
MockChangeNowAPI() { MockChangeNowAPI() {
_i1.throwOnMissingStub(this); _i1.throwOnMissingStub(this);
} }
@override @override
set client(_i13.Client? _client) => super.noSuchMethod( set client(_i12.Client? _client) => super.noSuchMethod(
Invocation.setter( Invocation.setter(
#client, #client,
_client, _client,
@ -651,7 +634,7 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>> getAvailableCurrencies({ _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>> getAvailableCurrencies({
bool? fixedRate, bool? fixedRate,
bool? active, bool? active,
}) => }) =>
@ -665,8 +648,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
returnValue: returnValue:
_i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>>.value( _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>.value(
_FakeExchangeResponse_0<List<_i14.Currency>>( _FakeExchangeResponse_0<List<_i13.Currency>>(
this, this,
Invocation.method( Invocation.method(
#getAvailableCurrencies, #getAvailableCurrencies,
@ -677,9 +660,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>>); ) as _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>);
@override @override
_i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>> getPairedCurrencies({ _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>> getPairedCurrencies({
required String? ticker, required String? ticker,
bool? fixedRate, bool? fixedRate,
}) => }) =>
@ -693,8 +676,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
returnValue: returnValue:
_i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>>.value( _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>.value(
_FakeExchangeResponse_0<List<_i14.Currency>>( _FakeExchangeResponse_0<List<_i13.Currency>>(
this, this,
Invocation.method( Invocation.method(
#getPairedCurrencies, #getPairedCurrencies,
@ -705,9 +688,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<List<_i14.Currency>>>); ) as _i6.Future<_i2.ExchangeResponse<List<_i13.Currency>>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i15.Decimal>> getMinimalExchangeAmount({ _i6.Future<_i2.ExchangeResponse<_i14.Decimal>> getMinimalExchangeAmount({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
String? apiKey, String? apiKey,
@ -722,8 +705,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future<_i2.ExchangeResponse<_i15.Decimal>>.value( returnValue: _i6.Future<_i2.ExchangeResponse<_i14.Decimal>>.value(
_FakeExchangeResponse_0<_i15.Decimal>( _FakeExchangeResponse_0<_i14.Decimal>(
this, this,
Invocation.method( Invocation.method(
#getMinimalExchangeAmount, #getMinimalExchangeAmount,
@ -735,9 +718,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i15.Decimal>>); ) as _i6.Future<_i2.ExchangeResponse<_i14.Decimal>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i16.Range>> getRange({ _i6.Future<_i2.ExchangeResponse<_i15.Range>> getRange({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required bool? isFixedRate, required bool? isFixedRate,
@ -754,8 +737,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future<_i2.ExchangeResponse<_i16.Range>>.value( returnValue: _i6.Future<_i2.ExchangeResponse<_i15.Range>>.value(
_FakeExchangeResponse_0<_i16.Range>( _FakeExchangeResponse_0<_i15.Range>(
this, this,
Invocation.method( Invocation.method(
#getRange, #getRange,
@ -768,12 +751,12 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i16.Range>>); ) as _i6.Future<_i2.ExchangeResponse<_i15.Range>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i17.Estimate>> getEstimatedExchangeAmount({ _i6.Future<_i2.ExchangeResponse<_i16.Estimate>> getEstimatedExchangeAmount({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required _i15.Decimal? fromAmount, required _i14.Decimal? fromAmount,
String? apiKey, String? apiKey,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -787,8 +770,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>.value( returnValue: _i6.Future<_i2.ExchangeResponse<_i16.Estimate>>.value(
_FakeExchangeResponse_0<_i17.Estimate>( _FakeExchangeResponse_0<_i16.Estimate>(
this, this,
Invocation.method( Invocation.method(
#getEstimatedExchangeAmount, #getEstimatedExchangeAmount,
@ -801,13 +784,13 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>); ) as _i6.Future<_i2.ExchangeResponse<_i16.Estimate>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i17.Estimate>> _i6.Future<_i2.ExchangeResponse<_i16.Estimate>>
getEstimatedExchangeAmountFixedRate({ getEstimatedExchangeAmountFixedRate({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required _i15.Decimal? fromAmount, required _i14.Decimal? fromAmount,
required bool? reversed, required bool? reversed,
bool? useRateId = true, bool? useRateId = true,
String? apiKey, String? apiKey,
@ -825,8 +808,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>.value( returnValue: _i6.Future<_i2.ExchangeResponse<_i16.Estimate>>.value(
_FakeExchangeResponse_0<_i17.Estimate>( _FakeExchangeResponse_0<_i16.Estimate>(
this, this,
Invocation.method( Invocation.method(
#getEstimatedExchangeAmountFixedRate, #getEstimatedExchangeAmountFixedRate,
@ -841,17 +824,17 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i17.Estimate>>); ) as _i6.Future<_i2.ExchangeResponse<_i16.Estimate>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i18.CNExchangeEstimate>> _i6.Future<_i2.ExchangeResponse<_i17.CNExchangeEstimate>>
getEstimatedExchangeAmountV2({ getEstimatedExchangeAmountV2({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required _i18.CNEstimateType? fromOrTo, required _i17.CNEstimateType? fromOrTo,
required _i15.Decimal? amount, required _i14.Decimal? amount,
String? fromNetwork, String? fromNetwork,
String? toNetwork, String? toNetwork,
_i18.CNFlowType? flow = _i18.CNFlowType.standard, _i17.CNFlowType? flow = _i17.CNFlowType.standard,
String? apiKey, String? apiKey,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -870,8 +853,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
returnValue: returnValue:
_i7.Future<_i2.ExchangeResponse<_i18.CNExchangeEstimate>>.value( _i6.Future<_i2.ExchangeResponse<_i17.CNExchangeEstimate>>.value(
_FakeExchangeResponse_0<_i18.CNExchangeEstimate>( _FakeExchangeResponse_0<_i17.CNExchangeEstimate>(
this, this,
Invocation.method( Invocation.method(
#getEstimatedExchangeAmountV2, #getEstimatedExchangeAmountV2,
@ -888,18 +871,18 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i18.CNExchangeEstimate>>); ) as _i6.Future<_i2.ExchangeResponse<_i17.CNExchangeEstimate>>);
@override @override
_i7.Future<_i2.ExchangeResponse<List<_i19.FixedRateMarket>>> _i6.Future<_i2.ExchangeResponse<List<_i18.FixedRateMarket>>>
getAvailableFixedRateMarkets({String? apiKey}) => (super.noSuchMethod( getAvailableFixedRateMarkets({String? apiKey}) => (super.noSuchMethod(
Invocation.method( Invocation.method(
#getAvailableFixedRateMarkets, #getAvailableFixedRateMarkets,
[], [],
{#apiKey: apiKey}, {#apiKey: apiKey},
), ),
returnValue: _i7.Future< returnValue: _i6.Future<
_i2.ExchangeResponse<List<_i19.FixedRateMarket>>>.value( _i2.ExchangeResponse<List<_i18.FixedRateMarket>>>.value(
_FakeExchangeResponse_0<List<_i19.FixedRateMarket>>( _FakeExchangeResponse_0<List<_i18.FixedRateMarket>>(
this, this,
Invocation.method( Invocation.method(
#getAvailableFixedRateMarkets, #getAvailableFixedRateMarkets,
@ -907,14 +890,14 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
{#apiKey: apiKey}, {#apiKey: apiKey},
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<List<_i19.FixedRateMarket>>>); ) as _i6.Future<_i2.ExchangeResponse<List<_i18.FixedRateMarket>>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i20.ExchangeTransaction>> _i6.Future<_i2.ExchangeResponse<_i19.ExchangeTransaction>>
createStandardExchangeTransaction({ createStandardExchangeTransaction({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required String? receivingAddress, required String? receivingAddress,
required _i15.Decimal? amount, required _i14.Decimal? amount,
String? extraId = r'', String? extraId = r'',
String? userId = r'', String? userId = r'',
String? contactEmail = r'', String? contactEmail = r'',
@ -939,9 +922,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future< returnValue: _i6.Future<
_i2.ExchangeResponse<_i20.ExchangeTransaction>>.value( _i2.ExchangeResponse<_i19.ExchangeTransaction>>.value(
_FakeExchangeResponse_0<_i20.ExchangeTransaction>( _FakeExchangeResponse_0<_i19.ExchangeTransaction>(
this, this,
Invocation.method( Invocation.method(
#createStandardExchangeTransaction, #createStandardExchangeTransaction,
@ -960,14 +943,14 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i20.ExchangeTransaction>>); ) as _i6.Future<_i2.ExchangeResponse<_i19.ExchangeTransaction>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i20.ExchangeTransaction>> _i6.Future<_i2.ExchangeResponse<_i19.ExchangeTransaction>>
createFixedRateExchangeTransaction({ createFixedRateExchangeTransaction({
required String? fromTicker, required String? fromTicker,
required String? toTicker, required String? toTicker,
required String? receivingAddress, required String? receivingAddress,
required _i15.Decimal? amount, required _i14.Decimal? amount,
required String? rateId, required String? rateId,
required bool? reversed, required bool? reversed,
String? extraId = r'', String? extraId = r'',
@ -996,9 +979,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future< returnValue: _i6.Future<
_i2.ExchangeResponse<_i20.ExchangeTransaction>>.value( _i2.ExchangeResponse<_i19.ExchangeTransaction>>.value(
_FakeExchangeResponse_0<_i20.ExchangeTransaction>( _FakeExchangeResponse_0<_i19.ExchangeTransaction>(
this, this,
Invocation.method( Invocation.method(
#createFixedRateExchangeTransaction, #createFixedRateExchangeTransaction,
@ -1019,9 +1002,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<_i20.ExchangeTransaction>>); ) as _i6.Future<_i2.ExchangeResponse<_i19.ExchangeTransaction>>);
@override @override
_i7.Future<_i2.ExchangeResponse<_i21.ExchangeTransactionStatus>> _i6.Future<_i2.ExchangeResponse<_i20.ExchangeTransactionStatus>>
getTransactionStatus({ getTransactionStatus({
required String? id, required String? id,
String? apiKey, String? apiKey,
@ -1035,9 +1018,9 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
#apiKey: apiKey, #apiKey: apiKey,
}, },
), ),
returnValue: _i7.Future< returnValue: _i6.Future<
_i2.ExchangeResponse<_i21.ExchangeTransactionStatus>>.value( _i2.ExchangeResponse<_i20.ExchangeTransactionStatus>>.value(
_FakeExchangeResponse_0<_i21.ExchangeTransactionStatus>( _FakeExchangeResponse_0<_i20.ExchangeTransactionStatus>(
this, this,
Invocation.method( Invocation.method(
#getTransactionStatus, #getTransactionStatus,
@ -1048,10 +1031,10 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
}, },
), ),
)), )),
) as _i7 ) as _i6
.Future<_i2.ExchangeResponse<_i21.ExchangeTransactionStatus>>); .Future<_i2.ExchangeResponse<_i20.ExchangeTransactionStatus>>);
@override @override
_i7.Future<_i2.ExchangeResponse<List<_i22.Pair>>> _i6.Future<_i2.ExchangeResponse<List<_i21.Pair>>>
getAvailableFloatingRatePairs({bool? includePartners = false}) => getAvailableFloatingRatePairs({bool? includePartners = false}) =>
(super.noSuchMethod( (super.noSuchMethod(
Invocation.method( Invocation.method(
@ -1060,8 +1043,8 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
{#includePartners: includePartners}, {#includePartners: includePartners},
), ),
returnValue: returnValue:
_i7.Future<_i2.ExchangeResponse<List<_i22.Pair>>>.value( _i6.Future<_i2.ExchangeResponse<List<_i21.Pair>>>.value(
_FakeExchangeResponse_0<List<_i22.Pair>>( _FakeExchangeResponse_0<List<_i21.Pair>>(
this, this,
Invocation.method( Invocation.method(
#getAvailableFloatingRatePairs, #getAvailableFloatingRatePairs,
@ -1069,5 +1052,5 @@ class MockChangeNowAPI extends _i1.Mock implements _i12.ChangeNowAPI {
{#includePartners: includePartners}, {#includePartners: includePartners},
), ),
)), )),
) as _i7.Future<_i2.ExchangeResponse<List<_i22.Pair>>>); ) as _i6.Future<_i2.ExchangeResponse<List<_i21.Pair>>>);
} }

View file

@ -641,6 +641,11 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -806,6 +811,15 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -428,6 +428,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -593,6 +598,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -428,6 +428,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -593,6 +598,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -428,6 +428,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -593,6 +598,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -426,6 +426,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -591,6 +596,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -641,6 +641,11 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -806,6 +811,15 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -482,6 +482,11 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -647,6 +652,15 @@ class MockManager extends _i1.Mock implements _i12.Manager {
returnValue: _i8.Future<bool>.value(false), returnValue: _i8.Future<bool>.value(false),
) as _i8.Future<bool>); ) as _i8.Future<bool>);
@override @override
_i8.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
@override
void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( void addListener(_i11.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -583,6 +588,15 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: _i8.Future<bool>.value(false), returnValue: _i8.Future<bool>.value(false),
) as _i8.Future<bool>); ) as _i8.Future<bool>);
@override @override
_i8.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
@override
void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( void addListener(_i10.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -418,6 +418,11 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -583,6 +588,15 @@ class MockManager extends _i1.Mock implements _i11.Manager {
returnValue: _i8.Future<bool>.value(false), returnValue: _i8.Future<bool>.value(false),
) as _i8.Future<bool>); ) as _i8.Future<bool>);
@override @override
_i8.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
@override
void addListener(_i10.VoidCallback? listener) => super.noSuchMethod( void addListener(_i10.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -426,6 +426,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -591,6 +596,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -683,6 +683,11 @@ class MockManager extends _i1.Mock implements _i15.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -848,6 +853,15 @@ class MockManager extends _i1.Mock implements _i15.Manager {
returnValue: _i8.Future<bool>.value(false), returnValue: _i8.Future<bool>.value(false),
) as _i8.Future<bool>); ) as _i8.Future<bool>);
@override @override
_i8.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i8.Future<void>.value(),
returnValueForMissingStub: _i8.Future<void>.value(),
) as _i8.Future<void>);
@override
void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( void addListener(_i14.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -426,6 +426,11 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -591,6 +596,15 @@ class MockManager extends _i1.Mock implements _i9.Manager {
returnValue: _i6.Future<bool>.value(false), returnValue: _i6.Future<bool>.value(false),
) as _i6.Future<bool>); ) as _i6.Future<bool>);
@override @override
_i6.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i6.Future<void>.value(),
returnValueForMissingStub: _i6.Future<void>.value(),
) as _i6.Future<void>);
@override
void addListener(_i8.VoidCallback? listener) => super.noSuchMethod( void addListener(_i8.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -205,6 +205,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -370,6 +375,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -204,6 +204,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -369,6 +374,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -203,6 +203,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -368,6 +373,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -245,6 +245,11 @@ class MockManager extends _i1.Mock implements _i8.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -410,6 +415,15 @@ class MockManager extends _i1.Mock implements _i8.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i11.VoidCallback? listener) => super.noSuchMethod( void addListener(_i11.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -205,6 +205,11 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -370,6 +375,15 @@ class MockManager extends _i1.Mock implements _i5.Manager {
returnValue: _i7.Future<bool>.value(false), returnValue: _i7.Future<bool>.value(false),
) as _i7.Future<bool>); ) as _i7.Future<bool>);
@override @override
_i7.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i7.Future<void>.value(),
returnValueForMissingStub: _i7.Future<void>.value(),
) as _i7.Future<void>);
@override
void addListener(_i9.VoidCallback? listener) => super.noSuchMethod( void addListener(_i9.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -2320,6 +2320,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -2485,6 +2490,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i21.Future<bool>.value(false), returnValue: _i21.Future<bool>.value(false),
) as _i21.Future<bool>); ) as _i21.Future<bool>);
@override @override
_i21.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i21.Future<void>.value(),
returnValueForMissingStub: _i21.Future<void>.value(),
) as _i21.Future<void>);
@override
void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( void addListener(_i23.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -9,14 +9,12 @@ import 'dart:ui' as _i12;
import 'package:flutter/foundation.dart' as _i4; import 'package:flutter/foundation.dart' as _i4;
import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5; import 'package:flutter_riverpod/flutter_riverpod.dart' as _i5;
import 'package:mockito/mockito.dart' as _i1; import 'package:mockito/mockito.dart' as _i1;
import 'package:stackwallet/models/node_model.dart' as _i16; import 'package:stackwallet/models/node_model.dart' as _i15;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart'
as _i14;
import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/coins/manager.dart' as _i6;
import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/node_service.dart' as _i3;
import 'package:stackwallet/services/wallets.dart' as _i8; import 'package:stackwallet/services/wallets.dart' as _i8;
import 'package:stackwallet/services/wallets_service.dart' as _i2; import 'package:stackwallet/services/wallets_service.dart' as _i2;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i15; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i14;
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i9; import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i9;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i13; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i13;
import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart' import 'package:stackwallet/utilities/flutter_secure_storage_interface.dart'
@ -416,20 +414,6 @@ class MockPrefs extends _i1.Mock implements _i11.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i14.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i14.ExchangeRateType.estimated,
) as _i14.ExchangeRateType);
@override
set exchangeRateType(_i14.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -503,12 +487,12 @@ class MockPrefs extends _i1.Mock implements _i11.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i15.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i14.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i15.BackupFrequencyType.everyTenMinutes, returnValue: _i14.BackupFrequencyType.everyTenMinutes,
) as _i15.BackupFrequencyType); ) as _i14.BackupFrequencyType);
@override @override
set backupFrequencyType(_i15.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i14.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -672,15 +656,15 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
), ),
) as _i7.SecureStorageInterface); ) as _i7.SecureStorageInterface);
@override @override
List<_i16.NodeModel> get primaryNodes => (super.noSuchMethod( List<_i15.NodeModel> get primaryNodes => (super.noSuchMethod(
Invocation.getter(#primaryNodes), Invocation.getter(#primaryNodes),
returnValue: <_i16.NodeModel>[], returnValue: <_i15.NodeModel>[],
) as List<_i16.NodeModel>); ) as List<_i15.NodeModel>);
@override @override
List<_i16.NodeModel> get nodes => (super.noSuchMethod( List<_i15.NodeModel> get nodes => (super.noSuchMethod(
Invocation.getter(#nodes), Invocation.getter(#nodes),
returnValue: <_i16.NodeModel>[], returnValue: <_i15.NodeModel>[],
) as List<_i16.NodeModel>); ) as List<_i15.NodeModel>);
@override @override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
@ -698,7 +682,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
@override @override
_i10.Future<void> setPrimaryNodeFor({ _i10.Future<void> setPrimaryNodeFor({
required _i9.Coin? coin, required _i9.Coin? coin,
required _i16.NodeModel? node, required _i15.NodeModel? node,
bool? shouldNotifyListeners = false, bool? shouldNotifyListeners = false,
}) => }) =>
(super.noSuchMethod( (super.noSuchMethod(
@ -715,40 +699,40 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
returnValueForMissingStub: _i10.Future<void>.value(), returnValueForMissingStub: _i10.Future<void>.value(),
) as _i10.Future<void>); ) as _i10.Future<void>);
@override @override
_i16.NodeModel? getPrimaryNodeFor({required _i9.Coin? coin}) => _i15.NodeModel? getPrimaryNodeFor({required _i9.Coin? coin}) =>
(super.noSuchMethod(Invocation.method( (super.noSuchMethod(Invocation.method(
#getPrimaryNodeFor, #getPrimaryNodeFor,
[], [],
{#coin: coin}, {#coin: coin},
)) as _i16.NodeModel?); )) as _i15.NodeModel?);
@override @override
List<_i16.NodeModel> getNodesFor(_i9.Coin? coin) => (super.noSuchMethod( List<_i15.NodeModel> getNodesFor(_i9.Coin? coin) => (super.noSuchMethod(
Invocation.method( Invocation.method(
#getNodesFor, #getNodesFor,
[coin], [coin],
), ),
returnValue: <_i16.NodeModel>[], returnValue: <_i15.NodeModel>[],
) as List<_i16.NodeModel>); ) as List<_i15.NodeModel>);
@override @override
_i16.NodeModel? getNodeById({required String? id}) => _i15.NodeModel? getNodeById({required String? id}) =>
(super.noSuchMethod(Invocation.method( (super.noSuchMethod(Invocation.method(
#getNodeById, #getNodeById,
[], [],
{#id: id}, {#id: id},
)) as _i16.NodeModel?); )) as _i15.NodeModel?);
@override @override
List<_i16.NodeModel> failoverNodesFor({required _i9.Coin? coin}) => List<_i15.NodeModel> failoverNodesFor({required _i9.Coin? coin}) =>
(super.noSuchMethod( (super.noSuchMethod(
Invocation.method( Invocation.method(
#failoverNodesFor, #failoverNodesFor,
[], [],
{#coin: coin}, {#coin: coin},
), ),
returnValue: <_i16.NodeModel>[], returnValue: <_i15.NodeModel>[],
) as List<_i16.NodeModel>); ) as List<_i15.NodeModel>);
@override @override
_i10.Future<void> add( _i10.Future<void> add(
_i16.NodeModel? node, _i15.NodeModel? node,
String? password, String? password,
bool? shouldNotifyListeners, bool? shouldNotifyListeners,
) => ) =>
@ -800,7 +784,7 @@ class MockNodeService extends _i1.Mock implements _i3.NodeService {
) as _i10.Future<void>); ) as _i10.Future<void>);
@override @override
_i10.Future<void> edit( _i10.Future<void> edit(
_i16.NodeModel? editedNode, _i15.NodeModel? editedNode,
String? password, String? password,
bool? shouldNotifyListeners, bool? shouldNotifyListeners,
) => ) =>

View file

@ -2045,6 +2045,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -2210,6 +2215,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i20.Future<bool>.value(false), returnValue: _i20.Future<bool>.value(false),
) as _i20.Future<bool>); ) as _i20.Future<bool>);
@override @override
_i20.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i20.Future<void>.value(),
returnValueForMissingStub: _i20.Future<void>.value(),
) as _i20.Future<void>);
@override
void addListener(_i22.VoidCallback? listener) => super.noSuchMethod( void addListener(_i22.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -16,20 +16,18 @@ import 'package:stackwallet/electrumx_rpc/electrumx.dart' as _i11;
import 'package:stackwallet/models/balance.dart' as _i9; import 'package:stackwallet/models/balance.dart' as _i9;
import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21; import 'package:stackwallet/models/isar/models/isar_models.dart' as _i21;
import 'package:stackwallet/models/models.dart' as _i8; import 'package:stackwallet/models/models.dart' as _i8;
import 'package:stackwallet/pages/exchange_view/sub_widgets/exchange_rate_sheet.dart'
as _i25;
import 'package:stackwallet/services/coins/coin_service.dart' as _i7; import 'package:stackwallet/services/coins/coin_service.dart' as _i7;
import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i22; import 'package:stackwallet/services/coins/firo/firo_wallet.dart' as _i22;
import 'package:stackwallet/services/coins/manager.dart' as _i6; import 'package:stackwallet/services/coins/manager.dart' as _i6;
import 'package:stackwallet/services/locale_service.dart' as _i23; import 'package:stackwallet/services/locale_service.dart' as _i23;
import 'package:stackwallet/services/node_service.dart' as _i3; import 'package:stackwallet/services/node_service.dart' as _i3;
import 'package:stackwallet/services/notes_service.dart' as _i28; import 'package:stackwallet/services/notes_service.dart' as _i27;
import 'package:stackwallet/services/price_service.dart' as _i27; import 'package:stackwallet/services/price_service.dart' as _i26;
import 'package:stackwallet/services/transaction_notification_tracker.dart' import 'package:stackwallet/services/transaction_notification_tracker.dart'
as _i10; as _i10;
import 'package:stackwallet/services/wallets.dart' as _i16; import 'package:stackwallet/services/wallets.dart' as _i16;
import 'package:stackwallet/services/wallets_service.dart' as _i2; import 'package:stackwallet/services/wallets_service.dart' as _i2;
import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i26; import 'package:stackwallet/utilities/enums/backup_frequency_type.dart' as _i25;
import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17; import 'package:stackwallet/utilities/enums/coin_enum.dart' as _i17;
import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i24; import 'package:stackwallet/utilities/enums/sync_type_enum.dart' as _i24;
import 'package:stackwallet/utilities/prefs.dart' as _i19; import 'package:stackwallet/utilities/prefs.dart' as _i19;
@ -548,6 +546,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -713,6 +716,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i18.Future<bool>.value(false), returnValue: _i18.Future<bool>.value(false),
) as _i18.Future<bool>); ) as _i18.Future<bool>);
@override @override
_i18.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i18.Future<void>.value(),
returnValueForMissingStub: _i18.Future<void>.value(),
) as _i18.Future<void>);
@override
void addListener(_i20.VoidCallback? listener) => super.noSuchMethod( void addListener(_i20.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,
@ -2164,20 +2176,6 @@ class MockPrefs extends _i1.Mock implements _i19.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i25.ExchangeRateType get exchangeRateType => (super.noSuchMethod(
Invocation.getter(#exchangeRateType),
returnValue: _i25.ExchangeRateType.estimated,
) as _i25.ExchangeRateType);
@override
set exchangeRateType(_i25.ExchangeRateType? exchangeRateType) =>
super.noSuchMethod(
Invocation.setter(
#exchangeRateType,
exchangeRateType,
),
returnValueForMissingStub: null,
);
@override
bool get useBiometrics => (super.noSuchMethod( bool get useBiometrics => (super.noSuchMethod(
Invocation.getter(#useBiometrics), Invocation.getter(#useBiometrics),
returnValue: false, returnValue: false,
@ -2251,12 +2249,12 @@ class MockPrefs extends _i1.Mock implements _i19.Prefs {
returnValueForMissingStub: null, returnValueForMissingStub: null,
); );
@override @override
_i26.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod( _i25.BackupFrequencyType get backupFrequencyType => (super.noSuchMethod(
Invocation.getter(#backupFrequencyType), Invocation.getter(#backupFrequencyType),
returnValue: _i26.BackupFrequencyType.everyTenMinutes, returnValue: _i25.BackupFrequencyType.everyTenMinutes,
) as _i26.BackupFrequencyType); ) as _i25.BackupFrequencyType);
@override @override
set backupFrequencyType(_i26.BackupFrequencyType? backupFrequencyType) => set backupFrequencyType(_i25.BackupFrequencyType? backupFrequencyType) =>
super.noSuchMethod( super.noSuchMethod(
Invocation.setter( Invocation.setter(
#backupFrequencyType, #backupFrequencyType,
@ -2406,7 +2404,7 @@ class MockPrefs extends _i1.Mock implements _i19.Prefs {
/// A class which mocks [PriceService]. /// A class which mocks [PriceService].
/// ///
/// See the documentation for Mockito's code generation for more information. /// See the documentation for Mockito's code generation for more information.
class MockPriceService extends _i1.Mock implements _i27.PriceService { class MockPriceService extends _i1.Mock implements _i26.PriceService {
MockPriceService() { MockPriceService() {
_i1.throwOnMissingStub(this); _i1.throwOnMissingStub(this);
} }
@ -2514,7 +2512,7 @@ class MockPriceService extends _i1.Mock implements _i27.PriceService {
/// A class which mocks [NotesService]. /// A class which mocks [NotesService].
/// ///
/// See the documentation for Mockito's code generation for more information. /// See the documentation for Mockito's code generation for more information.
class MockNotesService extends _i1.Mock implements _i28.NotesService { class MockNotesService extends _i1.Mock implements _i27.NotesService {
MockNotesService() { MockNotesService() {
_i1.throwOnMissingStub(this); _i1.throwOnMissingStub(this);
} }

View file

@ -2257,6 +2257,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -2422,6 +2427,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i21.Future<bool>.value(false), returnValue: _i21.Future<bool>.value(false),
) as _i21.Future<bool>); ) as _i21.Future<bool>);
@override @override
_i21.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i21.Future<void>.value(),
returnValueForMissingStub: _i21.Future<void>.value(),
) as _i21.Future<void>);
@override
void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( void addListener(_i23.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,

View file

@ -2257,6 +2257,11 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: false, returnValue: false,
) as bool); ) as bool);
@override @override
int get rescanOnOpenVersion => (super.noSuchMethod(
Invocation.getter(#rescanOnOpenVersion),
returnValue: 0,
) as int);
@override
bool get hasListeners => (super.noSuchMethod( bool get hasListeners => (super.noSuchMethod(
Invocation.getter(#hasListeners), Invocation.getter(#hasListeners),
returnValue: false, returnValue: false,
@ -2422,6 +2427,15 @@ class MockManager extends _i1.Mock implements _i6.Manager {
returnValue: _i21.Future<bool>.value(false), returnValue: _i21.Future<bool>.value(false),
) as _i21.Future<bool>); ) as _i21.Future<bool>);
@override @override
_i21.Future<void> resetRescanOnOpen() => (super.noSuchMethod(
Invocation.method(
#resetRescanOnOpen,
[],
),
returnValue: _i21.Future<void>.value(),
returnValueForMissingStub: _i21.Future<void>.value(),
) as _i21.Future<void>);
@override
void addListener(_i23.VoidCallback? listener) => super.noSuchMethod( void addListener(_i23.VoidCallback? listener) => super.noSuchMethod(
Invocation.method( Invocation.method(
#addListener, #addListener,