Hibok
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

609 satır
21 KiB

  1. import 'package:chat/data/UserData.dart';
  2. import 'package:chat/data/WebData.dart';
  3. import 'package:chat/data/conversation.dart';
  4. import 'package:chat/data/group_data_mgr.dart';
  5. import 'package:chat/generated/i18n.dart';
  6. import 'package:chat/home/InfoList.dart';
  7. import 'package:chat/home/last_chat_record_widget.dart';
  8. import 'package:chat/home/rich_title.dart';
  9. import 'package:chat/home/unread_dot_widget.dart';
  10. import 'package:chat/models/group_info_model.dart';
  11. import 'package:chat/utils/CustomUI.dart';
  12. import 'package:chat/utils/HttpUtil.dart';
  13. import 'package:chat/utils/MessageMgr.dart';
  14. import 'package:chat/utils/TokenMgr.dart';
  15. import 'package:chat/utils/screen.dart';
  16. import 'package:dio/dio.dart';
  17. import 'package:flutter/cupertino.dart';
  18. import 'package:flutter/material.dart';
  19. import 'package:shared_preferences/shared_preferences.dart';
  20. import '../data/constants.dart' show AppColors, AppStyles, Constants, GlobalSearchPageType, GroupOperatingPageType;
  21. import 'package:cached_network_image/cached_network_image.dart';
  22. import 'create_group_view.dart';
  23. import 'global_search.dart';
  24. import 'group_item_widget.dart';
  25. class _ConversationItem extends StatelessWidget {
  26. const _ConversationItem(
  27. {Key key,
  28. this.conversation,
  29. this.callback,
  30. this.icon,
  31. this.bgColor,
  32. this.iconSize = 20})
  33. : assert(conversation != null),
  34. super(key: key);
  35. final icon;
  36. final double iconSize;
  37. final Conversation conversation;
  38. final callback;
  39. final bgColor;
  40. @override
  41. Widget build(BuildContext context) {
  42. Widget avatar;
  43. if (icon != null) {
  44. avatar = Container(
  45. height: 47.5,
  46. width: 47.5,
  47. margin: EdgeInsets.only(left: 6),
  48. alignment: Alignment.center,
  49. decoration: BoxDecoration(
  50. gradient: bgColor,
  51. borderRadius: BorderRadius.all(Radius.circular(50))),
  52. child: Image.asset(
  53. icon,
  54. height: iconSize,
  55. ));
  56. } else if (conversation.isAvatarFromNet()) {
  57. avatar = CachedNetworkImage(
  58. imageUrl: conversation.avatar,
  59. placeholder: CustomUI.buildImgLoding,
  60. width: Constants.ConversationAvatarSize,
  61. height: Constants.ConversationAvatarSize,
  62. );
  63. } else {
  64. avatar = Image.asset(
  65. conversation.avatar,
  66. width: Constants.ConversationAvatarSize,
  67. height: Constants.ConversationAvatarSize,
  68. );
  69. }
  70. List<Widget> _rightArea = [
  71. Container(
  72. padding: EdgeInsets.only(top: 4),
  73. alignment: Alignment.center,
  74. child: Text(conversation.updateAt,
  75. textScaleFactor: 1.0,
  76. style: TextStyle(fontSize: 11, color: const Color(0xFFC6C6C6))),
  77. )
  78. ];
  79. if (conversation.unreadMsgCount > 0) {
  80. var countStr = conversation.unreadMsgCount.toString();
  81. if (conversation.unreadMsgCount > 99) {
  82. countStr = '99+';
  83. }
  84. // 未读消息角标
  85. Widget unreadMsgCountText = Container(
  86. width: Constants.UnReadMsgNotifyDotSize,
  87. height: Constants.UnReadMsgNotifyDotSize,
  88. alignment: Alignment.center,
  89. decoration: BoxDecoration(
  90. borderRadius:
  91. BorderRadius.circular(Constants.UnReadMsgNotifyDotSize / 2.0),
  92. color: Color(0xFFFF5454),
  93. ),
  94. child: Text(countStr,
  95. textScaleFactor: 1.0, style: AppStyles.UnreadMsgCountDotStyle),
  96. );
  97. _rightArea.add(Expanded(
  98. child: Align(
  99. alignment: Alignment.bottomCenter,
  100. child: unreadMsgCountText,
  101. )));
  102. }
  103. return InkWell(
  104. child: Container(
  105. padding: const EdgeInsets.all(10.0),
  106. decoration: BoxDecoration(
  107. color: Color(AppColors.ConversationItemBgColor),
  108. ),
  109. child: Row(
  110. crossAxisAlignment: CrossAxisAlignment.center,
  111. children: <Widget>[
  112. avatar,
  113. Container(width: 17.0),
  114. Expanded(
  115. child: Column(
  116. crossAxisAlignment: CrossAxisAlignment.start,
  117. children: <Widget>[
  118. Text(conversation.title,
  119. textScaleFactor: 1.0,
  120. style: TextStyle(
  121. color: Colors.black,
  122. )),
  123. SizedBox(
  124. height: 5,
  125. ),
  126. Text(conversation.desc,
  127. textScaleFactor: 1.0,
  128. style: TextStyle(
  129. fontSize: 12, color: const Color(0xFF9B9B9B)))
  130. ],
  131. ),
  132. ),
  133. // Container(width: 10.0),
  134. SizedBox(
  135. height: Constants.ConversationAvatarSize,
  136. child: Column(
  137. crossAxisAlignment: CrossAxisAlignment.end,
  138. mainAxisAlignment: MainAxisAlignment.start,
  139. children: _rightArea,
  140. ),
  141. )
  142. ],
  143. ),
  144. ),
  145. onTap: () {
  146. callback();
  147. },
  148. );
  149. }
  150. }
  151. class ConversActionPage extends StatefulWidget {
  152. ConversActionPage({Key key}) : super(key: key);
  153. _ConversActionPageState createState() => _ConversActionPageState();
  154. }
  155. Map systemInfo = {
  156. 'applyList': null,
  157. 'applyCount': 0,
  158. 'evaluateList': null,
  159. 'evaluateCount': 0,
  160. 'parkList': null,
  161. 'parkCount': 0,
  162. 'castList': null,
  163. 'castCount': 0,
  164. 'walletList': null,
  165. 'walletCount': 0,
  166. };
  167. int msgNum = 0;
  168. bool isShowMsg() {
  169. return msgNum > 0;
  170. }
  171. getAllResNum(prefs) {
  172. getResNum(prefs, Constants.ApplyCount);
  173. getResNum(prefs, Constants.EvaluateCount);
  174. getResNum(prefs, Constants.ParkCount);
  175. getResNum(prefs, Constants.CastCount);
  176. getResNum(prefs, Constants.WalletCount);
  177. }
  178. getResNum(prefs, url) async {
  179. var count = prefs.getInt(url + UserData().basicInfo.userId.toString());
  180. systemInfo[url] = count == null ? systemInfo[url] : (systemInfo[url] - count);
  181. msgNum += systemInfo[url];
  182. }
  183. setResNum(url) async {
  184. var localKey = url + UserData().basicInfo.userId.toString();
  185. if (systemInfo[url] > 0) {
  186. SharedPreferences prefs = await SharedPreferences.getInstance();
  187. var count = prefs.getInt(localKey);
  188. prefs.setInt(
  189. localKey, count == null ? systemInfo[url] : (systemInfo[url] + count));
  190. msgNum -= systemInfo[url];
  191. systemInfo[url] = 0;
  192. }
  193. }
  194. class _ConversActionPageState extends State<ConversActionPage>
  195. with SingleTickerProviderStateMixin {
  196. TabController tabCtrl;
  197. void getSystemMsg(data) async {
  198. Map data = {
  199. "userId": UserData().basicInfo.userId,
  200. "type": UserData().basicInfo.sex
  201. };
  202. data['sign'] = TokenMgr().getSign(data);
  203. Response res = await HttpUtil().post('message/all/message', data: data);
  204. if (res == null) {
  205. return;
  206. }
  207. Map resData = res.data;
  208. if (resData['code'] == 0) {
  209. SharedPreferences prefs = await SharedPreferences.getInstance();
  210. systemInfo = resData['data'];
  211. msgNum = 0;
  212. getAllResNum(prefs);
  213. if (mounted) {
  214. setState(() {});
  215. }
  216. }
  217. }
  218. @override
  219. void initState() {
  220. super.initState();
  221. MessageMgr().on('update_system', getSystemMsg);
  222. MessageMgr().on('Quit Group', quitGroup);
  223. MessageMgr().on('Update Group List', updateGroupLastMsg);
  224. getSystemMsg(null);
  225. tabCtrl = TabController(length: 3, vsync: this);
  226. }
  227. @override
  228. void dispose() {
  229. tabCtrl.dispose();
  230. MessageMgr().off('update_system', getSystemMsg);
  231. super.dispose();
  232. }
  233. @override
  234. Widget build(BuildContext context) {
  235. List<GroupInfoModel> groupList = GroupInfoMgr().groupInfoList;
  236. return Scaffold(
  237. backgroundColor: Colors.white,
  238. appBar: AppBar(
  239. //backgroundColor: Constants.LightGreyBackgroundColor,
  240. centerTitle: false,
  241. title: Text(
  242. I18n.of(context).message_center,
  243. textScaleFactor: 1.0,
  244. style: Constants.MainTitleStyle,
  245. ),
  246. actions: <Widget>[
  247. Container(
  248. child: IconButton(
  249. icon: CircleAvatar(
  250. backgroundColor: Constants.GreyBackgroundColor,
  251. radius: 13.75,
  252. child: Padding(
  253. padding: EdgeInsets.only(bottom: 1.5),
  254. child: Icon(
  255. IconData(0xe659,
  256. fontFamily: Constants.IconFontFamily),
  257. color: Constants.BlackTextColor,
  258. size: 21,
  259. ))),
  260. onPressed: () {
  261. CustomUI().goScanPage(context);
  262. },
  263. ),
  264. ),
  265. // InkWell(
  266. // onTap: () {
  267. // Navigator.of(context).push(
  268. // new MaterialPageRoute(
  269. // builder: (context) {
  270. // return MessagePushPage();
  271. // },
  272. // ),
  273. // );
  274. // },
  275. // child: Padding(
  276. // padding: EdgeInsets.only(right: 10),
  277. // child: CircleAvatar(
  278. // backgroundColor: Constants.GreyBackgroundColor,
  279. // radius: 13.75,
  280. // child: Icon(
  281. // Icons.settings,
  282. // color: Constants.BlackTextColor,
  283. // size: 22,
  284. // )),
  285. // )),
  286. ],
  287. elevation: 0,
  288. bottom: PreferredSize(
  289. preferredSize: Size.fromHeight(28),
  290. child: Container(
  291. padding: EdgeInsets.only(left: 2),
  292. decoration: BoxDecoration(
  293. //color: Constants.LightGreyBackgroundColor,
  294. border:
  295. Border(bottom: BorderSide(color: Color(0xffeaeaea)))),
  296. alignment: Alignment.centerLeft,
  297. child: TabBar(
  298. isScrollable: true,
  299. indicatorPadding: EdgeInsets.only(left: 9, right: 9),
  300. tabs: <Widget>[
  301. UnreadDot(
  302. child: Container(
  303. margin: EdgeInsets.only(right: 4),
  304. child: Text(I18n.of(context).text_chat,
  305. textScaleFactor: 1.0),
  306. ),
  307. type: 1),
  308. UnreadDot(
  309. child: Container(
  310. margin: EdgeInsets.only(right: 4),
  311. child: Text(I18n.of(context).group_chat,
  312. textScaleFactor: 1.0),
  313. ),
  314. type: 4),
  315. UnreadDot(
  316. child: Container(
  317. margin: EdgeInsets.only(right: 4),
  318. child: Text(I18n.of(context).system_information,
  319. textScaleFactor: 1.0)),
  320. type: 2),
  321. ],
  322. controller: tabCtrl,
  323. ),
  324. )),
  325. ),
  326. body: SafeArea(
  327. child: TabBarView(
  328. children: <Widget>[
  329. LastChatPage(),
  330. ListView.builder(
  331. // controller: _scrollController,
  332. itemBuilder: (BuildContext context, int index) {
  333. if (index == 0) {
  334. return _buildCreateButton();
  335. } else {
  336. var info = groupList[index - 1];
  337. return GroupItem(ValueKey(info), groupInfoModel: info);
  338. }
  339. },
  340. itemCount: groupList.length + 1,
  341. ),
  342. ListView(
  343. children: <Widget>[
  344. SizedBox(height: 8.5),
  345. _ConversationItem(
  346. icon: 'assets/images/chat/icon1.png',
  347. bgColor: Constants.RadioGradient,
  348. conversation: Conversation(
  349. avatar: 'assets/images/ic_tx_news.png',
  350. title: I18n.of(context).radio_message,
  351. desc: RichTitle.normalTitle(
  352. systemInfo['castList'], context, InfoType.Radio),
  353. updateAt: systemInfo['castList'] == null
  354. ? ""
  355. : WebData().getLoginTime(
  356. context, systemInfo['castList']['CreateTime']),
  357. unreadMsgCount: systemInfo['castCount'],
  358. ),
  359. callback: () {
  360. setResNum(Constants.CastCount);
  361. Navigator.of(context).push(
  362. new MaterialPageRoute(
  363. builder: (context) {
  364. return InfoListPage(
  365. title: I18n.of(context).radio_message,
  366. type: InfoType.Radio,
  367. );
  368. },
  369. ),
  370. );
  371. },
  372. ),
  373. _ConversationItem(
  374. icon: 'assets/images/chat/icon4.png',
  375. bgColor: Constants.MoneyGradient,
  376. conversation: Conversation(
  377. avatar: 'assets/images/ic_tx_news.png',
  378. title: I18n.of(context).wallet_reminder,
  379. desc: RichTitle.normalTitle(
  380. systemInfo['walletList'], context, InfoType.Money),
  381. updateAt: systemInfo['walletList'] == null
  382. ? ""
  383. : WebData().getLoginTime(
  384. context, systemInfo['walletList']['CreateTime']),
  385. unreadMsgCount: systemInfo['walletCount'],
  386. ),
  387. callback: () {
  388. setResNum(Constants.WalletCount);
  389. Navigator.of(context).push(
  390. new MaterialPageRoute(
  391. builder: (context) {
  392. return InfoListPage(
  393. title: I18n.of(context).wallet_reminder,
  394. type: InfoType.Money,
  395. );
  396. },
  397. ),
  398. );
  399. },
  400. ),
  401. _ConversationItem(
  402. icon: 'assets/images/chat/icon3.png',
  403. iconSize: 27,
  404. bgColor: Constants.ApplyGradient,
  405. conversation: Conversation(
  406. avatar: 'assets/images/ic_tx_news.png',
  407. title: I18n.of(context).application_notice,
  408. desc: RichTitle.normalTitle(
  409. systemInfo['applyList'], context, InfoType.Apply),
  410. updateAt: systemInfo['applyList'] == null
  411. ? ""
  412. : WebData().getLoginTime(
  413. context, systemInfo['applyList']['CreatTime']),
  414. unreadMsgCount: systemInfo['applyCount'],
  415. ),
  416. callback: () {
  417. setResNum(Constants.ApplyCount);
  418. Navigator.of(context).push(
  419. new MaterialPageRoute(
  420. builder: (context) {
  421. return InfoListPage(
  422. title: I18n.of(context).application_notice,
  423. type: InfoType.Apply,
  424. );
  425. },
  426. ),
  427. );
  428. },
  429. ),
  430. _ConversationItem(
  431. icon: 'assets/images/chat/icon6.png',
  432. bgColor: Constants.EvaGradient,
  433. conversation: Conversation(
  434. avatar: 'assets/images/ic_tx_news.png',
  435. title: I18n.of(context).evaluation_notice,
  436. desc: RichTitle.normalTitle(systemInfo['evaluateList'],
  437. context, InfoType.Evaluation),
  438. updateAt: systemInfo['evaluateList'] == null
  439. ? ''
  440. : WebData().getLoginTime(
  441. context, systemInfo['evaluateList']['CreateTime']),
  442. unreadMsgCount: systemInfo['evaluateCount'],
  443. ),
  444. callback: () {
  445. setResNum(Constants.EvaluateCount);
  446. Navigator.of(context).push(
  447. new MaterialPageRoute(
  448. builder: (context) {
  449. return InfoListPage(
  450. title: I18n.of(context).evaluation_notice,
  451. type: 2,
  452. );
  453. },
  454. ),
  455. );
  456. },
  457. ),
  458. _ConversationItem(
  459. icon: 'assets/images/chat/icon5.png',
  460. bgColor: Constants.ParkGradient,
  461. conversation: Conversation(
  462. avatar: 'assets/images/ic_tx_news.png',
  463. title: I18n.of(context).appName,
  464. desc: RichTitle.normalTitle(
  465. systemInfo['parkList'], context, InfoType.System),
  466. updateAt: systemInfo['parkList'] == null
  467. ? ""
  468. : WebData().getLoginTime(
  469. context, systemInfo['parkList']['CreateTime']),
  470. unreadMsgCount: systemInfo['parkCount'],
  471. ),
  472. callback: () {
  473. setResNum(Constants.ParkCount);
  474. Navigator.of(context).push(
  475. new MaterialPageRoute(
  476. builder: (context) {
  477. return InfoListPage(
  478. title: I18n.of(context).appName,
  479. type: InfoType.System,
  480. );
  481. },
  482. ),
  483. );
  484. },
  485. )
  486. ],
  487. )
  488. ],
  489. controller: tabCtrl,
  490. )));
  491. }
  492. Widget _buildCreateButton() {
  493. List<GroupInfoModel> groupList = GroupInfoMgr().groupInfoList;
  494. Widget _avatarIcon = ClipRRect(
  495. borderRadius: BorderRadius.circular(GroupRadius),
  496. child: Container(
  497. color: const Color(0xFFF2F2F2),
  498. height: AvatarSize,
  499. width: AvatarSize,
  500. child: Icon(
  501. IconData(0xe66f, fontFamily: Constants.IconFontFamily),
  502. color: Constants.BlueTextColor,
  503. size: 35,
  504. ),
  505. ));
  506. Widget _button = InkWell(
  507. onTap: () {
  508. Navigator.of(context).push(
  509. new MaterialPageRoute(
  510. builder: (context) {
  511. return CreateGroupPage(
  512. GroupOperatingPageType.CreateGroup, [], null);
  513. },
  514. ),
  515. );
  516. },
  517. child: Container(
  518. height: ItemHeight-20,
  519. // margin: EdgeInsets.only(top: 1.5, bottom:1),
  520. decoration: BoxDecoration(color: Colors.white),
  521. child: Row(
  522. children: <Widget>[
  523. SizedBox(width: LeftPadding),
  524. _avatarIcon,
  525. SizedBox(width: 14.0),
  526. Text(
  527. I18n.of(context).create_group_chat,
  528. style: TextStyle(fontSize: 15.5),
  529. ),
  530. ],
  531. ),
  532. ));
  533. Widget tips = Container(
  534. alignment: Alignment.centerLeft,
  535. width: Screen.width,
  536. height: 33.5,
  537. padding: EdgeInsets.only(left: LeftPadding),
  538. decoration: BoxDecoration(
  539. color: Colors.white,
  540. border: Border(bottom: Constants.GreyBorderSide)),
  541. child: Text(I18n.of(context).group_chat + '(${groupList.length})'),
  542. );
  543. return Column(
  544. children: <Widget>[
  545. SizedBox(height: 10,),
  546. CustomUI.buildSearchButton(context, () {
  547. Navigator.of(context).push(
  548. new MaterialPageRoute(
  549. builder: (context) {
  550. return GlobalSearchPage(
  551. type: GlobalSearchPageType.SearchGroup,
  552. );
  553. },
  554. ),
  555. );
  556. },bottom: 10 ),
  557. _button,
  558. tips,
  559. ],
  560. );
  561. }
  562. quitGroup(args) {
  563. if (mounted) {
  564. setState(() {
  565. print('更新群列表');
  566. });
  567. }
  568. }
  569. updateGroupLastMsg(args) async {
  570. await GroupInfoMgr().sortGroupList();
  571. if (mounted) {
  572. setState(() {});
  573. }
  574. }
  575. }