mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-24 03:26:38 +00:00
Added 'AddBalanceViewModel'
Added form validations
This commit is contained in:
parent
93e7c129f1
commit
2798132313
6 changed files with 165 additions and 46 deletions
|
@ -8,6 +8,7 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
|||
import 'package:cake_wallet/src/screens/cake_phone/phone_number_service/auto_renew_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/cake_phone/phone_number_service/number_settings_page.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
|
||||
import 'package:cake_wallet/view_model/cake_phone/add_balance_view_model.dart';
|
||||
import 'package:cake_wallet/view_model/cake_phone/phone_plan_view_model.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cake_wallet/core/backup_service.dart';
|
||||
|
@ -662,7 +663,13 @@ Future setup(
|
|||
));
|
||||
|
||||
getIt.registerFactory(() {
|
||||
return AddBalancePage(/* Add balance view model */);
|
||||
final wallet = getIt.get<AppStore>().wallet;
|
||||
|
||||
return AddBalanceViewModel(getIt.get<BuyAmountViewModel>(), wallet: wallet);
|
||||
});
|
||||
|
||||
getIt.registerFactory(() {
|
||||
return AddBalancePage(addBalanceViewModel: getIt.get<AddBalanceViewModel>());
|
||||
});
|
||||
|
||||
_isSetupFinished = true;
|
||||
|
|
|
@ -4,18 +4,26 @@ import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
import 'package:cake_wallet/view_model/cake_phone/add_balance_view_model.dart';
|
||||
|
||||
class AddBalancePage extends BasePage {
|
||||
AddBalancePage()
|
||||
AddBalancePage({@required this.addBalanceViewModel})
|
||||
: _amountFocus = FocusNode(),
|
||||
_amountController = TextEditingController() {
|
||||
_amountController.addListener(() {});
|
||||
_amountController.addListener(() {
|
||||
final amount = _amountController.text;
|
||||
|
||||
if (amount != addBalanceViewModel.buyAmountViewModel.amount) {
|
||||
addBalanceViewModel.buyAmountViewModel.amount = amount;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static const _amountPattern = '^([0-9]+([.\,][0-9]{0,2})?|[.\,][0-9]{1,2})\$';
|
||||
|
@ -25,6 +33,7 @@ class AddBalancePage extends BasePage {
|
|||
"500 additional SMS",
|
||||
];
|
||||
|
||||
final AddBalanceViewModel addBalanceViewModel;
|
||||
final FocusNode _amountFocus;
|
||||
final TextEditingController _amountController;
|
||||
|
||||
|
@ -151,13 +160,19 @@ class AddBalancePage extends BasePage {
|
|||
],
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: LoadingPrimaryButton(
|
||||
onPressed: () {},
|
||||
text: S.of(context).buy,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
isDisabled: _amountController.text.isEmpty,
|
||||
bottomSection: Observer(
|
||||
builder: (_) {
|
||||
return LoadingPrimaryButton(
|
||||
onPressed: () {
|
||||
|
||||
},
|
||||
text: S.of(context).buy,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isLoading: false,
|
||||
isDisabled: addBalanceViewModel.buyAmountViewModel.amount.isEmpty,
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -39,6 +39,9 @@ class CakePhoneAuthBody extends StatefulWidget {
|
|||
|
||||
class CakePhoneAuthBodyState extends State<CakePhoneAuthBody> {
|
||||
final _emailController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
AutovalidateMode _autoValidate = AutovalidateMode.disabled;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -46,11 +49,23 @@ class CakePhoneAuthBodyState extends State<CakePhoneAuthBody> {
|
|||
padding: EdgeInsets.only(top: 16),
|
||||
child: ScrollableWithBottomSection(
|
||||
contentPadding: EdgeInsets.fromLTRB(24, 100, 24, 20),
|
||||
content: BaseTextFormField(
|
||||
controller: _emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
maxLines: 1,
|
||||
hintText: S.of(context).email_address,
|
||||
content: Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: _autoValidate,
|
||||
child: BaseTextFormField(
|
||||
controller: _emailController,
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
maxLines: 1,
|
||||
hintText: S.of(context).email_address,
|
||||
validator: (String text) {
|
||||
text = text.trim();
|
||||
if (text.isNotEmpty && RegExp(r"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$").hasMatch(text)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return S.of(context).invalid_email;
|
||||
},
|
||||
),
|
||||
),
|
||||
bottomSectionPadding: EdgeInsets.only(bottom: 24, right: 24, left: 24),
|
||||
bottomSection: Column(
|
||||
|
@ -114,11 +129,23 @@ class CakePhoneAuthBodyState extends State<CakePhoneAuthBody> {
|
|||
|
||||
void _registerCakePhone() {
|
||||
// TODO: Add Registration logic
|
||||
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||
if (_formKey.currentState.validate()) {
|
||||
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||
} else {
|
||||
setState(() {
|
||||
_autoValidate = AutovalidateMode.always;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _loginCakePhone() {
|
||||
// TODO: Add Login logic
|
||||
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||
if (_formKey.currentState.validate()) {
|
||||
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||
} else {
|
||||
setState(() {
|
||||
_autoValidate = AutovalidateMode.always;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,15 +37,30 @@ class CakePhoneVerificationBody extends StatefulWidget {
|
|||
|
||||
class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
|
||||
final _codeController = TextEditingController();
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
AutovalidateMode _autoValidate = AutovalidateMode.disabled;
|
||||
|
||||
int resendCount = 0;
|
||||
int timeLeft = 0;
|
||||
|
||||
bool disabled = true;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_startTimer();
|
||||
|
||||
_codeController.addListener(() {
|
||||
if (_codeController.text.isEmpty) {
|
||||
disabled = true;
|
||||
setState(() {});
|
||||
} else if (disabled) {
|
||||
disabled = false;
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -70,29 +85,40 @@ class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
|
|||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 25),
|
||||
child: BaseTextFormField(
|
||||
controller: _codeController,
|
||||
maxLines: 1,
|
||||
hintText: S.of(context).verification_code,
|
||||
suffixIcon: timeLeft > 0
|
||||
? null
|
||||
: InkWell(
|
||||
onTap: _startTimer,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
margin: EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).accentTextTheme.caption.color,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).get_code,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontWeight: FontWeight.w900,
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
autovalidateMode: _autoValidate,
|
||||
child: BaseTextFormField(
|
||||
controller: _codeController,
|
||||
maxLines: 1,
|
||||
hintText: S.of(context).verification_code,
|
||||
suffixIcon: timeLeft > 0
|
||||
? null
|
||||
: InkWell(
|
||||
onTap: _startTimer,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||
margin: EdgeInsets.only(bottom: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).accentTextTheme.caption.color,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
)),
|
||||
),
|
||||
child: Text(
|
||||
S.of(context).get_code,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).primaryTextTheme.title.color,
|
||||
fontWeight: FontWeight.w900,
|
||||
),
|
||||
)),
|
||||
),
|
||||
validator: (String text) {
|
||||
// TODO: check and apply verification constraints with backend
|
||||
if (text.length < 4) {
|
||||
return S.of(context).invalid_verification_code;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (timeLeft > 0)
|
||||
|
@ -123,16 +149,22 @@ class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
|
|||
children: <Widget>[
|
||||
PrimaryButton(
|
||||
onPressed: () {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
Routes.cakePhoneProducts,
|
||||
ModalRoute.withName(Routes.cakePhoneWelcome),
|
||||
);
|
||||
if (_formKey.currentState.validate()) {
|
||||
Navigator.pushNamedAndRemoveUntil(
|
||||
context,
|
||||
Routes.cakePhoneProducts,
|
||||
ModalRoute.withName(Routes.cakePhoneWelcome),
|
||||
);
|
||||
} else {
|
||||
setState(() {
|
||||
_autoValidate = AutovalidateMode.always;
|
||||
});
|
||||
}
|
||||
},
|
||||
text: S.of(context).continue_text,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
textColor: Colors.white,
|
||||
isDisabled: _codeController.text.isEmpty,
|
||||
isDisabled: disabled,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
36
lib/view_model/cake_phone/add_balance_view_model.dart
Normal file
36
lib/view_model/cake_phone/add_balance_view_model.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
|
||||
part 'add_balance_view_model.g.dart';
|
||||
|
||||
class AddBalanceViewModel = AddBalanceViewModelBase with _$AddBalanceViewModel;
|
||||
|
||||
abstract class AddBalanceViewModelBase with Store {
|
||||
AddBalanceViewModelBase(this.buyAmountViewModel, {@required this.wallet}) {
|
||||
isRunning = false;
|
||||
isDisabled = true;
|
||||
}
|
||||
|
||||
final BuyAmountViewModel buyAmountViewModel;
|
||||
final WalletBase wallet;
|
||||
|
||||
@observable
|
||||
bool isRunning;
|
||||
|
||||
@observable
|
||||
bool isDisabled;
|
||||
|
||||
WalletType get type => wallet.type;
|
||||
|
||||
double get doubleAmount => buyAmountViewModel.doubleAmount;
|
||||
|
||||
@computed
|
||||
FiatCurrency get fiatCurrency => buyAmountViewModel.fiatCurrency;
|
||||
|
||||
CryptoCurrency get cryptoCurrency => walletTypeToCryptoCurrency(type);
|
||||
}
|
|
@ -594,5 +594,7 @@
|
|||
"transaction_sent_popup_info": "Your transaction was sent. \n\nIf the screen doesn’t proceed after 1 minute, check a block explorer and your email.",
|
||||
"cake_phone_products_example": "Example independent uses",
|
||||
"add_balance": "Add Balance",
|
||||
"forwards": "forwards"
|
||||
"forwards": "forwards",
|
||||
"invalid_email": "Invalid Email",
|
||||
"invalid_verification_code": "Invalid verification code"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue