Hibok
您不能選擇超過 %s 個話題 話題必須以字母或數字為開頭,可包含連接號 ('-') 且最長為 35 個字
 
 
 
 
 
 

464 行
16 KiB

  1. import 'dart:async';
  2. import 'package:chat/data/UserData.dart';
  3. import 'package:chat/data/constants.dart';
  4. import 'package:chat/generated/i18n.dart';
  5. import 'package:chat/home/find_page.dart';
  6. import 'package:chat/home/group_chat_page.dart';
  7. import 'package:chat/home/realtimehelper/real_time_helper_page.dart';
  8. import 'package:chat/home/unread_dot_widget.dart';
  9. import 'package:chat/models/UserInfo.dart';
  10. import 'package:chat/models/ref_name_provider.dart';
  11. import 'package:chat/utils/HttpUtil.dart';
  12. import 'package:chat/utils/MessageMgr.dart';
  13. import 'package:chat/utils/TokenMgr.dart';
  14. import 'package:chat/utils/app_navigator.dart';
  15. import 'package:chat/utils/file_preview_local.dart';
  16. import 'package:chat/utils/local_notification_util.dart';
  17. import 'package:chat/utils/msgHandler.dart';
  18. import 'package:chat/utils/receive_share_file.dart';
  19. import 'package:chat/utils/screen.dart';
  20. import 'package:chat/utils/sound_util.dart';
  21. import 'package:chat/utils/version_update_utils.dart';
  22. import 'package:dio/dio.dart';
  23. import 'package:flutter/material.dart';
  24. import 'package:chat/home/ConversActionPage.dart';
  25. import 'package:chat/home/ProfilePage.dart';
  26. import 'package:flutter/services.dart';
  27. import 'package:location_permissions/location_permissions.dart';
  28. import 'package:oktoast/oktoast.dart';
  29. import 'package:provider/provider.dart';
  30. import 'package:shared_preferences/shared_preferences.dart';
  31. import 'package:chat/utils/my_bottom_navigation_bar.dart' as myBottm;
  32. import 'friend_page.dart';
  33. class NavigationIconView {
  34. final BottomNavigationBarItem item;
  35. NavigationIconView({
  36. Key key,
  37. String title,
  38. IconData icon,
  39. int type,
  40. double iconSize = 24,
  41. bool isCenter = false,
  42. bool isShowdot = false,
  43. }) : item = BottomNavigationBarItem(
  44. activeIcon: Stack(
  45. alignment: Alignment.center,
  46. children: <Widget>[
  47. isCenter
  48. ? Container(
  49. decoration: BoxDecoration(
  50. shape: BoxShape.circle,
  51. boxShadow: [
  52. BoxShadow(
  53. color: const Color(0x82008DED),
  54. blurRadius: 5.5,
  55. ),
  56. ],
  57. gradient: LinearGradient(
  58. begin: Alignment.topCenter,
  59. end: Alignment.bottomCenter,
  60. colors: <Color>[
  61. const Color(0xFF11E6FF),
  62. const Color(0xFF008AFF),
  63. ]),
  64. ),
  65. margin: EdgeInsets.only(bottom: 4),
  66. width: iconSize + 10,
  67. height: iconSize + 10,
  68. )
  69. : Container(),
  70. Container(
  71. margin: isCenter
  72. ? EdgeInsets.only(bottom: 8, right: 6)
  73. : EdgeInsets.zero,
  74. child: Icon(icon,
  75. size: iconSize,
  76. color:
  77. isCenter ? Colors.white : Constants.BlueTextColor)),
  78. ],
  79. ),
  80. title: Text(''),
  81. backgroundColor: Colors.white,
  82. icon: Stack(
  83. alignment: Alignment.center,
  84. children: <Widget>[
  85. isCenter
  86. ? Container(
  87. decoration: BoxDecoration(
  88. shape: BoxShape.circle,
  89. boxShadow: [
  90. BoxShadow(
  91. color: const Color(0x82008DED),
  92. blurRadius: 5.5,
  93. ),
  94. ],
  95. gradient: LinearGradient(
  96. begin: Alignment.topCenter,
  97. end: Alignment.bottomCenter,
  98. colors: <Color>[
  99. const Color(0xFF11E6FF),
  100. const Color(0xFF008AFF),
  101. ]),
  102. ),
  103. margin: EdgeInsets.only(bottom: 4),
  104. width: iconSize + 10,
  105. height: iconSize + 10,
  106. )
  107. : Container(),
  108. Container(
  109. margin: isCenter
  110. ? EdgeInsets.only(bottom: 8, right: 6)
  111. : EdgeInsets.zero,
  112. child: isShowdot
  113. ? UnreadDot(
  114. child: Icon(icon,
  115. size: iconSize,
  116. color: Constants.BottomIconGreyColor),
  117. type: type)
  118. : Icon(icon,
  119. size: iconSize,
  120. color: isCenter
  121. ? Colors.white
  122. : Constants.BottomIconGreyColor))
  123. ],
  124. ));
  125. }
  126. class HomeMain extends StatefulWidget {
  127. HomeMain({Key key}) : super(key: key);
  128. _HomeMainState createState() => _HomeMainState();
  129. }
  130. class _HomeMainState extends State<HomeMain> {
  131. List<Widget> _pages;
  132. int _currentIndex = 0;
  133. List<NavigationIconView> _navigationViews;
  134. List<String> _titles = [];
  135. DateTime lastPopTime;
  136. Timer time;
  137. @override
  138. void initState() {
  139. SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
  140. super.initState();
  141. LocalNotificationUtil.instance.initState(context);
  142. HttpUtil().checkReceiptCache();
  143. HttpUtil().getSettingInfo();
  144. MessageMgr().on('Receive AudioChat Request', receiveAudioChatRequest);
  145. MessageMgr().on('Login Out', loginOut);
  146. MessageMgr().on('PostContact', postContact);
  147. MessageMgr().on('Show My Profile', showMyProfile);
  148. MessageMgr().on('test_Permission', msgTestPermission);
  149. MessageMgr().on(MessageMgr.RECEIVE_THIRD_SHARE, goShareInfo);
  150. ///初始化语音播放是外放还是听筒-默认外放
  151. SoundUtils.instance.initPlayMode();
  152. postContact(null);
  153. postLoaction();
  154. locationSchedule();
  155. WidgetsBinding.instance.addPostFrameCallback((_) {
  156. VersionUtils.versionUpdate(context);
  157. ReceiveShareFile.start();
  158. });
  159. }
  160. @override
  161. void didChangeDependencies() {
  162. super.didChangeDependencies();
  163. Provider.of<RefNameProvider>(context, listen: false).init();
  164. }
  165. showMyProfile(args) {
  166. setState(() {
  167. _currentIndex = _pages.length - 1;
  168. UserData().homemainIndex = _currentIndex;
  169. });
  170. }
  171. //三分钟获取一次位置信息
  172. void locationSchedule() {
  173. time = Timer.periodic(Duration(milliseconds: 180000), (timer) async {
  174. postLoaction();
  175. });
  176. }
  177. postLoaction() async {
  178. if (UserData().hasLocationPermission) {
  179. UserData().getCurrentPosition(callback: (loc) async {
  180. if (UserData().basicInfo.userId != null) {
  181. //传给服务器
  182. Map data = {
  183. "userId": UserData().basicInfo.userId,
  184. };
  185. data['sign'] = TokenMgr().getSign(data);
  186. data['lat'] = loc.latitude;
  187. data['lon'] = loc.longitude;
  188. Response res =
  189. await HttpUtil().post('location/user/insert', data: data);
  190. if (res == null) {
  191. return;
  192. }
  193. var resData = res.data;
  194. print('location/user/insert $resData');
  195. }
  196. });
  197. }
  198. }
  199. //上传通讯录
  200. postContact(args) async {
  201. SharedPreferences prefs = await SharedPreferences.getInstance();
  202. int localNum = prefs.getInt(Constants.ContactNum);
  203. if (UserData().contactList.length != 0 &&
  204. UserData().contactList.length != localNum &&
  205. UserData().basicInfo.userId != null) {
  206. Map data = {
  207. "userId": UserData().basicInfo.userId,
  208. };
  209. data['sign'] = TokenMgr().getSign(data);
  210. data['list'] = UserData().contactList;
  211. Response res = await HttpUtil().post('maillist/user/insert', data: data);
  212. if (res == null) {
  213. return;
  214. }
  215. var resData = res.data;
  216. if (resData['code'] == 0) {
  217. prefs.setInt(Constants.ContactNum, UserData().contactList.length);
  218. }
  219. }
  220. }
  221. @override
  222. void dispose() {
  223. MessageMgr().off('Receive AudioChat Request', receiveAudioChatRequest);
  224. MessageMgr().off('Login Out', loginOut);
  225. MessageMgr().off('PostContact', postContact);
  226. MessageMgr().off('Show My Profile', showMyProfile);
  227. MessageMgr().off('test_Permission', msgTestPermission);
  228. MessageMgr().off(MessageMgr.RECEIVE_THIRD_SHARE, goShareInfo);
  229. LocalNotificationUtil.instance.dispose();
  230. if (time != null) {
  231. time.cancel();
  232. }
  233. super.dispose();
  234. }
  235. goShareInfo(data) async {
  236. Future.delayed(Duration(milliseconds: 1000), () {
  237. Navigator.of(Constants.getCurrentContext()).push(
  238. new MaterialPageRoute(
  239. builder: (context) {
  240. return FilePreview(data);
  241. },
  242. ),
  243. );
  244. });
  245. }
  246. msgTestPermission(data) async {
  247. PermissionStatus status =
  248. await LocationPermissions().checkPermissionStatus();
  249. if (status == PermissionStatus.granted) {
  250. if (UserData().hasLocationPermission == false) {
  251. UserData().getCurrentPosition();
  252. }
  253. UserData().hasLocationPermission = true;
  254. } else {
  255. UserData().hasLocationPermission = false;
  256. }
  257. }
  258. receiveAudioChatRequest(args) {
  259. print('处理连麦消息');
  260. int friendId = args;
  261. if (!MsgHandler.isAudioConnect) {
  262. if (LocalNotificationUtil.isBackground) {
  263. print('如果在后台,标记不弹');
  264. MsgHandler.audioChatRequestFriendId = friendId;
  265. } else {
  266. HttpUtil().getUserInfo(friendId, (data) {
  267. var info = UserInfo.fromJson(data);
  268. AppNavigator.pushAudioChatPage(context, info, true);
  269. });
  270. }
  271. }
  272. }
  273. loginOut(args) {
  274. HttpUtil().postLoginOut(context);
  275. showToast(I18n.of(context).otherLogin);
  276. }
  277. initValue() {
  278. _titles = [
  279. I18n.of(context).park,
  280. I18n.of(context).radio,
  281. I18n.of(context).news,
  282. I18n.of(context).me
  283. ];
  284. _navigationViews = [
  285. NavigationIconView(
  286. title: _titles[2],
  287. icon: IconData(
  288. 0xe67c,
  289. fontFamily: 'iconfont',
  290. ),
  291. isShowdot: true,
  292. type: 3,
  293. iconSize: 25),
  294. NavigationIconView(
  295. title: _titles[0],
  296. isShowdot: true,
  297. type: 5,
  298. icon: IconData(
  299. 0xe66e,
  300. fontFamily: 'iconfont',
  301. ),
  302. iconSize: 26.5),
  303. NavigationIconView(
  304. title: _titles[1],
  305. icon: IconData(
  306. 0xe656,
  307. fontFamily: 'iconfont',
  308. ),
  309. isCenter: true,
  310. iconSize: 31),
  311. NavigationIconView(
  312. title: _titles[1],
  313. isShowdot: true,
  314. icon: IconData(
  315. 0xe60b,
  316. fontFamily: 'iconfont',
  317. ),
  318. type: 4,
  319. iconSize: 26.5),
  320. NavigationIconView(
  321. title: _titles[3],
  322. icon: IconData(
  323. 0xe67b,
  324. fontFamily: 'iconfont',
  325. ),
  326. iconSize: 26.5),
  327. ];
  328. _pages = [
  329. RealTimeHelperPage(),
  330. FriendPage(),
  331. FindPage(),
  332. ConversActionPage(),
  333. // GroupChatListPage(),
  334. ProfilePage(
  335. userId: UserData().basicInfo.userId,
  336. ),
  337. ];
  338. }
  339. @override
  340. Widget build(BuildContext context) {
  341. initValue();
  342. return WillPopScope(
  343. onWillPop: () async {
  344. if (lastPopTime == null ||
  345. DateTime.now().difference(lastPopTime) > Duration(seconds: 2)) {
  346. lastPopTime = DateTime.now();
  347. showToast(I18n.of(context).confirm_exit);
  348. } else {
  349. lastPopTime = DateTime.now();
  350. await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
  351. }
  352. return new Future.value(false);
  353. },
  354. child: Container(
  355. // color: Colors.white,
  356. color: AppColors.NewAppbarBgColor,
  357. child: Scaffold(
  358. appBar: PreferredSize(
  359. preferredSize: Size.fromHeight(1),
  360. child: AppBar(
  361. backgroundColor: AppColors.NewAppbarBgColor,
  362. ),
  363. ),
  364. resizeToAvoidBottomPadding: false,
  365. body: SafeArea(
  366. child: Stack(
  367. alignment: AlignmentDirectional.bottomStart,
  368. children: <Widget>[
  369. Container(
  370. padding: EdgeInsets.only(bottom: 48),
  371. color: Constants.LightGreyBackgroundColor,
  372. child: SafeArea(
  373. child: IndexedStack(
  374. index: _currentIndex,
  375. children: _pages,
  376. )),
  377. ),
  378. Positioned(
  379. bottom: 0,
  380. child: Container(
  381. margin: EdgeInsets.only(bottom: 0),
  382. child: Image.asset(
  383. 'assets/images/bg.png',
  384. width: Screen.width,
  385. ),
  386. ),
  387. ),
  388. Positioned(
  389. bottom: 0,
  390. child: Container(
  391. width: Screen.width,
  392. height: 0,
  393. color: Colors.white,
  394. ),
  395. ),
  396. Container(
  397. height: 57,
  398. child: myBottm.BottomNavigationBar(
  399. elevation: 0,
  400. showSelectedLabels: false,
  401. showUnselectedLabels: false,
  402. //iconSize: 23.5,
  403. backgroundColor: Colors
  404. .transparent, //Constants.LightGreyBackgroundColor,
  405. currentIndex: _currentIndex,
  406. type: myBottm.BottomNavigationBarType.fixed,
  407. fixedColor: const Color(AppColors.TabIconActive),
  408. items:
  409. _navigationViews.map((NavigationIconView view) {
  410. return view.item;
  411. }).toList(),
  412. onTap: (int index) {
  413. if (_currentIndex == index) {
  414. //在当前页面点击不刷新
  415. return;
  416. }
  417. //刷新我的界面数据
  418. if (index == 4) {
  419. MessageMgr().emit('update_data');
  420. }
  421. // if (index == 1) {
  422. // MessageMgr().emit('refresh_list_when_no_data');
  423. // }
  424. MessageMgr().emit('update_system');
  425. MessageMgr().emit('do_friend_apply');
  426. // LocalNotificationUtil.instance.cleanAllNotifications();
  427. setState(() {
  428. _currentIndex = index;
  429. UserData().homemainIndex = _currentIndex;
  430. });
  431. })),
  432. ],
  433. ))),
  434. ));
  435. }
  436. }