Untitled
import 'dart:developer'; import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:google_sign_in/google_sign_in.dart'; import 'package:local_auth/local_auth.dart'; import 'package:nadsoft_bloc_core/config/navigator/navigator.dart'; import 'package:nadsoft_bloc_core/config/theme/colors.dart'; import 'package:nadsoft_bloc_core/core/cache/cash_manager.dart'; import 'package:nadsoft_bloc_core/core/cache/secure_storage.dart'; import 'package:nadsoft_bloc_core/core/common/constants/assets.dart'; import 'package:nadsoft_bloc_core/core/common/constants/strings.dart'; import 'package:nadsoft_bloc_core/core/common/enum/biometric_enum.dart'; import 'package:nadsoft_bloc_core/core/common/helper/validators.dart'; import 'package:nadsoft_bloc_core/core/common/shared_widgets/ar_scaffold.dart'; import 'package:nadsoft_bloc_core/core/common/shared_widgets/button_widget.dart'; import 'package:nadsoft_bloc_core/core/common/shared_widgets/loading_widget.dart'; import 'package:nadsoft_bloc_core/core/common/shared_widgets/text_form_field_widget.dart'; import 'package:nadsoft_bloc_core/core/main_notifier/main_notifier.dart'; import 'package:nadsoft_bloc_core/feature/feed/presentation/notifier/feed_notifier.dart'; import 'package:nadsoft_bloc_core/feature/forgot_password/presentation/view/forgot_password_page.dart'; import 'package:nadsoft_bloc_core/feature/main_page/presentation/view/main_page.dart'; import 'package:nadsoft_bloc_core/feature/sign_in/presentation/notifier/sign_in_notifier.dart'; import 'package:nadsoft_bloc_core/feature/sign_up_email/presentation/view/sign_up_email_page.dart'; import 'package:provider/provider.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; class SignInPage extends StatelessWidget { const SignInPage({super.key}); @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (context) => SignInNotifier(), child: const SignInScreen(), ); } } class SignInScreen extends StatefulWidget { const SignInScreen({super.key}); @override State<SignInScreen> createState() => _SignInScreenState(); } class _SignInScreenState extends State<SignInScreen> { late SignInNotifier signInNotifier; late MainNotifier mainNotifier; late FeedNotifier feedNotifier; @override void initState() { super.initState(); mainNotifier = Provider.of<MainNotifier>(context, listen: false); signInNotifier = Provider.of<SignInNotifier>(context, listen: false); feedNotifier = Provider.of<FeedNotifier>(context, listen: false); signInNotifier.initDeviceInfo(); checkGoogleLogged(); hasBiometric(); } checkGoogleLogged() async { if (GoogleSignIn().currentUser != null) { await GoogleSignIn().signOut(); try { await GoogleSignIn().disconnect().then((value) {}); } catch (e) { log(e.toString()); } } } hasBiometric() async { bool hasBiometric = await CachManager.getCachedBiometric() ?? false; bool support = mainNotifier.biometricType != BiometricEnum.none; signInNotifier.setHasBiometricChecker(hasBiometric && support); } @override Widget build(BuildContext context) { return ARScaffold( title: 'signin', backgroundColor: ColorManager.white, resizeToAvoidBottomInset: false, body: Stack( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 24), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// white space const SizedBox(height: 64), /// archivee logo Row( children: [ Image.asset( Assets.logoA, width: 36, ), const SizedBox(width: 2), Image.asset( Assets.logoV, width: 36, ), IconButton( icon: Icon(Icons.abc), onPressed: () async { List<AssetEntity>? _selectedAssets; try { final List<AssetEntity>? result = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( maxAssets: 10, requestType: RequestType .common, // Allows both images and videos textDelegate: AssetPickerTextDelegate(), // You can customize this to change dialog texts specialItemPosition: SpecialItemPosition.none, specialItemBuilder: (context, path, length) { return Text(length.toString()); }, ), ); if (result != null) { setState(() { _selectedAssets = result; }); } } catch (e) { // Handle any exceptions that occur during asset selection print('Error picking assets: $e'); } }, ), ], ), /// white space const SizedBox(height: 32), /// welcome text Text( Strings.signInWelcome, style: Theme.of(context) .textTheme .displayMedium! .copyWith(fontSize: 16, fontWeight: FontWeight.w500), ), /// white space const SizedBox(height: 12), /// description Text( Strings.signInTitle, style: Theme.of(context) .textTheme .displayMedium! .copyWith(fontSize: 20, fontWeight: FontWeight.w600), ), /// white space const SizedBox(height: 40), Form( key: signInNotifier.formKey, child: Column( children: [ /// email text field TextFormFieldWidget( keyboardType: TextInputType.emailAddress, controller: signInNotifier.emailController, enabledBorderColor: ColorManager.textFormFieldBorderColor, focusedBorderColor: ColorManager.textFormFieldBorderColor, borderRadius: 8, backgroundColor: signInNotifier.passController.text.isEmpty ? ColorManager.lGray1 : ColorManager.white, label: Strings.email, contentPaddingHorizontal: 16, validator: (val) => Validators() .emailSignInValidate( val!, signInNotifier.emailController)), /// white space const SizedBox(height: 20), /// password text field Selector<SignInNotifier, bool>( builder: (context, provider, widget) { return TextFormFieldWidget( keyboardType: TextInputType.visiblePassword, controller: signInNotifier.passController, enabledBorderColor: ColorManager.textFormFieldBorderColor, focusedBorderColor: ColorManager.textFormFieldBorderColor, borderRadius: 8, backgroundColor: signInNotifier.passController.text.isEmpty ? ColorManager.lGray1 : ColorManager.white, label: Strings.password, maxLines: 1, obscure: provider, contentPaddingHorizontal: 16, validator: (val) => Validators() .signInPasswordValid( val!, signInNotifier.passController), suffixIcon: GestureDetector( onTap: () { signInNotifier.setPassObscure(!provider); }, child: SvgPicture.asset( signInNotifier.passObscure ? Assets.icObscureOff : Assets.icObscureOn, width: 24, ), ), fontSize: 16, ); }, selector: (context, selector) => selector.passObscure, ), ], ), ), /// white space const SizedBox(height: 8), /// forgot password GestureDetector( onTap: () { navigatePushAndRemoveUntil( context: context, pageName: ForgotPasswordPage()); }, child: Align( alignment: Alignment.centerRight, child: Text( Strings.forgotPassword, style: Theme.of(context) .textTheme .displayMedium! .copyWith( fontSize: 12, fontWeight: FontWeight.w500, color: ColorManager.dGray5), ), ), ), /// white space SizedBox(height: MediaQuery.of(context).size.height * 0.07), /// sign in buttons Align( alignment: Alignment.center, child: Selector<SignInNotifier, String>( builder: (context, notifier, _) { return SizedBox( width: MediaQuery.of(context).size.width * 0.78, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ !signInNotifier.hasBiometricChecker ? const SizedBox() : Expanded( child: ButtonWidget( onTap: () async { String deviceId = await CachManager.getDeviceId() ?? ''; String email = await SecureStorageManager .getEmail(); String password = await SecureStorageManager .getPass(); final LocalAuthentication auth = LocalAuthentication(); await auth .authenticate( localizedReason: 'Authenticate with fingerprint or Face ID', options: AuthenticationOptions( stickyAuth: true, biometricOnly: true)) .then((value) { signInNotifier .executeSignIn( deviceId, email, password) .then((value) { if (signInNotifier.doneSignIn) { navigatePushAndRemoveUntil( context: context, pageName: MainScreen()); } }); }); }, backgroundColor: ColorManager.white, borderColor: ColorManager.lGray2, widget: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset( mainNotifier.biometricType == BiometricEnum.faceId ? Assets.icFaceId : Assets.icTouchId, width: MediaQuery.of(context) .size .width * 0.055, height: MediaQuery.of(context) .size .width * 0.055, ), const SizedBox(width: 10), Text( mainNotifier.biometricType == BiometricEnum.faceId ? Strings.faceId : Strings.touchId, style: Theme.of(context) .textTheme .displayMedium! .copyWith( fontSize: 18, fontWeight: FontWeight.w500, color: ColorManager.black), ), ], ), ), ), mainNotifier.biometricType == BiometricEnum.none ? const SizedBox() : SizedBox( width: MediaQuery.of(context).size.width * 0.037, ), Expanded( child: ButtonWidget( onTap: () { if (signInNotifier.formKey.currentState! .validate()) { signInNotifier.executeSignIn( notifier, signInNotifier.emailController.text, signInNotifier.passController.text); } }, backgroundColor: ColorManager.black, widget: Text( Strings.signIn, style: Theme.of(context) .textTheme .displayMedium! .copyWith( fontSize: 18, fontWeight: FontWeight.w500, color: ColorManager.white), ), ), ), ], ), ); }, selector: (context, selector) => selector.deviceID, ), ), /// white space SizedBox(height: MediaQuery.of(context).size.height * 0.04), Align( child: Text( Strings.continueWith, style: Theme.of(context) .textTheme .displayMedium! .copyWith(fontWeight: FontWeight.w400, fontSize: 12), ), ), SizedBox(height: MediaQuery.of(context).size.height * 0.04), /// social login Align( alignment: Alignment.center, child: SizedBox( width: MediaQuery.of(context).size.width * 0.78, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Platform.isIOS ? Expanded( child: ButtonWidget( onTap: () { signInNotifier.signInWithApple( signInNotifier.deviceID); }, backgroundColor: ColorManager.lGray1, borderColor: ColorManager.lGray2, widget: SvgPicture.asset( Assets.icApple, width: MediaQuery.of(context).size.width * 0.055, height: MediaQuery.of(context).size.width * 0.055, ), ), ) : SizedBox(), Platform.isIOS ? SizedBox( width: MediaQuery.of(context).size.width * 0.037, ) : SizedBox(), Expanded( child: ButtonWidget( onTap: () async { signInNotifier .signInWithGoogle(signInNotifier.deviceID); }, backgroundColor: ColorManager.lGray1, borderColor: ColorManager.lGray2, widget: SvgPicture.asset( Assets.icGoogle, width: MediaQuery.of(context).size.width * 0.055, height: MediaQuery.of(context).size.width * 0.055, ), ), ), ], ), ), ), SizedBox(height: MediaQuery.of(context).size.height * 0.12), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( Strings.dontHaveAccount.tr(), style: Theme.of(context) .textTheme .displayMedium! .copyWith( fontSize: 16, fontWeight: FontWeight.w400, color: ColorManager.dGray1), ), GestureDetector( onTap: () async { navigatePushAndRemoveUntil( context: context, pageName: const SignUpEmailPage()); }, child: Text( Strings.signUp.tr(), style: Theme.of(context) .textTheme .displayMedium! .copyWith( fontSize: 16, fontWeight: FontWeight.w500), ), ), ], ), SizedBox(height: MediaQuery.of(context).size.height * 0.07), ], ), ), ), Selector<SignInNotifier, bool>( builder: (context, provider, widget) { return provider ? const Center(child: LoadingWidget()) : const SizedBox(); }, selector: (context, selector) => selector.isLoading, ) ], ), ); } }
Leave a Comment