handle getting currency via ticker or name a bit more nicely

This commit is contained in:
julian 2024-05-23 11:05:30 -06:00
parent 92802fc559
commit 3ee22cbbac
12 changed files with 148 additions and 94 deletions

View file

@ -13,21 +13,28 @@ abstract class AppConfig {
static List<CryptoCurrency> get coins => _supportedCoins; static List<CryptoCurrency> get coins => _supportedCoins;
static CryptoCurrency getCryptoCurrencyFor(String coinIdentifier) => static CryptoCurrency? getCryptoCurrencyFor(String coinIdentifier) {
coins.firstWhere( try {
(e) => e.identifier == coinIdentifier, return coins.firstWhere((e) => e.identifier == coinIdentifier);
); } catch (_) {
return null;
}
}
static CryptoCurrency getCryptoCurrencyForTicker( static CryptoCurrency? getCryptoCurrencyForTicker(
final String ticker, { final String ticker, {
bool caseInsensitive = true, bool caseInsensitive = true,
}) { }) {
final _ticker = caseInsensitive ? ticker.toLowerCase() : ticker; final _ticker = caseInsensitive ? ticker.toLowerCase() : ticker;
return coins.firstWhere( try {
caseInsensitive return coins.firstWhere(
? (e) => e.ticker.toLowerCase() == _ticker && e is! FrostCurrency caseInsensitive
: (e) => e.ticker == _ticker && e is! FrostCurrency, ? (e) => e.ticker.toLowerCase() == _ticker && e is! FrostCurrency
); : (e) => e.ticker == _ticker && e is! FrostCurrency,
);
} catch (_) {
return null;
}
} }
/// Fuzzy logic. Use with caution!! /// Fuzzy logic. Use with caution!!

View file

@ -557,7 +557,7 @@ class DbVersionMigrator with WalletDB {
final count = await MainDB.instance.getTransactions(walletId).count(); final count = await MainDB.instance.getTransactions(walletId).count();
final crypto = AppConfig.getCryptoCurrencyFor(info.coinIdentifier); final crypto = AppConfig.getCryptoCurrencyFor(info.coinIdentifier)!;
for (var i = 0; i < count; i += 50) { for (var i = 0; i < count; i += 50) {
final txns = await MainDB.instance final txns = await MainDB.instance

View file

@ -2,9 +2,8 @@ import 'dart:convert';
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import '../app_config.dart'; import '../app_config.dart';
import 'hive/db.dart';
import 'isar/main_db.dart';
import '../models/isar/models/blockchain_data/v2/transaction_v2.dart'; import '../models/isar/models/blockchain_data/v2/transaction_v2.dart';
import '../models/isar/models/isar_models.dart'; import '../models/isar/models/isar_models.dart';
import '../utilities/flutter_secure_storage_interface.dart'; import '../utilities/flutter_secure_storage_interface.dart';
@ -13,6 +12,8 @@ import '../wallets/isar/models/token_wallet_info.dart';
import '../wallets/isar/models/wallet_info.dart'; import '../wallets/isar/models/wallet_info.dart';
import '../wallets/isar/models/wallet_info_meta.dart'; import '../wallets/isar/models/wallet_info_meta.dart';
import '../wallets/wallet/supporting/epiccash_wallet_info_extension.dart'; import '../wallets/wallet/supporting/epiccash_wallet_info_extension.dart';
import 'hive/db.dart';
import 'isar/main_db.dart';
Future<void> migrateWalletsToIsar({ Future<void> migrateWalletsToIsar({
required SecureStorageInterface secureStore, required SecureStorageInterface secureStore,
@ -167,8 +168,8 @@ Future<void> migrateWalletsToIsar({
coinName: old.coinIdentifier, coinName: old.coinIdentifier,
walletId: old.walletId, walletId: old.walletId,
name: old.name, name: old.name,
mainAddressType: mainAddressType: AppConfig.getCryptoCurrencyFor(old.coinIdentifier)!
AppConfig.getCryptoCurrencyFor(old.coinIdentifier).primaryAddressType, .primaryAddressType,
favouriteOrderIndex: favourites.indexOf(old.walletId), favouriteOrderIndex: favourites.indexOf(old.walletId),
cachedChainHeight: walletBox.get( cachedChainHeight: walletBox.get(
DBKeys.storedChainHeight, DBKeys.storedChainHeight,

View file

@ -43,7 +43,7 @@ class ContactAddressEntry {
factory ContactAddressEntry.fromJson(Map<String, dynamic> jsonObject) { factory ContactAddressEntry.fromJson(Map<String, dynamic> jsonObject) {
return ContactAddressEntry( return ContactAddressEntry(
coin: AppConfig.getCryptoCurrencyFor(jsonObject["coin"] as String), coin: AppConfig.getCryptoCurrencyFor(jsonObject["coin"] as String)!,
address: jsonObject["address"] as String, address: jsonObject["address"] as String,
label: jsonObject["label"] as String, label: jsonObject["label"] as String,
other: jsonObject["other"] as String?, other: jsonObject["other"] as String?,

View file

@ -9,6 +9,7 @@
*/ */
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import '../../../app_config.dart'; import '../../../app_config.dart';
import '../../../wallets/crypto_currency/crypto_currency.dart'; import '../../../wallets/crypto_currency/crypto_currency.dart';
@ -102,7 +103,7 @@ class ContactAddressEntry {
late final String? other; late final String? other;
@ignore @ignore
CryptoCurrency get coin => AppConfig.getCryptoCurrencyFor(coinName); CryptoCurrency get coin => AppConfig.getCryptoCurrencyFor(coinName)!;
ContactAddressEntry(); ContactAddressEntry();

View file

@ -13,6 +13,7 @@ import 'dart:io';
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:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import '../../../app_config.dart'; import '../../../app_config.dart';
import '../../../models/buy/response_objects/crypto.dart'; import '../../../models/buy/response_objects/crypto.dart';
import '../../../themes/coin_icon_provider.dart'; import '../../../themes/coin_icon_provider.dart';
@ -305,7 +306,7 @@ class CoinIconForTicker extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
try { try {
final coin = AppConfig.getCryptoCurrencyForTicker(ticker); final coin = AppConfig.getCryptoCurrencyForTicker(ticker)!;
return SvgPicture.file( return SvgPicture.file(
File( File(
ref.watch(coinIconProvider(coin)), ref.watch(coinIconProvider(coin)),

View file

@ -12,6 +12,7 @@ import 'package:decimal/decimal.dart';
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:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import '../../../app_config.dart'; import '../../../app_config.dart';
import '../../../models/exchange/response_objects/estimate.dart'; import '../../../models/exchange/response_objects/estimate.dart';
import '../../../providers/exchange/exchange_form_state_provider.dart'; import '../../../providers/exchange/exchange_form_state_provider.dart';
@ -95,7 +96,8 @@ class _ExchangeOptionState extends ConsumerState<ExchangeOption> {
try { try {
decimals = AppConfig.getCryptoCurrencyForTicker( decimals = AppConfig.getCryptoCurrencyForTicker(
receivingCurrency.ticker, receivingCurrency.ticker,
).fractionDigits; )!
.fractionDigits;
} catch (_) { } catch (_) {
decimals = 8; // some reasonable alternative decimals = 8; // some reasonable alternative
} }

View file

@ -17,15 +17,14 @@ import 'package:flutter/services.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:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:tuple/tuple.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../app_config.dart'; import '../../app_config.dart';
import '../../models/exchange/change_now/exchange_transaction_status.dart'; import '../../models/exchange/change_now/exchange_transaction_status.dart';
import '../../models/isar/models/blockchain_data/transaction.dart'; import '../../models/isar/models/blockchain_data/transaction.dart';
import '../../models/isar/stack_theme.dart'; import '../../models/isar/stack_theme.dart';
import '../../notifications/show_flush_bar.dart'; import '../../notifications/show_flush_bar.dart';
import 'edit_trade_note_view.dart';
import 'send_from_view.dart';
import '../wallet_view/transaction_views/edit_note_view.dart';
import '../wallet_view/transaction_views/transaction_details_view.dart';
import '../../providers/global/trades_service_provider.dart'; import '../../providers/global/trades_service_provider.dart';
import '../../providers/providers.dart'; import '../../providers/providers.dart';
import '../../route_generator.dart'; import '../../route_generator.dart';
@ -54,8 +53,10 @@ import '../../widgets/desktop/secondary_button.dart';
import '../../widgets/rounded_container.dart'; import '../../widgets/rounded_container.dart';
import '../../widgets/rounded_white_container.dart'; import '../../widgets/rounded_white_container.dart';
import '../../widgets/stack_dialog.dart'; import '../../widgets/stack_dialog.dart';
import 'package:tuple/tuple.dart'; import '../wallet_view/transaction_views/edit_note_view.dart';
import 'package:url_launcher/url_launcher.dart'; import '../wallet_view/transaction_views/transaction_details_view.dart';
import 'edit_trade_note_view.dart';
import 'send_from_view.dart';
class TradeDetailsView extends ConsumerStatefulWidget { class TradeDetailsView extends ConsumerStatefulWidget {
const TradeDetailsView({ const TradeDetailsView({
@ -281,7 +282,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
try { try {
coin = AppConfig.getCryptoCurrencyForTicker( coin = AppConfig.getCryptoCurrencyForTicker(
trade.payInCurrency, trade.payInCurrency,
); )!;
} catch (_) { } catch (_) {
coin = AppConfig.getCryptoCurrencyByPrettyName( coin = AppConfig.getCryptoCurrencyByPrettyName(
trade.payInCurrency, trade.payInCurrency,
@ -382,7 +383,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
final coin = final coin =
AppConfig.getCryptoCurrencyForTicker( AppConfig.getCryptoCurrencyForTicker(
trade.payInCurrency, trade.payInCurrency,
); )!;
final amount = sendAmount.toAmount( final amount = sendAmount.toAmount(
fractionDigits: coin.fractionDigits, fractionDigits: coin.fractionDigits,
); );
@ -628,10 +629,9 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
CustomTextButton( CustomTextButton(
text: "View transaction", text: "View transaction",
onTap: () { onTap: () {
final CryptoCurrency coin = final coin = AppConfig.getCryptoCurrencyForTicker(
AppConfig.getCryptoCurrencyForTicker(
trade.payInCurrency, trade.payInCurrency,
); )!;
if (isDesktop) { if (isDesktop) {
Navigator.of(context).push( Navigator.of(context).push(
@ -737,7 +737,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
text: address, text: address,
), ),
); );
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -908,7 +908,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
text: address, text: address,
), ),
); );
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -1276,7 +1276,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
onTap: () async { onTap: () async {
final data = ClipboardData(text: trade.tradeId); final data = ClipboardData(text: trade.tradeId);
await clipboard.setData(data); await clipboard.setData(data);
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -1384,7 +1384,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
try { try {
coin = AppConfig.getCryptoCurrencyForTicker( coin = AppConfig.getCryptoCurrencyForTicker(
trade.payInCurrency, trade.payInCurrency,
); )!;
} catch (_) { } catch (_) {
coin = AppConfig.getCryptoCurrencyByPrettyName( coin = AppConfig.getCryptoCurrencyByPrettyName(
trade.payInCurrency, trade.payInCurrency,
@ -1415,7 +1415,7 @@ class _TradeDetailsViewState extends ConsumerState<TradeDetailsView> {
} }
class _Divider extends StatelessWidget { class _Divider extends StatelessWidget {
const _Divider({Key? key}) : super(key: key); const _Divider({super.key});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View file

@ -16,6 +16,10 @@ import 'dart:typed_data';
import 'package:frostdart/frostdart.dart' as frost; import 'package:frostdart/frostdart.dart' as frost;
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:stack_wallet_backup/stack_wallet_backup.dart'; import 'package:stack_wallet_backup/stack_wallet_backup.dart';
import 'package:tuple/tuple.dart';
import 'package:uuid/uuid.dart';
import 'package:wakelock/wakelock.dart';
import '../../../../../app_config.dart'; import '../../../../../app_config.dart';
import '../../../../../db/hive/db.dart'; import '../../../../../db/hive/db.dart';
import '../../../../../db/isar/main_db.dart'; import '../../../../../db/isar/main_db.dart';
@ -52,9 +56,6 @@ import '../../../../../wallets/wallet/wallet.dart';
import '../../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/cw_based_interface.dart';
import '../../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/mnemonic_interface.dart';
import '../../../../../wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart'; import '../../../../../wallets/wallet/wallet_mixin_interfaces/private_key_interface.dart';
import 'package:tuple/tuple.dart';
import 'package:uuid/uuid.dart';
import 'package:wakelock/wakelock.dart';
class PreRestoreState { class PreRestoreState {
final Set<String> walletIds; final Set<String> walletIds;
@ -776,7 +777,7 @@ abstract class SWB {
final coin = AppConfig.getCryptoCurrencyFor( final coin = AppConfig.getCryptoCurrencyFor(
walletbackup['coinName'] as String, walletbackup['coinName'] as String,
); )!;
final walletName = walletbackup['name'] as String; final walletName = walletbackup['name'] as String;
final walletId = oldToNewWalletIdMap[walletbackup["id"] as String]!; final walletId = oldToNewWalletIdMap[walletbackup["id"] as String]!;

View file

@ -14,15 +14,11 @@ import 'package:decimal/decimal.dart';
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:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import '../../../app_config.dart'; import '../../../app_config.dart';
import '../../../models/exchange/incomplete_exchange.dart'; import '../../../models/exchange/incomplete_exchange.dart';
import '../../../models/exchange/response_objects/trade.dart'; import '../../../models/exchange/response_objects/trade.dart';
import '../../../pages/exchange_view/send_from_view.dart'; import '../../../pages/exchange_view/send_from_view.dart';
import 'subwidgets/desktop_step_1.dart';
import 'subwidgets/desktop_step_2.dart';
import 'subwidgets/desktop_step_3.dart';
import 'subwidgets/desktop_step_4.dart';
import '../subwidgets/desktop_exchange_steps_indicator.dart';
import '../../../providers/exchange/exchange_form_state_provider.dart'; import '../../../providers/exchange/exchange_form_state_provider.dart';
import '../../../providers/global/trades_service_provider.dart'; import '../../../providers/global/trades_service_provider.dart';
import '../../../route_generator.dart'; import '../../../route_generator.dart';
@ -41,12 +37,18 @@ import '../../../widgets/desktop/primary_button.dart';
import '../../../widgets/desktop/secondary_button.dart'; import '../../../widgets/desktop/secondary_button.dart';
import '../../../widgets/desktop/simple_desktop_dialog.dart'; import '../../../widgets/desktop/simple_desktop_dialog.dart';
import '../../../widgets/fade_stack.dart'; import '../../../widgets/fade_stack.dart';
import '../subwidgets/desktop_exchange_steps_indicator.dart';
import 'subwidgets/desktop_step_1.dart';
import 'subwidgets/desktop_step_2.dart';
import 'subwidgets/desktop_step_3.dart';
import 'subwidgets/desktop_step_4.dart';
final ssss = StateProvider<IncompleteExchangeModel?>((_) => null); final ssss = StateProvider<IncompleteExchangeModel?>((_) => null);
final desktopExchangeModelProvider = final desktopExchangeModelProvider =
ChangeNotifierProvider<IncompleteExchangeModel?>( ChangeNotifierProvider<IncompleteExchangeModel?>(
(ref) => ref.watch(ssss.state).state); (ref) => ref.watch(ssss.state).state,
);
class StepScaffold extends ConsumerStatefulWidget { class StepScaffold extends ConsumerStatefulWidget {
const StepScaffold({ const StepScaffold({
@ -120,8 +122,9 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
context: context, context: context,
barrierDismissible: true, barrierDismissible: true,
builder: (_) => SimpleDesktopDialog( builder: (_) => SimpleDesktopDialog(
title: "Failed to create trade", title: "Failed to create trade",
message: response.exception?.toString() ?? ""), message: response.exception?.toString() ?? "",
),
), ),
); );
} }
@ -193,7 +196,7 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
void sendFromStack() { void sendFromStack() {
final trade = ref.read(desktopExchangeModelProvider)!.trade!; final trade = ref.read(desktopExchangeModelProvider)!.trade!;
final address = trade.payInAddress; final address = trade.payInAddress;
final coin = AppConfig.getCryptoCurrencyForTicker(trade.payInCurrency); final coin = AppConfig.getCryptoCurrencyForTicker(trade.payInCurrency)!;
final amount = Decimal.parse(trade.payInAmount).toAmount( final amount = Decimal.parse(trade.payInAmount).toAmount(
fractionDigits: coin.fractionDigits, fractionDigits: coin.fractionDigits,
); );
@ -387,9 +390,11 @@ class _StepScaffoldState extends ConsumerState<StepScaffold> {
child: QrImageView( child: QrImageView(
// TODO: grab coin uri scheme from somewhere // TODO: grab coin uri scheme from somewhere
// data: "${coin.uriScheme}:$receivingAddress", // data: "${coin.uriScheme}:$receivingAddress",
data: ref.watch(desktopExchangeModelProvider data: ref.watch(
.select((value) => desktopExchangeModelProvider.select(
value!.trade!.payInAddress)), (value) => value!.trade!.payInAddress,
),
),
size: 290, size: 290,
foregroundColor: Theme.of(context) foregroundColor: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!

View file

@ -11,11 +11,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:tuple/tuple.dart';
import '../../../../app_config.dart'; import '../../../../app_config.dart';
import '../../../../models/contact_address_entry.dart'; import '../../../../models/contact_address_entry.dart';
import '../step_scaffold.dart';
import '../../subwidgets/desktop_choose_from_stack.dart';
import '../../../my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
import '../../../../providers/exchange/exchange_send_from_wallet_id_provider.dart'; import '../../../../providers/exchange/exchange_send_from_wallet_id_provider.dart';
import '../../../../providers/global/wallets_provider.dart'; import '../../../../providers/global/wallets_provider.dart';
import '../../../../themes/stack_colors.dart'; import '../../../../themes/stack_colors.dart';
@ -32,7 +31,9 @@ import '../../../../widgets/icon_widgets/x_icon.dart';
import '../../../../widgets/rounded_white_container.dart'; import '../../../../widgets/rounded_white_container.dart';
import '../../../../widgets/stack_text_field.dart'; import '../../../../widgets/stack_text_field.dart';
import '../../../../widgets/textfield_icon_button.dart'; import '../../../../widgets/textfield_icon_button.dart';
import 'package:tuple/tuple.dart'; import '../../../my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/address_book_address_chooser.dart';
import '../../subwidgets/desktop_choose_from_stack.dart';
import '../step_scaffold.dart';
class DesktopStep2 extends ConsumerStatefulWidget { class DesktopStep2 extends ConsumerStatefulWidget {
const DesktopStep2({ const DesktopStep2({
@ -70,7 +71,7 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
try { try {
final coin = AppConfig.getCryptoCurrencyForTicker( final coin = AppConfig.getCryptoCurrencyForTicker(
ref.read(desktopExchangeModelProvider)!.receiveTicker, ref.read(desktopExchangeModelProvider)!.receiveTicker,
); )!;
final info = await showDialog<Tuple2<String, String>?>( final info = await showDialog<Tuple2<String, String>?>(
context: context, context: context,
@ -96,14 +97,15 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
} }
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _refundController.text.isNotEmpty); _toController.text.isNotEmpty && _refundController.text.isNotEmpty,
);
} }
void selectRefundAddressFromStack() async { void selectRefundAddressFromStack() async {
try { try {
final coin = AppConfig.getCryptoCurrencyForTicker( final coin = AppConfig.getCryptoCurrencyForTicker(
ref.read(desktopExchangeModelProvider)!.sendTicker, ref.read(desktopExchangeModelProvider)!.sendTicker,
); )!;
final info = await showDialog<Tuple2<String, String>?>( final info = await showDialog<Tuple2<String, String>?>(
context: context, context: context,
@ -127,7 +129,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
Logging.instance.log("$e\n$s", level: LogLevel.Info); Logging.instance.log("$e\n$s", level: LogLevel.Info);
} }
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _refundController.text.isNotEmpty); _toController.text.isNotEmpty && _refundController.text.isNotEmpty,
);
} }
void selectRecipientFromAddressBook() async { void selectRecipientFromAddressBook() async {
@ -173,7 +176,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
_toController.text = entry.address; _toController.text = entry.address;
ref.read(desktopExchangeModelProvider)!.recipientAddress = entry.address; ref.read(desktopExchangeModelProvider)!.recipientAddress = entry.address;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _refundController.text.isNotEmpty); _toController.text.isNotEmpty && _refundController.text.isNotEmpty,
);
} }
} }
@ -220,7 +224,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
_refundController.text = entry.address; _refundController.text = entry.address;
ref.read(desktopExchangeModelProvider)!.refundAddress = entry.address; ref.read(desktopExchangeModelProvider)!.refundAddress = entry.address;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _refundController.text.isNotEmpty); _toController.text.isNotEmpty && _refundController.text.isNotEmpty,
);
} }
} }
@ -301,12 +306,17 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
Text( Text(
"Recipient Wallet", "Recipient Wallet",
style: STextStyles.desktopTextExtraExtraSmall(context).copyWith( style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.textFieldActiveSearchIconRight), .textFieldActiveSearchIconRight,
),
), ),
if (isStackCoin(ref.watch(desktopExchangeModelProvider if (isStackCoin(
.select((value) => value!.receiveTicker)))) ref.watch(
desktopExchangeModelProvider
.select((value) => value!.receiveTicker),
),
))
CustomTextButton( CustomTextButton(
text: "Choose from Stack", text: "Choose from Stack",
onTap: selectRecipientAddressFromStack, onTap: selectRecipientAddressFromStack,
@ -339,8 +349,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
focusNode: _toFocusNode, focusNode: _toFocusNode,
style: STextStyles.field(context), style: STextStyles.field(context),
onChanged: (value) { onChanged: (value) {
widget.enableNextChanged.call(_toController.text.isNotEmpty && widget.enableNextChanged.call(
_refundController.text.isNotEmpty); _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty,
);
}, },
decoration: standardInputDecoration( decoration: standardInputDecoration(
"Enter the ${ref.watch(desktopExchangeModelProvider.select((value) => value!.receiveTicker.toUpperCase()))} payout address", "Enter the ${ref.watch(desktopExchangeModelProvider.select((value) => value!.receiveTicker.toUpperCase()))} payout address",
@ -365,21 +377,24 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
_toController.text.isNotEmpty _toController.text.isNotEmpty
? TextFieldIconButton( ? TextFieldIconButton(
key: const Key( key: const Key(
"sendViewClearAddressFieldButtonKey"), "sendViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
_toController.text = ""; _toController.text = "";
ref ref
.read(desktopExchangeModelProvider)! .read(desktopExchangeModelProvider)!
.recipientAddress = _toController.text; .recipientAddress = _toController.text;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty); _refundController.text.isNotEmpty,
);
}, },
child: const XIcon(), child: const XIcon(),
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"sendViewPasteAddressFieldButtonKey"), "sendViewPasteAddressFieldButtonKey",
),
onTap: () async { onTap: () async {
final ClipboardData? data = await clipboard final ClipboardData? data = await clipboard
.getData(Clipboard.kTextPlain); .getData(Clipboard.kTextPlain);
@ -391,8 +406,9 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
.read(desktopExchangeModelProvider)! .read(desktopExchangeModelProvider)!
.recipientAddress = _toController.text; .recipientAddress = _toController.text;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty); _refundController.text.isNotEmpty,
);
} }
}, },
child: _toController.text.isEmpty child: _toController.text.isEmpty
@ -400,8 +416,12 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
: const XIcon(), : const XIcon(),
), ),
if (_toController.text.isEmpty && if (_toController.text.isEmpty &&
isStackCoin(ref.watch(desktopExchangeModelProvider isStackCoin(
.select((value) => value!.receiveTicker)))) ref.watch(
desktopExchangeModelProvider
.select((value) => value!.receiveTicker),
),
))
TextFieldIconButton( TextFieldIconButton(
key: const Key("sendViewAddressBookButtonKey"), key: const Key("sendViewAddressBookButtonKey"),
onTap: selectRecipientFromAddressBook, onTap: selectRecipientFromAddressBook,
@ -433,12 +453,17 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
Text( Text(
"Refund Wallet (required)", "Refund Wallet (required)",
style: STextStyles.desktopTextExtraExtraSmall(context).copyWith( style: STextStyles.desktopTextExtraExtraSmall(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.textFieldActiveSearchIconRight), .textFieldActiveSearchIconRight,
),
), ),
if (isStackCoin(ref.watch(desktopExchangeModelProvider if (isStackCoin(
.select((value) => value!.sendTicker)))) ref.watch(
desktopExchangeModelProvider
.select((value) => value!.sendTicker),
),
))
CustomTextButton( CustomTextButton(
text: "Choose from Stack", text: "Choose from Stack",
onTap: selectRefundAddressFromStack, onTap: selectRefundAddressFromStack,
@ -470,8 +495,10 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
focusNode: _refundFocusNode, focusNode: _refundFocusNode,
style: STextStyles.field(context), style: STextStyles.field(context),
onChanged: (value) { onChanged: (value) {
widget.enableNextChanged.call(_toController.text.isNotEmpty && widget.enableNextChanged.call(
_refundController.text.isNotEmpty); _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty,
);
}, },
decoration: standardInputDecoration( decoration: standardInputDecoration(
"Enter ${ref.watch(desktopExchangeModelProvider.select((value) => value!.sendTicker.toUpperCase()))} refund address", "Enter ${ref.watch(desktopExchangeModelProvider.select((value) => value!.sendTicker.toUpperCase()))} refund address",
@ -496,7 +523,8 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
_refundController.text.isNotEmpty _refundController.text.isNotEmpty
? TextFieldIconButton( ? TextFieldIconButton(
key: const Key( key: const Key(
"sendViewClearAddressFieldButtonKey"), "sendViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
_refundController.text = ""; _refundController.text = "";
ref ref
@ -504,14 +532,16 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
.refundAddress = _refundController.text; .refundAddress = _refundController.text;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty); _refundController.text.isNotEmpty,
);
}, },
child: const XIcon(), child: const XIcon(),
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"sendViewPasteAddressFieldButtonKey"), "sendViewPasteAddressFieldButtonKey",
),
onTap: () async { onTap: () async {
final ClipboardData? data = await clipboard final ClipboardData? data = await clipboard
.getData(Clipboard.kTextPlain); .getData(Clipboard.kTextPlain);
@ -525,8 +555,9 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
.refundAddress = _refundController.text; .refundAddress = _refundController.text;
widget.enableNextChanged.call( widget.enableNextChanged.call(
_toController.text.isNotEmpty && _toController.text.isNotEmpty &&
_refundController.text.isNotEmpty); _refundController.text.isNotEmpty,
);
} }
}, },
child: _refundController.text.isEmpty child: _refundController.text.isEmpty
@ -534,8 +565,12 @@ class _DesktopStep2State extends ConsumerState<DesktopStep2> {
: const XIcon(), : const XIcon(),
), ),
if (_refundController.text.isEmpty && if (_refundController.text.isEmpty &&
isStackCoin(ref.watch(desktopExchangeModelProvider isStackCoin(
.select((value) => value!.sendTicker)))) ref.watch(
desktopExchangeModelProvider
.select((value) => value!.sendTicker),
),
))
TextFieldIconButton( TextFieldIconButton(
key: const Key("sendViewAddressBookButtonKey"), key: const Key("sendViewAddressBookButtonKey"),
onTap: selectRefundFromAddressBook, onTap: selectRefundFromAddressBook,

View file

@ -1,13 +1,14 @@
import 'dart:convert'; import 'dart:convert';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
import 'package:uuid/uuid.dart';
import '../../../app_config.dart'; import '../../../app_config.dart';
import '../../../models/balance.dart'; import '../../../models/balance.dart';
import '../../../models/isar/models/blockchain_data/address.dart'; import '../../../models/isar/models/blockchain_data/address.dart';
import '../../crypto_currency/crypto_currency.dart'; import '../../crypto_currency/crypto_currency.dart';
import '../isar_id_interface.dart'; import '../isar_id_interface.dart';
import 'wallet_info_meta.dart'; import 'wallet_info_meta.dart';
import 'package:uuid/uuid.dart';
part 'wallet_info.g.dart'; part 'wallet_info.g.dart';
@ -96,7 +97,7 @@ class WalletInfo implements IsarId {
} }
@ignore @ignore
CryptoCurrency get coin => AppConfig.getCryptoCurrencyFor(coinName); CryptoCurrency get coin => AppConfig.getCryptoCurrencyFor(coinName)!;
@ignore @ignore
Balance get cachedBalance { Balance get cachedBalance {
@ -466,7 +467,7 @@ class WalletInfo implements IsarId {
) { ) {
final coin = AppConfig.getCryptoCurrencyFor( final coin = AppConfig.getCryptoCurrencyFor(
jsonObject["coin"] as String, jsonObject["coin"] as String,
); )!;
return WalletInfo( return WalletInfo(
coinName: coin.identifier, coinName: coin.identifier,
walletId: jsonObject["id"] as String, walletId: jsonObject["id"] as String,