@@ -37,9 +37,9 @@ import '../../Utils/asset_util.dart';
3737import '../../Utils/enums.dart' ;
3838import '../../Utils/request_util.dart' ;
3939import '../../Utils/utils.dart' ;
40- import '../../Widgets/Scaffold/custom_cupertino_route.dart' ;
4140import '../../Widgets/Item/input_item.dart' ;
4241import '../../Widgets/Item/item_builder.dart' ;
42+ import '../../Widgets/Scaffold/custom_cupertino_route.dart' ;
4343import '../main_screen.dart' ;
4444
4545class LoginByPasswordScreen extends StatefulWidget {
@@ -65,11 +65,13 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
6565 late InputValidateAsyncController _passwordValidateAsyncController;
6666 late InputValidateAsyncController _backupCodeValidateAsyncController;
6767 late PinPutValidateAsyncController _twoFAValidateAsyncController;
68+ late InputValidateAsyncController _emailValidateAsyncController;
6869 String _guestToken = "" ;
6970 String _flowToken = "" ;
7071 InitPhase _inited = InitPhase .connecting;
7172 InitPhase _connected = InitPhase .haveNotConnected;
72- final FocusNode _pinFocusNode = FocusNode ();
73+ final FocusNode _twoFAPinFocusNode = FocusNode ();
74+ final FocusNode _emailPinFocusNode = FocusNode ();
7375 UserInfo ? _userInfo;
7476 String errorMessage = "" ;
7577 bool _isMaximized = false ;
@@ -166,6 +168,15 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
166168 },
167169 controller: TextEditingController (),
168170 );
171+ _emailValidateAsyncController = InputValidateAsyncController (
172+ validator: (text) async {
173+ if (text.isEmpty) {
174+ return "邮箱代码不能为空" ;
175+ }
176+ return null ;
177+ },
178+ controller: TextEditingController (),
179+ );
169180 initLogin ();
170181 }
171182
@@ -212,7 +223,7 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
212223 setState (() {
213224 _connected = InitPhase .connecting;
214225 });
215- controller.animateToPage (5 ,
226+ controller.animateToPage (6 ,
216227 duration: const Duration (milliseconds: 300 ), curve: Curves .easeInOut);
217228 await LoginApi .fetchCsrfToken (_guestToken);
218229 await RequestUtil .shareCookie ();
@@ -250,7 +261,7 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
250261 await LoginApi .checkUsername (_guestToken, _flowToken, account);
251262 if (! res.success || res.data.isEmpty) {
252263 if (res.code == 399 ) {
253- _identifierValidateAsyncController.setError ("用户不存在" );
264+ _identifierValidateAsyncController.setError ("用户不存在(${ res . message }) " );
254265 } else {
255266 _identifierValidateAsyncController
256267 .setError ("未知错误(code: ${res .code }, message:${res .message })" );
@@ -301,7 +312,7 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
301312 _guestToken, _flowToken, account);
302313 if (! res.success || res.data.isEmpty) {
303314 if (res.code == 399 ) {
304- _alternativeIdentifierValidateAsyncController.setError ("用户名验证失败" );
315+ _alternativeIdentifierValidateAsyncController.setError ("用户名验证失败(${ res . message }) " );
305316 } else {
306317 _alternativeIdentifierValidateAsyncController
307318 .setError ("未知错误(code: ${res .code }, message:${res .message })" );
@@ -324,7 +335,7 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
324335 await LoginApi .checkPassword (_guestToken, _flowToken, password);
325336 if (! res.success || res.data.isEmpty) {
326337 if (res.code == 399 ) {
327- _passwordValidateAsyncController.setError ("密码错误" );
338+ _passwordValidateAsyncController.setError ("密码错误(${ res . message }) " );
328339 } else {
329340 _passwordValidateAsyncController
330341 .setError ("未知错误(code: ${res .code }, message:${res .message })" );
@@ -336,11 +347,16 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
336347 }
337348 ILogger .info ("Check password" , "Get flow_token: $_flowToken " );
338349 switch (res.flag as LoginPhase ) {
339- case LoginPhase .check2FA :
350+ case LoginPhase .loginAcid :
340351 controller.animateToPage (3 ,
341352 duration: const Duration (milliseconds: 300 ),
342353 curve: Curves .easeInOut);
343354 break ;
355+ case LoginPhase .check2FA:
356+ controller.animateToPage (4 ,
357+ duration: const Duration (milliseconds: 300 ),
358+ curve: Curves .easeInOut);
359+ break ;
344360 case LoginPhase .loginSuccess:
345361 success ();
346362 break ;
@@ -350,19 +366,39 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
350366 }
351367 break ;
352368 case 3 :
369+ bool valid = (await _emailValidateAsyncController.validate ()) == null ;
370+ if (! valid) return ;
371+ String pin = _emailValidateAsyncController.controller.text;
372+ CustomLoadingDialog .showLoading (title: "验证邮箱代码中..." );
373+ var res = await LoginApi .checkEmail (_guestToken, _flowToken, pin);
374+ if (! res.success || res.data.isEmpty) {
375+ if (res.code == 399 ) {
376+ _emailValidateAsyncController.setError ("邮箱代码错误(${res .message })" );
377+ } else {
378+ _emailValidateAsyncController
379+ .setError ("未知错误(code: ${res .code }, message:${res .message })" );
380+ }
381+ _emailPinFocusNode.requestFocus ();
382+ } else {
383+ _flowToken = res.data;
384+ ILogger .info ("Check email" , "Get flow_token: $_flowToken " );
385+ success ();
386+ }
387+ break ;
388+ case 4 :
353389 bool valid = (await _twoFAValidateAsyncController.validate ()) == null ;
354390 if (! valid) return ;
355391 String pin = _twoFAValidateAsyncController.controller.text;
356392 CustomLoadingDialog .showLoading (title: "验证一次性代码中..." );
357393 var res = await LoginApi .check2FA (_guestToken, _flowToken, pin);
358394 if (! res.success || res.data.isEmpty) {
359395 if (res.code == 399 ) {
360- _twoFAValidateAsyncController.setError ("一次性代码错误" );
396+ _twoFAValidateAsyncController.setError ("一次性代码错误(${ res . message }) " );
361397 } else {
362398 _twoFAValidateAsyncController
363399 .setError ("未知错误(code: ${res .code }, message:${res .message })" );
364400 }
365- _pinFocusNode .requestFocus ();
401+ _twoFAPinFocusNode .requestFocus ();
366402 } else {
367403 _flowToken = res.data;
368404 ILogger .info ("Check 2FA" , "Get flow_token: $_flowToken " );
@@ -555,6 +591,30 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
555591 ),
556592 );
557593 case 3 :
594+ return _buildPhasePage (
595+ title: "输入你的邮箱代码" ,
596+ message: "在下方输入你的邮箱代码" ,
597+ body: ItemBuilder .buildContainerItem (
598+ context: context,
599+ topRadius: true ,
600+ bottomRadius: true ,
601+ padding: const EdgeInsets .symmetric (vertical: 10 ),
602+ child: InputItem (
603+ hint: "输入邮箱代码" ,
604+ textInputAction: TextInputAction .done,
605+ tailingType: InputItemTailingType .clear,
606+ leadingIcon: Icons .email_outlined,
607+ leadingType: InputItemLeadingType .icon,
608+ keyboardType: TextInputType .text,
609+ validateAsyncController:
610+ _emailValidateAsyncController,
611+ onSubmit: (_) {
612+ _login ();
613+ },
614+ ),
615+ ),
616+ );
617+ case 4 :
558618 return _buildPhasePage (
559619 title: "输入你的验证码" ,
560620 message: "使用代码生成器应用生成一个代码并在下方输入" ,
@@ -569,29 +629,35 @@ class _LoginByPasswordScreenState extends State<LoginByPasswordScreen>
569629 onCompleted: (_) {
570630 _login ();
571631 },
572- pinFocusNode: _pinFocusNode ,
632+ pinFocusNode: _twoFAPinFocusNode ,
573633 ),
574634 ),
575635 );
576- case 4 :
636+ case 5 :
577637 return _buildPhasePage (
578638 title: "输入你的备用码" ,
579639 message: "在下方输入你的备用码" ,
580- body: InputItem (
581- hint: "输入备用码" ,
582- textInputAction: TextInputAction .done,
583- tailingType: InputItemTailingType .clear,
584- leadingIcon: Icons .backup_outlined,
585- leadingType: InputItemLeadingType .icon,
586- keyboardType: TextInputType .text,
587- validateAsyncController:
588- _backupCodeValidateAsyncController,
589- onSubmit: (_) {
590- _login ();
591- },
640+ body: ItemBuilder .buildContainerItem (
641+ context: context,
642+ topRadius: true ,
643+ bottomRadius: true ,
644+ padding: const EdgeInsets .symmetric (vertical: 10 ),
645+ child: InputItem (
646+ hint: "输入备用码" ,
647+ textInputAction: TextInputAction .done,
648+ tailingType: InputItemTailingType .clear,
649+ leadingIcon: Icons .backup_outlined,
650+ leadingType: InputItemLeadingType .icon,
651+ keyboardType: TextInputType .text,
652+ validateAsyncController:
653+ _backupCodeValidateAsyncController,
654+ onSubmit: (_) {
655+ _login ();
656+ },
657+ ),
592658 ),
593659 );
594- case 5 :
660+ case 6 :
595661 return _buildPhasePage (
596662 title: "登录成功" ,
597663 message: "正在准备连接至Twitee..." ,
0 commit comments