From f9247c98bf732dd72ebbeee8eebc43d6491ac6c5 Mon Sep 17 00:00:00 2001 From: Jordan Miller Date: Mon, 16 Sep 2024 23:23:25 -0600 Subject: [PATCH 1/2] balances updating on home page --- magic/lib/cubits/pane/wallet/cubit.dart | 8 +++++++- magic/lib/services/maestro.dart | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/magic/lib/cubits/pane/wallet/cubit.dart b/magic/lib/cubits/pane/wallet/cubit.dart index ee8231b7..2f371e65 100644 --- a/magic/lib/cubits/pane/wallet/cubit.dart +++ b/magic/lib/cubits/pane/wallet/cubit.dart @@ -23,6 +23,8 @@ part 'state.dart'; class WalletCubit extends UpdatableCubit { WalletCubit() : super(const WalletState()); + DateTime populatedAt = DateTime.now(); + List defaultChips = [ Chips.all, Chips.evrmore, @@ -101,7 +103,11 @@ class WalletCubit extends UpdatableCubit { update(holdings: [], active: true); } - Future populateAssets() async { + Future populateAssets([int cooldown = 0]) async { + if (cooldown > 0 && DateTime.now().difference(populatedAt!).inSeconds < cooldown) { + return false; + } + populatedAt = DateTime.now(); // remember to order by currency first, amount second, alphabetical third update(isSubmitting: true); see('populateAssets'); diff --git a/magic/lib/services/maestro.dart b/magic/lib/services/maestro.dart index 7c8ad844..4af34df6 100644 --- a/magic/lib/services/maestro.dart +++ b/magic/lib/services/maestro.dart @@ -220,6 +220,7 @@ class Maestro { } else { locked = true; } + cubits.wallet.populateAssets(30); cubits.app.animating = true; // if pane is not in middle move it to middle first if (cubits.pane.height != screen.pane.midHeight) { From 26d8cfb8a6e997cd55f11d8bc66cc75b39cc4829 Mon Sep 17 00:00:00 2001 From: Jordan Miller Date: Tue, 17 Sep 2024 17:15:13 -0600 Subject: [PATCH 2/2] balance updating fix plus fixing lots of things --- magic/lib/cubits/data/keys/cubit.dart | 6 +- magic/lib/cubits/pane/receive/cubit.dart | 54 ++- magic/lib/cubits/pane/wallet/cubit.dart | 9 +- magic/lib/main.dart | 4 +- magic/lib/presentation/ui/appbar/header.dart | 7 +- .../presentation/ui/canvas/holding/page.dart | 12 +- magic/lib/presentation/ui/pane/send/page.dart | 317 ++++++++++-------- .../lib/presentation/ui/welcome/welcome.dart | 69 +++- .../presentation/widgets/assets/names.dart | 2 +- magic/lib/services/maestro.dart | 2 +- magic/lib/services/subscription.dart | 13 +- magic/lib/services/testing.dart | 6 +- magic/lib/services/triggers/rate.dart | 12 +- 13 files changed, 309 insertions(+), 204 deletions(-) diff --git a/magic/lib/cubits/data/keys/cubit.dart b/magic/lib/cubits/data/keys/cubit.dart index 2b6b1a07..56b236f7 100644 --- a/magic/lib/cubits/data/keys/cubit.dart +++ b/magic/lib/cubits/data/keys/cubit.dart @@ -47,9 +47,9 @@ class KeysCubit extends UpdatableCubit { //see(mnemonics); //try { // see('-----------------------------'); - // see(master.derivationWallets.first.mnemonic); - // see(master.derivationWallets.first.roots(Blockchain.evrmoreMain)); - // see(master.derivationWallets.first.roots(Blockchain.ravencoinMain)); + // see(master.derivationWallets.last.mnemonic); + // see(master.derivationWallets.last.roots(Blockchain.evrmoreMain)); + // see(master.derivationWallets.last.roots(Blockchain.ravencoinMain)); //} catch (e) {} emit(KeysState( xpubs: xpubs ?? state.xpubs, diff --git a/magic/lib/cubits/pane/receive/cubit.dart b/magic/lib/cubits/pane/receive/cubit.dart index 39dfa620..57078f78 100644 --- a/magic/lib/cubits/pane/receive/cubit.dart +++ b/magic/lib/cubits/pane/receive/cubit.dart @@ -79,14 +79,14 @@ class ReceiveCubit extends UpdatableCubit { Blockchain blockchain, { int? overrideIndex, }) async { - if (cubits.keys.master.derivationWallets.first.cold) { + if (cubits.keys.master.derivationWallets.last.cold) { final xpubs = - cubits.keys.master.derivationWallets.first.rootsMap(blockchain); + cubits.keys.master.derivationWallets.last.rootsMap(blockchain); final index = overrideIndex ?? await _getIndex( blockchain: blockchain, exposure: Exposure.external, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex); update( address: blockchain.addressFromH160( @@ -96,32 +96,30 @@ class ReceiveCubit extends UpdatableCubit { return; } final seedWallet = - cubits.keys.master.derivationWallets.first.seedWallet(blockchain); + cubits.keys.master.derivationWallets.last.seedWallet(blockchain); if (seedWallet.highestIndex.isEmpty) { - cubits.keys.master.derivationWallets.first.seedWallet(blockchain).derive({ + cubits.keys.master.derivationWallets.last.seedWallet(blockchain).derive({ Exposure.internal: await _getIndex( blockchain: blockchain, exposure: Exposure.internal, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex), Exposure.external: await _getIndex( blockchain: blockchain, exposure: Exposure.external, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex), }); } else { - cubits.keys.master.derivationWallets.first - .seedWallet(blockchain) - .derive(); + cubits.keys.master.derivationWallets.last.seedWallet(blockchain).derive(); } update( - address: cubits.keys.master.derivationWallets.first + address: cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .externals .lastOrNull ?.address, - changeAddress: cubits.keys.master.derivationWallets.first + changeAddress: cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .internals .lastOrNull @@ -168,14 +166,14 @@ class ReceiveCubit extends UpdatableCubit { Blockchain blockchain, { int? overrideIndex, }) async { - if (cubits.keys.master.derivationWallets.first.cold) { - final xpub = cubits.keys.master.derivationWallets.first + if (cubits.keys.master.derivationWallets.last.cold) { + final xpub = cubits.keys.master.derivationWallets.last .rootsMap(blockchain)[Exposure.external]!; final index = overrideIndex ?? await _getIndex( blockchain: blockchain, exposure: Exposure.external, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex); final address = blockchain.addressFromH160(h160FromXPubForAddress(xpub, index)); @@ -183,21 +181,21 @@ class ReceiveCubit extends UpdatableCubit { return; } final seedWallet = - cubits.keys.master.derivationWallets.first.seedWallet(blockchain); + cubits.keys.master.derivationWallets.last.seedWallet(blockchain); if (seedWallet.highestIndex.isEmpty) { - cubits.keys.master.derivationWallets.first.seedWallet(blockchain).derive({ + cubits.keys.master.derivationWallets.last.seedWallet(blockchain).derive({ Exposure.external: await _getIndex( blockchain: blockchain, exposure: Exposure.external, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex), }); } else { - cubits.keys.master.derivationWallets.first + cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .derive({Exposure.external: 0}); } - final addressFromSeed = cubits.keys.master.derivationWallets.first + final addressFromSeed = cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .externals .lastOrNull @@ -209,14 +207,14 @@ class ReceiveCubit extends UpdatableCubit { Blockchain blockchain, { int? overrideIndex, }) async { - if (cubits.keys.master.derivationWallets.first.cold) { - final xpub = cubits.keys.master.derivationWallets.first + if (cubits.keys.master.derivationWallets.last.cold) { + final xpub = cubits.keys.master.derivationWallets.last .rootsMap(blockchain)[Exposure.internal]!; final index = overrideIndex ?? await _getIndex( blockchain: blockchain, exposure: Exposure.internal, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex); final address = blockchain.addressFromH160(h160FromXPubForAddress(xpub, index)); @@ -224,22 +222,22 @@ class ReceiveCubit extends UpdatableCubit { return address; } final seedWallet = - cubits.keys.master.derivationWallets.first.seedWallet(blockchain); + cubits.keys.master.derivationWallets.last.seedWallet(blockchain); if (seedWallet.highestIndex.isEmpty) { - cubits.keys.master.derivationWallets.first.seedWallet(blockchain).derive({ + cubits.keys.master.derivationWallets.last.seedWallet(blockchain).derive({ Exposure.internal: await _getIndex( blockchain: blockchain, exposure: Exposure.internal, - derivationWallet: cubits.keys.master.derivationWallets.first, + derivationWallet: cubits.keys.master.derivationWallets.last, overrideIndex: overrideIndex), }); } else { - cubits.keys.master.derivationWallets.first + cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .derive({Exposure.internal: 0}); } update( - changeAddress: cubits.keys.master.derivationWallets.first + changeAddress: cubits.keys.master.derivationWallets.last .seedWallet(blockchain) .internals .last diff --git a/magic/lib/cubits/pane/wallet/cubit.dart b/magic/lib/cubits/pane/wallet/cubit.dart index 2f371e65..966bf466 100644 --- a/magic/lib/cubits/pane/wallet/cubit.dart +++ b/magic/lib/cubits/pane/wallet/cubit.dart @@ -104,7 +104,8 @@ class WalletCubit extends UpdatableCubit { } Future populateAssets([int cooldown = 0]) async { - if (cooldown > 0 && DateTime.now().difference(populatedAt!).inSeconds < cooldown) { + if (cooldown > 0 && + DateTime.now().difference(populatedAt!).inSeconds < cooldown) { return false; } populatedAt = DateTime.now(); @@ -127,7 +128,11 @@ class WalletCubit extends UpdatableCubit { derivationWallets: cubits.keys.master.derivationWallets, keypairWallets: cubits.keys.master.keypairWallets, ).call()))); - update(holdings: holdings, isSubmitting: false); + see('holdings:', holdings, LogColors.magenta); + if (holdings.isNotEmpty) { + update(holdings: [], isSubmitting: false); + update(holdings: holdings, isSubmitting: false); + } if (rates.rvnUsdRate != null) { cacheRate(rates.rvnUsdRate!); } diff --git a/magic/lib/main.dart b/magic/lib/main.dart index 9a8e39c3..ca7df6e3 100644 --- a/magic/lib/main.dart +++ b/magic/lib/main.dart @@ -60,7 +60,9 @@ Future main() async { await cubits.keys.loadXPubs(); await cubits.menu.loadSettings(); // Initialize the Serverpod client with a retry mechanism to handle connection issues + print('setting up client'); await subscription.setupClient(FlutterConnectivityMonitor()); + print('setted up client'); await precacheSvgPicture(LogoIcons.magic); //ApiService.init(); @@ -141,7 +143,7 @@ Future _clearAuthAndLoadKeys(BuildContext context) async { /// TODO: rework to save at the root level. await cubits.keys.loadXPubs(); ////see( - //// cubits.keys.master.derivationWallets.first.roots(Blockchain.evrmoreMain)); + //// cubits.keys.master.derivationWallets.last.roots(Blockchain.evrmoreMain)); ////[xpub6EyL2KHeobgPS891ygwWVrZUAqRArjUk5Fs4zxQ9d6Yy1GMF78AULHZaRUNmg6BZzhPj7P6Qc6SXUGc4YHMV8A9wFcxw19tmNxnF1XfMHWZ, xpub6EyL2KHeobgPSohWN2j4xPiX5PFJvnbAi64u2yA3qDQTBcBd8jdN21jmvVsuTL8HDmyCN6cf7qaV3VbBR1DQeS7JFiq6JzRw6dToyLA4Qqq] ////[xpub6Djoyq41s3QGoGefbJCEkrdfHquk5315tdeuQMr21QxA3jSzGAxxLpqPfAz22RmmofBEx98MJf27KYyT8NN31SS6EzsiDxbYNDsv6hLBSfD, xpub6Djoyq41s3QGrA8YgAaZgdS3ALyG2vij5Fp1XSM9JRdx4kCrhWLtrifW67ncQhgWMmUQxRto3SS7zktvL81SxWwBtR63b9tLpDvc7ddrhHe] subscription.ensureConnected().then((_) { diff --git a/magic/lib/presentation/ui/appbar/header.dart b/magic/lib/presentation/ui/appbar/header.dart index 2f4cea9b..1eb3e4e5 100644 --- a/magic/lib/presentation/ui/appbar/header.dart +++ b/magic/lib/presentation/ui/appbar/header.dart @@ -97,9 +97,10 @@ class Leading extends StatelessWidget { onTap: state.onLead, child: Container( height: 16 + screen.iconMedium + 16, - width: 24 + screen.iconMedium, + width: 24 + screen.iconMedium + 8, alignment: Alignment.centerRight, color: Colors.transparent, + padding: const EdgeInsets.only(right: 8), child: () { if (state.leading == AppbarLeading.menu) { return Icon(Icons.menu_rounded, @@ -154,7 +155,7 @@ class Title extends StatelessWidget { ? state.titleChild : (state.title == 'Magic' ? Padding( - padding: const EdgeInsets.only(left: 8, top: 8.0), + padding: const EdgeInsets.only(left: 0, top: 8.0), child: SvgPicture.asset( LogoIcons.magic, height: screen.appbar.logoHeight, @@ -162,7 +163,7 @@ class Title extends StatelessWidget { alignment: Alignment.center, )) : Padding( - padding: const EdgeInsets.only(left: 16, top: 2.0), + padding: const EdgeInsets.only(left: 8, top: 2.0), child: Text(state.title, style: Theme.of(context) .textTheme diff --git a/magic/lib/presentation/ui/canvas/holding/page.dart b/magic/lib/presentation/ui/canvas/holding/page.dart index f5d633b9..532133c1 100644 --- a/magic/lib/presentation/ui/canvas/holding/page.dart +++ b/magic/lib/presentation/ui/canvas/holding/page.dart @@ -5,6 +5,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:magic/cubits/canvas/holding/cubit.dart'; import 'package:magic/cubits/cubit.dart'; import 'package:magic/cubits/toast/cubit.dart'; +import 'package:magic/domain/blockchain/blockchain.dart'; import 'package:magic/domain/concepts/holding.dart'; import 'package:magic/domain/concepts/numbers/coin.dart'; import 'package:magic/presentation/ui/pane/wallet/page.dart'; @@ -17,6 +18,10 @@ import 'package:magic/presentation/theme/theme.dart'; import 'package:magic/presentation/widgets/assets/icons.dart'; import 'package:magic/domain/concepts/asset_icons.dart'; +Holding getHoldingOf(Blockchain blockchain) => cubits.wallet.state.holdings + .where((x) => x.blockchain == blockchain && x.isCurrency) + .first; + class HodingDetailPage extends StatelessWidget { const HodingDetailPage({super.key}); @@ -133,7 +138,12 @@ class AnimatedCoinSpec extends StatelessWidget { width: screen.width * .8, child: Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ const SizedBox.shrink(), - if (cubits.holding.state.holding.sats.value > 0) + if (cubits.holding.state.holding.sats.value > 0 && + (cubits.holding.state.holding.isCurrency || + getHoldingOf(cubits.holding.state.holding.blockchain) + .sats + .value > + 0)) GestureDetector( onTap: //!['\$ -', '\$ 0.00'].contains(cubits.holding.state.usd) diff --git a/magic/lib/presentation/ui/pane/send/page.dart b/magic/lib/presentation/ui/pane/send/page.dart index 4898cf5c..e231c3f0 100644 --- a/magic/lib/presentation/ui/pane/send/page.dart +++ b/magic/lib/presentation/ui/pane/send/page.dart @@ -345,155 +345,194 @@ class SendContentState extends State { mainAxisAlignment: MainAxisAlignment.start, children: [ const SizedBox(height: 8), - CustomTextField( - textInputAction: TextInputAction.next, - controller: addressText, - labelText: 'To', - suffixIcon: Padding( - padding: const EdgeInsets.only(bottom: 16), - child: GestureDetector( - onTap: () { - cubits.send.update( - scanActive: !cubits.send.state.scanActive); - }, - child: const Icon(Icons.qr_code_scanner, - color: AppColors.white60))), - errorText: addressText.text.trim() == '' || - validateAddress(addressText.text) - ? null - : invalidAddressMessages(addressText.text).firstOrNull, - onChanged: (value) => setState(() { - if (validateAddress(addressText.text)) { - cubits.send.update(address: value); + GestureDetector( + onDoubleTap: () async { + String potentialAddress = + (await Clipboard.getData('text/plain'))?.text ?? ''; + if (validateAddress(potentialAddress)) { + addressText.text = potentialAddress; + cubits.send.update(address: potentialAddress); } - }), + }, + child: CustomTextField( + textInputAction: TextInputAction.next, + controller: addressText, + labelText: 'To', + suffixIcon: Padding( + padding: const EdgeInsets.only(bottom: 16), + child: GestureDetector( + onTap: () { + cubits.send.update( + scanActive: !cubits.send.state.scanActive); + }, + child: const Icon(Icons.qr_code_scanner, + color: AppColors.white60))), + errorText: addressText.text.trim() == '' || + validateAddress(addressText.text) + ? null + : invalidAddressMessages(addressText.text) + .firstOrNull, + onChanged: (value) => setState(() { + if (validateAddress(addressText.text)) { + cubits.send.update(address: value); + } + }), + ), ), const SizedBox(height: 16), - CustomTextField( - textInputAction: TextInputAction.done, - controller: amountText, - keyboardType: const TextInputType.numberWithOptions( - signed: false, decimal: true), - labelText: amountDollars ? 'Amount in USD' : 'Amount', - suffixIcon: ['0', '-'].contains( - Coin.fromString(amountText.text.replaceAll(',', '')) - .toFiat(cubits.holding.state.holding.rate) - .toString()) - ? null - : Padding( - padding: const EdgeInsets.only(bottom: 16), - child: GestureDetector( - onTap: () { - setState(() => automaticConversion = true); - setState(() { - if (amountDollars) { - if (userChanged) { - final convertedAmount = Fiat( - double.tryParse(amountText.text - .trim() - .replaceAll(',', '')) ?? - 0) - .toCoin(cubits - .holding.state.holding.rate) - .toString(); - amountText.text = - formatWithCommas(convertedAmount); - } else { - amountText.text = formatWithCommas( - cubits.send.state.originalAmount); - } - } else { - // Store the original token amount before conversion - final originalAmount = - amountText.text.replaceAll(',', ''); - final usdAmount = Coin.fromString( - originalAmount) - .toFiat( - cubits.holding.state.holding.rate) - .toString(); - amountText.text = usdAmount; - // Store the original amount for later use - cubits.send.update( - originalAmount: originalAmount); - } - amountDollars = !amountDollars; - }); - setState(() { - automaticConversion = false; - userChanged = false; - }); - }, - child: Icon( - amountDollars - ? Icons.attach_money_rounded - : Icons.toll_rounded, - color: AppColors.white60))), - errorText: amountDollars - ? userChanged - ? invalidAmountMessages(Fiat(double.tryParse( - amountText.text - .trim() - .replaceAll(',', '')) ?? - 0) - .toCoin(cubits.holding.state.holding.rate) - .toString()) - .firstOrNull - : invalidAmountMessages(cubits.send.state.amount) - .firstOrNull - : amountText.text.trim() == '' || - validateAmount(amountText.text) - ? null - : invalidAmountMessages(amountText.text).first, - onChanged: (value) { - see(value); - if (automaticConversion) { - return; - } - userChanged = true; - - // Remove existing commas before processing - String cleanValue = value.replaceAll(',', ''); - + GestureDetector( + onDoubleTap: () async { if (amountDollars) { - // Format USD input with commas - final formattedValue = formatWithCommas(cleanValue); - if (formattedValue != value) { - amountText.value = amountText.value.copyWith( - text: formattedValue, - selection: TextSelection.collapsed( - offset: formattedValue.length), - ); + String potentialAmount = + (await Clipboard.getData('text/plain'))?.text ?? ''; + try { + final fiatAmount = Fiat(double.tryParse( + potentialAmount.trim().replaceAll(',', '')) ?? + 0); + setState(() { + amountText.text = fiatAmount.toString(); + }); + } catch (e) { + print(e); } - - // Convert USD to coin amount for validation and cubit update - final coinAmount = - Fiat(double.tryParse(cleanValue) ?? 0) - .toCoin(cubits.holding.state.holding.rate) - .toString(); - - setState(() { - if (validateAmount(coinAmount)) { - cubits.send.update(amount: coinAmount); - } - }); } else { - // Format coin amount input with commas - final formattedValue = formatWithCommas(cleanValue); - if (formattedValue != value) { - amountText.value = amountText.value.copyWith( - text: formattedValue, - selection: TextSelection.collapsed( - offset: formattedValue.length), - ); - } - + amountText.text = + cubits.holding.state.holding.coin.entire(); setState(() { - if (validateAmount(cleanValue)) { - cubits.send.update(amount: cleanValue); - } + cubits.send.update( + amount: + cubits.holding.state.holding.coin.entire()); }); } }, + child: CustomTextField( + textInputAction: TextInputAction.done, + controller: amountText, + keyboardType: const TextInputType.numberWithOptions( + signed: false, decimal: true), + labelText: amountDollars ? 'Amount in USD' : 'Amount', + suffixIcon: ['0', '-'].contains(Coin.fromString( + amountText.text.replaceAll(',', '')) + .toFiat(cubits.holding.state.holding.rate) + .toString()) + ? null + : Padding( + padding: const EdgeInsets.only(bottom: 16), + child: GestureDetector( + onTap: () { + setState(() => automaticConversion = true); + setState(() { + if (amountDollars) { + if (userChanged) { + final convertedAmount = Fiat( + double.tryParse(amountText + .text + .trim() + .replaceAll( + ',', '')) ?? + 0) + .toCoin(cubits + .holding.state.holding.rate) + .toString(); + amountText.text = + formatWithCommas(convertedAmount); + } else { + amountText.text = formatWithCommas( + cubits.send.state.originalAmount); + } + } else { + // Store the original token amount before conversion + final originalAmount = + amountText.text.replaceAll(',', ''); + final usdAmount = + Coin.fromString(originalAmount) + .toFiat(cubits + .holding.state.holding.rate) + .toString(); + amountText.text = usdAmount; + // Store the original amount for later use + cubits.send.update( + originalAmount: originalAmount); + } + amountDollars = !amountDollars; + }); + setState(() { + automaticConversion = false; + userChanged = false; + }); + }, + child: Icon( + amountDollars + ? Icons.attach_money_rounded + : Icons.toll_rounded, + color: AppColors.white60))), + errorText: amountDollars + ? userChanged + ? invalidAmountMessages(Fiat(double.tryParse( + amountText.text + .trim() + .replaceAll(',', '')) ?? + 0) + .toCoin(cubits.holding.state.holding.rate) + .toString()) + .firstOrNull + : invalidAmountMessages(cubits.send.state.amount) + .firstOrNull + : amountText.text.trim() == '' || + validateAmount(amountText.text) + ? null + : invalidAmountMessages(amountText.text).first, + onChanged: (value) { + see(value); + if (automaticConversion) { + return; + } + userChanged = true; + + // Remove existing commas before processing + String cleanValue = value.replaceAll(',', ''); + + if (amountDollars) { + // Format USD input with commas + final formattedValue = formatWithCommas(cleanValue); + if (formattedValue != value) { + amountText.value = amountText.value.copyWith( + text: formattedValue, + selection: TextSelection.collapsed( + offset: formattedValue.length), + ); + } + + // Convert USD to coin amount for validation and cubit update + final coinAmount = + Fiat(double.tryParse(cleanValue) ?? 0) + .toCoin(cubits.holding.state.holding.rate) + .toString(); + + setState(() { + if (validateAmount(coinAmount)) { + cubits.send.update(amount: coinAmount); + } + }); + } else { + // Format coin amount input with commas + final formattedValue = formatWithCommas(cleanValue); + if (formattedValue != value) { + amountText.value = amountText.value.copyWith( + text: formattedValue, + selection: TextSelection.collapsed( + offset: formattedValue.length), + ); + } + + setState(() { + if (validateAmount(cleanValue)) { + cubits.send.update(amount: cleanValue); + } + }); + } + }, + ), ), ], ); diff --git a/magic/lib/presentation/ui/welcome/welcome.dart b/magic/lib/presentation/ui/welcome/welcome.dart index 69a35dfc..d6fa1972 100644 --- a/magic/lib/presentation/ui/welcome/welcome.dart +++ b/magic/lib/presentation/ui/welcome/welcome.dart @@ -4,10 +4,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:magic/cubits/app/cubit.dart'; import 'package:magic/cubits/cubit.dart'; import 'package:magic/cubits/toast/cubit.dart'; import 'package:magic/cubits/welcome/cubit.dart'; import 'package:magic/domain/blockchain/blockchain.dart'; +import 'package:magic/domain/server/serverv2_client.dart'; import 'package:magic/presentation/theme/colors.dart'; import 'package:magic/presentation/utils/animation.dart'; import 'package:magic/presentation/widgets/animations/fading.dart'; @@ -241,24 +243,55 @@ class WelcomeBackScreenState extends State { child: SizedBox( width: double.infinity, height: 60, - child: ElevatedButton( - onHover: (_) => cubits.app.animating = true, - onPressed: _handleAuthentication, // Changed this line - style: ElevatedButton.styleFrom( - backgroundColor: AppColors.button, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(30), - ), - ), - child: const Text( - "LET'S GO", - style: TextStyle( - fontSize: 18, - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ), + child: BlocBuilder( + buildWhen: (AppState previous, AppState current) => + previous.connection != current.connection, + builder: (BuildContext context, AppState state) { + if (state.connection == + StreamingConnectionStatus.connected) { + return ElevatedButton( + onHover: (_) => cubits.app.animating = true, + onPressed: + _handleAuthentication, // Changed this line + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.button, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + child: const Text( + "LET'S GO", + style: TextStyle( + fontSize: 18, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ); + } + return ElevatedButton( + onHover: (_) => cubits.app.animating = true, + onPressed: () => cubits.toast.flash( + msg: const ToastMessage( + title: 'Connection Failed:', + text: 'please check connection', + force: true)), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[800], + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + child: const Text( + "LET'S GO", + style: TextStyle( + fontSize: 18, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), + ), + ); + }), ), ), const SizedBox(height: 16), diff --git a/magic/lib/presentation/widgets/assets/names.dart b/magic/lib/presentation/widgets/assets/names.dart index 35fa5ee6..90baee54 100644 --- a/magic/lib/presentation/widgets/assets/names.dart +++ b/magic/lib/presentation/widgets/assets/names.dart @@ -52,7 +52,7 @@ class ResponsiveHighlightedNameView extends StatelessWidget { @override Widget build(BuildContext context) => BlocBuilder( builder: (BuildContext context, HoldingState state) => Padding( - padding: const EdgeInsets.only(left: 16, top: 2.0, right: 16), + padding: const EdgeInsets.only(left: 8, top: 2.0, right: 16), child: FittedBox( fit: BoxFit.scaleDown, alignment: Alignment.centerLeft, diff --git a/magic/lib/services/maestro.dart b/magic/lib/services/maestro.dart index 4af34df6..1733f075 100644 --- a/magic/lib/services/maestro.dart +++ b/magic/lib/services/maestro.dart @@ -294,7 +294,7 @@ class Maestro { /// place for testing stuff since mint is unused: /// //see(makeMnemonic()); - //see(cubits.keys.master.derivationWallets.first.mnemonic); + //see(cubits.keys.master.derivationWallets.last.mnemonic); //see(cubits.keys.state.mnemonics); //cubits.keys.reset(); //see(cubits.keys.dump()); diff --git a/magic/lib/services/subscription.dart b/magic/lib/services/subscription.dart index 8349c9da..2b016280 100644 --- a/magic/lib/services/subscription.dart +++ b/magic/lib/services/subscription.dart @@ -28,11 +28,9 @@ class SubscriptionService { client.connectivityMonitor?.addListener((connected) { if (!connected) { see('Disconnected, attempting to reconnect...'); - _attemptReconnect(); } }); - await _setupConnection(); } @@ -172,9 +170,20 @@ class SubscriptionService { } Future _waitForConnection() async { + int stillWaiting = 0; while (connectionHandler.status.status != StreamingConnectionStatus.connected) { await Future.delayed(const Duration(seconds: 1)); + stillWaiting += 1; + if (stillWaiting == 2) { + print('-------------------'); + cubits.toast.flash( + msg: const ToastMessage( + duration: Duration(seconds: 7), + title: 'Connection Failed:', + text: 'please check connection', + force: true)); + } } } diff --git a/magic/lib/services/testing.dart b/magic/lib/services/testing.dart index d24276b8..bc0f9822 100644 --- a/magic/lib/services/testing.dart +++ b/magic/lib/services/testing.dart @@ -105,11 +105,11 @@ class Testing { // .populateAddresses(Blockchain.evrmoreMain, overrideIndex: i); //} //see( - // 'pubkey ${cubits.keys.master.derivationWallets.first.pubkey(Blockchain.evrmoreMain)}'); + // 'pubkey ${cubits.keys.master.derivationWallets.last.pubkey(Blockchain.evrmoreMain)}'); //see( - // 'roots ${cubits.keys.master.derivationWallets.first.roots(Blockchain.evrmoreMain)}'); + // 'roots ${cubits.keys.master.derivationWallets.last.roots(Blockchain.evrmoreMain)}'); //see('externals'); - //see(cubits.keys.master.derivationWallets.first.seedWallets); + //see(cubits.keys.master.derivationWallets.last.seedWallets); //see(cubits.keys.master.derivationWallets.first // .seedWallet(Blockchain.evrmoreMain) // .externals diff --git a/magic/lib/services/triggers/rate.dart b/magic/lib/services/triggers/rate.dart index cf571d2f..58ef13e0 100644 --- a/magic/lib/services/triggers/rate.dart +++ b/magic/lib/services/triggers/rate.dart @@ -53,8 +53,16 @@ class RateWaiter extends Trigger { } } - Future _rate(RateGrabber rateGrabber) async => - (await rateGrabber.get()) ?? await _getExistingRate(rateGrabber) ?? 0; + Future _rate(RateGrabber rateGrabber) async { + try { + return (await rateGrabber.get()) ?? + await _getExistingRate(rateGrabber) ?? + 0; + } catch (e) { + see('unable to grab rates', '', LogColors.red); + return 0; + } + } Future getRateOf(String symbol) async { if (symbol == 'EVR') {