diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 76699a9..28348e3 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,9 +1,12 @@ - + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true" + tools:replace="android:label"> UserController(), fenix: true, ); + Get.lazyPut( + () => PublishController(), + fenix: true, + ); }, ), ); diff --git a/lib/models/auth/auth_model.dart b/lib/models/auth/auth_model.dart index a550862..c359182 100644 --- a/lib/models/auth/auth_model.dart +++ b/lib/models/auth/auth_model.dart @@ -1,20 +1,20 @@ import 'package:chat/models/user_info_model.dart'; class AuthModel { - String accessToken; + String userToken; String userSig; String userID; UserInfoModel userInfo; AuthModel({ - required this.accessToken, + required this.userToken, required this.userID, required this.userSig, required this.userInfo, }); factory AuthModel.fromJson(Map json) => AuthModel( - accessToken: json['access_token'], + userToken: json['access_token'], userID: json['user_id'].toString(), userSig: json['user_sig'], userInfo: UserInfoModel.fromJson(json['user_info']), diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart index f6eab6c..7611f6f 100644 --- a/lib/services/auth_service.dart +++ b/lib/services/auth_service.dart @@ -2,6 +2,7 @@ import 'package:chat/models/user_info_model.dart'; import 'package:chat/providers/auth_provider.dart'; import 'package:chat/routes/auth_routes.dart'; import 'package:chat/services/tim_service.dart'; +import 'package:chat/utils/hd_wallet.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:tencent_im_sdk_plugin/tencent_im_sdk_plugin.dart'; @@ -44,19 +45,24 @@ class AuthService extends GetxService { } } - Future login(String address) async { - address = '12dUut3dG5xWi6JPDMjSSK6s2JPcfeKYL1'; + Future login(String mnemonic) async { + String? address = HDWallet.mnemonicToAddress(mnemonic); + + if (address == null) { + return false; + } + var result = await AuthProvider.login(address); if (result != null) { _box.write('userId', result.userID); _box.write('userSig', result.userSig); - _box.write('userToken', result.accessToken); + _box.write('userToken', result.userToken); _box.write('userInfo', result.userInfo.toJson()); userId = result.userID; userSig = result.userSig; - userToken = result.accessToken; + userToken = result.userToken; userInfo.value = result.userInfo; isLogin.value = true; @@ -88,7 +94,6 @@ class AuthService extends GetxService { } Future updateUserInfo(String key, String value) async { - // userInfo.value.nickname = nickname; if (key == 'nickname') { userInfo.value.nickname = value; } else if (key == 'avatar') { diff --git a/lib/views/auth/create/verify_page.dart b/lib/views/auth/create/verify_page.dart index 5f10977..1e7c6f4 100644 --- a/lib/views/auth/create/verify_page.dart +++ b/lib/views/auth/create/verify_page.dart @@ -1,4 +1,6 @@ import 'package:chat/configs/app_colors.dart'; +import 'package:chat/routes/app_routes.dart'; +import 'package:chat/services/auth_service.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -11,13 +13,21 @@ class AuthCreateVerifyPage extends StatefulWidget { class _AuthCreateVerifyPageState extends State { late final List _mnemonicList; + late final List _originList; + List _sureList = List.generate(12, (index) => ''); + @override void initState() { super.initState(); Get.arguments['language']; var m = Get.arguments['mnemonic'] as List; + _originList = List.from(m); m.shuffle(); _mnemonicList = m; + + setState(() { + _sureList = _originList; + }); } @override @@ -26,25 +36,103 @@ class _AuthCreateVerifyPageState extends State { appBar: AppBar( title: const Text('校验助记词'), ), - body: _moArea(_mnemonicList), + body: ListView( + padding: const EdgeInsets.all(16), + children: [ + _sureArea(), + const Padding( + padding: EdgeInsets.symmetric(vertical: 8), + child: Text('请按正确顺序点击您所备份的助记词'), + ), + _moArea(_mnemonicList), + const SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + ElevatedButton( + onPressed: () { + setState(() { + _sureList = List.generate(12, (index) => ''); + }); + }, + child: const Text('重新输入'), + ), + ElevatedButton( + onPressed: _originList.join('') == _sureList.join('') + ? () async { + var result = + await AuthService.to.login(_originList.join(' ')); + if (result) { + Get.offAllNamed(AppRoutes.app); + } + } + : null, + child: const Text('确认备份'), + ), + ], + ), + ], + ), + ); + } + + Widget _sureArea() { + return GridView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.5 / 1, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemCount: 12, + itemBuilder: (_, i) { + return Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + border: Border.all( + color: AppColors.border, + width: 1, + ), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + '${i + 1}. ${_sureList[i]}', + style: const TextStyle( + fontSize: 16, + ), + ), + ); + }, ); } Widget _moArea(List mnemonic) { - return Padding( - padding: const EdgeInsets.all(16.0), - child: GridView.builder( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 4.5 / 1, - crossAxisSpacing: 8, - mainAxisSpacing: 8, - ), - itemCount: mnemonic.length, - itemBuilder: (_, i) { - return Container( + return GridView.builder( + shrinkWrap: true, + physics: const ClampingScrollPhysics(), + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 4.5 / 1, + crossAxisSpacing: 8, + mainAxisSpacing: 8, + ), + itemCount: mnemonic.length, + itemBuilder: (_, i) { + return InkWell( + onTap: !_sureList.contains(mnemonic[i]) + ? () { + int len = _sureList.where((element) => element != '').length; + setState(() { + _sureList[len] = mnemonic[i]; + }); + } + : null, + child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( + color: _sureList.contains(mnemonic[i]) ? AppColors.primary : null, border: Border.all( color: AppColors.border, width: 1, @@ -52,14 +140,14 @@ class _AuthCreateVerifyPageState extends State { borderRadius: BorderRadius.circular(8), ), child: Text( - '${i + 1}. ${mnemonic[i]}', + mnemonic[i], style: const TextStyle( fontSize: 16, ), ), - ); - }, - ), + ), + ); + }, ); } } diff --git a/lib/views/auth/import/index_page.dart b/lib/views/auth/import/index_page.dart index 87d94c9..d795f9b 100644 --- a/lib/views/auth/import/index_page.dart +++ b/lib/views/auth/import/index_page.dart @@ -1,7 +1,6 @@ import 'package:chat/configs/app_colors.dart'; import 'package:chat/routes/app_routes.dart'; import 'package:chat/services/auth_service.dart'; -import 'package:chat/utils/hd_wallet.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -13,24 +12,7 @@ class AuthImportPage extends StatefulWidget { } class _AuthImportPageState extends State { - final TextEditingController _editingController = TextEditingController(); - - @override - void initState() { - super.initState(); - - setState(() { - _editingController.text = - 'demise sell awesome tragic faith village party elbow lady leopard wrestle civil'; - }); - } - - @override - void dispose() { - _editingController.dispose(); - super.dispose(); - } - + String _mn = ''; @override Widget build(BuildContext context) { return Scaffold( @@ -42,7 +24,6 @@ class _AuthImportPageState extends State { child: Column( children: [ TextField( - controller: _editingController, maxLines: 5, decoration: const InputDecoration( hintText: '请输入您的助记词,以空格分割单词或汉字', @@ -53,21 +34,24 @@ class _AuthImportPageState extends State { ), ), ), + onChanged: (e) { + setState(() { + _mn = e; + }); + }, ), const SizedBox(height: 16), const Text('支持导入所有遵循BIP标准生成的助记词'), const SizedBox(height: 16), ElevatedButton( - onPressed: () async { - String? address = - HDWallet.mnemonicToAddress(_editingController.text); - if (address != null) { - var result = await AuthService.to.login(address); - if (result) { - Get.offAllNamed(AppRoutes.app); - } - } - }, + onPressed: _mn.isNotEmpty + ? () async { + var result = await AuthService.to.login(_mn); + if (result) { + Get.offAllNamed(AppRoutes.app); + } + } + : null, child: const Text('开始导入'), ), ], diff --git a/lib/views/auth/index/index_page.dart b/lib/views/auth/index/index_page.dart index 8c76401..53c22f5 100644 --- a/lib/views/auth/index/index_page.dart +++ b/lib/views/auth/index/index_page.dart @@ -1,3 +1,4 @@ +import 'package:chat/configs/app_colors.dart'; import 'package:chat/routes/auth_routes.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -13,29 +14,82 @@ class _AuthPageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar( - title: const Text('ZH-CHAT'), - ), - body: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - ElevatedButton( - onPressed: () { - Get.toNamed(AuthRoutes.create); - }, - child: const Text('创建账户'), + body: Padding( + padding: const EdgeInsets.all(24.0), + child: Column( + children: [ + const SizedBox(height: 128), + const Text( + 'ZH-CHAT', + style: TextStyle( + fontSize: 48, + fontWeight: FontWeight.bold, + color: AppColors.primary, ), - ElevatedButton( - onPressed: () { - Get.toNamed(AuthRoutes.import); - }, - child: const Text('导入账户'), + ), + const SizedBox(height: 24), + Image.asset( + 'assets/images/login_bg.png', + fit: BoxFit.contain, + color: AppColors.primary, + ), + const SizedBox(height: 48), + Container( + decoration: BoxDecoration( + color: AppColors.active, + borderRadius: BorderRadius.circular(8), + image: const DecorationImage( + image: AssetImage('assets/images/login_bg.png'), + opacity: 0.2, + fit: BoxFit.contain, + alignment: Alignment.topRight, + ), ), - ], - ), - ], + padding: const EdgeInsets.all(24), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + '助记词账户', + style: TextStyle( + color: AppColors.white, + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 40), + Row( + children: [ + ElevatedButton( + onPressed: () { + Get.toNamed(AuthRoutes.create); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + AppColors.white, + ), + ), + child: const Text( + '创建账户', + style: TextStyle( + color: AppColors.active, + ), + ), + ), + const SizedBox(width: 16), + ElevatedButton( + onPressed: () { + Get.toNamed(AuthRoutes.import); + }, + child: const Text('导入账户'), + ), + ], + ), + ], + ), + ), + ], + ), ), ); }