From 3840b7fe9005544c27e387368e9ea56b702aa63a Mon Sep 17 00:00:00 2001 From: lcy <2503978335@qq.com> Date: Tue, 18 Jul 2023 09:11:15 +0800 Subject: [PATCH] feat:更新设置页面 --- assets/images/bg_reback.png | Bin 0 -> 66936 bytes assets/images/photo_pause.png | Bin 311675 -> 0 bytes assets/images/re_button.png | Bin 0 -> 8609 bytes assets/images/re_button_dis.png | Bin 0 -> 9235 bytes lib/common/dialogs/customer_dialog.dart | 4 ++-- lib/common/dialogs/show_dialog.dart | 6 +++--- lib/pages/login/loginpage/login_page.dart | 67 ++++++++++++++++++++++++++++++++++--------------------------------- lib/pages/repeataftercontent/bloc/repeat_after_content_bloc.dart | 4 ++-- lib/pages/user/modify/modify_user_information_page.dart | 4 ++-- lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart | 4 ++-- lib/pages/user/setting/delete_account_page.dart | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pages/user/setting/reback_page.dart | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pages/user/setting/setting_page.dart | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/pages/user/user_page.dart | 52 +++++++++++++++++++++++++++++++--------------------- lib/pages/video/lookvideo/widgets/video_widget.dart | 6 ++++++ lib/route/route.dart | 19 ++++++++++++++++--- 16 files changed, 421 insertions(+), 68 deletions(-) create mode 100644 assets/images/bg_reback.png create mode 100644 assets/images/re_button.png create mode 100644 assets/images/re_button_dis.png create mode 100644 lib/pages/user/setting/delete_account_page.dart create mode 100644 lib/pages/user/setting/reback_page.dart create mode 100644 lib/pages/user/setting/setting_page.dart diff --git a/assets/images/bg_reback.png b/assets/images/bg_reback.png new file mode 100644 index 0000000..adb39ae Binary files /dev/null and b/assets/images/bg_reback.png differ diff --git a/assets/images/photo_pause.png b/assets/images/photo_pause.png index a339e26..d1cca72 100644 Binary files a/assets/images/photo_pause.png and b/assets/images/photo_pause.png differ diff --git a/assets/images/re_button.png b/assets/images/re_button.png new file mode 100644 index 0000000..daeb680 Binary files /dev/null and b/assets/images/re_button.png differ diff --git a/assets/images/re_button_dis.png b/assets/images/re_button_dis.png new file mode 100644 index 0000000..7c995c1 Binary files /dev/null and b/assets/images/re_button_dis.png differ diff --git a/lib/common/dialogs/customer_dialog.dart b/lib/common/dialogs/customer_dialog.dart index 74324b4..61bcadf 100644 --- a/lib/common/dialogs/customer_dialog.dart +++ b/lib/common/dialogs/customer_dialog.dart @@ -14,8 +14,8 @@ class CustomerTwoActionDialog extends Dialog { final String leftTitle; final String rightTitle; final String content; - final GestureTapCallback leftTap; - final GestureTapCallback rightTap; + final GestureTapCallback? leftTap; + final GestureTapCallback? rightTap; @override Widget build(BuildContext context) { diff --git a/lib/common/dialogs/show_dialog.dart b/lib/common/dialogs/show_dialog.dart index 632c570..216f5b3 100644 --- a/lib/common/dialogs/show_dialog.dart +++ b/lib/common/dialogs/show_dialog.dart @@ -13,9 +13,9 @@ void showOneActionDialog(String title, String ensureTitle, String content, Gestu }); } -void showTwoActionDialog(String title, String leftTitle, String rightTitle, String content, GestureTapCallback leftTap, - GestureTapCallback rightTap, - {bool? barrierDismissible}) { +void showTwoActionDialog(String title, String leftTitle, String rightTitle, String content, + {GestureTapCallback? leftTap, + GestureTapCallback? rightTap,bool? barrierDismissible}) { showDialog( context: AppRouter.context, barrierDismissible: barrierDismissible ?? true, diff --git a/lib/pages/login/loginpage/login_page.dart b/lib/pages/login/loginpage/login_page.dart index 662c911..6af7d9e 100644 --- a/lib/pages/login/loginpage/login_page.dart +++ b/lib/pages/login/loginpage/login_page.dart @@ -88,39 +88,40 @@ class _LoginPageView extends StatelessWidget { ), 6.horizontalSpace, RichText( - text: TextSpan(children: [ - TextSpan( - text: '我已阅读并同意', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF333333), - )), - TextSpan( - text: '《用户隐私协议》', - style: TextStyle( - fontSize: 12.sp, - color: const Color(0xFF333333), - ), - recognizer: TapGestureRecognizer() - ..onTap = () { - Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { - 'urlStr': AppConsts.userPrivacyPolicyUrl, - 'webViewTitle': '用户隐私协议' - }); - }), - TextSpan( - text: ',', style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333))), - TextSpan( - text: '《儿童隐私政策》', - style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333)), - recognizer: TapGestureRecognizer() - ..onTap = () { - Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { - 'urlStr': AppConsts.childrenPrivacyPolicyUrl, - 'webViewTitle': '儿童隐私协议' - }); - }) - ]), + text: TextSpan( + children: [ + TextSpan( + text: '我已阅读并同意', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF333333), + )), + TextSpan( + text: '《用户隐私协议》', + style: TextStyle( + fontSize: 12.sp, + color: const Color(0xFF333333), + ), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { + 'urlStr': AppConsts.userPrivacyPolicyUrl, + 'webViewTitle': '用户隐私协议' + }); + }), + TextSpan( + text: ',', style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333))), + TextSpan( + text: '《儿童隐私政策》', + style: TextStyle(fontSize: 12.sp, color: const Color(0xFF333333)), + recognizer: TapGestureRecognizer() + ..onTap = () { + Navigator.of(context).pushNamed(AppRouteName.webView, arguments: { + 'urlStr': AppConsts.childrenPrivacyPolicyUrl, + 'webViewTitle': '儿童隐私协议' + }); + }) + ]), ) ], ), diff --git a/lib/pages/repeataftercontent/bloc/repeat_after_content_bloc.dart b/lib/pages/repeataftercontent/bloc/repeat_after_content_bloc.dart index c1fe85a..4c3a7da 100644 --- a/lib/pages/repeataftercontent/bloc/repeat_after_content_bloc.dart +++ b/lib/pages/repeataftercontent/bloc/repeat_after_content_bloc.dart @@ -346,9 +346,9 @@ class RepeatAfterContentBloc extends Bloc(context); if (bloc.isChangeInfo) { - showTwoActionDialog('提示', '确定离开', '继续修改', '您的信息尚未保存', () { + showTwoActionDialog('提示', '确定离开', '继续修改', '您的信息尚未保存',leftTap: (){ popPage(); popPage(); - }, () { + },rightTap: (){ popPage(); }); } else { diff --git a/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart b/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart index 625cfd4..7cc3100 100644 --- a/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart +++ b/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart @@ -122,9 +122,9 @@ class UserAvatarBloc extends Bloc { void showDialog(Permission permission) { final contentStr = permission == Permission.camera ? '相机权限未开启,请到设置中打开' : '相册权限未开启,请到设置中打开'; - showTwoActionDialog('提示', '取消', '去设置', contentStr, () { + showTwoActionDialog('提示', '取消', '去设置', contentStr, leftTap: (){ popPage(); - }, () { + },rightTap: (){ popPage(); openAppSettings(); }); diff --git a/lib/pages/user/setting/delete_account_page.dart b/lib/pages/user/setting/delete_account_page.dart new file mode 100644 index 0000000..7a6dc93 --- /dev/null +++ b/lib/pages/user/setting/delete_account_page.dart @@ -0,0 +1,156 @@ +import 'package:common_utils/common_utils.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/request/dao/user_dao.dart'; +import 'package:wow_english/common/widgets/we_app_bar.dart'; +import 'package:wow_english/utils/color_util.dart'; + +import '../../../common/dialogs/show_dialog.dart'; +import '../../../route/route.dart'; + +class DeleteAccountPage extends StatefulWidget { + const DeleteAccountPage({super.key}); + + @override + State createState() { + return DeleteAccountPageState(); + } +} + +class DeleteAccountPageState extends State { + + late String _text; + late TimerUtil _timerUtil; + late bool _endTime; + + @override + void initState() { + super.initState(); + _endTime = false; + _text = '请阅读注销条款15s'; + _timerUtil = TimerUtil(mTotalTime: 15000); + _timerUtil.setOnTimerTickCallback((int tick) { + setState(() { + if (tick == 0) { + _endTime = true; + _text = '确认注销'; + } else { + _text = '请阅读注销账号条款${tick~/1000}s'; + } + }); + }); + _timerUtil.startCountDown(); + } + + void deleteAccount() async { + showTwoActionDialog( + '注销账号', '取消', '注销', '请谨慎操作,注销后不可恢复!', + leftTap: () {popPage();}, + rightTap: () { + popPage(); + UserDao.deleteAccount(); + }); + } + + @override + void dispose() { + if (_timerUtil.isActive()) { + _timerUtil.cancel(); + } + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const WEAppBar( + titleText: '注销账号', + ), + body: Container( + color: Colors.white, + padding: EdgeInsets.only( + bottom: 20.h + ), + child: SafeArea( + child: Center( + child: Column( + children: [ + 26.verticalSpace, + Expanded( + child: ListView( + children: [ + RichText( + textAlign: TextAlign.left, + text: TextSpan( + children: [ + TextSpan( + text: '注销账号条件:\n', + style: TextStyle( + fontSize: 17.sp, + color: const Color(0xFF333333), + fontWeight: FontWeight.bold + ) + ), + TextSpan( + text: '您提交注销申请后,wow english团队将对下列信息进行验证,以保证您的账号、财产安全:\n1.请确保帐户内没有余额。\n2.请确保账户内没有优惠券或其他卡券。\n3.请确保账户内没有虚拟财产权益。\n4.请确保账户内没有剩余课程\n5.请确保账户内没有VIP会员权益。\n\n', + style: TextStyle( + fontSize: 13.sp, + color: const Color(0xFF333333), + fontWeight: FontWeight.bold + ) + ), + TextSpan( + text: '注销账号须知:\n', + style: TextStyle( + fontSize: 17.sp, + color: const Color(0xFF333333), + fontWeight: FontWeight.bold + ) + ), + TextSpan( + text: '点击下方"确认注销”按钮,即表示您已阅读井同意《注销账号须知》\n1.注销账号是不可恢复的操作,请道慎操作,注销账号后,会永久删除账号下所有个人资料和历史信息,且无法找回。包括但不限于昵称头像、课程信息、关注、交易记录、余额、课时、优惠券、虚拟财产权益、VIP会员权益以及解除对外授权的绑定关系等。\n2.注销账号并不代表账号注销前的账号行为和相关责任得到豁免或减轻。\n3.操作前,请确认wow english账号内所有服务均己妥善处理,如因注销账号造成的损失,由您自行承担。', + style: TextStyle( + fontSize: 13.sp, + color: const Color(0xFF333333), + fontWeight: FontWeight.bold + ) + ) + ] + ), + ) + ], + ), + ), + 14.verticalSpace, + InkWell( + onTap: () => deleteAccount(), + child: Container( + height: 40.h, + width: 430.w, + decoration: BoxDecoration( + color: _endTime?HexColor('#00B6F1'):HexColor('#C7C7C7'), + border: Border.all( + width: 1.5.w, + color: const Color(0xFF140C10) + ), + borderRadius: BorderRadius.circular(15.r), + ), + alignment: Alignment.center, + child: Text( + _text, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 17.sp, + color: _endTime?Colors.white:const Color(0xFF333333) + ), + ), + ), + ) + ], + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/user/setting/reback_page.dart b/lib/pages/user/setting/reback_page.dart new file mode 100644 index 0000000..879d586 --- /dev/null +++ b/lib/pages/user/setting/reback_page.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/extension/string_extension.dart'; +import 'package:wow_english/utils/color_util.dart'; + +import '../../../common/widgets/we_app_bar.dart'; + +class ReBackPage extends StatefulWidget { + const ReBackPage({super.key}); + + @override + State createState() { + return ReBackPageState(); + } +} + +class ReBackPageState extends State { + late bool _canEnsure; + + @override + void initState() { + super.initState(); + _canEnsure = false; + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const WEAppBar( + titleText: '我要反馈', + ), + body: Container( + color: Colors.white, + padding: EdgeInsets.symmetric( + horizontal: 24.w + ), + child: SafeArea( + child: Column( + children: [ + 20.verticalSpace, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + '请输入您要反馈的问题和意见,10-500个字', + textAlign: TextAlign.left, + style: TextStyle( + fontSize: 19.sp, + color: HexColor('#333333') + ), + ), + Text( + '48/500', + textAlign: TextAlign.right, + style: TextStyle( + fontSize: 19.sp, + color: HexColor('#333333') + ),) + ], + ), + 9.5.verticalSpace, + Expanded( + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + fit: BoxFit.fill, + image: AssetImage('bg_reback'.assetPng) + ) + ), + ), + ), + 4.5.verticalSpace, + Container( + decoration: BoxDecoration( + image: DecorationImage( + fit: BoxFit.fill, + image: AssetImage(_canEnsure?'re_button'.assetPng:'re_button_dis'.assetPng) + ) + ), + alignment: Alignment.center, + width: 91.w, + height: 45.h, + child: Text( + '提交', + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 17.sp + ), + ), + ) + ], + ), + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/pages/user/setting/setting_page.dart b/lib/pages/user/setting/setting_page.dart new file mode 100644 index 0000000..b5b62b1 --- /dev/null +++ b/lib/pages/user/setting/setting_page.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:wow_english/common/widgets/we_app_bar.dart'; + +import '../../../route/route.dart'; + +class SettingPage extends StatefulWidget { + const SettingPage({super.key}); + + @override + State createState() { + return SettingPageState(); + } +} + +class SettingPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const WEAppBar( + titleText: '设置', + ), + body: Container( + color: Colors.white, + padding: EdgeInsets.only(left: 17.w, right: 17.w), + child: SafeArea( + child: Center( + child: ListView( + children: [ + 34.verticalSpace, + _buildItemWidget('注销账号', onPress: (){ + pushNamed(AppRouteName.deleteAccount); + }), + 12.verticalSpace, + _buildItemWidget('清除缓存', onPress: (){ + + }), + 12.verticalSpace, + _buildItemWidget('帮助与反馈', onPress: (){ + pushNamed(AppRouteName.reBack); + }), + ], + ), + ), + ), + ), + ); + } + + Widget _buildItemWidget(String text,{VoidCallback? onPress}) { + return OutlinedButton( + onPressed: () => onPress?.call(), + style: ButtonStyle( + side: MaterialStateProperty.all(BorderSide(color: const Color(0xFF140C10), width: 1.5.w)), + shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))), + minimumSize: MaterialStateProperty.all(Size(double.infinity, 58.h)), + backgroundColor: MaterialStateProperty.all(Colors.white), + ), + child: Text( + text, + style: TextStyle( + //fontWeight: FontWeight.w600, + color: const Color(0xFF333333), + fontSize: 21.sp, + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/user/user_page.dart b/lib/pages/user/user_page.dart index 55dfee2..69b6533 100644 --- a/lib/pages/user/user_page.dart +++ b/lib/pages/user/user_page.dart @@ -169,12 +169,22 @@ class _UserView extends StatelessWidget { "隐私协议", style: textStyle21sp, )), + 12.verticalSpace, + OutlinedButton( + onPressed: () { + pushNamed(AppRouteName.setting); + }, + style: normalButtonStyle, + child: Text( + "设置", + style: textStyle21sp, + )), 30.verticalSpace, OutlinedButton( onPressed: () { - showTwoActionDialog(barrierDismissible:false,'提示', '取消', '确认', '您确认要退出Wow English吗?', () { + showTwoActionDialog(barrierDismissible:false,'提示', '取消', '确认', '您确认要退出Wow English吗?',leftTap: (){ popPage(); - }, () { + },rightTap: (){ popPage(); userBloc.add(UserLogout()); }); @@ -194,25 +204,25 @@ class _UserView extends StatelessWidget { fontSize: 17.sp, ), )), - 30.verticalSpace, - TextButton( - onPressed: () { - //userBloc.add(UserDelete()) - showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () { - popPage(); - }, () { - userBloc.add(UserDelete()); - popPage(); - }); - }, - child: Text( - "注销账号", - style: TextStyle( - //fontWeight: FontWeight.w600, - color: Colors.red, - fontSize: 15.sp, - ), - )), + // 30.verticalSpace, + // TextButton( + // onPressed: () { + // //userBloc.add(UserDelete()) + // showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () { + // popPage(); + // }, () { + // userBloc.add(UserDelete()); + // popPage(); + // }); + // }, + // child: Text( + // "注销账号", + // style: TextStyle( + // //fontWeight: FontWeight.w600, + // color: Colors.red, + // fontSize: 15.sp, + // ), + // )), ], ), )); diff --git a/lib/pages/video/lookvideo/widgets/video_widget.dart b/lib/pages/video/lookvideo/widgets/video_widget.dart index 48201da..11d2cd3 100644 --- a/lib/pages/video/lookvideo/widgets/video_widget.dart +++ b/lib/pages/video/lookvideo/widgets/video_widget.dart @@ -44,6 +44,12 @@ class _VideoWidgetState extends State { int totalSecond = _controller!.value.duration.inMinutes.remainder(60)*60+_controller!.value.duration.inSeconds.remainder(60); _currentTime = formatDuration(_controller!.value.position); _playDegree = currentSecond/totalSecond; + if (_playDegree > 1.0) { + _playDegree = 1.0; + } + if(_playDegree < 0) { + _playDegree = 0.0; + } }); } } diff --git a/lib/route/route.dart b/lib/route/route.dart index 1f0a3ca..375b738 100644 --- a/lib/route/route.dart +++ b/lib/route/route.dart @@ -18,10 +18,13 @@ import 'package:wow_english/pages/tab/tab_page.dart'; import 'package:wow_english/pages/user/information/user_information_page.dart'; import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart'; import 'package:wow_english/pages/user/modify/modify_user_information_page.dart'; +import 'package:wow_english/pages/user/setting/setting_page.dart'; import 'package:wow_english/pages/user/user_page.dart'; import 'package:wow_english/pages/video/lookvideo/look_video_page.dart'; import '../pages/reading/reading_page.dart'; +import '../pages/user/setting/delete_account_page.dart'; +import '../pages/user/setting/reback_page.dart'; class AppRouteName { static const String splash = 'splash'; @@ -43,7 +46,6 @@ class AppRouteName { /// 用户详细信息页 static const String userInformation = 'userInformation'; - /// 修改用户头像 static const String userAvatar = 'userAvatar'; @@ -51,13 +53,18 @@ class AppRouteName { //static const String userModifyInformation = 'userModifyInformation'; ///看视频 static const String lookVideo = 'lookVideo'; - ///绘本 static const String reading = 'reading'; - ///视频跟读详情 static const String readAfterContent = 'readAfterContent'; + ///设置 + static const String setting = 'setting'; + ///注销账号 + static const String deleteAccount = 'deleteAccount'; + ///帮助与反馈 + static const String reBack = 'reBack'; + static const String tab = '/'; } @@ -158,6 +165,12 @@ class AppRouter { videoFollowReadId = (settings.arguments as Map)['videoFollowReadId'] as String; } return CupertinoPageRoute(builder: (_) => RepeatAfterContentPage(videoFollowReadId: videoFollowReadId)); + case AppRouteName.setting: + return CupertinoPageRoute(builder: (_) => const SettingPage()); + case AppRouteName.deleteAccount: + return CupertinoPageRoute(builder: (_) => const DeleteAccountPage()); + case AppRouteName.reBack: + return CupertinoPageRoute(builder: (_) => const ReBackPage()); case AppRouteName.tab: return PageRouteBuilder( opaque: false, -- libgit2 0.22.2