Untitled

mail@pastecode.io avatar
unknown
dart
5 months ago
24 kB
3
Indexable
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