diff --git a/lib/app/api/user_api.dart b/lib/app/api/user_api.dart new file mode 100644 index 0000000..add0f9e --- /dev/null +++ b/lib/app/api/user_api.dart @@ -0,0 +1,12 @@ +/// create by 张风捷特烈 on 2021/1/17 +/// contact me by email 1981462002@qq.com +/// 说明: + +class UserApi{ + + Future register({String email,String code}){ + + + } + +} \ No newline at end of file diff --git a/lib/app/router/unit_router.dart b/lib/app/router/unit_router.dart index aa2e30f..564dac7 100644 --- a/lib/app/router/unit_router.dart +++ b/lib/app/router/unit_router.dart @@ -9,6 +9,7 @@ import 'package:flutter_unit/views/pages/gallery/gallery_page.dart'; import 'package:flutter_unit/views/pages/issues_point/issues_detail.dart'; import 'package:flutter_unit/views/pages/issues_point/issues_point_page.dart'; import 'package:flutter_unit/views/pages/login/login_page.dart'; +import 'package:flutter_unit/views/pages/register/register_page.dart'; import 'package:flutter_unit/views/pages/search/serach_page.dart'; import 'package:flutter_unit/views/pages/setting/code_style_setting.dart'; import 'package:flutter_unit/views/pages/setting/font_setting.dart'; @@ -24,7 +25,6 @@ import 'package:flutter_unit/views/pages/setting/setting_page.dart'; import 'router_utils.dart'; class UnitRouter { - static const String widget_detail = '/widget_detail'; static const String detail = 'detail'; @@ -52,6 +52,7 @@ class UnitRouter { static const String layout = 'LayoutUnitPage'; static const String about_me = 'AboutMePage'; static const String about_app = 'AboutAppPage'; + static const String register = 'register'; static Route generateRoute(RouteSettings settings) { switch (settings.name) { @@ -83,11 +84,17 @@ class UnitRouter { case version_info: return Right2LeftRouter(child: VersionInfo()); + case version_info: + return Right2LeftRouter(child: VersionInfo()); + case issues_point: return Right2LeftRouter(child: IssuesPointPage()); case login: return Right2LeftRouter(child: LoginPage()); + case register: + return Right2LeftRouter(child: RegisterPage()); + case attr: return Right2LeftRouter(child: AttrUnitPage()); case bug: diff --git a/lib/blocs/register/bloc.dart b/lib/blocs/register/bloc.dart new file mode 100644 index 0000000..aeb8fb4 --- /dev/null +++ b/lib/blocs/register/bloc.dart @@ -0,0 +1,19 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'event.dart'; +import 'state.dart'; + +/// create by 张风捷特烈 on 2021/1/17 +/// contact me by email 1981462002@qq.com +/// 说明: + +class RegisterBloc extends Bloc { + RegisterBloc() : super(RegisterLoading()); + + @override + Stream mapEventToState(RegisterEvent event) async* { + if (event is DoRegister) { + yield RegisterLoading(); + } + } +} diff --git a/lib/blocs/register/event.dart b/lib/blocs/register/event.dart new file mode 100644 index 0000000..4ecad39 --- /dev/null +++ b/lib/blocs/register/event.dart @@ -0,0 +1,24 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_unit/model/enums.dart'; +import 'package:flutter_unit/storage/po/widget_po.dart'; +import 'package:flutter_unit/model/widget_model.dart'; + +/// create by 张风捷特烈 on 2020-03-03 +/// contact me by email 1981462002@qq.com +/// 说明: + +abstract class RegisterEvent extends Equatable { + const RegisterEvent(); + + @override + List get props => []; +} + +// 发送 邮箱验证 +class DoRegister extends RegisterEvent { + final String email; + final String code; + + DoRegister(this.email, this.code); +} diff --git a/lib/blocs/register/state.dart b/lib/blocs/register/state.dart new file mode 100644 index 0000000..3dc78b2 --- /dev/null +++ b/lib/blocs/register/state.dart @@ -0,0 +1,44 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_unit/model/enums.dart'; +import 'package:flutter_unit/app/res/cons.dart'; +import 'package:flutter_unit/model/widget_model.dart'; + +/// create by 张风捷特烈 on 2020-03-03 +/// contact me by email 1981462002@qq.com +/// 说明: 主页 Widget 列表 状态类 + +abstract class RegisterState extends Equatable { + const RegisterState(); + + @override + List get props => []; +} + +class RegisterLoading extends RegisterState { + @override + List get props => []; +} + +class RegisterError extends RegisterState { + final String message; + + const RegisterError(this.message); + + @override + List get props => [message]; + + @override + String toString() { + return 'RegisterError{message: $message}'; + } +} + +class RegisterSuccess extends RegisterState { + final String username; + + const RegisterSuccess(this.username); + + @override + List get props => [username]; +} diff --git a/lib/views/components/permanent/icon_input.dart b/lib/views/components/permanent/icon_input.dart new file mode 100644 index 0000000..bbd7cc9 --- /dev/null +++ b/lib/views/components/permanent/icon_input.dart @@ -0,0 +1,47 @@ +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2021/1/17 +/// contact me by email 1981462002@qq.com +/// 说明: + +class IconInput extends StatelessWidget { + + final Widget textFiled; + final IconData icon; + + IconInput({Key key,this.textFiled,this.icon}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.withOpacity(0.5), + width: 1.0, + ), + borderRadius: BorderRadius.circular(10.0), + ), + margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), + child: Row( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 15.0), + child: Icon( + icon, + color: Colors.grey, + ), + ), + Container( + height: 20.0, + width: 1.0, + color: Colors.grey.withOpacity(0.5), + margin: const EdgeInsets.only(left: 00.0, right: 10.0), + ), + Expanded( + child: textFiled, + ) + ], + ), + ); + } +} diff --git a/lib/views/pages/login/arc_clipper.dart b/lib/views/pages/login/arc_clipper.dart deleted file mode 100644 index f4ff754..0000000 --- a/lib/views/pages/login/arc_clipper.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; - -/// create by 张风捷特烈 on 2020/4/27 -/// contact me by email 1981462002@qq.com -/// 说明: - -class ArcClipper extends CustomClipper { - final double factor; - - ArcClipper({this.factor = 0.618}); - - @override - Path getClip(Size size) => Path() - ..moveTo(0, 0) - ..relativeLineTo(size.width, 0) - ..relativeLineTo(0, 0.8 * size.height) - ..arcToPoint( - Offset(0.0, size.height * 0.618), - radius: const Radius.elliptical(50.0, 10.0), - rotation: 0.0, - ) - ..close(); - - @override - bool shouldReclip(ArcClipper oldClipper) => factor != oldClipper.factor; -} diff --git a/lib/views/pages/login/login_form.dart b/lib/views/pages/login/login_form.dart index f8db2f8..63e4a5b 100644 --- a/lib/views/pages/login/login_form.dart +++ b/lib/views/pages/login/login_form.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_unit/app/res/toly_icon.dart'; +import 'package:flutter_unit/app/router/unit_router.dart'; import 'package:flutter_unit/views/components/permanent/feedback_widget.dart'; @@ -24,7 +25,7 @@ class _LoginFromState extends State { children: [ Text("FlutterUnit 登录",style: TextStyle(fontSize: 25),), SizedBox(height: 5,), - Text("请使用github用户名登录",style: TextStyle(color: Colors.grey),), + Text("更多精彩,更多体验 ~",style: TextStyle(color: Colors.grey),), SizedBox(height:20,), buildUsernameInput(), Stack( @@ -45,17 +46,23 @@ class _LoginFromState extends State { style: TextStyle(color: Color(0xff444444), fontSize: 14), ), Spacer(), - Text( - "如何注册?", - style: TextStyle( - color: Colors.blue, - fontSize: 14, - decoration: TextDecoration.underline), + FeedbackWidget( + onEnd: (){ + Navigator.of(context).pushNamed(UnitRouter.register); + }, + child: Text( + "用户注册", + style: TextStyle( + color: Colors.blue, + fontSize: 14, + decoration: TextDecoration.underline), + ), ) ], ), _buildBtn(), - buildOtherLogin() + buildOtherLogin(), + const Spacer(flex: 4), ], ); } @@ -82,7 +89,7 @@ class _LoginFromState extends State { borderRadius: BorderRadius.all(Radius.circular(20))), color: Colors.blue, onPressed: _doLogIn, - child: Text("登 录", + child: Text("进入 Unit 世界", style: TextStyle(color: Colors.white, fontSize: 18)), ), ); diff --git a/lib/views/pages/login/login_page.dart b/lib/views/pages/login/login_page.dart index d300283..7fc96b7 100644 --- a/lib/views/pages/login/login_page.dart +++ b/lib/views/pages/login/login_page.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; -import 'package:flutter_unit/app/res/toly_icon.dart'; +import 'package:flutter_unit/views/pages/register/arc_clipper.dart'; -import 'arc_clipper.dart'; import 'login_form.dart'; /// create by 张风捷特烈 on 2020/4/24 @@ -11,6 +10,8 @@ import 'login_form.dart'; class LoginPage extends StatelessWidget { @override Widget build(BuildContext context) { + Size winSize = MediaQuery.of(context).size; + return // BlocListener( @@ -21,11 +22,13 @@ class LoginPage extends StatelessWidget { // }, // child: - Scaffold( - body: SingleChildScrollView( - child: Wrap(children: [ - arcBackground(), + Scaffold( + body: SingleChildScrollView( + child: Wrap(children: [ + UnitArcBackground(height: winSize.height * 0.32), Container( + // color: Colors.green, + height: winSize.height * 0.68, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20), child: @@ -34,10 +37,10 @@ class LoginPage extends StatelessWidget { // builder: (_, state) { // return - Stack( - alignment: Alignment.center, - children: [ - LoginFrom(), + Stack( + alignment: Alignment.center, + children: [ + LoginFrom(), // if (state is LoginFailure) // Positioned( // bottom: 0, @@ -48,56 +51,17 @@ class LoginPage extends StatelessWidget { // LoadingView( // text: "登录中...", // ) - ], - - ) + ], + ) // ); // }, // ), // ) // ] - )] + ) + ] // ), - ), - )); - } - - Widget arcBackground() { - return ArcBackground( - image: AssetImage("assets/images/caver.webp"), - child: Padding( - padding: const EdgeInsets.all(50.0), - child: Container( - padding: const EdgeInsets.all(20), - decoration: BoxDecoration( - color: Colors.blue.withAlpha(88), shape: BoxShape.circle), - child: Icon(TolyIcon.icon_github,size: 100,) - ), - ), - ); - } -} - -class ArcBackground extends StatelessWidget { - final Widget child; - final ImageProvider image; - - ArcBackground({this.child, this.image}); - - @override - Widget build(BuildContext context) { - return ClipPath( - clipper: ArcClipper(), - child: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: image, - fit: BoxFit.cover, ), - ), - alignment: Alignment.center, - child: child, - ), - ); + )); } } diff --git a/lib/views/pages/register/arc_clipper.dart b/lib/views/pages/register/arc_clipper.dart new file mode 100644 index 0000000..4fbf5a8 --- /dev/null +++ b/lib/views/pages/register/arc_clipper.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_unit/views/components/permanent/circle_image.dart'; + +/// create by 张风捷特烈 on 2020/4/27 +/// contact me by email 1981462002@qq.com +/// 说明: + +class ArcClipper extends CustomClipper { + final double factor; + + ArcClipper({this.factor = 0.618}); + + @override + Path getClip(Size size) => Path() + ..moveTo(0, 0) + ..relativeLineTo(size.width, 0) + ..relativeLineTo(0, 0.8 * size.height) + ..arcToPoint( + Offset(0.0, size.height * 0.618), + radius: const Radius.elliptical(50.0, 10.0), + rotation: 0.0, + ) + ..close(); + + @override + bool shouldReclip(ArcClipper oldClipper) => factor != oldClipper.factor; +} + +class ArcBackground extends StatelessWidget { + final Widget child; + final ImageProvider image; + + ArcBackground({this.child, this.image}); + + @override + Widget build(BuildContext context) { + return ClipPath( + clipper: ArcClipper(), + child: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: image, + fit: BoxFit.cover, + ), + ), + alignment: Alignment.center, + child: child, + ), + ); + } +} + +class UnitArcBackground extends StatelessWidget { + final double height; + UnitArcBackground({Key key,this.height}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: height, + child: ArcBackground( + image: AssetImage("assets/images/caver.webp"), + child: Container( + padding: const EdgeInsets.all(30), + decoration: BoxDecoration( + color: Colors.blue.withAlpha(88), shape: BoxShape.circle), + child: CircleImage( + size: 100, + roundColor: Colors.blue, + image: AssetImage( + 'assets/images/sabar.webp', + )), + ), + ), + ); + } +} diff --git a/lib/views/pages/register/register_page.dart b/lib/views/pages/register/register_page.dart new file mode 100644 index 0000000..a96a133 --- /dev/null +++ b/lib/views/pages/register/register_page.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_unit/views/components/permanent/icon_input.dart'; + +import 'arc_clipper.dart'; +import 'send_code.dart'; + +/// create by 张风捷特烈 on 2020/4/24 +/// contact me by email 1981462002@qq.com +/// 说明: + +class RegisterPage extends StatefulWidget { + @override + _RegisterPageState createState() => _RegisterPageState(); +} + +class _RegisterPageState extends State { + final _usernameController = TextEditingController(text: '1981462002@qq.com'); + final _passwordController = TextEditingController(text: ''); + + @override + Widget build(BuildContext context) { + Size winSize = MediaQuery.of(context).size; + + return Scaffold( + body: SingleChildScrollView( + child: Wrap(children: [ + UnitArcBackground(height: winSize.height * 0.32), + Container( + width: winSize.width, + height: winSize.height * 0.68, + padding: const EdgeInsets.only(left: 20.0, right: 20, top: 20), + child: Container( + // color: Colors.green, + child: Column( + children: [ + const Text( + "FlutterUnit 注册", + style: TextStyle(fontSize: 25), + ), + const SizedBox( + height: 5, + ), + const Text( + "更多精彩,更多体验 ~", + style: TextStyle(color: Colors.grey), + ), + const Spacer( + flex: 1, + ), + IconInput( + icon: Icons.person_outline, + textFiled: TextField( + controller: _usernameController, + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入邮箱', + hintStyle: TextStyle(color: Colors.grey), + ), + ), + ), + + const SizedBox(height: 10), + + buildInputWithSend(), + + const Spacer(flex: 1), + _buildBtn(), + const Spacer(flex: 4), + ], + ), + )) + ]), + )); + } + + Stack buildInputWithSend() { + return Stack( + alignment: Alignment(.8, 0), + children: [ + IconInput( + icon: Icons.code_outlined, + textFiled: TextField( + controller: _passwordController, + decoration: InputDecoration( + border: InputBorder.none, + hintText: '请输入验证码', + hintStyle: TextStyle(color: Colors.grey), + ), + ), + ), + CountDownWidget( + onPress: () { + + }, + ) + ], + ); + } + + Widget _buildBtn() => Container( + margin: EdgeInsets.only(top: 10, left: 10, right: 10, bottom: 0), + height: 40, + width: MediaQuery.of(context).size.width, + child: RaisedButton( + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(20))), + color: Colors.blue, + onPressed: _doRegister, + child: Text("开启 Unit 新世界", + style: TextStyle(color: Colors.white, fontSize: 18)), + ), + ); + + void _doRegister() {} +} diff --git a/lib/views/pages/register/send_code.dart b/lib/views/pages/register/send_code.dart new file mode 100644 index 0000000..3474ee3 --- /dev/null +++ b/lib/views/pages/register/send_code.dart @@ -0,0 +1,50 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +/// create by 张风捷特烈 on 2021/1/17 +/// contact me by email 1981462002@qq.com +/// 说明: + +class CountDownWidget extends StatefulWidget { + final VoidCallback onPress; + + CountDownWidget({Key key, this.onPress}) : super(key: key); + + @override + _CountDownWidgetState createState() => _CountDownWidgetState(); +} + +class _CountDownWidgetState extends State { + Timer timer; + int count = 60; + bool startTimer = false; + + @override + void initState() { + super.initState(); + + } + + @override + Widget build(BuildContext context) { + return TextButton( + onPressed: startTimer?null:() { + timer = Timer.periodic(Duration(seconds: 1), _update); + setState(() { + startTimer = true; + }); + }, + child: Text(startTimer?'$count 秒后重试':'获取验证码')); + } + + void _update(Timer timer) { + count--; + if (count == 0) { + timer.cancel(); + startTimer = false; + count=5; + } + setState(() {}); + } +}