mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-22 19:49:22 +00:00
align the hint with the prefix in the text field (#1571)
* Update send_card.dart * update currency amount text field widget * Update qr_widget.dart
This commit is contained in:
parent
fb33a6f23d
commit
14e99daa73
10 changed files with 371 additions and 650 deletions
|
@ -67,17 +67,6 @@ class ExchangePage extends BasePage {
|
||||||
Debounce _depositAmountDebounce = Debounce(Duration(milliseconds: 500));
|
Debounce _depositAmountDebounce = Debounce(Duration(milliseconds: 500));
|
||||||
var _isReactionsSet = false;
|
var _isReactionsSet = false;
|
||||||
|
|
||||||
final arrowBottomPurple = Image.asset(
|
|
||||||
'assets/images/arrow_bottom_purple_icon.png',
|
|
||||||
color: Colors.white,
|
|
||||||
height: 8,
|
|
||||||
);
|
|
||||||
final arrowBottomCakeGreen = Image.asset(
|
|
||||||
'assets/images/arrow_bottom_cake_green.png',
|
|
||||||
color: Colors.white,
|
|
||||||
height: 8,
|
|
||||||
);
|
|
||||||
|
|
||||||
late final String? depositWalletName;
|
late final String? depositWalletName;
|
||||||
late final String? receiveWalletName;
|
late final String? receiveWalletName;
|
||||||
|
|
||||||
|
@ -101,11 +90,11 @@ class ExchangePage extends BasePage {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Function(BuildContext)? get pushToNextWidget => (context) {
|
Function(BuildContext)? get pushToNextWidget => (context) {
|
||||||
FocusScopeNode currentFocus = FocusScope.of(context);
|
FocusScopeNode currentFocus = FocusScope.of(context);
|
||||||
if (!currentFocus.hasPrimaryFocus) {
|
if (!currentFocus.hasPrimaryFocus) {
|
||||||
currentFocus.focusedChild?.unfocus();
|
currentFocus.focusedChild?.unfocus();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget middle(BuildContext context) => Row(
|
Widget middle(BuildContext context) => Row(
|
||||||
|
@ -340,7 +329,6 @@ class ExchangePage extends BasePage {
|
||||||
|
|
||||||
void applyTemplate(
|
void applyTemplate(
|
||||||
BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async {
|
BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async {
|
||||||
|
|
||||||
final depositCryptoCurrency = CryptoCurrency.fromString(template.depositCurrency);
|
final depositCryptoCurrency = CryptoCurrency.fromString(template.depositCurrency);
|
||||||
final receiveCryptoCurrency = CryptoCurrency.fromString(template.receiveCurrency);
|
final receiveCryptoCurrency = CryptoCurrency.fromString(template.receiveCurrency);
|
||||||
|
|
||||||
|
@ -354,10 +342,12 @@ class ExchangePage extends BasePage {
|
||||||
exchangeViewModel.isFixedRateMode = false;
|
exchangeViewModel.isFixedRateMode = false;
|
||||||
|
|
||||||
var domain = template.depositAddress;
|
var domain = template.depositAddress;
|
||||||
exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, depositCryptoCurrency);
|
exchangeViewModel.depositAddress =
|
||||||
|
await fetchParsedAddress(context, domain, depositCryptoCurrency);
|
||||||
|
|
||||||
domain = template.receiveAddress;
|
domain = template.receiveAddress;
|
||||||
exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, receiveCryptoCurrency);
|
exchangeViewModel.receiveAddress =
|
||||||
|
await fetchParsedAddress(context, domain, receiveCryptoCurrency);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) {
|
void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) {
|
||||||
|
@ -529,14 +519,16 @@ class ExchangePage extends BasePage {
|
||||||
_depositAddressFocus.addListener(() async {
|
_depositAddressFocus.addListener(() async {
|
||||||
if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) {
|
if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) {
|
||||||
final domain = depositAddressController.text;
|
final domain = depositAddressController.text;
|
||||||
exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency);
|
exchangeViewModel.depositAddress =
|
||||||
|
await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_receiveAddressFocus.addListener(() async {
|
_receiveAddressFocus.addListener(() async {
|
||||||
if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) {
|
if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) {
|
||||||
final domain = receiveAddressController.text;
|
final domain = receiveAddressController.text;
|
||||||
exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency);
|
exchangeViewModel.receiveAddress =
|
||||||
|
await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -589,7 +581,8 @@ class ExchangePage extends BasePage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> fetchParsedAddress(BuildContext context, String domain, CryptoCurrency currency) async {
|
Future<String> fetchParsedAddress(
|
||||||
|
BuildContext context, String domain, CryptoCurrency currency) async {
|
||||||
final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency);
|
final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency);
|
||||||
final address = await extractAddressFromParsed(context, parsedAddress);
|
final address = await extractAddressFromParsed(context, parsedAddress);
|
||||||
return address;
|
return address;
|
||||||
|
@ -658,7 +651,6 @@ class ExchangePage extends BasePage {
|
||||||
|
|
||||||
exchangeViewModel.changeDepositCurrency(currency: currency);
|
exchangeViewModel.changeDepositCurrency(currency: currency);
|
||||||
},
|
},
|
||||||
imageArrow: arrowBottomPurple,
|
|
||||||
currencyButtonColor: Colors.transparent,
|
currencyButtonColor: Colors.transparent,
|
||||||
addressButtonsColor:
|
addressButtonsColor:
|
||||||
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||||
|
@ -705,7 +697,6 @@ class ExchangePage extends BasePage {
|
||||||
currencies: exchangeViewModel.receiveCurrencies,
|
currencies: exchangeViewModel.receiveCurrencies,
|
||||||
onCurrencySelected: (currency) =>
|
onCurrencySelected: (currency) =>
|
||||||
exchangeViewModel.changeReceiveCurrency(currency: currency),
|
exchangeViewModel.changeReceiveCurrency(currency: currency),
|
||||||
imageArrow: arrowBottomCakeGreen,
|
|
||||||
currencyButtonColor: Colors.transparent,
|
currencyButtonColor: Colors.transparent,
|
||||||
addressButtonsColor:
|
addressButtonsColor:
|
||||||
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:cake_wallet/core/amount_validator.dart';
|
import 'package:cake_wallet/core/amount_validator.dart';
|
||||||
import 'package:cake_wallet/entities/contact_base.dart';
|
import 'package:cake_wallet/entities/contact_base.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||||
|
@ -27,7 +28,7 @@ class ExchangeCard extends StatefulWidget {
|
||||||
required this.isAmountEstimated,
|
required this.isAmountEstimated,
|
||||||
required this.currencies,
|
required this.currencies,
|
||||||
required this.onCurrencySelected,
|
required this.onCurrencySelected,
|
||||||
required this.imageArrow,
|
this.imageArrow,
|
||||||
this.currencyValueValidator,
|
this.currencyValueValidator,
|
||||||
this.addressTextFieldValidator,
|
this.addressTextFieldValidator,
|
||||||
this.title = '',
|
this.title = '',
|
||||||
|
@ -58,7 +59,7 @@ class ExchangeCard extends StatefulWidget {
|
||||||
final bool isAmountEstimated;
|
final bool isAmountEstimated;
|
||||||
final bool hasRefundAddress;
|
final bool hasRefundAddress;
|
||||||
final bool isMoneroWallet;
|
final bool isMoneroWallet;
|
||||||
final Image imageArrow;
|
final Image? imageArrow;
|
||||||
final Color currencyButtonColor;
|
final Color currencyButtonColor;
|
||||||
final Color? addressButtonsColor;
|
final Color? addressButtonsColor;
|
||||||
final Color borderColor;
|
final Color borderColor;
|
||||||
|
@ -191,120 +192,18 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
CurrencyAmountTextField(
|
||||||
padding: EdgeInsets.only(top: 20),
|
imageArrow: widget.imageArrow,
|
||||||
child: Row(
|
selectedCurrency: _selectedCurrency.toString(),
|
||||||
children: [
|
amountFocusNode: widget.amountFocusNode,
|
||||||
Container(
|
amountController: amountController,
|
||||||
padding: EdgeInsets.only(right: 8),
|
onTapPicker: () => _presentPicker(context),
|
||||||
height: 32,
|
isAmountEditable: _isAmountEditable,
|
||||||
color: widget.currencyButtonColor,
|
isPickerEnable: true,
|
||||||
child: InkWell(
|
allAmountButton: widget.hasAllAmount,
|
||||||
onTap: () => _presentPicker(context),
|
currencyValueValidator: widget.currencyValueValidator,
|
||||||
child: Row(
|
tag: _selectedCurrency.tag,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
allAmountCallback: widget.allAmount),
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(right: 5),
|
|
||||||
child: widget.imageArrow,
|
|
||||||
),
|
|
||||||
Text(_selectedCurrency.toString(),
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600, fontSize: 16, color: Colors.white))
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (_selectedCurrency.tag != null)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 3.0),
|
|
||||||
child: Container(
|
|
||||||
height: 32,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: widget.addressButtonsColor ??
|
|
||||||
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(6))),
|
|
||||||
child: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(6.0),
|
|
||||||
child: Text(_selectedCurrency.tag!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonIconColor)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 4.0),
|
|
||||||
child: Text(':',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600, fontSize: 16, color: Colors.white)),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Flexible(
|
|
||||||
child: FocusTraversalOrder(
|
|
||||||
order: NumericFocusOrder(1),
|
|
||||||
child: BaseTextFormField(
|
|
||||||
focusNode: widget.amountFocusNode,
|
|
||||||
controller: amountController,
|
|
||||||
enabled: _isAmountEditable,
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
keyboardType:
|
|
||||||
TextInputType.numberWithOptions(signed: false, decimal: true),
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))
|
|
||||||
],
|
|
||||||
hintText: '0.0000',
|
|
||||||
borderColor: Colors.transparent,
|
|
||||||
//widget.borderColor,
|
|
||||||
textStyle: TextStyle(
|
|
||||||
fontSize: 16, fontWeight: FontWeight.w600, color: Colors.white),
|
|
||||||
placeholderTextStyle: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<ExchangePageTheme>()!
|
|
||||||
.hintTextColor),
|
|
||||||
validator: _isAmountEditable
|
|
||||||
? widget.currencyValueValidator
|
|
||||||
: null),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (widget.hasAllAmount)
|
|
||||||
Container(
|
|
||||||
height: 32,
|
|
||||||
width: 32,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonColor,
|
|
||||||
borderRadius: BorderRadius.all(Radius.circular(6))),
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => widget.allAmount?.call(),
|
|
||||||
child: Center(
|
|
||||||
child: Text(S.of(context).all,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonIconColor)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
Divider(height: 1, color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
Divider(height: 1, color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 5),
|
padding: EdgeInsets.only(top: 5),
|
||||||
|
|
|
@ -1,135 +1,210 @@
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
import 'package:cake_wallet/themes/extensions/exchange_page_theme.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
import 'package:cw_core/currency.dart';
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/dashboard_page_theme.dart';
|
|
||||||
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
|
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
|
||||||
|
|
||||||
class CurrencyInputField extends StatelessWidget {
|
class CurrencyAmountTextField extends StatelessWidget {
|
||||||
const CurrencyInputField({
|
const CurrencyAmountTextField({
|
||||||
super.key,
|
|
||||||
required this.onTapPicker,
|
|
||||||
required this.selectedCurrency,
|
required this.selectedCurrency,
|
||||||
this.focusNode,
|
required this.amountFocusNode,
|
||||||
required this.controller,
|
required this.amountController,
|
||||||
required this.isLight,
|
required this.isAmountEditable,
|
||||||
|
this.allAmountButton = false,
|
||||||
|
this.isPickerEnable = false,
|
||||||
|
this.isSelected = false,
|
||||||
|
this.currentTheme = ThemeType.dark,
|
||||||
|
this.onTapPicker,
|
||||||
|
this.padding,
|
||||||
|
this.imageArrow,
|
||||||
|
this.hintText,
|
||||||
|
this.tag,
|
||||||
|
this.tagBackgroundColor,
|
||||||
|
this.currencyValueValidator,
|
||||||
|
this.allAmountCallback,
|
||||||
});
|
});
|
||||||
|
|
||||||
final Function() onTapPicker;
|
final Widget? imageArrow;
|
||||||
final Currency selectedCurrency;
|
final String selectedCurrency;
|
||||||
final FocusNode? focusNode;
|
final String? tag;
|
||||||
final TextEditingController controller;
|
final String? hintText;
|
||||||
final bool isLight;
|
final Color? tagBackgroundColor;
|
||||||
|
final EdgeInsets? padding;
|
||||||
String get _currencyName {
|
final FocusNode? amountFocusNode;
|
||||||
if (selectedCurrency is CryptoCurrency) {
|
final TextEditingController amountController;
|
||||||
return (selectedCurrency as CryptoCurrency).title.toUpperCase();
|
final bool isAmountEditable;
|
||||||
}
|
final FormFieldValidator<String>? currencyValueValidator;
|
||||||
return selectedCurrency.name.toUpperCase();
|
final bool isPickerEnable;
|
||||||
}
|
final ThemeType currentTheme;
|
||||||
|
final bool isSelected;
|
||||||
|
final bool allAmountButton;
|
||||||
|
final VoidCallback? allAmountCallback;
|
||||||
|
final VoidCallback? onTapPicker;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrowBottomPurple = Image.asset(
|
final textColor = currentTheme == ThemeType.light
|
||||||
'assets/images/arrow_bottom_purple_icon.png',
|
? Theme.of(context).appBarTheme.titleTextStyle!.color!
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
: Colors.white;
|
||||||
height: 8,
|
final _prefixContent = Row(
|
||||||
);
|
|
||||||
// This magic number for wider screen sets the text input focus at center of the inputfield
|
|
||||||
final _width =
|
|
||||||
responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500;
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
isPickerEnable
|
||||||
padding: EdgeInsets.only(top: 20),
|
? Container(
|
||||||
child: SizedBox(
|
height: 32,
|
||||||
height: 40,
|
child: InkWell(
|
||||||
child: BaseTextFormField(
|
onTap: onTapPicker,
|
||||||
focusNode: focusNode,
|
child: Row(
|
||||||
controller: controller,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
mainAxisSize: MainAxisSize.min,
|
||||||
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,8}'))],
|
children: <Widget>[
|
||||||
hintText: '0.000',
|
Padding(
|
||||||
placeholderTextStyle: isLight
|
padding: const EdgeInsets.only(right: 5),
|
||||||
? null
|
child: imageArrow ??
|
||||||
: TextStyle(
|
Image.asset('assets/images/arrow_bottom_purple_icon.png',
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
color: textColor, height: 8)),
|
||||||
fontWeight: FontWeight.w600,
|
Text(
|
||||||
),
|
selectedCurrency,
|
||||||
borderColor: Theme.of(context).extension<PickerTheme>()!.dividerColor,
|
style: TextStyle(
|
||||||
textColor: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
fontWeight: FontWeight.w600,
|
||||||
textStyle: TextStyle(
|
fontSize: 16,
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
color: textColor,
|
||||||
),
|
),
|
||||||
prefixIcon: Padding(
|
),
|
||||||
padding: EdgeInsets.only(
|
],
|
||||||
left: _width / 4,
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
)
|
||||||
padding: EdgeInsets.only(right: 8),
|
: Text(
|
||||||
child: InkWell(
|
selectedCurrency,
|
||||||
onTap: onTapPicker,
|
style: TextStyle(
|
||||||
child: Row(
|
fontWeight: FontWeight.w600,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
fontSize: 16,
|
||||||
mainAxisSize: MainAxisSize.min,
|
color: textColor,
|
||||||
children: <Widget>[
|
),
|
||||||
Padding(
|
),
|
||||||
padding: EdgeInsets.only(right: 5),
|
if (tag != null)
|
||||||
child: arrowBottomPurple,
|
Padding(
|
||||||
),
|
padding: const EdgeInsets.symmetric(horizontal: 3.0),
|
||||||
Text(
|
child: Container(
|
||||||
_currencyName,
|
height: 32,
|
||||||
style: TextStyle(
|
decoration: BoxDecoration(
|
||||||
fontWeight: FontWeight.w600,
|
color: tagBackgroundColor ??
|
||||||
fontSize: 16,
|
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||||
),
|
),
|
||||||
),
|
child: Center(
|
||||||
if (selectedCurrency.tag != null)
|
child: Padding(
|
||||||
Padding(
|
padding: const EdgeInsets.all(6.0),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 3.0),
|
child: Text(
|
||||||
child: Container(
|
tag!,
|
||||||
decoration: BoxDecoration(
|
style: TextStyle(
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
fontSize: 12,
|
||||||
borderRadius: BorderRadius.all(
|
fontWeight: FontWeight.bold,
|
||||||
Radius.circular(6),
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
|
||||||
),
|
),
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
selectedCurrency.tag!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonIconColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 3.0),
|
|
||||||
child: Text(
|
|
||||||
':',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
fontSize: 20,
|
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: 4.0),
|
||||||
|
child: Text(
|
||||||
|
':',
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontSize: 16,
|
||||||
|
color: textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
return Padding(
|
||||||
|
padding: padding ?? const EdgeInsets.only(top: 20),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
isSelected
|
||||||
|
? Container(
|
||||||
|
child: _prefixContent,
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
||||||
|
margin: const EdgeInsets.only(right: 3),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.all(
|
||||||
|
color: textColor,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(26),
|
||||||
|
color: Theme.of(context).primaryColor))
|
||||||
|
: _prefixContent,
|
||||||
|
Expanded(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
|
child: FocusTraversalOrder(
|
||||||
|
order: NumericFocusOrder(1),
|
||||||
|
child: BaseTextFormField(
|
||||||
|
focusNode: amountFocusNode,
|
||||||
|
controller: amountController,
|
||||||
|
enabled: isAmountEditable,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
keyboardType: const TextInputType.numberWithOptions(
|
||||||
|
signed: false,
|
||||||
|
decimal: true,
|
||||||
|
),
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]')),
|
||||||
|
],
|
||||||
|
hintText: hintText ?? '0.0000',
|
||||||
|
borderColor: Colors.transparent,
|
||||||
|
textStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: textColor,
|
||||||
|
),
|
||||||
|
placeholderTextStyle: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
color: currentTheme == ThemeType.light
|
||||||
|
? Theme.of(context).appBarTheme.titleTextStyle!.color!
|
||||||
|
: Theme.of(context).extension<ExchangePageTheme>()!.hintTextColor,
|
||||||
|
),
|
||||||
|
validator: isAmountEditable ? currencyValueValidator : null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (allAmountButton)
|
||||||
|
Container(
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||||
|
),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: allAmountCallback,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
S.of(context).all,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
color: Theme.of(context)
|
||||||
|
.extension<SendPageTheme>()!
|
||||||
|
.textFieldButtonIconColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import 'package:cake_wallet/entities/qr_view_data.dart';
|
import 'package:cake_wallet/entities/qr_view_data.dart';
|
||||||
|
import 'package:cake_wallet/themes/extensions/picker_theme.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
import 'package:cake_wallet/themes/extensions/qr_code_theme.dart';
|
||||||
import 'package:cake_wallet/routes.dart';
|
import 'package:cake_wallet/routes.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||||
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
||||||
|
import 'package:cake_wallet/themes/theme_base.dart';
|
||||||
import 'package:cake_wallet/utils/brightness_util.dart';
|
import 'package:cake_wallet/utils/brightness_util.dart';
|
||||||
|
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||||
import 'package:cake_wallet/utils/show_bar.dart';
|
import 'package:cake_wallet/utils/show_bar.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||||
|
@ -38,6 +42,10 @@ class QRWidget extends StatelessWidget {
|
||||||
final copyImage = Image.asset('assets/images/copy_address.png',
|
final copyImage = Image.asset('assets/images/copy_address.png',
|
||||||
color: Theme.of(context).extension<QRCodeTheme>()!.qrWidgetCopyButtonColor);
|
color: Theme.of(context).extension<QRCodeTheme>()!.qrWidgetCopyButtonColor);
|
||||||
|
|
||||||
|
// This magic number for wider screen sets the text input focus at center of the inputfield
|
||||||
|
final _width =
|
||||||
|
responsiveLayoutUtil.shouldRenderMobileUI ? MediaQuery.of(context).size.width : 500;
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
@ -85,8 +93,9 @@ class QRWidget extends StatelessWidget {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
width: 3,
|
width: 3,
|
||||||
color:
|
color: Theme.of(context)
|
||||||
Theme.of(context).extension<DashboardPageTheme>()!.textColor,
|
.extension<DashboardPageTheme>()!
|
||||||
|
.textColor,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Container(
|
child: Container(
|
||||||
|
@ -116,20 +125,23 @@ class QRWidget extends StatelessWidget {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Form(
|
child: Form(
|
||||||
key: formKey,
|
key: formKey,
|
||||||
child: CurrencyInputField(
|
child: CurrencyAmountTextField(
|
||||||
focusNode: amountTextFieldFocusNode,
|
selectedCurrency: _currencyName,
|
||||||
controller: amountController,
|
amountFocusNode: amountTextFieldFocusNode,
|
||||||
onTapPicker: () => _presentPicker(context),
|
amountController: amountController,
|
||||||
selectedCurrency: addressListViewModel.selectedCurrency,
|
padding: EdgeInsets.only(top: 20, left: _width / 4),
|
||||||
isLight: isLight,
|
currentTheme: isLight ? ThemeType.light : ThemeType.dark,
|
||||||
),
|
isAmountEditable: true,
|
||||||
),
|
tag: addressListViewModel.selectedCurrency.tag,
|
||||||
|
onTapPicker: () => _presentPicker(context),
|
||||||
|
isPickerEnable: true)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
|
Divider(height: 1, color: Theme.of(context).extension<PickerTheme>()!.dividerColor),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 20, bottom: 8),
|
padding: EdgeInsets.only(top: 20, bottom: 8),
|
||||||
child: Builder(
|
child: Builder(
|
||||||
|
@ -150,7 +162,8 @@ class QRWidget extends StatelessWidget {
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 15,
|
fontSize: 15,
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: Theme.of(context).extension<DashboardPageTheme>()!.textColor),
|
color:
|
||||||
|
Theme.of(context).extension<DashboardPageTheme>()!.textColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
|
@ -169,6 +182,13 @@ class QRWidget extends StatelessWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get _currencyName {
|
||||||
|
if (addressListViewModel.selectedCurrency is CryptoCurrency) {
|
||||||
|
return (addressListViewModel.selectedCurrency as CryptoCurrency).title.toUpperCase();
|
||||||
|
}
|
||||||
|
return addressListViewModel.selectedCurrency.name.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
void _presentPicker(BuildContext context) async {
|
void _presentPicker(BuildContext context) async {
|
||||||
await showPopUp<void>(
|
await showPopUp<void>(
|
||||||
builder: (_) => CurrencyPicker(
|
builder: (_) => CurrencyPicker(
|
||||||
|
|
|
@ -144,7 +144,7 @@ class SendTemplatePage extends BasePage {
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
sendTemplateViewModel.addTemplate(
|
sendTemplateViewModel.addTemplate(
|
||||||
isCurrencySelected: mainTemplate.isCurrencySelected,
|
isCurrencySelected: mainTemplate.isCryptoSelected,
|
||||||
name: mainTemplate.name,
|
name: mainTemplate.name,
|
||||||
address: mainTemplate.address,
|
address: mainTemplate.address,
|
||||||
cryptoCurrency: mainTemplate.selectedCurrency.title,
|
cryptoCurrency: mainTemplate.selectedCurrency.title,
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class PrefixCurrencyIcon extends StatelessWidget {
|
|
||||||
PrefixCurrencyIcon({
|
|
||||||
required this.isSelected,
|
|
||||||
required this.title,
|
|
||||||
this.onTap,
|
|
||||||
});
|
|
||||||
|
|
||||||
final bool isSelected;
|
|
||||||
final String title;
|
|
||||||
final Function()? onTap;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return GestureDetector(
|
|
||||||
onTap: onTap,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.fromLTRB(0, 6.0, 8.0, 0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 4, horizontal: 8),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(26),
|
|
||||||
color: isSelected
|
|
||||||
? Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.templateSelectedCurrencyBackgroundColor
|
|
||||||
: Colors.transparent,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
if (onTap != null)
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(right: 5),
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/arrow_bottom_purple_icon.png',
|
|
||||||
color: Colors.white,
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
title + ':',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: isSelected
|
|
||||||
? Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.templateSelectedCurrencyTitleColor
|
|
||||||
: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
import 'package:cake_wallet/entities/priority_for_wallet_type.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
||||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
import 'package:cake_wallet/themes/extensions/keyboard_theme.dart';
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||||
|
@ -207,166 +208,19 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
validator: sendViewModel.addressValidator)),
|
validator: sendViewModel.addressValidator)),
|
||||||
Observer(
|
CurrencyAmountTextField(
|
||||||
builder: (_) => Padding(
|
selectedCurrency: sendViewModel.selectedCryptoCurrency.title,
|
||||||
padding: const EdgeInsets.only(top: 20),
|
amountFocusNode: cryptoAmountFocus,
|
||||||
child: Row(
|
amountController: cryptoAmountController,
|
||||||
children: [
|
isAmountEditable: true,
|
||||||
Padding(
|
onTapPicker: () => _presentPicker(context),
|
||||||
padding: const EdgeInsets.only(bottom: 8.0),
|
isPickerEnable: sendViewModel.hasMultipleTokens,
|
||||||
child: Row(
|
tag: sendViewModel.selectedCryptoCurrency.tag,
|
||||||
children: [
|
allAmountButton: !sendViewModel.isBatchSending,
|
||||||
sendViewModel.hasMultipleTokens
|
currencyValueValidator: output.sendAll
|
||||||
? Container(
|
? sendViewModel.allAmountValidator
|
||||||
padding: EdgeInsets.only(right: 8),
|
: sendViewModel.amountValidator,
|
||||||
height: 32,
|
allAmountCallback: () async => output.setSendAll(sendViewModel.balance)),
|
||||||
child: InkWell(
|
|
||||||
onTap: () => _presentPicker(context),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(right: 5),
|
|
||||||
child: Image.asset(
|
|
||||||
'assets/images/arrow_bottom_purple_icon.png',
|
|
||||||
color: Colors.white,
|
|
||||||
height: 8,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
sendViewModel.selectedCryptoCurrency.title,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.white),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Text(
|
|
||||||
sendViewModel.selectedCryptoCurrency.title,
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.white),
|
|
||||||
),
|
|
||||||
sendViewModel.selectedCryptoCurrency.tag != null
|
|
||||||
? Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(3.0, 0, 3.0, 0),
|
|
||||||
child: Container(
|
|
||||||
height: 32,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonColor,
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(6),
|
|
||||||
)),
|
|
||||||
child: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(6.0),
|
|
||||||
child: Text(
|
|
||||||
sendViewModel.selectedCryptoCurrency.tag!,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonIconColor),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Container(),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 10.0),
|
|
||||||
child: Text(
|
|
||||||
':',
|
|
||||||
style: TextStyle(
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.white),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Stack(
|
|
||||||
children: [
|
|
||||||
BaseTextFormField(
|
|
||||||
focusNode: cryptoAmountFocus,
|
|
||||||
controller: cryptoAmountController,
|
|
||||||
keyboardType: TextInputType.numberWithOptions(
|
|
||||||
signed: false, decimal: true),
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))
|
|
||||||
],
|
|
||||||
suffixIcon: SizedBox(
|
|
||||||
width: prefixIconWidth,
|
|
||||||
),
|
|
||||||
hintText: '0.0000',
|
|
||||||
borderColor: Colors.transparent,
|
|
||||||
textStyle: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.white),
|
|
||||||
placeholderTextStyle: TextStyle(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldHintColor,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 14),
|
|
||||||
validator: output.sendAll
|
|
||||||
? sendViewModel.allAmountValidator
|
|
||||||
: sendViewModel.amountValidator,
|
|
||||||
),
|
|
||||||
if (!sendViewModel.isBatchSending)
|
|
||||||
Positioned(
|
|
||||||
top: 2,
|
|
||||||
right: 0,
|
|
||||||
child: Container(
|
|
||||||
width: prefixIconWidth,
|
|
||||||
height: prefixIconHeight,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () async {
|
|
||||||
output.setSendAll(sendViewModel.balance);
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonColor,
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(6),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
S.of(context).all,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 12,
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Theme.of(context)
|
|
||||||
.extension<SendPageTheme>()!
|
|
||||||
.textFieldButtonIconColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
Divider(
|
Divider(
|
||||||
height: 1,
|
height: 1,
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
||||||
|
@ -402,41 +256,16 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!sendViewModel.isFiatDisabled)
|
if (!sendViewModel.isFiatDisabled)
|
||||||
Padding(
|
CurrencyAmountTextField(
|
||||||
padding: const EdgeInsets.only(top: 20),
|
selectedCurrency: sendViewModel.fiat.title,
|
||||||
child: BaseTextFormField(
|
amountFocusNode: fiatAmountFocus,
|
||||||
focusNode: fiatAmountFocus,
|
amountController: fiatAmountController,
|
||||||
controller: fiatAmountController,
|
|
||||||
keyboardType:
|
|
||||||
TextInputType.numberWithOptions(signed: false, decimal: true),
|
|
||||||
inputFormatters: [
|
|
||||||
FilteringTextInputFormatter.deny(
|
|
||||||
RegExp('[\\-|\\ ]'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
prefixIcon: Padding(
|
|
||||||
padding: EdgeInsets.only(top: 9),
|
|
||||||
child: Text(
|
|
||||||
sendViewModel.fiat.title + ':',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w600,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
hintText: '0.00',
|
hintText: '0.00',
|
||||||
borderColor:
|
isAmountEditable: true,
|
||||||
Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
allAmountButton: false),
|
||||||
textStyle: TextStyle(
|
Divider(
|
||||||
fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
height: 1,
|
||||||
placeholderTextStyle: TextStyle(
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor),
|
||||||
color:
|
|
||||||
Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 14),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 20),
|
padding: EdgeInsets.only(top: 20),
|
||||||
child: BaseTextFormField(
|
child: BaseTextFormField(
|
||||||
|
@ -715,12 +544,11 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
|
||||||
showPopUp<void>(
|
showPopUp<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => CurrencyPicker(
|
builder: (_) => CurrencyPicker(
|
||||||
selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
|
selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
|
||||||
items: sendViewModel.currencies,
|
items: sendViewModel.currencies,
|
||||||
hintText: S.of(context).search_currency,
|
hintText: S.of(context).search_currency,
|
||||||
onItemSelected: (Currency cur) =>
|
onItemSelected: (Currency cur) =>
|
||||||
sendViewModel.selectedCryptoCurrency = (cur as CryptoCurrency),
|
sendViewModel.selectedCryptoCurrency = (cur as CryptoCurrency)),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
|
||||||
import 'package:cake_wallet/src/screens/send/widgets/prefix_currency_icon_widget.dart';
|
import 'package:cake_wallet/src/screens/receive/widgets/currency_input_field.dart';
|
||||||
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
import 'package:cake_wallet/themes/extensions/send_page_theme.dart';
|
||||||
import 'package:cake_wallet/utils/payment_request.dart';
|
import 'package:cake_wallet/utils/payment_request.dart';
|
||||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||||
|
@ -59,7 +59,8 @@ class SendTemplateCard extends StatelessWidget {
|
||||||
hintText: sendTemplateViewModel.recipients.length > 1
|
hintText: sendTemplateViewModel.recipients.length > 1
|
||||||
? S.of(context).template_name
|
? S.of(context).template_name
|
||||||
: S.of(context).send_name,
|
: S.of(context).send_name,
|
||||||
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
borderColor:
|
||||||
|
Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
||||||
textStyle:
|
textStyle:
|
||||||
TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
||||||
placeholderTextStyle: TextStyle(
|
placeholderTextStyle: TextStyle(
|
||||||
|
@ -69,107 +70,87 @@ class SendTemplateCard extends StatelessWidget {
|
||||||
validator: sendTemplateViewModel.templateValidator),
|
validator: sendTemplateViewModel.templateValidator),
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 20),
|
padding: EdgeInsets.only(top: 20),
|
||||||
child: Observer(
|
child: Observer(builder: (context) {
|
||||||
builder: (context) {
|
return AddressTextField(
|
||||||
return AddressTextField(
|
selectedCurrency: template.selectedCurrency,
|
||||||
selectedCurrency: template.selectedCurrency,
|
controller: _addressController,
|
||||||
controller: _addressController,
|
onURIScanned: (uri) {
|
||||||
onURIScanned: (uri) {
|
final paymentRequest = PaymentRequest.fromUri(uri);
|
||||||
final paymentRequest = PaymentRequest.fromUri(uri);
|
_addressController.text = paymentRequest.address;
|
||||||
_addressController.text = paymentRequest.address;
|
_cryptoAmountController.text = paymentRequest.amount;
|
||||||
_cryptoAmountController.text = paymentRequest.amount;
|
},
|
||||||
},
|
options: [
|
||||||
options: [
|
AddressTextFieldOption.paste,
|
||||||
AddressTextFieldOption.paste,
|
AddressTextFieldOption.qrCode,
|
||||||
AddressTextFieldOption.qrCode,
|
AddressTextFieldOption.addressBook
|
||||||
AddressTextFieldOption.addressBook
|
],
|
||||||
],
|
onPushPasteButton: (context) async {
|
||||||
onPushPasteButton: (context) async {
|
template.output.resetParsedAddress();
|
||||||
template.output.resetParsedAddress();
|
await template.output.fetchParsedAddress(context);
|
||||||
await template.output.fetchParsedAddress(context);
|
},
|
||||||
},
|
onPushAddressBookButton: (context) async {
|
||||||
onPushAddressBookButton: (context) async {
|
template.output.resetParsedAddress();
|
||||||
template.output.resetParsedAddress();
|
await template.output.fetchParsedAddress(context);
|
||||||
await template.output.fetchParsedAddress(context);
|
},
|
||||||
},
|
buttonColor:
|
||||||
buttonColor: Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
Theme.of(context).extension<SendPageTheme>()!.textFieldButtonColor,
|
||||||
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
borderColor:
|
||||||
textStyle: TextStyle(
|
Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
||||||
fontSize: 14,
|
textStyle: TextStyle(
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Colors.white,
|
|
||||||
),
|
|
||||||
hintStyle: TextStyle(
|
|
||||||
fontSize: 14,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
|
||||||
),
|
|
||||||
validator: sendTemplateViewModel.addressValidator,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 20),
|
|
||||||
child: Focus(
|
|
||||||
onFocusChange: (hasFocus) {
|
|
||||||
if (hasFocus) {
|
|
||||||
template.selectCurrency();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: BaseTextFormField(
|
|
||||||
focusNode: _cryptoAmountFocus,
|
|
||||||
controller: _cryptoAmountController,
|
|
||||||
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
|
||||||
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
|
|
||||||
prefixIcon: Observer(
|
|
||||||
builder: (_) => PrefixCurrencyIcon(
|
|
||||||
title: template.selectedCurrency.title,
|
|
||||||
isSelected: template.isCurrencySelected,
|
|
||||||
onTap: sendTemplateViewModel.walletCurrencies.length > 1
|
|
||||||
? () => _presentPicker(context)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
hintText: '0.0000',
|
|
||||||
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
|
||||||
textStyle:
|
|
||||||
TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
|
||||||
placeholderTextStyle: TextStyle(
|
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 14),
|
|
||||||
validator: sendTemplateViewModel.amountValidator,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 20),
|
|
||||||
child: Focus(
|
|
||||||
onFocusChange: (hasFocus) {
|
|
||||||
if (hasFocus) {
|
|
||||||
template.selectFiat();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: BaseTextFormField(
|
|
||||||
focusNode: _fiatAmountFocus,
|
|
||||||
controller: _fiatAmountController,
|
|
||||||
keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
|
|
||||||
inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
|
|
||||||
prefixIcon: Observer(
|
|
||||||
builder: (_) => PrefixCurrencyIcon(
|
|
||||||
title: sendTemplateViewModel.fiatCurrency,
|
|
||||||
isSelected: template.isFiatSelected)),
|
|
||||||
hintText: '0.00',
|
|
||||||
borderColor: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor,
|
|
||||||
textStyle:
|
|
||||||
TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Colors.white),
|
|
||||||
placeholderTextStyle: TextStyle(
|
|
||||||
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
hintStyle: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldHintColor,
|
||||||
|
),
|
||||||
|
validator: sendTemplateViewModel.addressValidator,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
Focus(
|
||||||
|
onFocusChange: (hasFocus) {
|
||||||
|
if (hasFocus) template.setCryptoCurrency(true);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Observer(
|
||||||
|
builder: (context) => CurrencyAmountTextField(
|
||||||
|
selectedCurrency: template.selectedCurrency.title,
|
||||||
|
amountFocusNode: _cryptoAmountFocus,
|
||||||
|
amountController: _cryptoAmountController,
|
||||||
|
isSelected: template.isCryptoSelected,
|
||||||
|
tag: template.selectedCurrency.tag,
|
||||||
|
isPickerEnable: sendTemplateViewModel.hasMultipleTokens,
|
||||||
|
onTapPicker: () => _presentPicker(context),
|
||||||
|
currencyValueValidator: sendTemplateViewModel.amountValidator,
|
||||||
|
isAmountEditable: true)),
|
||||||
|
Divider(
|
||||||
|
height: 1,
|
||||||
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Focus(
|
||||||
|
onFocusChange: (hasFocus) {
|
||||||
|
if (hasFocus) template.setCryptoCurrency(false);
|
||||||
|
},
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Observer(
|
||||||
|
builder: (context) => CurrencyAmountTextField(
|
||||||
|
selectedCurrency: sendTemplateViewModel.fiatCurrency,
|
||||||
|
amountFocusNode: _fiatAmountFocus,
|
||||||
|
amountController: _fiatAmountController,
|
||||||
|
isSelected: !template.isCryptoSelected,
|
||||||
|
hintText: '0.00',
|
||||||
|
isAmountEditable: true)),
|
||||||
|
Divider(
|
||||||
|
height: 1,
|
||||||
|
color: Theme.of(context).extension<SendPageTheme>()!.textFieldBorderColor)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:cake_wallet/reactions/wallet_connect.dart';
|
||||||
import 'package:cake_wallet/view_model/send/template_view_model.dart';
|
import 'package:cake_wallet/view_model/send/template_view_model.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/wallet_type.dart';
|
import 'package:cw_core/wallet_type.dart';
|
||||||
|
@ -97,4 +98,8 @@ abstract class SendTemplateViewModelBase with Store {
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
|
List<CryptoCurrency> get walletCurrencies => _wallet.balance.keys.toList();
|
||||||
|
|
||||||
|
bool get hasMultipleTokens => isEVMCompatibleChain(_wallet.type) ||
|
||||||
|
_wallet.type == WalletType.solana ||
|
||||||
|
_wallet.type == WalletType.tron;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,35 +40,22 @@ abstract class TemplateViewModelBase with Store {
|
||||||
CryptoCurrency _currency;
|
CryptoCurrency _currency;
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
bool isCurrencySelected = true;
|
bool isCryptoSelected = true;
|
||||||
|
|
||||||
@observable
|
|
||||||
bool isFiatSelected = false;
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void selectCurrency() {
|
void setCryptoCurrency(bool value) => isCryptoSelected = value;
|
||||||
isCurrencySelected = true;
|
|
||||||
isFiatSelected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
void selectFiat() {
|
|
||||||
isFiatSelected = true;
|
|
||||||
isCurrencySelected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void reset() {
|
void reset() {
|
||||||
name = '';
|
name = '';
|
||||||
address = '';
|
address = '';
|
||||||
isCurrencySelected = true;
|
isCryptoSelected = true;
|
||||||
isFiatSelected = false;
|
|
||||||
output.reset();
|
output.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Template toTemplate({required String cryptoCurrency, required String fiatCurrency}) {
|
Template toTemplate({required String cryptoCurrency, required String fiatCurrency}) {
|
||||||
return Template(
|
return Template(
|
||||||
isCurrencySelectedRaw: isCurrencySelected,
|
isCurrencySelectedRaw: isCryptoSelected,
|
||||||
nameRaw: name,
|
nameRaw: name,
|
||||||
addressRaw: address,
|
addressRaw: address,
|
||||||
cryptoCurrencyRaw: cryptoCurrency,
|
cryptoCurrencyRaw: cryptoCurrency,
|
||||||
|
@ -79,7 +66,7 @@ abstract class TemplateViewModelBase with Store {
|
||||||
|
|
||||||
@action
|
@action
|
||||||
void changeSelectedCurrency(CryptoCurrency currency) {
|
void changeSelectedCurrency(CryptoCurrency currency) {
|
||||||
isCurrencySelected = true;
|
isCryptoSelected = true;
|
||||||
_currency = currency;
|
_currency = currency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue