import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import "package:photos/generated/l10n.dart"; import 'package:photos/services/user_service.dart'; import 'package:photos/ui/lifecycle_event_handler.dart'; import 'package:pinput/pin_put/pin_put.dart'; class TwoFactorAuthenticationPage extends StatefulWidget { final String sessionID; const TwoFactorAuthenticationPage(this.sessionID, {Key? key}) : super(key: key); @override State createState() => _TwoFactorAuthenticationPageState(); } class _TwoFactorAuthenticationPageState extends State { final _pinController = TextEditingController(); final _pinPutDecoration = BoxDecoration( border: Border.all(color: const Color.fromRGBO(45, 194, 98, 1.0)), borderRadius: BorderRadius.circular(15.0), ); String _code = ""; late LifecycleEventHandler _lifecycleEventHandler; @override void initState() { _lifecycleEventHandler = LifecycleEventHandler( resumeCallBack: () async { if (mounted) { final data = await Clipboard.getData(Clipboard.kTextPlain); if (data != null && data.text != null && data.text!.length == 6) { _pinController.text = data.text!; } } }, ); WidgetsBinding.instance.addObserver(_lifecycleEventHandler); super.initState(); } @override void dispose() { WidgetsBinding.instance.removeObserver(_lifecycleEventHandler); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( S.of(context).twofactorAuthenticationPageTitle, ), ), body: _getBody(), ); } Widget _getBody() { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.max, children: [ Text( S.of(context).enterThe6digitCodeFromnyourAuthenticatorApp, style: const TextStyle( height: 1.4, fontSize: 16, ), textAlign: TextAlign.center, ), const Padding(padding: EdgeInsets.all(32)), Padding( padding: const EdgeInsets.fromLTRB(40, 0, 40, 0), child: PinPut( fieldsCount: 6, onSubmit: (String code) { _verifyTwoFactorCode(code); }, onChanged: (String pin) { setState(() { _code = pin; }); }, controller: _pinController, submittedFieldDecoration: _pinPutDecoration.copyWith( borderRadius: BorderRadius.circular(20.0), ), selectedFieldDecoration: _pinPutDecoration, followingFieldDecoration: _pinPutDecoration.copyWith( borderRadius: BorderRadius.circular(5.0), border: Border.all( color: const Color.fromRGBO(45, 194, 98, 0.5), ), ), inputDecoration: const InputDecoration( focusedBorder: InputBorder.none, border: InputBorder.none, counterText: '', ), autofocus: true, ), ), const Padding(padding: EdgeInsets.all(24)), Container( padding: const EdgeInsets.fromLTRB(80, 0, 80, 0), width: double.infinity, height: 64, child: OutlinedButton( onPressed: _code.length == 6 ? () async { _verifyTwoFactorCode(_code); } : null, child: Text(S.of(context).verify), ), ), const Padding(padding: EdgeInsets.all(30)), GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { UserService.instance.recoverTwoFactor(context, widget.sessionID); }, child: Container( padding: const EdgeInsets.all(10), child: Center( child: Text( S.of(context).lostDevice, style: const TextStyle( decoration: TextDecoration.underline, fontSize: 12, ), ), ), ), ), ], ); } Future _verifyTwoFactorCode(String code) async { await UserService.instance.verifyTwoFactor(context, widget.sessionID, code); } }