yumi-flutter/lib/modules/auth/login_page.dart
2026-04-09 21:32:23 +08:00

436 lines
18 KiB
Dart

import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
import 'package:provider/provider.dart';
import 'package:yumi/app_localizations.dart';
import 'package:yumi/ui_kit/components/dialog/dialog_base.dart';
import 'package:yumi/ui_kit/components/text/sc_text.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/app/constants/sc_screen.dart';
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
import 'package:yumi/services/auth/authentication_manager.dart';
import 'package:yumi/ui_kit/widgets/pop/pop_route.dart';
import 'package:yumi/modules/webview/webview_page.dart';
import 'package:yumi/modules/auth/login_route.dart';
import '../../shared/data_sources/models/enum/sc_auth_type.dart';
/// 登录
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
LoginPageState createState() => LoginPageState();
}
class LoginPageState extends State<LoginPage> with WidgetsBindingObserver {
bool isAgreement = false;
SocialChatAuthenticationManager? authProvider;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
authProvider = Provider.of<SocialChatAuthenticationManager>(
context,
listen: false,
);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
Widget build(BuildContext context) {
final businessLogicStrategy = SCGlobalConfig.businessLogicStrategy;
return Scaffold(
resizeToAvoidBottomInset: false,
body: Stack(
alignment: Alignment.topCenter,
children: [
Image.asset(
businessLogicStrategy.getLoginMainBackgroundImage(),
width: ScreenUtil().screenWidth,
height: ScreenUtil().screenHeight,
fit: BoxFit.cover,
),
Positioned(
top: 120,
child: Image.asset(
businessLogicStrategy.getLoginMainAppIcon(),
width: 107.w,
height: 159.w,
),
),
Positioned(
top: 390.w,
left: 27.w,
right: 27.w,
child: SizedBox(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Platform.isAndroid
? SCDebounceWidget(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.w),
color:
businessLogicStrategy
.getLoginMainButtonBackgroundColor(),
),
padding: EdgeInsets.symmetric(
vertical: 12.w,
horizontal: 24.w,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
businessLogicStrategy
.getLoginMainGoogleIcon(),
width: 30.w,
height: 30.w,
),
SizedBox(width: 20.w),
Expanded(
child: text(
SCAppLocalizations.of(
context,
)!.signInWithGoogle,
textColor:
businessLogicStrategy
.getLoginMainButtonTextColor(),
fontSize: 16.sp,
fontWeight: FontWeight.bold,
textAlign: TextAlign.center,
),
),
],
),
),
onTap: () {
_loginByGoogle();
},
)
: Container(),
Platform.isIOS ? SizedBox(height: 20.w) : Container(),
Platform.isIOS
? SCDebounceWidget(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color:
businessLogicStrategy
.getLoginMainButtonBackgroundColor(),
),
padding: EdgeInsets.symmetric(
vertical: 12.w,
horizontal: 24.w,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
businessLogicStrategy
.getLoginMainAppleIcon(),
width: 30.w,
height: 30.w,
),
SizedBox(width: 20.w),
Expanded(
child: text(
SCAppLocalizations.of(
context,
)!.signInWithApple,
textColor:
businessLogicStrategy
.getLoginMainButtonTextColor(),
fontSize: 16.sp,
fontWeight: FontWeight.bold,
textAlign: TextAlign.center,
),
),
],
),
),
onTap: () {
_loginByApple();
},
)
: Container(),
SizedBox(height: 8.w), // 从5.w改为8.w
Container(
alignment: Alignment.center,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
color:
businessLogicStrategy
.getLoginMainDividerColor(),
height: 0.5.w,
width: 82.w,
),
SizedBox(width: 20.w),
text(
SCAppLocalizations.of(context)!.or,
textColor:
businessLogicStrategy
.getLoginMainDividerColor(),
fontSize: 18.sp,
fontWeight: FontWeight.w600,
),
SizedBox(width: 20.w),
Container(
color:
businessLogicStrategy
.getLoginMainDividerColor(),
height: 0.5.w,
width: 82.w,
),
],
),
),
SizedBox(height: 12.w), // 从8.w改为12.w
SCDebounceWidget(
onTap: () {
_goLoginWithAccount();
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color:
businessLogicStrategy
.getLoginMainButtonBackgroundColor(),
),
padding: EdgeInsets.symmetric(
vertical: 12.w,
horizontal: 24.w,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.asset(
businessLogicStrategy.getLoginMainAccountIcon(),
width: 30.w,
height: 30.w,
),
SizedBox(width: 20.w),
Expanded(
child: text(
SCAppLocalizations.of(
context,
)!.signInWithYourAccount,
textColor:
businessLogicStrategy
.getLoginMainButtonTextColor(),
fontSize: 16.sp,
fontWeight: FontWeight.bold,
textAlign: TextAlign.center,
),
),
],
),
),
),
],
),
SizedBox(height: 8.w),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(width: 8.w),
Column(
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
isAgreement = !isAgreement;
});
},
child: Container(
padding: EdgeInsets.all(3.w),
child: Image.asset(
businessLogicStrategy.getLoginMainAgreementIcon(
isAgreement,
),
width: 16.w,
height: 16.w,
),
),
),
],
),
Expanded(
child: Container(
margin: EdgeInsets.only(top: 3.w),
child: Text.rich(
TextSpan(
children: [
TextSpan(
text:
SCAppLocalizations.of(
context,
)!.loginRepresentsAgreementTo,
style: TextStyle(
color: Colors.white,
fontSize: sp(12),
fontWeight: FontWeight.w400,
),
),
TextSpan(
text:
SCAppLocalizations.of(
context,
)!.termsofService,
style: TextStyle(
color:
businessLogicStrategy
.getLoginMainLinkColor(),
fontSize: sp(12),
fontWeight: FontWeight.w500,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
Navigator.push(
context,
PopRoute(
child: WebViewPage(
title:
SCAppLocalizations.of(
context,
)!.termsofService,
url:
SCGlobalConfig
.userAgreementUrl,
),
),
);
},
),
TextSpan(
text: SCAppLocalizations.of(context)!.and,
style: TextStyle(
color: Colors.white,
fontSize: sp(12),
fontWeight: FontWeight.w400,
),
),
TextSpan(
text:
SCAppLocalizations.of(
context,
)!.privaceyPolicy,
style: TextStyle(
color:
businessLogicStrategy
.getLoginMainLinkColor(),
fontSize: sp(12),
fontWeight: FontWeight.w500,
),
recognizer:
TapGestureRecognizer()
..onTap = () async {
Navigator.push(
context,
PopRoute(
child: WebViewPage(
title:
SCAppLocalizations.of(
context,
)!.privaceyPolicy,
url:
SCGlobalConfig
.privacyAgreementUrl,
),
),
);
},
),
],
),
textAlign: TextAlign.center,
),
),
),
SizedBox(width: 10.w),
],
),
SizedBox(height: 45.w),
],
),
),
),
],
),
);
}
void _loginByGoogle() async {
if (!isAgreement) {
//弹出勾选确认
showPolicyConfirm();
return;
}
await authProvider?.authenticateUser(context, SCAuthType.GOOGLE.name);
}
void showPolicyConfirm() {
SmartDialog.show(
tag: "showConfirmDialog",
alignment: Alignment.center,
debounce: true,
animationType: SmartAnimationType.fade,
builder: (_) {
return MsgDialog(
title: SCAppLocalizations.of(context)!.tips,
msg: SCAppLocalizations.of(context)!.termsOfServicePrivacyPolicyTips,
btnText: SCAppLocalizations.of(context)!.yes,
onEnsure: () {
isAgreement = true;
setState(() {});
},
);
},
);
}
void _goLoginWithAccount() async {
if (!isAgreement) {
//弹出勾选确认
showPolicyConfirm();
return;
}
SCNavigatorUtils.push(
context,
LoginRouter.loginWithAccount,
replace: false,
);
}
void _loginByApple() {
if (!isAgreement) {
//弹出勾选确认
showPolicyConfirm();
return;
}
authProvider?.authenticateUser(context, SCAuthType.APPLE.name);
}
}