mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
Merge branch 'release-4.2.4' into CAKE-345-batch-sending
# Conflicts: # lib/bitcoin/electrum_wallet.dart # lib/src/screens/send/send_page.dart # lib/src/screens/send/send_template_page.dart # lib/view_model/send/send_view_model.dart # res/values/strings_de.arb # res/values/strings_en.arb # res/values/strings_es.arb # res/values/strings_hi.arb # res/values/strings_hr.arb # res/values/strings_it.arb # res/values/strings_ja.arb # res/values/strings_ko.arb # res/values/strings_nl.arb # res/values/strings_pl.arb # res/values/strings_pt.arb # res/values/strings_ru.arb # res/values/strings_uk.arb # res/values/strings_zh.arb
This commit is contained in:
@@ -151,17 +151,19 @@ class ContactListPage extends BasePage {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
image ?? Offstage(),
|
||||
Padding(
|
||||
padding: image != null
|
||||
? EdgeInsets.only(left: 12)
|
||||
: EdgeInsets.only(left: 0),
|
||||
child: Text(
|
||||
contact.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: image != null
|
||||
? EdgeInsets.only(left: 12)
|
||||
: EdgeInsets.only(left: 0),
|
||||
child: Text(
|
||||
contact.name,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/entities/sync_status.dart';
|
||||
import 'package:cake_wallet/entities/wallet_type.dart';
|
||||
import 'package:cake_wallet/exchange/changenow/changenow_exchange_provider.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_checkbox.dart';
|
||||
import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -9,8 +11,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_provider.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_template.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_trade_state.dart';
|
||||
import 'package:cake_wallet/exchange/limits_state.dart';
|
||||
@@ -23,7 +23,6 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/entities/crypto_currency.dart';
|
||||
import 'package:cake_wallet/exchange/xmrto/xmrto_exchange_provider.dart';
|
||||
import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
@@ -42,7 +41,9 @@ class ExchangePage extends BasePage {
|
||||
final checkBoxKey = GlobalKey<StandardCheckboxState>();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
final _depositAmountFocus = FocusNode();
|
||||
final _depositAddressFocus = FocusNode();
|
||||
final _receiveAmountFocus = FocusNode();
|
||||
final _receiveAddressFocus = FocusNode();
|
||||
var _isReactionsSet = false;
|
||||
|
||||
@override
|
||||
@@ -171,6 +172,7 @@ class ExchangePage extends BasePage {
|
||||
.calculateDepositAllAmount()
|
||||
: null,
|
||||
amountFocusNode: _depositAmountFocus,
|
||||
addressFocusNode: _depositAddressFocus,
|
||||
key: depositKey,
|
||||
title: S.of(context).you_will_send,
|
||||
initialCurrency:
|
||||
@@ -179,7 +181,7 @@ class ExchangePage extends BasePage {
|
||||
initialAddress:
|
||||
exchangeViewModel.depositCurrency ==
|
||||
exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
? exchangeViewModel.wallet.walletAddresses.address
|
||||
: exchangeViewModel.depositAddress,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable:
|
||||
@@ -223,6 +225,15 @@ class ExchangePage extends BasePage {
|
||||
type: exchangeViewModel.wallet.type),
|
||||
addressTextFieldValidator: AddressValidator(
|
||||
type: exchangeViewModel.depositCurrency),
|
||||
onPushPasteButton: (context) async {
|
||||
final domain =
|
||||
exchangeViewModel.depositAddress;
|
||||
final ticker = exchangeViewModel
|
||||
.depositCurrency.title.toLowerCase();
|
||||
exchangeViewModel.depositAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(
|
||||
context, domain, ticker);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -232,6 +243,7 @@ class ExchangePage extends BasePage {
|
||||
child: Observer(
|
||||
builder: (_) => ExchangeCard(
|
||||
amountFocusNode: _receiveAmountFocus,
|
||||
addressFocusNode: _receiveAddressFocus,
|
||||
key: receiveKey,
|
||||
title: S.of(context).you_will_get,
|
||||
initialCurrency:
|
||||
@@ -240,7 +252,7 @@ class ExchangePage extends BasePage {
|
||||
initialAddress: exchangeViewModel
|
||||
.receiveCurrency ==
|
||||
exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
? exchangeViewModel.wallet.walletAddresses.address
|
||||
: exchangeViewModel.receiveAddress,
|
||||
initialIsAmountEditable: exchangeViewModel
|
||||
.isReceiveAmountEditable,
|
||||
@@ -268,6 +280,15 @@ class ExchangePage extends BasePage {
|
||||
AddressValidator(
|
||||
type: exchangeViewModel
|
||||
.receiveCurrency),
|
||||
onPushPasteButton: (context) async {
|
||||
final domain =
|
||||
exchangeViewModel.receiveAddress;
|
||||
final ticker = exchangeViewModel
|
||||
.receiveCurrency.title.toLowerCase();
|
||||
exchangeViewModel.receiveAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(
|
||||
context, domain, ticker);
|
||||
},
|
||||
)),
|
||||
)
|
||||
],
|
||||
@@ -371,7 +392,7 @@ class ExchangePage extends BasePage {
|
||||
from: template.depositCurrency,
|
||||
to: template.receiveCurrency,
|
||||
onTap: () {
|
||||
applyTemplate(
|
||||
applyTemplate(context,
|
||||
exchangeViewModel, template);
|
||||
},
|
||||
onRemove: () {
|
||||
@@ -472,8 +493,8 @@ class ExchangePage extends BasePage {
|
||||
));
|
||||
}
|
||||
|
||||
void applyTemplate(
|
||||
ExchangeViewModel exchangeViewModel, ExchangeTemplate template) {
|
||||
void applyTemplate(BuildContext context,
|
||||
ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async {
|
||||
exchangeViewModel.changeDepositCurrency(
|
||||
currency: CryptoCurrency.fromString(template.depositCurrency));
|
||||
exchangeViewModel.changeReceiveCurrency(
|
||||
@@ -491,6 +512,16 @@ class ExchangePage extends BasePage {
|
||||
exchangeViewModel.receiveAddress = template.receiveAddress;
|
||||
exchangeViewModel.isReceiveAmountEntered = false;
|
||||
exchangeViewModel.isFixedRateMode = false;
|
||||
|
||||
var domain = template.depositAddress;
|
||||
var ticker = template.depositCurrency.toLowerCase();
|
||||
exchangeViewModel.depositAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(context, domain, ticker);
|
||||
|
||||
domain = template.receiveAddress;
|
||||
ticker = template.receiveCurrency.toLowerCase();
|
||||
exchangeViewModel.receiveAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(context, domain, ticker);
|
||||
}
|
||||
|
||||
void _setReactions(
|
||||
@@ -646,7 +677,8 @@ class ExchangePage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => exchangeViewModel.wallet.address, (String address) {
|
||||
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
|
||||
(String address) {
|
||||
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||
depositKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
@@ -656,6 +688,26 @@ class ExchangePage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
_depositAddressFocus.addListener(() async {
|
||||
if (!_depositAddressFocus.hasFocus &&
|
||||
depositAddressController.text.isNotEmpty) {
|
||||
final domain = depositAddressController.text;
|
||||
final ticker = exchangeViewModel.depositCurrency.title.toLowerCase();
|
||||
exchangeViewModel.depositAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(context, domain, ticker);
|
||||
}
|
||||
});
|
||||
|
||||
_receiveAddressFocus.addListener(() async {
|
||||
if (!_receiveAddressFocus.hasFocus &&
|
||||
receiveAddressController.text.isNotEmpty) {
|
||||
final domain = receiveAddressController.text;
|
||||
final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase();
|
||||
exchangeViewModel.receiveAddress =
|
||||
await applyOpenaliasOrUnstoppableDomains(context, domain, ticker);
|
||||
}
|
||||
});
|
||||
|
||||
_receiveAmountFocus.addListener(() {
|
||||
if (_receiveAmountFocus.hasFocus && !exchangeViewModel.isFixedRateMode) {
|
||||
showPopUp<void>(
|
||||
@@ -707,7 +759,8 @@ class ExchangePage extends BasePage {
|
||||
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
||||
|
||||
key.currentState.changeAddress(
|
||||
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
|
||||
address: isCurrentTypeWallet
|
||||
? exchangeViewModel.wallet.walletAddresses.address : '');
|
||||
|
||||
key.currentState.changeAmount(amount: '');
|
||||
}
|
||||
@@ -719,11 +772,35 @@ class ExchangePage extends BasePage {
|
||||
if (isCurrentTypeWallet) {
|
||||
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||
key.currentState.addressController.text =
|
||||
exchangeViewModel.wallet.address;
|
||||
exchangeViewModel.wallet.walletAddresses.address;
|
||||
} else if (key.currentState.addressController.text ==
|
||||
exchangeViewModel.wallet.address) {
|
||||
exchangeViewModel.wallet.walletAddresses.address) {
|
||||
key.currentState.changeWalletName(null);
|
||||
key.currentState.addressController.text = null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> applyOpenaliasOrUnstoppableDomains(
|
||||
BuildContext context, String domain, String ticker) async {
|
||||
final parsedAddress = await parseAddressFromDomain(domain, ticker);
|
||||
|
||||
switch (parsedAddress.parseFrom) {
|
||||
case ParseFrom.unstoppableDomains:
|
||||
showAddressAlert(
|
||||
context,
|
||||
S.of(context).address_detected,
|
||||
S.of(context).address_from_domain(parsedAddress.name));
|
||||
break;
|
||||
case ParseFrom.openAlias:
|
||||
showAddressAlert(
|
||||
context,
|
||||
S.of(context).openalias_alert_title,
|
||||
S.of(context).openalias_alert_content(parsedAddress.name));
|
||||
break;
|
||||
case ParseFrom.notParsed:
|
||||
break;
|
||||
}
|
||||
|
||||
return parsedAddress.address;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ class ExchangeTemplatePage extends BasePage {
|
||||
initialAddress: exchangeViewModel
|
||||
.depositCurrency ==
|
||||
exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
? exchangeViewModel.wallet.walletAddresses.address
|
||||
: exchangeViewModel.depositAddress,
|
||||
initialIsAmountEditable: true,
|
||||
initialIsAddressEditable: exchangeViewModel
|
||||
@@ -150,9 +150,8 @@ class ExchangeTemplatePage extends BasePage {
|
||||
.color,
|
||||
currencyValueValidator: AmountValidator(
|
||||
type: exchangeViewModel.wallet.type),
|
||||
addressTextFieldValidator: AddressValidator(
|
||||
type:
|
||||
exchangeViewModel.depositCurrency),
|
||||
//addressTextFieldValidator: AddressValidator(
|
||||
// type: exchangeViewModel.depositCurrency),
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -168,7 +167,7 @@ class ExchangeTemplatePage extends BasePage {
|
||||
initialAddress:
|
||||
exchangeViewModel.receiveCurrency ==
|
||||
exchangeViewModel.wallet.currency
|
||||
? exchangeViewModel.wallet.address
|
||||
? exchangeViewModel.wallet.walletAddresses.address
|
||||
: exchangeViewModel.receiveAddress,
|
||||
initialIsAmountEditable:
|
||||
exchangeViewModel.provider is
|
||||
@@ -190,8 +189,8 @@ class ExchangeTemplatePage extends BasePage {
|
||||
.decorationColor,
|
||||
currencyValueValidator: AmountValidator(
|
||||
type: exchangeViewModel.wallet.type),
|
||||
addressTextFieldValidator: AddressValidator(
|
||||
type: exchangeViewModel.receiveCurrency),
|
||||
//addressTextFieldValidator: AddressValidator(
|
||||
// type: exchangeViewModel.receiveCurrency),
|
||||
)),
|
||||
)
|
||||
],
|
||||
@@ -383,7 +382,8 @@ class ExchangeTemplatePage extends BasePage {
|
||||
}
|
||||
});
|
||||
|
||||
reaction((_) => exchangeViewModel.wallet.address, (String address) {
|
||||
reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
|
||||
(String address) {
|
||||
if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
|
||||
depositKey.currentState.changeAddress(address: address);
|
||||
}
|
||||
@@ -405,7 +405,8 @@ class ExchangeTemplatePage extends BasePage {
|
||||
isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
|
||||
|
||||
key.currentState.changeAddress(
|
||||
address: isCurrentTypeWallet ? exchangeViewModel.wallet.address : '');
|
||||
address: isCurrentTypeWallet
|
||||
? exchangeViewModel.wallet.walletAddresses.address : '');
|
||||
|
||||
key.currentState.changeAmount(amount: '');
|
||||
}
|
||||
@@ -417,9 +418,9 @@ class ExchangeTemplatePage extends BasePage {
|
||||
if (isCurrentTypeWallet) {
|
||||
key.currentState.changeWalletName(exchangeViewModel.wallet.name);
|
||||
key.currentState.addressController.text =
|
||||
exchangeViewModel.wallet.address;
|
||||
exchangeViewModel.wallet.walletAddresses.address;
|
||||
} else if (key.currentState.addressController.text ==
|
||||
exchangeViewModel.wallet.address) {
|
||||
exchangeViewModel.wallet.walletAddresses.address) {
|
||||
key.currentState.changeWalletName(null);
|
||||
key.currentState.addressController.text = null;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ class ExchangeCard extends StatefulWidget {
|
||||
this.currencyValueValidator,
|
||||
this.addressTextFieldValidator,
|
||||
this.amountFocusNode,
|
||||
this.addressFocusNode,
|
||||
this.hasAllAmount = false,
|
||||
this.allAmount})
|
||||
this.allAmount,
|
||||
this.onPushPasteButton})
|
||||
: super(key: key);
|
||||
|
||||
final List<CryptoCurrency> currencies;
|
||||
@@ -49,8 +51,10 @@ class ExchangeCard extends StatefulWidget {
|
||||
final FormFieldValidator<String> currencyValueValidator;
|
||||
final FormFieldValidator<String> addressTextFieldValidator;
|
||||
final FocusNode amountFocusNode;
|
||||
final FocusNode addressFocusNode;
|
||||
final bool hasAllAmount;
|
||||
Function allAmount;
|
||||
final Function allAmount;
|
||||
final Function(BuildContext context) onPushPasteButton;
|
||||
|
||||
@override
|
||||
ExchangeCardState createState() => ExchangeCardState();
|
||||
@@ -288,6 +292,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: AddressTextField(
|
||||
focusNode: widget.addressFocusNode,
|
||||
controller: addressController,
|
||||
placeholder: widget.hasRefundAddress
|
||||
? S.of(context).refund_address
|
||||
@@ -311,6 +316,7 @@ class ExchangeCardState extends State<ExchangeCard> {
|
||||
.decorationColor),
|
||||
buttonColor: widget.addressButtonsColor,
|
||||
validator: widget.addressTextFieldValidator,
|
||||
onPushPasteButton: widget.onPushPasteButton,
|
||||
),
|
||||
)
|
||||
: Padding(
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import 'dart:ui';
|
||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/entities/transaction_priority.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import 'package:cake_wallet/src/screens/transaction_details/textfield_list_item.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/widgets/textfield_list_row.dart';
|
||||
import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_switch_row.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_details_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_switch_item.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:cake_wallet/src/widgets/standart_list_row.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class UnspentCoinsDetailsPage extends BasePage {
|
||||
UnspentCoinsDetailsPage({this.unspentCoinsDetailsViewModel});
|
||||
|
||||
@override
|
||||
String get title => S.current.unspent_coins_details_title;
|
||||
|
||||
final UnspentCoinsDetailsViewModel unspentCoinsDetailsViewModel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return SectionStandardList(
|
||||
sectionCount: 1,
|
||||
itemCounter: (int _) => unspentCoinsDetailsViewModel.items.length,
|
||||
itemBuilder: (_, __, index) {
|
||||
final item = unspentCoinsDetailsViewModel.items[index];
|
||||
|
||||
if (item is StandartListItem) {
|
||||
return StandartListRow(
|
||||
title: '${item.title}:',
|
||||
value: item.value);
|
||||
}
|
||||
|
||||
if (item is TextFieldListItem) {
|
||||
return TextFieldListRow(
|
||||
title: item.title,
|
||||
value: item.value,
|
||||
onSubmitted: item.onSubmitted,
|
||||
);
|
||||
}
|
||||
|
||||
if (item is UnspentCoinsSwitchItem) {
|
||||
return Observer(builder: (_) => UnspentCoinsSwitchRow(
|
||||
title: item.title,
|
||||
switchValue: item.switchValue(),
|
||||
onSwitchValueChange: item.onSwitchValueChange
|
||||
));
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
import 'package:cake_wallet/routes.dart';
|
||||
import 'package:cake_wallet/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:cake_wallet/view_model/unspent_coins/unspent_coins_list_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class UnspentCoinsListPage extends BasePage {
|
||||
UnspentCoinsListPage({this.unspentCoinsListViewModel});
|
||||
|
||||
@override
|
||||
String get title => S.current.unspent_coins_title;
|
||||
|
||||
@override
|
||||
Widget trailing(BuildContext context) {
|
||||
final questionImage = Image.asset('assets/images/question_mark.png',
|
||||
color: Theme.of(context).primaryTextTheme.title.color);
|
||||
|
||||
return SizedBox(
|
||||
height: 20.0,
|
||||
width: 20.0,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => showUnspentCoinsAlert(context),
|
||||
child: questionImage),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final UnspentCoinsListViewModel unspentCoinsListViewModel;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) =>
|
||||
UnspentCoinsListForm(unspentCoinsListViewModel);
|
||||
}
|
||||
|
||||
class UnspentCoinsListForm extends StatefulWidget {
|
||||
UnspentCoinsListForm(this.unspentCoinsListViewModel);
|
||||
|
||||
final UnspentCoinsListViewModel unspentCoinsListViewModel;
|
||||
|
||||
@override
|
||||
UnspentCoinsListFormState createState() =>
|
||||
UnspentCoinsListFormState(unspentCoinsListViewModel);
|
||||
}
|
||||
|
||||
class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
|
||||
UnspentCoinsListFormState(this.unspentCoinsListViewModel);
|
||||
|
||||
final UnspentCoinsListViewModel unspentCoinsListViewModel;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback(afterLayout);
|
||||
}
|
||||
|
||||
void afterLayout(dynamic _) {
|
||||
showUnspentCoinsAlert(context);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.fromLTRB(24, 12, 24, 24),
|
||||
child: Observer(
|
||||
builder: (_) => ListView.separated(
|
||||
itemCount: unspentCoinsListViewModel.items.length,
|
||||
separatorBuilder: (_, __) =>
|
||||
SizedBox(height: 15),
|
||||
itemBuilder: (_, int index) {
|
||||
return Observer(builder: (_) {
|
||||
final item = unspentCoinsListViewModel.items[index];
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () =>
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.unspentCoinsDetails,
|
||||
arguments: [item, unspentCoinsListViewModel]),
|
||||
child: UnspentCoinsListItem(
|
||||
address: item.address,
|
||||
amount: item.amount,
|
||||
isSending: item.isSending,
|
||||
onCheckBoxTap: item.isFrozen
|
||||
? null
|
||||
: () async {
|
||||
item.isSending = !item.isSending;
|
||||
await unspentCoinsListViewModel
|
||||
.saveUnspentCoinInfo(item);}));
|
||||
});
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void showUnspentCoinsAlert(BuildContext context) {
|
||||
showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: 'Information about unspent coins',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class UnspentCoinsListItem extends StatelessWidget {
|
||||
UnspentCoinsListItem({
|
||||
@required this.address,
|
||||
@required this.amount,
|
||||
@required this.isSending,
|
||||
@required this.onCheckBoxTap,
|
||||
});
|
||||
|
||||
static const amountColor = Palette.darkBlueCraiola;
|
||||
static const addressColor = Palette.darkGray;
|
||||
static const selectedItemColor = Palette.paleCornflowerBlue;
|
||||
static const unselectedItemColor = Palette.moderateLavender;
|
||||
|
||||
final String address;
|
||||
final String amount;
|
||||
final bool isSending;
|
||||
final Function() onCheckBoxTap;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final itemColor = isSending? selectedItemColor : unselectedItemColor;
|
||||
|
||||
return Container(
|
||||
height: 62,
|
||||
padding: EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
color: itemColor),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(right: 12),
|
||||
child: GestureDetector(
|
||||
onTap: () => onCheckBoxTap?.call(),
|
||||
child: Container(
|
||||
height: 24.0,
|
||||
width: 24.0,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.caption
|
||||
.color,
|
||||
width: 1.0),
|
||||
borderRadius: BorderRadius.all(
|
||||
Radius.circular(8.0)),
|
||||
color: Theme.of(context).backgroundColor),
|
||||
child: isSending
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: Colors.blue,
|
||||
size: 20.0,
|
||||
)
|
||||
: Offstage(),
|
||||
)
|
||||
)
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AutoSizeText(
|
||||
amount,
|
||||
style: TextStyle(
|
||||
color: amountColor,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600
|
||||
),
|
||||
maxLines: 1,
|
||||
),
|
||||
AutoSizeText(
|
||||
address,
|
||||
style: TextStyle(
|
||||
color: addressColor,
|
||||
fontSize: 12,
|
||||
),
|
||||
maxLines: 1,
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'package:cake_wallet/src/widgets/standart_switch.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class UnspentCoinsSwitchRow extends StatelessWidget {
|
||||
UnspentCoinsSwitchRow(
|
||||
{this.title,
|
||||
this.titleFontSize = 14,
|
||||
this.switchValue,
|
||||
this.onSwitchValueChange});
|
||||
|
||||
final String title;
|
||||
final double titleFontSize;
|
||||
final bool switchValue;
|
||||
final void Function(bool value) onSwitchValueChange;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
color: Theme.of(context).backgroundColor,
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 24, top: 16, bottom: 16, right: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: titleFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme.overline.color),
|
||||
textAlign: TextAlign.left),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 12),
|
||||
child: StandartSwitch(
|
||||
value: switchValue,
|
||||
onTaped: () => onSwitchValueChange(!switchValue))
|
||||
)
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,8 @@ class AddressTextField extends StatelessWidget {
|
||||
this.iconColor,
|
||||
this.textStyle,
|
||||
this.hintStyle,
|
||||
this.validator});
|
||||
this.validator,
|
||||
this.onPushPasteButton});
|
||||
|
||||
static const prefixIconWidth = 34.0;
|
||||
static const prefixIconHeight = 34.0;
|
||||
@@ -43,6 +44,7 @@ class AddressTextField extends StatelessWidget {
|
||||
final TextStyle textStyle;
|
||||
final TextStyle hintStyle;
|
||||
final FocusNode focusNode;
|
||||
final Function(BuildContext context) onPushPasteButton;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -225,5 +227,7 @@ class AddressTextField extends StatelessWidget {
|
||||
if (address?.isNotEmpty ?? false) {
|
||||
controller.text = address;
|
||||
}
|
||||
|
||||
onPushPasteButton?.call(context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,6 @@ class StandardCheckboxState extends State<StandardCheckbox> {
|
||||
Container(
|
||||
height: 24.0,
|
||||
width: 24.0,
|
||||
margin: EdgeInsets.only(
|
||||
right: 10.0,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context)
|
||||
@@ -65,14 +62,17 @@ class StandardCheckboxState extends State<StandardCheckbox> {
|
||||
)
|
||||
: Offstage(),
|
||||
),
|
||||
Text(
|
||||
caption,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color),
|
||||
if (caption.isNotEmpty) Padding(
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
caption,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.title
|
||||
.color),
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:cake_wallet/palette.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user