login_page.dart 10.1 KB
import 'dart:io';

import 'package:Parlando/login/models/auth_entity.dart';
import 'package:Parlando/net/dio_utils.dart';
import 'package:Parlando/net/http_api.dart';
import 'package:Parlando/util/toast_utils.dart';
import 'package:flustars/flustars.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:Parlando/common/permission_request_widget.dart';
import 'package:Parlando/common/protocol_model.dart';
import 'package:Parlando/home/webview_page.dart';
import 'package:Parlando/login/widgets/my_text_field.dart';
import 'package:Parlando/res/constant.dart';
import 'package:Parlando/res/resources.dart';
import 'package:Parlando/routers/fluro_navigator.dart';
import 'package:Parlando/routers/routers.dart';
import 'package:Parlando/util/change_notifier_manage.dart';
import 'package:Parlando/util/other_utils.dart';
import 'package:Parlando/widgets/my_app_bar.dart';
import 'package:Parlando/widgets/my_button.dart';
import 'package:Parlando/widgets/my_scroll_view.dart';
import 'package:getwidget/getwidget.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

import '../login_router.dart';

import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart';
import 'package:Parlando/extension/int_extension.dart';

import 'package:permission_handler/permission_handler.dart';

/// design/1注册登录/index.html
class LoginPage extends StatefulWidget {
  const LoginPage({Key? key}) : super(key: key);

  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage>
    with ChangeNotifierMixin<LoginPage>, ProtocolModel {
  //定义一个controller
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();
  final FocusNode _nodeText1 = FocusNode();
  final FocusNode _nodeText2 = FocusNode();
  bool _clickable = false;
  bool _isLoading = false;

  @override
  Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() {
    final List<VoidCallback> callbacks = <VoidCallback>[_verify];
    return <ChangeNotifier, List<VoidCallback>?>{
      _nameController: callbacks,
      _passwordController: callbacks,
      _nodeText1: null,
      _nodeText2: null,
    };
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      /// 显示状态栏和导航栏
      SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
          overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
    });
    _nameController.text = SpUtil.getString(Constant.phone).nullSafe;

    List<String> _list = [
      "为您更好的体验应用,所以需要获取您的手机文件存储权限,以保存您的一些偏好设置",
      "您已拒绝权限,所以无法保存您的一些偏好设置,将无法使用APP",
      "您已拒绝权限,请在设置中心中同意APP的权限请求",
      "其他错误"
    ];

    // Future.delayed(
    //   Duration.zero,
    //   () {
    //     NavigatorUtils.pushPageByFade(
    //       context: context,
    //       //目标页面
    //       targetPage: PermissionRequestWidget(
    //         //所需要申请的权限
    //         permission: Permission.camera,
    //         //显示关闭应用按钮
    //         isCloseApp: true,
    //         //提示文案
    //         permissionList: _list,
    //       ),
    //       //权限申请结果
    //       dismissCallBack: (value) {
    //         showPrivacyPage();
    //       },
    //     );
    //   },
    // );
  }

  void showPrivacyPage() async {
    bool isAgreement = await showProtocolFunction(context);
    if (isAgreement) {
      // next();
    } else {
      SystemChannels.platform.invokeMethod("SystemNavigator.pop");
    }
  }

  void _verify() {
    final String name = _nameController.text;
    final String password = _passwordController.text;
    bool clickable = true;
    if (name.isEmpty || name.length < 5) {
      clickable = false;
    }
    if (password.isEmpty || password.length < 6) {
      clickable = false;
    }

    /// 状态不一样再刷新,避免不必要的setState
    if (clickable != _clickable) {
      setState(() {
        _clickable = clickable;
      });
    }
  }

  void _login() {
    _isLoading = true;
    setState(() {});
    Map<String, String> params = <String, String>{
      "email": _nameController.text,
      "password": _passwordController.text,
    };
    DioUtils.instance.asyncRequestNetwork<AuthEntity>(
      Method.post,
      HttpApi.login,
      params: params,
      onSuccess: (data) {
        SpUtil.putString(Constant.userToken, data!.data!.token!);
        NavigatorUtils.push(context, Routes.home, clearStack: true);
        _isLoading = false;
      },
      onError: (code, msg) {
        Toast.show(msg.toString());
        _isLoading = false;
        setState(() {});
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MyAppBar(
        isBack: false,
        isTransparent: true,
        onPressed: () {
          NavigatorUtils.push(context, LoginRouter.smsLoginPage);
        },
        homeActionWidgets: TextButton(
          onPressed: () {
            NavigatorUtils.push(context, LoginRouter.smsLoginPage);
          },
          child: Text(
            "验证码登录",
            style: TextStyle(
              color: Colors.black45,
              fontSize: 15.px,
            ),
          ),
        ),
      ),
      body: Stack(
        children: [
          MyScrollView(
            keyboardConfig: Utils.getKeyboardActionsConfig(context, <FocusNode>[
              _nodeText1,
              _nodeText2,
            ]),
            padding: EdgeInsets.only(
              left: 16.px,
              right: 16.px,
              top: 20.px,
            ),
            children: _buildBody,
          ),
          Container(
            child: _isLoading ? const GFLoader() : null,
          ),
        ],
      ),
    );
  }

  List<Widget> get _buildBody =>
      <Widget>[
        Text(
          ParlandoLocalizations.of(context).passwordLogin,
          style: TextStyles.textBold26,
        ),
        Gaps.vGap16,
        MyTextField(
          key: const Key('email'),
          focusNode: _nodeText1,
          controller: _nameController,
          maxLength: 100,
          keyboardType: TextInputType.emailAddress,
          hintText: ParlandoLocalizations.of(context).inputEmailHint,
        ),
        Gaps.vGap8,
        MyTextField(
          key: const Key('password'),
          keyName: 'password',
          focusNode: _nodeText2,
          isInputPwd: true,
          controller: _passwordController,
          keyboardType: TextInputType.visiblePassword,
          hintText: ParlandoLocalizations.of(context).inputPasswordHint,
        ),
        Gaps.vGap24,
        Text.rich(
          TextSpan(
              text: '登录即代表同意并阅读',
              style: const TextStyle(fontSize: 12, color: Color(0xFF999999)),
              children: [
                TextSpan(
                  text: '《用户协议》',
                  style: TextStyle(color: Theme.of(context).primaryColor),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      Navigator.of(context)
                          .push(MaterialPageRoute(builder: (context) {
                        return const WebViewPage(
                          title: '《用户协议》',
                          url: Constant.protocolUrl,
                        );
                      }));
                    },
                ),
                const TextSpan(text: ' & '),
                TextSpan(
                  text: '《隐私政策》',
                  style: TextStyle(color: Theme.of(context).primaryColor),
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {
                      Navigator.of(context).push(
                        MaterialPageRoute(
                          builder: (context) {
                            return const WebViewPage(
                              title: '《隐私政策》',
                              url: Constant.privacyUrl,
                            );
                          },
                        ),
                      );
                    },
                ),
              ]),
        ),
        Gaps.vGap16,
        MyButton(
          key: const Key('login'),
          onPressed: _clickable ? _login : null,
          text: ParlandoLocalizations.of(context).login,
        ),
        Container(
          height: 40.px,
          alignment: Alignment.centerRight,
          child: GestureDetector(
            child: Text(
              ParlandoLocalizations.of(context).forgotPasswordLink,
              key: const Key('forgotPassword'),
              style: Theme.of(context).textTheme.subtitle2,
            ),
            onTap: () =>
                NavigatorUtils.push(context, LoginRouter.resetPasswordPage),
          ),
        ),
        Gaps.vGap16,
        Container(
            alignment: Alignment.center,
            child: GestureDetector(
              child: Text(
                ParlandoLocalizations.of(context).noAccountRegisterLink,
                key: const Key('noAccountRegister'),
                style: TextStyle(color: Theme.of(context).primaryColor),
              ),
              onTap: () =>
                  NavigatorUtils.push(context, LoginRouter.registerPage),
            )),
        Gaps.vGap16,
        Platform.isIOS
            ? Center(
                child: SignInWithAppleButton(
                  onPressed: () async {
                    final credential =
                        await SignInWithApple.getAppleIDCredential(
                      scopes: [
                        AppleIDAuthorizationScopes.email,
                        AppleIDAuthorizationScopes.fullName,
                      ],
                    );
                    print(credential);
                  },
                ),
              )
            : const Center(
                child: Text(""),
              ),
      ];
}