add extra info to spark transaction generating dialog and some linter clean up

This commit is contained in:
julian 2024-05-09 16:12:22 -06:00
parent 51807ac8e6
commit 9f4df0368a
7 changed files with 620 additions and 407 deletions

View file

@ -225,6 +225,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
builder: (context) { builder: (context) {
return BuildingTransactionDialog( return BuildingTransactionDialog(
coin: wallet.info.coin, coin: wallet.info.coin,
isSpark: wallet is FiroWallet && !firoPublicSend,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
}, },
@ -249,7 +250,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
address: address, address: address,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
note: "${model.trade!.payInCurrency.toUpperCase()}/" note: "${model.trade!.payInCurrency.toUpperCase()}/"
"${model.trade!.payOutCurrency.toUpperCase()} exchange", "${model.trade!.payOutCurrency.toUpperCase()} exchange",
@ -472,10 +473,10 @@ class _Step4ViewState extends ConsumerState<Step4View> {
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
final data = ClipboardData( final data = ClipboardData(
text: text: model.sendAmount.toString(),
model.sendAmount.toString()); );
await clipboard.setData(data); await clipboard.setData(data);
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -535,9 +536,10 @@ class _Step4ViewState extends ConsumerState<Step4View> {
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
final data = ClipboardData( final data = ClipboardData(
text: model.trade!.payInAddress); text: model.trade!.payInAddress,
);
await clipboard.setData(data); await clipboard.setData(data);
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -598,10 +600,10 @@ class _Step4ViewState extends ConsumerState<Step4View> {
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
final data = ClipboardData( final data = ClipboardData(
text: text: model.trade!.payInExtraId,
model.trade!.payInExtraId); );
await clipboard.setData(data); await clipboard.setData(data);
if (mounted) { if (context.mounted) {
unawaited( unawaited(
showFloatingFlushBar( showFloatingFlushBar(
type: FlushBarType.info, type: FlushBarType.info,
@ -670,9 +672,10 @@ class _Step4ViewState extends ConsumerState<Step4View> {
GestureDetector( GestureDetector(
onTap: () async { onTap: () async {
final data = ClipboardData( final data = ClipboardData(
text: model.trade!.tradeId); text: model.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,
@ -689,9 +692,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
.infoItemIcons, .infoItemIcons,
width: 12, width: 12,
), ),
) ),
], ],
) ),
], ],
), ),
), ),
@ -739,7 +742,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
child: Text( child: Text(
"Send ${model.sendTicker} to this address", "Send ${model.sendTicker} to this address",
style: STextStyles.pageTitleH2( style: STextStyles.pageTitleH2(
context), context,
),
), ),
), ),
const SizedBox( const SizedBox(
@ -773,12 +777,13 @@ class _Step4ViewState extends ConsumerState<Step4View> {
style: Theme.of(context) style: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.getSecondaryEnabledButtonStyle( .getSecondaryEnabledButtonStyle(
context), context,
),
child: Text( child: Text(
"Cancel", "Cancel",
style: STextStyles.button( style: STextStyles.button(
context) context,
.copyWith( ).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension< .extension<
StackColors>()! StackColors>()!
@ -788,7 +793,7 @@ class _Step4ViewState extends ConsumerState<Step4View> {
), ),
), ),
], ],
) ),
], ],
), ),
); );
@ -814,8 +819,9 @@ class _Step4ViewState extends ConsumerState<Step4View> {
final tuple = ref final tuple = ref
.read( .read(
exchangeSendFromWalletIdStateProvider exchangeSendFromWalletIdStateProvider
.state) .state,
)
.state; .state;
if (tuple != null && if (tuple != null &&
model.sendTicker.toLowerCase() == model.sendTicker.toLowerCase() ==
@ -845,8 +851,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
(BuildContext context) { (BuildContext context) {
final coin = final coin =
coinFromTickerCaseInsensitive( coinFromTickerCaseInsensitive(
model.trade! model.trade!.payInCurrency,
.payInCurrency); );
return SendFromView( return SendFromView(
coin: coin, coin: coin,
amount: model.sendAmount amount: model.sendAmount
@ -868,7 +874,8 @@ class _Step4ViewState extends ConsumerState<Step4View> {
style: Theme.of(context) style: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.getSecondaryEnabledButtonStyle( .getSecondaryEnabledButtonStyle(
context), context,
),
child: Text( child: Text(
buttonTitle, buttonTitle,
style: style:

View file

@ -205,13 +205,13 @@ class _SendFromViewState extends ConsumerState<SendFromView> {
class SendFromCard extends ConsumerStatefulWidget { class SendFromCard extends ConsumerStatefulWidget {
const SendFromCard({ const SendFromCard({
Key? key, super.key,
required this.walletId, required this.walletId,
required this.amount, required this.amount,
required this.address, required this.address,
required this.trade, required this.trade,
this.fromDesktopStep4 = false, this.fromDesktopStep4 = false,
}) : super(key: key); });
final String walletId; final String walletId;
final Amount amount; final Amount amount;
@ -235,6 +235,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
try { try {
bool wasCancelled = false; bool wasCancelled = false;
final wallet = ref.read(pWallets).getWallet(walletId);
unawaited( unawaited(
showDialog<dynamic>( showDialog<dynamic>(
context: context, context: context,
@ -253,6 +255,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
), ),
child: BuildingTransactionDialog( child: BuildingTransactionDialog(
coin: coin, coin: coin,
isSpark:
wallet is FiroWallet && shouldSendPublicFiroFunds != true,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
@ -273,8 +277,6 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
TxData txData; TxData txData;
Future<TxData> txDataFuture; Future<TxData> txDataFuture;
final wallet = ref.read(pWallets).getWallet(walletId);
// if not firo then do normal send // if not firo then do normal send
if (shouldSendPublicFiroFunds == null) { if (shouldSendPublicFiroFunds == null) {
final memo = coin == Coin.stellar || coin == Coin.stellarTestnet final memo = coin == Coin.stellar || coin == Coin.stellarTestnet
@ -371,38 +373,38 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
} }
} }
} catch (e) { } catch (e) {
// if (mounted) { if (mounted) {
// pop building dialog // pop building dialog
Navigator.of(context).pop(); Navigator.of(context).pop();
await showDialog<dynamic>( await showDialog<dynamic>(
context: context, context: context,
useSafeArea: false, useSafeArea: false,
barrierDismissible: true, barrierDismissible: true,
builder: (context) { builder: (context) {
return StackDialog( return StackDialog(
title: "Transaction failed", title: "Transaction failed",
message: e.toString(), message: e.toString(),
rightButton: TextButton( rightButton: TextButton(
style: Theme.of(context) style: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.getSecondaryEnabledButtonStyle(context), .getSecondaryEnabledButtonStyle(context),
child: Text( child: Text(
"Ok", "Ok",
style: STextStyles.button(context).copyWith( style: STextStyles.button(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.buttonTextSecondary, .buttonTextSecondary,
),
), ),
onPressed: () {
Navigator.of(context).pop();
},
), ),
onPressed: () { );
Navigator.of(context).pop(); },
}, );
), }
);
},
);
// }
} }
} }
@ -420,7 +422,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
final wallet = ref.watch(pWallets).getWallet(walletId); final wallet = ref.watch(pWallets).getWallet(walletId);
final locale = ref.watch( final locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale)); localeServiceChangeNotifierProvider.select((value) => value.locale),
);
final coin = ref.watch(pWalletCoin(walletId)); final coin = ref.watch(pWalletCoin(walletId));
@ -483,9 +486,11 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
Text( Text(
ref.watch(pAmountFormatter(coin)).format(ref ref.watch(pAmountFormatter(coin)).format(
.watch(pWalletBalanceTertiary(walletId)) ref
.spendable), .watch(pWalletBalanceTertiary(walletId))
.spendable,
),
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ],
@ -637,7 +642,8 @@ class _SendFromCardState extends ConsumerState<SendFromCard> {
if (!isFiro) if (!isFiro)
Text( Text(
ref.watch(pAmountFormatter(coin)).format( ref.watch(pAmountFormatter(coin)).format(
ref.watch(pWalletBalance(walletId)).spendable), ref.watch(pWalletBalance(walletId)).spendable,
),
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ],

View file

@ -154,8 +154,10 @@ class _SendViewState extends ConsumerState<SendView> {
// .state = true, // .state = true,
// ); // );
Logging.instance.log("qrResult content: ${qrResult.rawContent}", Logging.instance.log(
level: LogLevel.Info); "qrResult content: ${qrResult.rawContent}",
level: LogLevel.Info,
);
final results = AddressUtils.parseUri(qrResult.rawContent); final results = AddressUtils.parseUri(qrResult.rawContent);
@ -213,8 +215,9 @@ class _SendViewState extends ConsumerState<SendView> {
// here we ignore the exception caused by not giving permission // here we ignore the exception caused by not giving permission
// to use the camera to scan a qr code // to use the camera to scan a qr code
Logging.instance.log( Logging.instance.log(
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
level: LogLevel.Warning); level: LogLevel.Warning,
);
} }
} }
@ -280,8 +283,10 @@ class _SendViewState extends ConsumerState<SendView> {
return; return;
} }
_cachedAmountToSend = amount; _cachedAmountToSend = amount;
Logging.instance.log("it changed $amount $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $amount $_cachedAmountToSend",
level: LogLevel.Info,
);
final price = final price =
ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1; ref.read(priceAnd24hChangeNotifierProvider).getPrice(coin).item1;
@ -572,9 +577,10 @@ class _SendViewState extends ConsumerState<SendView> {
child: Text( child: Text(
"Cancel", "Cancel",
style: STextStyles.button(context).copyWith( style: STextStyles.button(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
onPressed: () { onPressed: () {
Navigator.of(context).pop(false); Navigator.of(context).pop(false);
@ -616,6 +622,9 @@ class _SendViewState extends ConsumerState<SendView> {
builder: (context) { builder: (context) {
return BuildingTransactionDialog( return BuildingTransactionDialog(
coin: wallet.info.coin, coin: wallet.info.coin,
isSpark: wallet is FiroWallet &&
ref.read(publicPrivateBalanceStateProvider.state).state ==
FiroType.spark,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
@ -645,7 +654,7 @@ class _SendViewState extends ConsumerState<SendView> {
address: widget.accountLite!.code, address: widget.accountLite!.code,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
feeRateType: feeRate, feeRateType: feeRate,
@ -668,7 +677,7 @@ class _SendViewState extends ConsumerState<SendView> {
amount: amount, amount: amount,
memo: memoController.text, memo: memoController.text,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
@ -687,7 +696,7 @@ class _SendViewState extends ConsumerState<SendView> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
@ -709,7 +718,7 @@ class _SendViewState extends ConsumerState<SendView> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
), ),
); );
@ -725,7 +734,7 @@ class _SendViewState extends ConsumerState<SendView> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
sparkRecipients: ref.read(pValidSparkSendToAddress) sparkRecipients: ref.read(pValidSparkSendToAddress)
? [ ? [
@ -734,7 +743,7 @@ class _SendViewState extends ConsumerState<SendView> {
amount: amount, amount: amount,
memo: memoController.text, memo: memoController.text,
isChange: false, isChange: false,
) ),
] ]
: null, : null,
), ),
@ -752,7 +761,7 @@ class _SendViewState extends ConsumerState<SendView> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
memo: memo, memo: memo,
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
@ -827,9 +836,10 @@ class _SendViewState extends ConsumerState<SendView> {
child: Text( child: Text(
"Ok", "Ok",
style: STextStyles.button(context).copyWith( style: STextStyles.button(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
@ -981,7 +991,8 @@ class _SendViewState extends ConsumerState<SendView> {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final wallet = ref.watch(pWallets).getWallet(walletId); final wallet = ref.watch(pWallets).getWallet(walletId);
final String locale = ref.watch( final String locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale)); localeServiceChangeNotifierProvider.select((value) => value.locale),
);
final showCoinControl = wallet is CoinControlInterface && final showCoinControl = wallet is CoinControlInterface &&
ref.watch( ref.watch(
@ -1033,7 +1044,7 @@ class _SendViewState extends ConsumerState<SendView> {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 50)); await Future<void>.delayed(const Duration(milliseconds: 50));
} }
if (mounted) { if (context.mounted) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
}, },
@ -1118,82 +1129,93 @@ class _SendViewState extends ConsumerState<SendView> {
], ],
), ),
const Spacer(), const Spacer(),
Builder(builder: (context) { Builder(
final Amount amount; builder: (context) {
if (isFiro) { final Amount amount;
switch (ref if (isFiro) {
.watch( switch (ref
.watch(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
.state) {
case FiroType.public:
amount = ref
.read(pWalletBalance(walletId))
.spendable;
break;
case FiroType.lelantus:
amount = ref
.read(pWalletBalanceSecondary(
walletId))
.spendable;
break;
case FiroType.spark:
amount = ref
.read(pWalletBalanceTertiary(
walletId))
.spendable;
break;
}
} else {
amount = ref
.read(pWalletBalance(walletId))
.spendable;
}
return GestureDetector(
onTap: () {
cryptoAmountController.text = ref
.read(pAmountFormatter(coin))
.format(
amount,
withUnitName: false,
);
},
child: Container(
color: Colors.transparent,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
ref
.watch(pAmountFormatter(coin))
.format(amount),
style: STextStyles.titleBold12(
context)
.copyWith(
fontSize: 10,
),
textAlign: TextAlign.right,
),
Text(
"${(amount.decimal * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1))).toAmount(
fractionDigits: 2,
).fiatString(
locale: locale,
)} ${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}",
style:
STextStyles.subtitle(context)
.copyWith(
fontSize: 8,
),
textAlign: TextAlign.right,
) )
], .state) {
case FiroType.public:
amount = ref
.read(pWalletBalance(walletId))
.spendable;
break;
case FiroType.lelantus:
amount = ref
.read(
pWalletBalanceSecondary(
walletId,
),
)
.spendable;
break;
case FiroType.spark:
amount = ref
.read(
pWalletBalanceTertiary(
walletId,
),
)
.spendable;
break;
}
} else {
amount = ref
.read(pWalletBalance(walletId))
.spendable;
}
return GestureDetector(
onTap: () {
cryptoAmountController.text = ref
.read(pAmountFormatter(coin))
.format(
amount,
withUnitName: false,
);
},
child: Container(
color: Colors.transparent,
child: Column(
crossAxisAlignment:
CrossAxisAlignment.end,
children: [
Text(
ref
.watch(
pAmountFormatter(coin),
)
.format(amount),
style: STextStyles.titleBold12(
context,
).copyWith(
fontSize: 10,
),
textAlign: TextAlign.right,
),
Text(
"${(amount.decimal * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getPrice(coin).item1))).toAmount(
fractionDigits: 2,
).fiatString(
locale: locale,
)} ${ref.watch(prefsChangeNotifierProvider.select((value) => value.currency))}",
style: STextStyles.subtitle(
context,
).copyWith(
fontSize: 8,
),
textAlign: TextAlign.right,
),
],
),
), ),
), );
); },
}), ),
], ],
), ),
), ),
@ -1295,12 +1317,14 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Clear Button. Clears The Address Field Input.", "Clear Button. Clears The Address Field Input.",
key: const Key( key: const Key(
"sendViewClearAddressFieldButtonKey"), "sendViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
sendToController.text = ""; sendToController.text = "";
_address = ""; _address = "";
_setValidAddressProviders( _setValidAddressProviders(
_address); _address,
);
setState(() { setState(() {
_addressToggleFlag = _addressToggleFlag =
false; false;
@ -1312,12 +1336,13 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Paste Button. Pastes From Clipboard To Address Field Input.", "Paste Button. Pastes From Clipboard To Address Field Input.",
key: const Key( key: const Key(
"sendViewPasteAddressFieldButtonKey"), "sendViewPasteAddressFieldButtonKey",
),
onTap: () async { onTap: () async {
final ClipboardData? data = final ClipboardData? data =
await clipboard.getData( await clipboard.getData(
Clipboard Clipboard.kTextPlain,
.kTextPlain); );
if (data?.text != null && if (data?.text != null &&
data! data!
.text!.isNotEmpty) { .text!.isNotEmpty) {
@ -1327,23 +1352,27 @@ class _SendViewState extends ConsumerState<SendView> {
.contains("\n")) { .contains("\n")) {
content = content =
content.substring( content.substring(
0, 0,
content.indexOf( content.indexOf(
"\n")); "\n",
),
);
} }
if (coin == if (coin ==
Coin.epicCash) { Coin.epicCash) {
// strip http:// and https:// if content contains @ // strip http:// and https:// if content contains @
content = formatAddress( content = formatAddress(
content); content,
);
} }
sendToController.text = sendToController.text =
content.trim(); content.trim();
_address = content.trim(); _address = content.trim();
_setValidAddressProviders( _setValidAddressProviders(
_address); _address,
);
setState(() { setState(() {
_addressToggleFlag = _addressToggleFlag =
sendToController sendToController
@ -1362,7 +1391,8 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Address Book Button. Opens Address Book For Address Field.", "Address Book Button. Opens Address Book For Address Field.",
key: const Key( key: const Key(
"sendViewAddressBookButtonKey"), "sendViewAddressBookButtonKey",
),
onTap: () { onTap: () {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
AddressBookView.routeName, AddressBookView.routeName,
@ -1376,7 +1406,8 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Scan QR Button. Opens Camera For Scanning QR Code.", "Scan QR Button. Opens Camera For Scanning QR Code.",
key: const Key( key: const Key(
"sendViewScanQrButtonKey"), "sendViewScanQrButtonKey",
),
onTap: _scanQr, onTap: _scanQr,
child: const QrCodeIcon(), child: const QrCodeIcon(),
), ),
@ -1393,7 +1424,8 @@ class _SendViewState extends ConsumerState<SendView> {
if (isStellar || if (isStellar ||
(ref.watch(pValidSparkSendToAddress) && (ref.watch(pValidSparkSendToAddress) &&
ref.watch( ref.watch(
publicPrivateBalanceStateProvider) != publicPrivateBalanceStateProvider,
) !=
FiroType.lelantus)) FiroType.lelantus))
ClipRRect( ClipRRect(
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
@ -1440,7 +1472,8 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Clear Button. Clears The Memo Field Input.", "Clear Button. Clears The Memo Field Input.",
key: const Key( key: const Key(
"sendViewClearMemoFieldButtonKey"), "sendViewClearMemoFieldButtonKey",
),
onTap: () { onTap: () {
memoController.text = ""; memoController.text = "";
setState(() {}); setState(() {});
@ -1451,16 +1484,17 @@ class _SendViewState extends ConsumerState<SendView> {
semanticsLabel: semanticsLabel:
"Paste Button. Pastes From Clipboard To Memo Field Input.", "Paste Button. Pastes From Clipboard To Memo Field Input.",
key: const Key( key: const Key(
"sendViewPasteMemoFieldButtonKey"), "sendViewPasteMemoFieldButtonKey",
),
onTap: () async { onTap: () async {
final ClipboardData? data = final ClipboardData? data =
await clipboard.getData( await clipboard.getData(
Clipboard Clipboard.kTextPlain,
.kTextPlain); );
if (data?.text != null && if (data?.text != null &&
data! data!
.text!.isNotEmpty) { .text!.isNotEmpty) {
String content = final String content =
data.text!.trim(); data.text!.trim();
memoController.text = memoController.text =
@ -1486,13 +1520,15 @@ class _SendViewState extends ConsumerState<SendView> {
error = null; error = null;
} else if (isFiro) { } else if (isFiro) {
if (ref.watch( if (ref.watch(
publicPrivateBalanceStateProvider) == publicPrivateBalanceStateProvider,
) ==
FiroType.lelantus) { FiroType.lelantus) {
if (_data != null && if (_data != null &&
_data!.contactLabel == _address) { _data!.contactLabel == _address) {
error = SparkInterface.validateSparkAddress( error = SparkInterface.validateSparkAddress(
address: _data!.address, address: _data!.address,
isTestNet: coin.isTestNet) isTestNet: coin.isTestNet,
)
? "Unsupported" ? "Unsupported"
: null; : null;
} else if (ref } else if (ref
@ -1611,51 +1647,65 @@ class _SendViewState extends ConsumerState<SendView> {
Text( Text(
"${ref.watch(publicPrivateBalanceStateProvider.state).state.name.capitalize()} balance", "${ref.watch(publicPrivateBalanceStateProvider.state).state.name.capitalize()} balance",
style: STextStyles.itemSubtitle12( style: STextStyles.itemSubtitle12(
context), context,
),
), ),
const SizedBox( const SizedBox(
width: 10, width: 10,
), ),
Builder(builder: (_) { Builder(
final Amount amount; builder: (_) {
switch (ref final Amount amount;
.read( switch (ref
.read(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
.state) { )
case FiroType.public: .state) {
amount = ref case FiroType.public:
.watch(pWalletBalance( amount = ref
walletId)) .watch(
.spendable; pWalletBalance(
break; walletId,
case FiroType.lelantus: ),
amount = ref )
.watch( .spendable;
break;
case FiroType.lelantus:
amount = ref
.watch(
pWalletBalanceSecondary( pWalletBalanceSecondary(
walletId)) walletId,
.spendable; ),
break; )
case FiroType.spark: .spendable;
amount = ref break;
.watch( case FiroType.spark:
amount = ref
.watch(
pWalletBalanceTertiary( pWalletBalanceTertiary(
walletId)) walletId,
.spendable; ),
break; )
} .spendable;
break;
}
return Text( return Text(
ref ref
.watch( .watch(
pAmountFormatter(coin)) pAmountFormatter(coin),
.format( )
amount, .format(
), amount,
style: STextStyles.itemSubtitle( ),
context), style:
); STextStyles.itemSubtitle(
}), context,
),
);
},
),
], ],
), ),
SvgPicture.asset( SvgPicture.asset(
@ -1669,7 +1719,7 @@ class _SendViewState extends ConsumerState<SendView> {
], ],
), ),
), ),
) ),
], ],
), ),
const SizedBox( const SizedBox(
@ -1691,8 +1741,9 @@ class _SendViewState extends ConsumerState<SendView> {
final Amount amount; final Amount amount;
switch (ref switch (ref
.read( .read(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state) { .state) {
case FiroType.public: case FiroType.public:
amount = ref amount = ref
@ -1701,14 +1752,20 @@ class _SendViewState extends ConsumerState<SendView> {
break; break;
case FiroType.lelantus: case FiroType.lelantus:
amount = ref amount = ref
.read(pWalletBalanceSecondary( .read(
walletId)) pWalletBalanceSecondary(
walletId,
),
)
.spendable; .spendable;
break; break;
case FiroType.spark: case FiroType.spark:
amount = ref amount = ref
.read(pWalletBalanceTertiary( .read(
walletId)) pWalletBalanceTertiary(
walletId,
),
)
.spendable; .spendable;
break; break;
} }
@ -1793,9 +1850,10 @@ class _SendViewState extends ConsumerState<SendView> {
.unitForCoin(coin), .unitForCoin(coin),
style: STextStyles.smallMed14(context) style: STextStyles.smallMed14(context)
.copyWith( .copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1855,13 +1913,16 @@ class _SendViewState extends ConsumerState<SendView> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Text( child: Text(
ref.watch(prefsChangeNotifierProvider ref.watch(
.select((value) => value.currency)), prefsChangeNotifierProvider
.select((value) => value.currency),
),
style: STextStyles.smallMed14(context) style: STextStyles.smallMed14(context)
.copyWith( .copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1898,7 +1959,7 @@ class _SendViewState extends ConsumerState<SendView> {
); );
} }
if (mounted) { if (context.mounted) {
final spendable = ref final spendable = ref
.read(pWalletBalance(walletId)) .read(pWalletBalance(walletId))
.spendable; .spendable;
@ -2096,8 +2157,9 @@ class _SendViewState extends ConsumerState<SendView> {
onPressed: isFiro && onPressed: isFiro &&
ref ref
.watch( .watch(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state != .state !=
FiroType.public FiroType.public
? null ? null
@ -2117,8 +2179,9 @@ class _SendViewState extends ConsumerState<SendView> {
TransactionFeeSelectionSheet( TransactionFeeSelectionSheet(
walletId: walletId, walletId: walletId,
amount: (Decimal.tryParse( amount: (Decimal.tryParse(
cryptoAmountController cryptoAmountController
.text) ?? .text,
) ??
ref ref
.watch(pSendAmount) .watch(pSendAmount)
?.decimal ?? ?.decimal ??
@ -2154,8 +2217,9 @@ class _SendViewState extends ConsumerState<SendView> {
child: (isFiro && child: (isFiro &&
ref ref
.watch( .watch(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state != .state !=
FiroType.public) FiroType.public)
? Row( ? Row(
@ -2175,7 +2239,8 @@ class _SendViewState extends ConsumerState<SendView> {
"~${snapshot.data!}", "~${snapshot.data!}",
style: STextStyles style: STextStyles
.itemSubtitle( .itemSubtitle(
context), context,
),
); );
} else { } else {
return AnimatedText( return AnimatedText(
@ -2187,7 +2252,8 @@ class _SendViewState extends ConsumerState<SendView> {
], ],
style: STextStyles style: STextStyles
.itemSubtitle( .itemSubtitle(
context), context,
),
); );
} }
}, },
@ -2203,13 +2269,15 @@ class _SendViewState extends ConsumerState<SendView> {
Text( Text(
ref ref
.watch( .watch(
feeRateTypeStateProvider feeRateTypeStateProvider
.state) .state,
)
.state .state
.prettyName, .prettyName,
style: STextStyles style: STextStyles
.itemSubtitle12( .itemSubtitle12(
context), context,
),
), ),
const SizedBox( const SizedBox(
width: 10, width: 10,
@ -2233,7 +2301,8 @@ class _SendViewState extends ConsumerState<SendView> {
: "~${snapshot.data!}", : "~${snapshot.data!}",
style: STextStyles style: STextStyles
.itemSubtitle( .itemSubtitle(
context), context,
),
); );
} else { } else {
return AnimatedText( return AnimatedText(
@ -2245,7 +2314,8 @@ class _SendViewState extends ConsumerState<SendView> {
], ],
style: STextStyles style: STextStyles
.itemSubtitle( .itemSubtitle(
context), context,
),
); );
} }
}, },
@ -2263,7 +2333,7 @@ class _SendViewState extends ConsumerState<SendView> {
], ],
), ),
), ),
) ),
], ],
), ),
if (isCustomFee) if (isCustomFee)

View file

@ -12,8 +12,8 @@ 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:stackwallet/themes/stack_colors.dart';
import 'package:stackwallet/themes/coin_image_provider.dart'; import 'package:stackwallet/themes/coin_image_provider.dart';
import 'package:stackwallet/themes/stack_colors.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/util.dart'; import 'package:stackwallet/utilities/util.dart';
@ -23,13 +23,15 @@ import 'package:stackwallet/widgets/stack_dialog.dart';
class BuildingTransactionDialog extends ConsumerStatefulWidget { class BuildingTransactionDialog extends ConsumerStatefulWidget {
const BuildingTransactionDialog({ const BuildingTransactionDialog({
Key? key, super.key,
required this.onCancel, required this.onCancel,
required this.coin, required this.coin,
}) : super(key: key); required this.isSpark,
});
final VoidCallback onCancel; final VoidCallback onCancel;
final Coin coin; final Coin coin;
final bool isSpark;
@override @override
ConsumerState<BuildingTransactionDialog> createState() => ConsumerState<BuildingTransactionDialog> createState() =>
@ -62,13 +64,24 @@ class _RestoringDialogState extends ConsumerState<BuildingTransactionDialog> {
"Generating transaction", "Generating transaction",
style: STextStyles.desktopH3(context), style: STextStyles.desktopH3(context),
), ),
if (widget.isSpark)
const SizedBox(
height: 16,
),
if (widget.isSpark)
Text(
"This may take a few minutes...",
style: STextStyles.desktopSubtitleH2(context),
),
const SizedBox( const SizedBox(
height: 40, height: 40,
), ),
assetPath.endsWith(".gif") assetPath.endsWith(".gif")
? Image.file(File( ? Image.file(
assetPath, File(
)) assetPath,
),
)
: const RotatingArrows( : const RotatingArrows(
width: 40, width: 40,
height: 40, height: 40,
@ -82,7 +95,7 @@ class _RestoringDialogState extends ConsumerState<BuildingTransactionDialog> {
onPressed: () { onPressed: () {
onCancel.call(); onCancel.call();
}, },
) ),
], ],
); );
} else { } else {
@ -96,14 +109,26 @@ class _RestoringDialogState extends ConsumerState<BuildingTransactionDialog> {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Image.file(File( Image.file(
assetPath, File(
)), assetPath,
),
),
Text( Text(
"Generating transaction", "Generating transaction",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: STextStyles.pageTitleH2(context), style: STextStyles.pageTitleH2(context),
), ),
if (widget.isSpark)
const SizedBox(
height: 12,
),
if (widget.isSpark)
Text(
"This may take a few minutes...",
textAlign: TextAlign.center,
style: STextStyles.w500_16(context),
),
const SizedBox( const SizedBox(
height: 32, height: 32,
), ),
@ -124,7 +149,7 @@ class _RestoringDialogState extends ConsumerState<BuildingTransactionDialog> {
onCancel.call(); onCancel.call();
}, },
), ),
) ),
], ],
), ),
], ],
@ -132,6 +157,8 @@ class _RestoringDialogState extends ConsumerState<BuildingTransactionDialog> {
) )
: StackDialog( : StackDialog(
title: "Generating transaction", title: "Generating transaction",
message:
widget.isSpark ? "This may take a few minutes..." : null,
icon: const RotatingArrows( icon: const RotatingArrows(
width: 24, width: 24,
height: 24, height: 24,

View file

@ -58,14 +58,14 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
class TokenSendView extends ConsumerStatefulWidget { class TokenSendView extends ConsumerStatefulWidget {
const TokenSendView({ const TokenSendView({
Key? key, super.key,
required this.walletId, required this.walletId,
required this.coin, required this.coin,
required this.tokenContract, required this.tokenContract,
this.autoFillData, this.autoFillData,
this.clipboard = const ClipboardWrapper(), this.clipboard = const ClipboardWrapper(),
this.barcodeScanner = const BarcodeScannerWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(),
}) : super(key: key); });
static const String routeName = "/tokenSendView"; static const String routeName = "/tokenSendView";
@ -156,8 +156,10 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
// .state = true, // .state = true,
// ); // );
Logging.instance.log("qrResult content: ${qrResult.rawContent}", Logging.instance.log(
level: LogLevel.Info); "qrResult content: ${qrResult.rawContent}",
level: LogLevel.Info,
);
final results = AddressUtils.parseUri(qrResult.rawContent); final results = AddressUtils.parseUri(qrResult.rawContent);
@ -216,8 +218,9 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
// here we ignore the exception caused by not giving permission // here we ignore the exception caused by not giving permission
// to use the camera to scan a qr code // to use the camera to scan a qr code
Logging.instance.log( Logging.instance.log(
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
level: LogLevel.Warning); level: LogLevel.Warning,
);
} }
} }
@ -239,15 +242,19 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
? Amount.zero ? Amount.zero
: Amount.fromDecimal( : Amount.fromDecimal(
(baseAmount.decimal / _price).toDecimal( (baseAmount.decimal / _price).toDecimal(
scaleOnInfinitePrecision: tokenContract.decimals), scaleOnInfinitePrecision: tokenContract.decimals,
fractionDigits: tokenContract.decimals); ),
fractionDigits: tokenContract.decimals,
);
} }
if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) { if (_cachedAmountToSend != null && _cachedAmountToSend == _amountToSend) {
return; return;
} }
_cachedAmountToSend = _amountToSend; _cachedAmountToSend = _amountToSend;
Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $_amountToSend $_cachedAmountToSend",
level: LogLevel.Info,
);
_cryptoAmountChangeLock = true; _cryptoAmountChangeLock = true;
cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format( cryptoAmountController.text = ref.read(pAmountFormatter(coin)).format(
@ -282,8 +289,10 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
return; return;
} }
_cachedAmountToSend = _amountToSend; _cachedAmountToSend = _amountToSend;
Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $_amountToSend $_cachedAmountToSend",
level: LogLevel.Info,
);
final price = ref final price = ref
.read(priceAnd24hChangeNotifierProvider) .read(priceAnd24hChangeNotifierProvider)
@ -457,6 +466,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
builder: (context) { builder: (context) {
return BuildingTransactionDialog( return BuildingTransactionDialog(
coin: wallet.info.coin, coin: wallet.info.coin,
isSpark: false,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
@ -484,7 +494,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
note: noteController.text, note: noteController.text,
@ -502,20 +512,22 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
// pop building dialog // pop building dialog
Navigator.of(context).pop(); Navigator.of(context).pop();
unawaited(Navigator.of(context).push( unawaited(
RouteGenerator.getRoute( Navigator.of(context).push(
shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute, RouteGenerator.getRoute(
builder: (_) => ConfirmTransactionView( shouldUseMaterialRoute: RouteGenerator.useMaterialPageRoute,
txData: txData, builder: (_) => ConfirmTransactionView(
walletId: walletId, txData: txData,
isTokenTx: true, walletId: walletId,
onSuccess: clearSendForm, isTokenTx: true,
), onSuccess: clearSendForm,
settings: const RouteSettings( ),
name: ConfirmTransactionView.routeName, settings: const RouteSettings(
name: ConfirmTransactionView.routeName,
),
), ),
), ),
)); );
} }
} catch (e) { } catch (e) {
if (mounted) { if (mounted) {
@ -538,9 +550,10 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
child: Text( child: Text(
"Ok", "Ok",
style: STextStyles.button(context).copyWith( style: STextStyles.button(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
onPressed: () { onPressed: () {
Navigator.of(context).pop(); Navigator.of(context).pop();
@ -626,7 +639,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final String locale = ref.watch( final String locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale)); localeServiceChangeNotifierProvider.select((value) => value.locale),
);
return Background( return Background(
child: Scaffold( child: Scaffold(
@ -638,7 +652,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
await Future<void>.delayed(const Duration(milliseconds: 50)); await Future<void>.delayed(const Duration(milliseconds: 50));
} }
if (mounted) { if (context.mounted) {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
}, },
@ -712,11 +726,15 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
.watch(pAmountFormatter(coin)) .watch(pAmountFormatter(coin))
.format( .format(
ref ref
.read(pTokenBalance(( .read(
walletId: widget.walletId, pTokenBalance(
contractAddress: (
tokenContract.address, walletId: widget.walletId,
))) contractAddress:
tokenContract.address,
),
),
)
.spendable, .spendable,
ethContract: tokenContract, ethContract: tokenContract,
withUnitName: false, withUnitName: false,
@ -734,13 +752,17 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
.watch(pAmountFormatter(coin)) .watch(pAmountFormatter(coin))
.format( .format(
ref ref
.watch(pTokenBalance(( .watch(
walletId: pTokenBalance(
widget.walletId, (
contractAddress: walletId:
tokenContract widget.walletId,
.address, contractAddress:
))) tokenContract
.address,
),
),
)
.spendable, .spendable,
ethContract: tokenContract, ethContract: tokenContract,
), ),
@ -752,13 +774,17 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
textAlign: TextAlign.right, textAlign: TextAlign.right,
), ),
Text( Text(
"${(ref.watch(pTokenBalance(( "${(ref.watch(
pTokenBalance(
(
walletId: walletId:
widget.walletId, widget.walletId,
contractAddress: contractAddress:
tokenContract tokenContract
.address, .address,
))).spendable.decimal * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getTokenPrice(tokenContract.address).item1))).toAmount( ),
),
).spendable.decimal * ref.watch(priceAnd24hChangeNotifierProvider.select((value) => value.getTokenPrice(tokenContract.address).item1))).toAmount(
fractionDigits: 2, fractionDigits: 2,
).fiatString( ).fiatString(
locale: locale, locale: locale,
@ -768,7 +794,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
fontSize: 8, fontSize: 8,
), ),
textAlign: TextAlign.right, textAlign: TextAlign.right,
) ),
], ],
), ),
), ),
@ -807,7 +833,9 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
onChanged: (newValue) { onChanged: (newValue) {
_address = newValue.trim(); _address = newValue.trim();
_updatePreviewButtonState( _updatePreviewButtonState(
_address, _amountToSend); _address,
_amountToSend,
);
setState(() { setState(() {
_addressToggleFlag = newValue.isNotEmpty; _addressToggleFlag = newValue.isNotEmpty;
@ -838,12 +866,15 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
_addressToggleFlag _addressToggleFlag
? TextFieldIconButton( ? TextFieldIconButton(
key: const Key( key: const Key(
"tokenSendViewClearAddressFieldButtonKey"), "tokenSendViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
sendToController.text = ""; sendToController.text = "";
_address = ""; _address = "";
_updatePreviewButtonState( _updatePreviewButtonState(
_address, _amountToSend); _address,
_amountToSend,
);
setState(() { setState(() {
_addressToggleFlag = false; _addressToggleFlag = false;
}); });
@ -852,7 +883,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"tokenSendViewPasteAddressFieldButtonKey"), "tokenSendViewPasteAddressFieldButtonKey",
),
onTap: onTap:
_onTokenSendViewPasteAddressFieldButtonPressed, _onTokenSendViewPasteAddressFieldButtonPressed,
child: sendToController child: sendToController
@ -863,7 +895,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
if (sendToController.text.isEmpty) if (sendToController.text.isEmpty)
TextFieldIconButton( TextFieldIconButton(
key: const Key( key: const Key(
"sendViewAddressBookButtonKey"), "sendViewAddressBookButtonKey",
),
onTap: () { onTap: () {
Navigator.of(context).pushNamed( Navigator.of(context).pushNamed(
AddressBookView.routeName, AddressBookView.routeName,
@ -875,11 +908,12 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
if (sendToController.text.isEmpty) if (sendToController.text.isEmpty)
TextFieldIconButton( TextFieldIconButton(
key: const Key( key: const Key(
"sendViewScanQrButtonKey"), "sendViewScanQrButtonKey",
),
onTap: onTap:
_onTokenSendViewScanQrButtonPressed, _onTokenSendViewScanQrButtonPressed,
child: const QrCodeIcon(), child: const QrCodeIcon(),
) ),
], ],
), ),
), ),
@ -997,9 +1031,10 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
tokenContract.symbol, tokenContract.symbol,
style: STextStyles.smallMed14(context) style: STextStyles.smallMed14(context)
.copyWith( .copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1058,13 +1093,16 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Text( child: Text(
ref.watch(prefsChangeNotifierProvider ref.watch(
.select((value) => value.currency)), prefsChangeNotifierProvider
.select((value) => value.currency),
),
style: STextStyles.smallMed14(context) style: STextStyles.smallMed14(context)
.copyWith( .copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1169,8 +1207,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
walletId: walletId, walletId: walletId,
isToken: true, isToken: true,
amount: (Decimal.tryParse( amount: (Decimal.tryParse(
cryptoAmountController cryptoAmountController.text,
.text) ?? ) ??
Decimal.zero) Decimal.zero)
.toAmount( .toAmount(
fractionDigits: fractionDigits:
@ -1193,12 +1231,15 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
children: [ children: [
Text( Text(
ref ref
.watch(feeRateTypeStateProvider .watch(
.state) feeRateTypeStateProvider
.state,
)
.state .state
.prettyName, .prettyName,
style: STextStyles.itemSubtitle12( style: STextStyles.itemSubtitle12(
context), context,
),
), ),
const SizedBox( const SizedBox(
width: 10, width: 10,
@ -1213,7 +1254,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
"~${snapshot.data!}", "~${snapshot.data!}",
style: style:
STextStyles.itemSubtitle( STextStyles.itemSubtitle(
context), context,
),
); );
} else { } else {
return AnimatedText( return AnimatedText(
@ -1225,7 +1267,8 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
], ],
style: style:
STextStyles.itemSubtitle( STextStyles.itemSubtitle(
context), context,
),
); );
} }
}, },
@ -1243,7 +1286,7 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
], ],
), ),
), ),
) ),
], ],
), ),
const Spacer(), const Spacer(),
@ -1253,13 +1296,15 @@ class _TokenSendViewState extends ConsumerState<TokenSendView> {
TextButton( TextButton(
onPressed: ref onPressed: ref
.watch( .watch(
previewTokenTxButtonStateProvider.state) previewTokenTxButtonStateProvider.state,
)
.state .state
? _previewTransaction ? _previewTransaction
: null, : null,
style: ref style: ref
.watch( .watch(
previewTokenTxButtonStateProvider.state) previewTokenTxButtonStateProvider.state,
)
.state .state
? Theme.of(context) ? Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!

View file

@ -272,6 +272,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: BuildingTransactionDialog( child: BuildingTransactionDialog(
coin: wallet.info.coin, coin: wallet.info.coin,
isSpark: wallet is FiroWallet &&
ref
.read(publicPrivateBalanceStateProvider.state)
.state ==
FiroType.spark,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
@ -306,7 +311,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
address: widget.accountLite!.code, address: widget.accountLite!.code,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
feeRateType: feeRate, feeRateType: feeRate,
@ -329,7 +334,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
amount: amount, amount: amount,
memo: memoController.text, memo: memoController.text,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
@ -348,7 +353,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
satsPerVByte: isCustomFee ? customFeeRate : null, satsPerVByte: isCustomFee ? customFeeRate : null,
@ -370,7 +375,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
), ),
); );
@ -386,7 +391,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
sparkRecipients: ref.read(pValidSparkSendToAddress) sparkRecipients: ref.read(pValidSparkSendToAddress)
? [ ? [
@ -395,7 +400,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
amount: amount, amount: amount,
memo: memoController.text, memo: memoController.text,
isChange: false, isChange: false,
) ),
] ]
: null, : null,
), ),
@ -411,7 +416,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
memo: memo, memo: memo,
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
@ -577,8 +582,10 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
if (_cachedAmountToSend != null && _cachedAmountToSend == amount) { if (_cachedAmountToSend != null && _cachedAmountToSend == amount) {
return; return;
} }
Logging.instance.log("it changed $amount $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $amount $_cachedAmountToSend",
level: LogLevel.Info,
);
_cachedAmountToSend = amount; _cachedAmountToSend = amount;
final price = final price =
@ -627,8 +634,10 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
final qrResult = await scanner.scan(); final qrResult = await scanner.scan();
Logging.instance.log("qrResult content: ${qrResult.rawContent}", Logging.instance.log(
level: LogLevel.Info); "qrResult content: ${qrResult.rawContent}",
level: LogLevel.Info,
);
final results = AddressUtils.parseUri(qrResult.rawContent); final results = AddressUtils.parseUri(qrResult.rawContent);
@ -679,8 +688,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
// here we ignore the exception caused by not giving permission // here we ignore the exception caused by not giving permission
// to use the camera to scan a qr code // to use the camera to scan a qr code
Logging.instance.log( Logging.instance.log(
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
level: LogLevel.Warning); level: LogLevel.Warning,
);
} }
} }
@ -734,7 +744,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
} else { } else {
final ClipboardData? data = await clipboard.getData(Clipboard.kTextPlain); final ClipboardData? data = await clipboard.getData(Clipboard.kTextPlain);
if (data?.text != null && data!.text!.isNotEmpty) { if (data?.text != null && data!.text!.isNotEmpty) {
String content = data.text!.trim(); final String content = data.text!.trim();
setState(() { setState(() {
memoController.text = content; memoController.text = content;
@ -865,7 +875,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
if (isPaynymSend) { if (isPaynymSend) {
sendToController.text = widget.accountLite!.nymName; sendToController.text = widget.accountLite!.nymName;
WidgetsBinding.instance.addPostFrameCallback( WidgetsBinding.instance.addPostFrameCallback(
(_) => _setValidAddressProviders(sendToController.text)); (_) => _setValidAddressProviders(sendToController.text),
);
} }
_cryptoFocus.addListener(() { _cryptoFocus.addListener(() {
@ -912,7 +923,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
debugPrint("BUILD: $runtimeType"); debugPrint("BUILD: $runtimeType");
final String locale = ref.watch( final String locale = ref.watch(
localeServiceChangeNotifierProvider.select((value) => value.locale)); localeServiceChangeNotifierProvider.select((value) => value.locale),
);
// add listener for epic cash to strip http:// and https:// prefixes if the address also ocntains an @ symbol (indicating an epicbox address) // add listener for epic cash to strip http:// and https:// prefixes if the address also ocntains an @ symbol (indicating an epicbox address)
if (coin == Coin.epicCash) { if (coin == Coin.epicCash) {
@ -975,9 +987,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
width: 10, width: 10,
), ),
Text( Text(
ref.watch(pAmountFormatter(coin)).format(ref ref.watch(pAmountFormatter(coin)).format(
.watch(pWalletBalanceTertiary(walletId)) ref
.spendable), .watch(pWalletBalanceTertiary(walletId))
.spendable,
),
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ],
@ -995,9 +1009,11 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
width: 10, width: 10,
), ),
Text( Text(
ref.watch(pAmountFormatter(coin)).format(ref ref.watch(pAmountFormatter(coin)).format(
.watch(pWalletBalanceSecondary(walletId)) ref
.spendable), .watch(pWalletBalanceSecondary(walletId))
.spendable,
),
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ],
@ -1016,7 +1032,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
), ),
Text( Text(
ref.watch(pAmountFormatter(coin)).format( ref.watch(pAmountFormatter(coin)).format(
ref.watch(pWalletBalance(walletId)).spendable), ref.watch(pWalletBalance(walletId)).spendable,
),
style: STextStyles.itemSubtitle(context), style: STextStyles.itemSubtitle(context),
), ),
], ],
@ -1164,9 +1181,10 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
child: Text( child: Text(
ref.watch(pAmountUnit(coin)).unitForCoin(coin), ref.watch(pAmountUnit(coin)).unitForCoin(coin),
style: STextStyles.smallMed14(context).copyWith( style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1223,12 +1241,15 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Text( child: Text(
ref.watch(prefsChangeNotifierProvider ref.watch(
.select((value) => value.currency)), prefsChangeNotifierProvider
.select((value) => value.currency),
),
style: STextStyles.smallMed14(context).copyWith( style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -1337,7 +1358,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
_addressToggleFlag _addressToggleFlag
? TextFieldIconButton( ? TextFieldIconButton(
key: const Key( key: const Key(
"sendViewClearAddressFieldButtonKey"), "sendViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
sendToController.text = ""; sendToController.text = "";
_address = ""; _address = "";
@ -1350,7 +1372,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"sendViewPasteAddressFieldButtonKey"), "sendViewPasteAddressFieldButtonKey",
),
onTap: pasteAddress, onTap: pasteAddress,
child: sendToController.text.isEmpty child: sendToController.text.isEmpty
? const ClipboardIcon() ? const ClipboardIcon()
@ -1380,7 +1403,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
child: Text( child: Text(
"Address book", "Address book",
style: STextStyles.desktopH3( style: STextStyles.desktopH3(
context), context,
),
), ),
), ),
const DesktopDialogCloseButton(), const DesktopDialogCloseButton(),
@ -1436,7 +1460,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
FiroType.lelantus) { FiroType.lelantus) {
if (_data != null && _data!.contactLabel == _address) { if (_data != null && _data!.contactLabel == _address) {
error = SparkInterface.validateSparkAddress( error = SparkInterface.validateSparkAddress(
address: _data!.address, isTestNet: coin.isTestNet) address: _data!.address,
isTestNet: coin.isTestNet,
)
? "Lelantus to Spark not supported" ? "Lelantus to Spark not supported"
: null; : null;
} else if (ref.watch(pValidSparkSendToAddress)) { } else if (ref.watch(pValidSparkSendToAddress)) {
@ -1662,8 +1688,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
if (coin == Coin.monero || if (coin == Coin.monero ||
coin == Coin.wownero) { coin == Coin.wownero) {
final fee = await wallet.estimateFeeFor( final fee = await wallet.estimateFeeFor(
amount, amount,
MoneroTransactionPriority.regular.raw!); MoneroTransactionPriority.regular.raw!,
);
ref ref
.read(feeSheetSessionCacheProvider) .read(feeSheetSessionCacheProvider)
.average[amount] = fee; .average[amount] = fee;
@ -1671,16 +1698,18 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
coin == Coin.firoTestNet) && coin == Coin.firoTestNet) &&
ref ref
.read( .read(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state != .state !=
FiroType.public) { FiroType.public) {
final firoWallet = wallet as FiroWallet; final firoWallet = wallet as FiroWallet;
if (ref if (ref
.read( .read(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state == .state ==
FiroType.lelantus) { FiroType.lelantus) {
ref ref
@ -1690,8 +1719,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
.estimateFeeForLelantus(amount); .estimateFeeForLelantus(amount);
} else if (ref } else if (ref
.read( .read(
publicPrivateBalanceStateProvider publicPrivateBalanceStateProvider
.state) .state,
)
.state == .state ==
FiroType.spark) { FiroType.spark) {
ref ref
@ -1705,7 +1735,9 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
.read(feeSheetSessionCacheProvider) .read(feeSheetSessionCacheProvider)
.average[amount] = .average[amount] =
await wallet.estimateFeeFor( await wallet.estimateFeeFor(
amount, feeRate); amount,
feeRate,
);
} }
} }
return ref return ref
@ -1720,8 +1752,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
AnimatedText( AnimatedText(
stringsToLoopThrough: stringsToLoopThrough, stringsToLoopThrough: stringsToLoopThrough,
style: STextStyles.desktopTextExtraExtraSmall( style: STextStyles.desktopTextExtraExtraSmall(
context) context,
.copyWith( ).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.textFieldActiveText, .textFieldActiveText,
@ -1735,7 +1767,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
: (coin == Coin.firo || coin == Coin.firoTestNet) && : (coin == Coin.firo || coin == Coin.firoTestNet) &&
ref ref
.watch( .watch(
publicPrivateBalanceStateProvider.state) publicPrivateBalanceStateProvider.state,
)
.state == .state ==
FiroType.lelantus FiroType.lelantus
? Text( ? Text(
@ -1760,8 +1793,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
Text( Text(
feeSelectionResult?.$2 ?? "", feeSelectionResult?.$2 ?? "",
style: STextStyles.desktopTextExtraExtraSmall( style: STextStyles.desktopTextExtraExtraSmall(
context) context,
.copyWith( ).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.textFieldActiveText, .textFieldActiveText,
@ -1771,8 +1804,8 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
Text( Text(
feeSelectionResult?.$3 ?? "", feeSelectionResult?.$3 ?? "",
style: STextStyles.desktopTextExtraExtraSmall( style: STextStyles.desktopTextExtraExtraSmall(
context) context,
.copyWith( ).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.textFieldActiveSearchIconRight, .textFieldActiveSearchIconRight,
@ -1803,7 +1836,7 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
enabled: ref.watch(pPreviewTxButtonEnabled(coin)), enabled: ref.watch(pPreviewTxButtonEnabled(coin)),
onPressed: onPressed:
ref.watch(pPreviewTxButtonEnabled(coin)) ? previewSend : null, ref.watch(pPreviewTxButtonEnabled(coin)) ? previewSend : null,
) ),
], ],
); );
} }

View file

@ -56,13 +56,13 @@ import 'package:stackwallet/widgets/textfield_icon_button.dart';
class DesktopTokenSend extends ConsumerStatefulWidget { class DesktopTokenSend extends ConsumerStatefulWidget {
const DesktopTokenSend({ const DesktopTokenSend({
Key? key, super.key,
required this.walletId, required this.walletId,
this.autoFillData, this.autoFillData,
this.clipboard = const ClipboardWrapper(), this.clipboard = const ClipboardWrapper(),
this.barcodeScanner = const BarcodeScannerWrapper(), this.barcodeScanner = const BarcodeScannerWrapper(),
this.accountLite, this.accountLite,
}) : super(key: key); });
final String walletId; final String walletId;
final SendViewAutoFillData? autoFillData; final SendViewAutoFillData? autoFillData;
@ -108,10 +108,14 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
final Amount amount = _amountToSend!; final Amount amount = _amountToSend!;
final Amount availableBalance = ref final Amount availableBalance = ref
.read(pTokenBalance(( .read(
walletId: walletId, pTokenBalance(
contractAddress: tokenWallet.tokenContract.address (
))) walletId: walletId,
contractAddress: tokenWallet.tokenContract.address
),
),
)
.spendable; .spendable;
// confirm send all // confirm send all
@ -221,6 +225,7 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
padding: const EdgeInsets.all(32), padding: const EdgeInsets.all(32),
child: BuildingTransactionDialog( child: BuildingTransactionDialog(
coin: tokenWallet.cryptoCurrency.coin, coin: tokenWallet.cryptoCurrency.coin,
isSpark: false,
onCancel: () { onCancel: () {
wasCancelled = true; wasCancelled = true;
@ -250,7 +255,7 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
address: _address!, address: _address!,
amount: amount, amount: amount,
isChange: false, isChange: false,
) ),
], ],
feeRateType: ref.read(feeRateTypeStateProvider), feeRateType: ref.read(feeRateTypeStateProvider),
nonce: int.tryParse(nonceController.text), nonce: int.tryParse(nonceController.text),
@ -405,8 +410,10 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
_cachedAmountToSend == _amountToSend) { _cachedAmountToSend == _amountToSend) {
return; return;
} }
Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $_amountToSend $_cachedAmountToSend",
level: LogLevel.Info,
);
_cachedAmountToSend = _amountToSend; _cachedAmountToSend = _amountToSend;
final price = ref final price = ref
@ -468,8 +475,10 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
final qrResult = await scanner.scan(); final qrResult = await scanner.scan();
Logging.instance.log("qrResult content: ${qrResult.rawContent}", Logging.instance.log(
level: LogLevel.Info); "qrResult content: ${qrResult.rawContent}",
level: LogLevel.Info,
);
final results = AddressUtils.parseUri(qrResult.rawContent); final results = AddressUtils.parseUri(qrResult.rawContent);
@ -524,8 +533,9 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
// here we ignore the exception caused by not giving permission // here we ignore the exception caused by not giving permission
// to use the camera to scan a qr code // to use the camera to scan a qr code
Logging.instance.log( Logging.instance.log(
"Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s", "Failed to get camera permissions while trying to scan qr code in SendView: $e\n$s",
level: LogLevel.Warning); level: LogLevel.Warning,
);
} }
} }
@ -579,8 +589,10 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
return; return;
} }
_cachedAmountToSend = _amountToSend; _cachedAmountToSend = _amountToSend;
Logging.instance.log("it changed $_amountToSend $_cachedAmountToSend", Logging.instance.log(
level: LogLevel.Info); "it changed $_amountToSend $_cachedAmountToSend",
level: LogLevel.Info,
);
final amountString = ref.read(pAmountFormatter(coin)).format( final amountString = ref.read(pAmountFormatter(coin)).format(
_amountToSend!, _amountToSend!,
@ -603,10 +615,15 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
Future<void> sendAllTapped() async { Future<void> sendAllTapped() async {
cryptoAmountController.text = ref cryptoAmountController.text = ref
.read(pTokenBalance(( .read(
walletId: walletId, pTokenBalance(
contractAddress: ref.read(pCurrentTokenWallet)!.tokenContract.address (
))) walletId: walletId,
contractAddress:
ref.read(pCurrentTokenWallet)!.tokenContract.address
),
),
)
.spendable .spendable
.decimal .decimal
.toStringAsFixed( .toStringAsFixed(
@ -788,9 +805,10 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
child: Text( child: Text(
tokenContract.symbol, tokenContract.symbol,
style: STextStyles.smallMed14(context).copyWith( style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -850,12 +868,15 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
child: Padding( child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Text( child: Text(
ref.watch(prefsChangeNotifierProvider ref.watch(
.select((value) => value.currency)), prefsChangeNotifierProvider
.select((value) => value.currency),
),
style: STextStyles.smallMed14(context).copyWith( style: STextStyles.smallMed14(context).copyWith(
color: Theme.of(context) color: Theme.of(context)
.extension<StackColors>()! .extension<StackColors>()!
.accentColorDark), .accentColorDark,
),
), ),
), ),
), ),
@ -936,12 +957,15 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
_addressToggleFlag _addressToggleFlag
? TextFieldIconButton( ? TextFieldIconButton(
key: const Key( key: const Key(
"sendTokenViewClearAddressFieldButtonKey"), "sendTokenViewClearAddressFieldButtonKey",
),
onTap: () { onTap: () {
sendToController.text = ""; sendToController.text = "";
_address = ""; _address = "";
_updatePreviewButtonState( _updatePreviewButtonState(
_address, _amountToSend); _address,
_amountToSend,
);
setState(() { setState(() {
_addressToggleFlag = false; _addressToggleFlag = false;
}); });
@ -950,7 +974,8 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
) )
: TextFieldIconButton( : TextFieldIconButton(
key: const Key( key: const Key(
"sendTokenViewPasteAddressFieldButtonKey"), "sendTokenViewPasteAddressFieldButtonKey",
),
onTap: pasteAddress, onTap: pasteAddress,
child: sendToController.text.isEmpty child: sendToController.text.isEmpty
? const ClipboardIcon() ? const ClipboardIcon()
@ -1129,7 +1154,7 @@ class _DesktopTokenSendState extends ConsumerState<DesktopTokenSend> {
onPressed: ref.watch(previewTokenTxButtonStateProvider.state).state onPressed: ref.watch(previewTokenTxButtonStateProvider.state).state
? previewSend ? previewSend
: null, : null,
) ),
], ],
); );
} }