Added 'AddBalanceViewModel'

Added form validations
This commit is contained in:
OmarHatem28 2022-07-07 14:37:09 +02:00
parent 93e7c129f1
commit 2798132313
6 changed files with 165 additions and 46 deletions

View file

@ -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;

View file

@ -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: () {},
bottomSection: Observer(
builder: (_) {
return LoadingPrimaryButton(
onPressed: () {
},
text: S.of(context).buy,
color: Theme.of(context).accentTextTheme.body2.color,
textColor: Colors.white,
isLoading: false,
isDisabled: _amountController.text.isEmpty,
isDisabled: addBalanceViewModel.buyAmountViewModel.amount.isEmpty,
);
}
),
),
),

View file

@ -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(
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
if (_formKey.currentState.validate()) {
Navigator.pushNamed(context, Routes.cakePhoneVerification);
} else {
setState(() {
_autoValidate = AutovalidateMode.always;
});
}
}
void _loginCakePhone() {
// TODO: Add Login logic
if (_formKey.currentState.validate()) {
Navigator.pushNamed(context, Routes.cakePhoneVerification);
} else {
setState(() {
_autoValidate = AutovalidateMode.always;
});
}
}
}

View file

@ -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,6 +85,9 @@ class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 25),
child: Form(
key: _formKey,
autovalidateMode: _autoValidate,
child: BaseTextFormField(
controller: _codeController,
maxLines: 1,
@ -93,6 +111,14 @@ class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
),
)),
),
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: () {
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,
),
],
),

View 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);
}

View file

@ -594,5 +594,7 @@
"transaction_sent_popup_info": "Your transaction was sent. \n\nIf the screen doesnt 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"
}