import 'dart:math'; import 'package:animations/animations.dart'; import 'package:dapp/main.dart'; import 'package:dapp/utils/FadeAnimation.dart'; import 'package:dapp/utils/delayed_animation.dart'; import 'package:dapp/utils/phone_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:country_code_picker/country_code_picker.dart'; import 'package:firebase_auth/firebase_auth.dart'; class LoginPage extends StatefulWidget { LoginPage({Key key}) : super(key: key); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _phoneKey = GlobalKey(); bool _autoValidate = false; bool _phoneValidate = false; String _mobile; Map userInputs = Map(); String _countryPrefix = "+90"; bool _verificationReceived = true; bool codeArrived = false; String verificationCode; static int currentWidget = 0; final FirebaseAuth _auth = FirebaseAuth.instance; @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.black, body: firstStep(context))); } /*Container secondStep(BuildContext context) { return Container( color: Colors.black, child: Center( child: IconButton( icon: Icon( Icons.access_alarm, color: Colors.white, ), onPressed: () { setState(() { currentWidget = 0; }); }, ), ), ); } */ SafeArea firstStep(BuildContext context) { return SafeArea( child: Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.black, body: FadeAnimation( 3.0, Container( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Continue with", style: TextStyle( fontWeight: FontWeight.normal, color: Colors.white, fontSize: 14), ), SizedBox( height: 20, ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Icon( Ionicons.logo_facebook, color: Colors.white, size: MediaQuery.of(context).size.height / 20, ), Icon( Ionicons.logo_instagram, color: Colors.white, size: MediaQuery.of(context).size.height / 20, ), Icon( Ionicons.logo_google, color: Colors.white, size: MediaQuery.of(context).size.height / 20, ), ], ), SizedBox( height: 50, ), Text( "Or sign in with phone-number", style: TextStyle( fontWeight: FontWeight.normal, color: Colors.white, fontSize: 12), ), SizedBox( height: 10, ), CountryCodePicker( countryFilter: ["+90", "+33", "US", "+49"], textStyle: TextStyle(color: Colors.white), initialSelection: 'TR', onInit: (c) { this._countryPrefix = c.dialCode; }, onChanged: (c) { this._countryPrefix = c.dialCode; }, showCountryOnly: true, showOnlyCountryWhenClosed: true, ), Container( margin: EdgeInsets.only(left: 30, right: 30, top: 50), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ phoneNumberValidation(), SizedBox( height: 30, ), FadeAnimation( 8, CircleAvatar( backgroundColor: Colors.white, child: IconButton( icon: Icon(CupertinoIcons.down_arrow, color: Colors.deepPurple), onPressed: this._verificationReceived == true ? () => this._validatePhoneNumber(context) : () => this._validatePhoneNumber(context)), ), ) ], ), ), ], ), ), ), ), ); } Form phoneNumberValidation() { return Form( autovalidate: _autoValidate, key: _formKey, child: Center( child: TextFormField( enabled: _verificationReceived, keyboardAppearance: Brightness.dark, maxLength: 10, autocorrect: true, textAlign: TextAlign.center, validator: (String value) { String patttern = r'(^(?:[+0]9)?[0-9]{10,12}$)'; RegExp regExp = new RegExp(patttern); if (value.length == 0) { return 'Lütfen geçerli bir telefon numarası girin.'; } else if (!regExp.hasMatch(value)) { return 'Lütfen geçerli bir telefon numarası girin.'; } return null; }, style: TextStyle(color: Colors.white, fontSize: 13), decoration: InputDecoration( errorStyle: TextStyle(color: Colors.red), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.deepPurple, width: 0.2), borderRadius: BorderRadius.all(Radius.circular(10))), errorBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.deepPurple, width: 0.2), borderRadius: BorderRadius.all(Radius.circular(10))), hintText: "555555-1234", hintStyle: TextStyle(color: Colors.white), prefixText: "${this._countryPrefix} ", prefixStyle: TextStyle(color: Colors.blue[800], fontSize: 13), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.deepPurple, width: 0.2), borderRadius: BorderRadius.all(Radius.circular(10))), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.deepPurple, width: 0.2), borderRadius: BorderRadius.all(Radius.circular(10))), alignLabelWithHint: true, labelStyle: TextStyle(color: Colors.white, fontSize: 13), labelText: 'Phone Number'), keyboardType: TextInputType.phone, onSaved: (String val) { setState(() { this._mobile = val; }); }, ), ), ); } void codeChecker(String code) { this.verificationCode = code; setState(() { this.codeArrived = true; }); } void _validatePhoneNumber(context) { if (_formKey.currentState.validate()) { _formKey.currentState.save(); PhoneAuth authenticator = PhoneAuth( this._countryPrefix + this._mobile, context, func: codeChecker); setState(() { this._verificationReceived = false; }); authenticator.auth().whenComplete(() async { FirebaseUser currentUser = await this._auth.currentUser(); if (currentUser == null) { createVerifyScreen(context); } }); } else { setState(() { _autoValidate = true; }); } } createVerifyScreen(context) async { showModalBottomSheet( context: this.context, isDismissible: false, isScrollControlled: true, builder: (BuildContext c) { return Container( height: MediaQuery.of(this.context).size.height / 1.2, decoration: BoxDecoration( border: Border.all(color: Colors.white60, width: 0.1), color: Colors.deepPurple, borderRadius: BorderRadius.only( topLeft: Radius.circular(30), topRight: Radius.circular(30))), child: FadeAnimation( 1, Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text("We sent you a code to verify", style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, )), Text("your mobile number", style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, )), SizedBox( height: 10, ), Container( height: 80, width: MediaQuery.of(context).size.width, margin: EdgeInsets.only(left: 15, right: 15, top: 25), color: Colors.transparent, child: Form( autovalidate: _phoneValidate, key: _phoneKey, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ numberInput(1.6, "1", 0), SizedBox(width: 3), numberInput(1.6, "3", 1), SizedBox(width: 3), numberInput(1.6, "0", 2), SizedBox(width: 3), numberInput(1.8, "6", 3), SizedBox(width: 3), numberInput(1.8, "9", 4), SizedBox(width: 3), numberInput(1.8, "7", 5), ]), ), ), Text("Enter your 6-digit verification code and click verify", style: TextStyle(color: Colors.white54, fontSize: 10)), SizedBox( height: 30, ), Text("1:59", style: TextStyle(color: Colors.white54, fontSize: 10)), RaisedButton.icon( animationDuration: Duration(seconds: 1), color: Colors.black, shape: RoundedRectangleBorder( borderRadius: new BorderRadius.circular(18.0), side: BorderSide(color: Colors.transparent)), onPressed: (codeArrived == true) ? () async { if (_phoneKey.currentState.validate()) { _phoneKey.currentState.save(); try { AuthResult result = await this ._auth .signInWithCredential( PhoneAuthProvider.getCredential( verificationId: this.verificationCode, smsCode: "${this.userInputs[0]}${this.userInputs[1]}${this.userInputs[2]}${this.userInputs[3]}${this.userInputs[4]}${this.userInputs[5]}")); if (result.user != null) { Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute( builder: (context) => MainPage()), ((Route route) => false)); } } catch (AuthException) { print("Authentication exception occured."); } } else { setState(() { _phoneValidate = true; }); } } : null, icon: Icon(FontAwesome5.check_circle, size: 13, color: Colors.deepPurple), label: Text("VERIFY NUMBER", style: TextStyle( color: Colors.white, fontSize: 10, )), ), InkWell( onTap: () => print(""), child: Text( "I did not receive the code.ntttttttResend the code.", style: TextStyle(color: Colors.white54, fontSize: 10)), ), ], ), ), ); }); } Flexible numberInput(double dur, hnt, int index) { return Flexible( flex: 2, child: DelayedAnimation( delay: dur.floor(), curve: Curves.fastOutSlowIn, offset: Offset(0, 1), child: TextFormField( inputFormatters: [WhitelistingTextInputFormatter.digitsOnly], showCursor: false, validator: (str) { if (str == "") { return ""; } else return null; }, style: TextStyle( color: Colors.black, fontSize: 14, fontWeight: FontWeight.bold), decoration: InputDecoration( counterText: "", hintText: hnt, hintStyle: TextStyle(color: Colors.black12), filled: true, helperText: "", fillColor: Colors.white, focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black, width: 0.8), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black, width: 0.5), borderRadius: BorderRadius.circular(50)), border: OutlineInputBorder( borderSide: BorderSide(color: Colors.purpleAccent))), maxLength: 1, textAlign: TextAlign.center, keyboardType: TextInputType.number, onChanged: (str) { this.userInputs[index] = str; print(this.userInputs[index]); }), ), ); } }