Untitled
unknown
dart
2 years ago
24 kB
12
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,
)
],
),
);
}
}
Editor is loading...
Leave a Comment