mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-23 11:15:33 +00:00
Add Verification screen
This commit is contained in:
parent
c2976cbe05
commit
65165aa5e0
7 changed files with 191 additions and 6 deletions
|
@ -65,6 +65,7 @@ import 'package:cake_wallet/wallet_types.g.dart';
|
||||||
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart';
|
||||||
import 'package:cake_wallet/src/screens/cake_phone/cake_phone_welcome_page.dart';
|
import 'package:cake_wallet/src/screens/cake_phone/cake_phone_welcome_page.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/cake_phone/cake_phone_verification_page.dart';
|
||||||
|
|
||||||
RouteSettings currentRouteSettings;
|
RouteSettings currentRouteSettings;
|
||||||
|
|
||||||
|
@ -415,6 +416,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||||
builder: (_) => CakePhoneAuthPage(isLogin: isLogin),
|
builder: (_) => CakePhoneAuthPage(isLogin: isLogin),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
case Routes.cakePhoneVerification:
|
||||||
|
return MaterialPageRoute<CakePhoneVerificationPage>(
|
||||||
|
builder: (_) => CakePhoneVerificationPage(),
|
||||||
|
);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute<void>(
|
return MaterialPageRoute<void>(
|
||||||
builder: (_) => Scaffold(
|
builder: (_) => Scaffold(
|
||||||
|
|
|
@ -62,4 +62,5 @@ class Routes {
|
||||||
static const fullscreenQR = '/fullscreen_qr';
|
static const fullscreenQR = '/fullscreen_qr';
|
||||||
static const cakePhoneWelcome = '/cake_phone_welcome';
|
static const cakePhoneWelcome = '/cake_phone_welcome';
|
||||||
static const cakePhoneAuth = '/cake_phone_auth';
|
static const cakePhoneAuth = '/cake_phone_auth';
|
||||||
|
static const cakePhoneVerification = '/cake_phone_verification';
|
||||||
}
|
}
|
|
@ -50,13 +50,19 @@ class CakePhoneAuthBodyState extends State<CakePhoneAuthBody> {
|
||||||
controller: _emailController,
|
controller: _emailController,
|
||||||
keyboardType: TextInputType.emailAddress,
|
keyboardType: TextInputType.emailAddress,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
hintText: S.of(context).emailAddress,
|
hintText: S.of(context).email_address,
|
||||||
),
|
),
|
||||||
bottomSectionPadding: EdgeInsets.only(bottom: 24, right: 24, left: 24),
|
bottomSectionPadding: EdgeInsets.only(bottom: 24, right: 24, left: 24),
|
||||||
bottomSection: Column(
|
bottomSection: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
onPressed: () {},
|
onPressed: () {
|
||||||
|
if (widget.isLogin) {
|
||||||
|
_loginCakePhone();
|
||||||
|
} else {
|
||||||
|
_registerCakePhone();
|
||||||
|
}
|
||||||
|
},
|
||||||
text: widget.isLogin ? S.of(context).login : S.of(context).create_account,
|
text: widget.isLogin ? S.of(context).login : S.of(context).create_account,
|
||||||
color: Theme.of(context).accentTextTheme.body2.color,
|
color: Theme.of(context).accentTextTheme.body2.color,
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
|
@ -105,4 +111,14 @@ class CakePhoneAuthBodyState extends State<CakePhoneAuthBody> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _registerCakePhone() {
|
||||||
|
// TODO: Add Registration logic
|
||||||
|
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _loginCakePhone() {
|
||||||
|
// TODO: Add Login logic
|
||||||
|
Navigator.pushNamed(context, Routes.cakePhoneVerification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
151
lib/src/screens/cake_phone/cake_phone_verification_page.dart
Normal file
151
lib/src/screens/cake_phone/cake_phone_verification_page.dart
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:cake_wallet/routes.dart';
|
||||||
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/primary_button.dart';
|
||||||
|
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||||
|
import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
|
||||||
|
|
||||||
|
class CakePhoneVerificationPage extends BasePage {
|
||||||
|
CakePhoneVerificationPage();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget body(BuildContext context) => CakePhoneVerificationBody();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget middle(BuildContext context) {
|
||||||
|
return Text(
|
||||||
|
S.of(context).email_verification,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 22,
|
||||||
|
fontWeight: FontWeight.w600,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
color: titleColor ?? Theme.of(context).primaryTextTheme.title.color),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CakePhoneVerificationBody extends StatefulWidget {
|
||||||
|
CakePhoneVerificationBody();
|
||||||
|
|
||||||
|
@override
|
||||||
|
CakePhoneVerificationBodyState createState() => CakePhoneVerificationBodyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class CakePhoneVerificationBodyState extends State<CakePhoneVerificationBody> {
|
||||||
|
final _codeController = TextEditingController();
|
||||||
|
|
||||||
|
int resendCount = 0;
|
||||||
|
int timeLeft = 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
_startTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: EdgeInsets.only(top: 16),
|
||||||
|
child: ScrollableWithBottomSection(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(24, 100, 24, 20),
|
||||||
|
content: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
child: Text(
|
||||||
|
S.of(context).fill_verification_code,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Theme.of(context).primaryTextTheme.title.color,
|
||||||
|
fontFamily: 'Lato',
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
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,
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (timeLeft > 0)
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
S.of(context).did_not_get_code,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).hintColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
S.of(context).resend_code_in + " ${timeLeft ~/ 60}:" + (timeLeft % 60).toString().padLeft(2, '0'),
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
color: Theme.of(context).textTheme.subtitle.color,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
bottomSectionPadding: EdgeInsets.only(bottom: 24, right: 24, left: 24),
|
||||||
|
bottomSection: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
PrimaryButton(
|
||||||
|
onPressed: () {},
|
||||||
|
text: S.of(context).continue_text,
|
||||||
|
color: Theme.of(context).accentTextTheme.body2.color,
|
||||||
|
textColor: Colors.white,
|
||||||
|
isDisabled: _codeController.text.isEmpty,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _startTimer() {
|
||||||
|
resendCount++;
|
||||||
|
timeLeft = (resendCount * 30);
|
||||||
|
setState(() {});
|
||||||
|
Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
|
timeLeft--;
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
if (timeLeft <= 0) {
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,9 +41,7 @@ class CakePhoneWelcomeBodyState extends State<CakePhoneWelcomeBody> {
|
||||||
child: ScrollableWithBottomSection(
|
child: ScrollableWithBottomSection(
|
||||||
contentPadding: EdgeInsets.fromLTRB(24, 100, 24, 20),
|
contentPadding: EdgeInsets.fromLTRB(24, 100, 24, 20),
|
||||||
content: Text(
|
content: Text(
|
||||||
'''Cake Phone allows you to purchase virtual phone numbers with digital assets!
|
S.of(context).cake_phone_introduction,
|
||||||
|
|
||||||
Only an email is required.''',
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Theme.of(context).primaryTextTheme.title.color,
|
color: Theme.of(context).primaryTextTheme.title.color,
|
||||||
|
|
|
@ -80,6 +80,12 @@ class WalletMenu {
|
||||||
image: Image.asset('assets/images/question_mark.png',
|
image: Image.asset('assets/images/question_mark.png',
|
||||||
height: 16, width: 16, color: Palette.darkBlue),
|
height: 16, width: 16, color: Palette.darkBlue),
|
||||||
handler: () => Navigator.of(context).pushNamed(Routes.support)),
|
handler: () => Navigator.of(context).pushNamed(Routes.support)),
|
||||||
|
// TODO: Move this to marketplace screen when ready
|
||||||
|
WalletMenuItem(
|
||||||
|
title: S.current.settings_support,
|
||||||
|
image: Image.asset('assets/images/question_mark.png',
|
||||||
|
height: 16, width: 16, color: Palette.darkBlue),
|
||||||
|
handler: () => Navigator.of(context).pushNamed(Routes.cakePhoneWelcome)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -544,5 +544,12 @@
|
||||||
"cake_phone_terms_conditions_second_section": "of Cake Phone, which indicates you will receive all account notices and information electronically to the email address provided",
|
"cake_phone_terms_conditions_second_section": "of Cake Phone, which indicates you will receive all account notices and information electronically to the email address provided",
|
||||||
"privacy_policy": "Privacy Policy",
|
"privacy_policy": "Privacy Policy",
|
||||||
"and": "and",
|
"and": "and",
|
||||||
"emailAddress": "Email Address"
|
"email_address": "Email Address",
|
||||||
|
"email_verification": "Email Verification",
|
||||||
|
"fill_verification_code": "Please fill in the verification code provided to your email:",
|
||||||
|
"verification_code": "Verification code",
|
||||||
|
"did_not_get_code": "Didn't get the code?",
|
||||||
|
"resend_code_in": "Resend code in",
|
||||||
|
"get_code": "Get Code",
|
||||||
|
"cake_phone_introduction": "Cake Phone allows you to purchase virtual phone numbers with digital assets!\n\nOnly an email is required."
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue