Hibok
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

677 lines
22 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:chat/data/UserData.dart';
  3. import 'package:chat/data/chat_data_mgr.dart';
  4. import 'package:chat/data/group_data_mgr.dart';
  5. import 'package:chat/home/add_friend.dart';
  6. import 'package:chat/home/group_announcement.dart';
  7. import 'package:chat/home/group_manage_page.dart';
  8. import 'package:chat/models/group_info_model.dart';
  9. import 'package:chat/models/ref_name_provider.dart';
  10. import 'package:chat/utils/MessageMgr.dart';
  11. import 'package:chat/utils/group_member_model.dart';
  12. import 'package:chat/utils/msgHandler.dart';
  13. import 'package:chat/utils/screen.dart';
  14. import 'package:flutter/cupertino.dart';
  15. import 'package:flutter/material.dart';
  16. import 'package:oktoast/oktoast.dart';
  17. import 'package:provider/provider.dart';
  18. import '../data/constants.dart';
  19. import '../generated/i18n.dart';
  20. import '../utils/CustomUI.dart';
  21. import '../utils/FullWithButton.dart';
  22. import '../utils/app_navigator.dart';
  23. import 'create_group_view.dart';
  24. class GroupSetting extends StatefulWidget {
  25. final GroupInfoModel groupInfoModel;
  26. GroupSetting({Key key, this.groupInfoModel}) : super(key: key);
  27. @override
  28. State<StatefulWidget> createState() {
  29. return GroupSettingState();
  30. }
  31. }
  32. class GroupSettingState extends State<GroupSetting> {
  33. static const Separate_Size = 15.0;
  34. bool notice = true; //消息提示
  35. bool stickyChat = false; //置顶聊天
  36. bool showGroupFriendNickname = true; //显示群成员昵称
  37. bool isHost;
  38. ///是否是群主
  39. @override
  40. void initState() {
  41. super.initState();
  42. stickyChat = widget.groupInfoModel.topTag > 0;
  43. MessageMgr().on('Update Group Info', updateGroupInfo);
  44. notice = widget.groupInfoModel.messageFree == 1;
  45. showGroupFriendNickname = widget.groupInfoModel.isShowName > 0;
  46. print(
  47. ' widget.groupInfoModel.hosterId : ${widget.groupInfoModel.hosterId}');
  48. }
  49. @override
  50. void dispose() {
  51. MessageMgr().off('Update Group Info', updateGroupInfo);
  52. super.dispose();
  53. }
  54. updateGroupInfo(args) {
  55. print('群设置 - 更新群信息');
  56. if (mounted) {
  57. setState(() {});
  58. }
  59. }
  60. quitGroup() {
  61. print('退出所有页面');
  62. GroupInfoMgr().deleteGroup(widget.groupInfoModel.sessionId);
  63. MessageMgr().emit('Quit Group', widget.groupInfoModel.sessionId);
  64. Navigator.of(context).popUntil(ModalRoute.withName('/main'));
  65. }
  66. //清空聊天记录
  67. clearRecord() {
  68. //清楚最后一条数据
  69. widget.groupInfoModel.lastMsg = null;
  70. //清空聊天数据
  71. ChatDataMgr().deleteMsg(widget.groupInfoModel.sessionId, true);
  72. }
  73. @override
  74. Widget build(BuildContext context) {
  75. isHost = widget.groupInfoModel.hosterId == UserData().basicInfo.userId;
  76. print(widget.groupInfoModel.myName);
  77. Widget appBar = AppBar(
  78. backgroundColor: AppColors.NewAppbarBgColor,
  79. title: new Text(
  80. I18n.of(context).chat_news +
  81. '(${widget.groupInfoModel.getMembersInGroup().length})',
  82. textScaleFactor: 1.0,
  83. style: TextStyle(color: AppColors.NewAppbarTextColor),
  84. ),
  85. leading: CustomUI.buildCustomLeading(context),
  86. centerTitle: true,
  87. );
  88. var groupName =
  89. (widget.groupInfoModel.name == '' || widget.groupInfoModel.name == null)
  90. ? I18n.of(context).undefine_name
  91. : widget.groupInfoModel.name;
  92. return Scaffold(
  93. appBar: appBar,
  94. body: SafeArea(
  95. child: ListView(
  96. children: <Widget>[
  97. SizedBox(
  98. height: 12,
  99. ),
  100. ///群成员
  101. buildMember(
  102. () {
  103. ///添加成员
  104. Navigator.of(context).push(
  105. new MaterialPageRoute(
  106. builder: (context) {
  107. return CreateGroupPage(
  108. GroupOperatingPageType.AddMember,
  109. widget.groupInfoModel.getMembersInGroup(),
  110. widget.groupInfoModel.sessionId);
  111. },
  112. ),
  113. );
  114. },
  115. () {
  116. ///删除成员
  117. Navigator.of(context).push(
  118. new MaterialPageRoute(
  119. builder: (context) {
  120. return CreateGroupPage(
  121. GroupOperatingPageType.DeleteMember,
  122. widget.groupInfoModel.getMembersInGroup(),
  123. widget.groupInfoModel.sessionId);
  124. },
  125. ),
  126. );
  127. },
  128. () {
  129. /// 查看更多成员
  130. AppNavigator.pushGroupAllMember(context, widget.groupInfoModel);
  131. },
  132. ),
  133. SizedBox(
  134. height: 12,
  135. ),
  136. ///群聊名称
  137. _buildSetting(I18n.of(context).group_chat_name, groupName, () {
  138. if (widget.groupInfoModel.canAlterGroupName()) {
  139. Navigator.of(context).push(
  140. new MaterialPageRoute(
  141. builder: (context) {
  142. return AddFriendPage(
  143. userId: widget.groupInfoModel.sessionId,
  144. pageType: SendMessagePageType.ChangeGroupName,
  145. originalName: groupName,
  146. );
  147. },
  148. ),
  149. );
  150. } else {
  151. showToast('权限不足');
  152. }
  153. }),
  154. ///群二维码
  155. UserData().groupQRCode == 0
  156. ? Container()
  157. : _buildSetting(I18n.of(context).group_qr, '', () {
  158. AppNavigator.pushGroupQrPage(
  159. context, widget.groupInfoModel);
  160. },
  161. extendWidget: Icon(
  162. IconData(0xe658, fontFamily: 'iconfont'),
  163. size: 20.0,
  164. color: Color(AppColors.TabIconNormal),
  165. )),
  166. ///群公告
  167. groupAnnounce(),
  168. ///群管理
  169. widget.groupInfoModel.hosterId == UserData().basicInfo.userId
  170. ? _buildSetting(I18n.of(context).group_setting, '', () {
  171. Navigator.of(context).push(
  172. new MaterialPageRoute(
  173. builder: (context) {
  174. return GroupManagePage(
  175. groupInfoModel: widget.groupInfoModel,
  176. );
  177. },
  178. ),
  179. );
  180. }, showDivider: false)
  181. : Container(),
  182. SizedBox(
  183. height: 11,
  184. ),
  185. ///消息免打扰
  186. _buildSettingWithSwitch(notice, I18n.of(context).close_news_notice,
  187. (bool val) {
  188. setState(() {
  189. notice = val;
  190. MsgHandler.updateMemberMsgFreeReq(
  191. widget.groupInfoModel.sessionId, notice);
  192. });
  193. }),
  194. Container(
  195. height: 0.5,
  196. color: Colors.white,
  197. child: Container(
  198. color: Color(0xffE5E5E5),
  199. ),
  200. padding: EdgeInsets.symmetric(horizontal: 20),
  201. ),
  202. ///置顶聊天
  203. _buildSettingWithSwitch(stickyChat, I18n.of(context).set_chat_top,
  204. (bool val) {
  205. setState(() {
  206. stickyChat = val;
  207. widget.groupInfoModel.updateTopTag(stickyChat);
  208. MessageMgr().emit('Update Group List');
  209. });
  210. }),
  211. SizedBox(
  212. height: 11,
  213. ),
  214. ///我在本群的昵称
  215. _buildSetting(
  216. I18n.of(context).my_group_nickname,
  217. widget.groupInfoModel.myName == null
  218. ? UserData().basicInfo.nickName
  219. : widget.groupInfoModel.myName, () {
  220. Navigator.of(context).push(
  221. new MaterialPageRoute(
  222. builder: (context) {
  223. return AddFriendPage(
  224. userId: widget.groupInfoModel.sessionId,
  225. pageType: SendMessagePageType.ChangeGroupNickName,
  226. originalName: widget.groupInfoModel.myName,
  227. );
  228. },
  229. ),
  230. );
  231. }),
  232. ///显示群成员昵称
  233. _buildSettingWithSwitch(showGroupFriendNickname,
  234. I18n.of(context).show_group_member_name, (bool val) {
  235. setState(() {
  236. showGroupFriendNickname = val;
  237. widget.groupInfoModel.updateShowNameSwitch(val);
  238. MsgHandler.setGroupIsShowMenberNiceNameReq(widget.groupInfoModel.sessionId, val);
  239. });
  240. }),
  241. SizedBox(
  242. height: 11,
  243. ),
  244. ///清除聊天记录
  245. _buildSettingWithConfirm(I18n.of(context).group_clean_chat_record,
  246. I18n.of(context).group_clean_chat_record, () {
  247. clearRecord();
  248. Navigator.of(context).pop();
  249. }),
  250. Padding(
  251. padding: EdgeInsets.symmetric(horizontal: Separate_Size),
  252. child: Divider(
  253. color: Color(0xffE5E5E5),
  254. height: 0.6,
  255. ),
  256. ),
  257. ///退出并删除按钮
  258. _buildSettingWithConfirm(I18n.of(context).quit_and_delete,
  259. I18n.of(context).quit_group_tips, () {
  260. print('退出群聊');
  261. quitGroup();
  262. MsgHandler.quitGroup(widget.groupInfoModel.sessionId);
  263. }),
  264. ],
  265. ),
  266. ),
  267. );
  268. }
  269. Widget _buildSetting(String title, String desc, Function func,
  270. {showRightIcon = true, showDivider = true, extendWidget}) {
  271. //版本
  272. return Container(
  273. padding: EdgeInsets.symmetric(horizontal: 10),
  274. child: FullWidthButton(
  275. showRightIcon: showRightIcon,
  276. title: title,
  277. description: desc,
  278. extendWidget: extendWidget,
  279. showDivider: showDivider,
  280. onPressed: func,
  281. ),
  282. decoration: BoxDecoration(
  283. color: Colors.white,
  284. ),
  285. );
  286. }
  287. Widget _buildSettingWithSwitch(
  288. bool switchValue, String title, Function onchang) {
  289. Widget left = new Text(
  290. title,
  291. textScaleFactor: 1.0,
  292. style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal),
  293. );
  294. Widget right = new Expanded(
  295. child: new Container(
  296. alignment: Alignment.centerRight,
  297. padding: EdgeInsets.only(right: 8),
  298. child: new Switch(
  299. value: switchValue,
  300. activeTrackColor: Constants.ConfrimButtonColor.withOpacity(0.3),
  301. onChanged: onchang,
  302. )));
  303. return new Container(
  304. decoration: BoxDecoration(
  305. color: Colors.white,
  306. ),
  307. padding: EdgeInsets.only(left: 20),
  308. height: 53,
  309. child: new Row(
  310. children: <Widget>[left, right],
  311. ),
  312. );
  313. }
  314. Widget _buildSettingWithConfirm(
  315. String title, String dialogTips, Function function) {
  316. return Container(
  317. color: Colors.white,
  318. padding: EdgeInsets.only(top: 11, bottom: 11),
  319. child: InkWell(
  320. onTap: () {
  321. showModalBottomSheet(
  322. context: context,
  323. backgroundColor: Colors.transparent,
  324. builder: (BuildContext context) {
  325. return Container(
  326. decoration: BoxDecoration(
  327. color: Colors.white,
  328. borderRadius: BorderRadius.only(
  329. topLeft: Radius.circular(13),
  330. topRight: Radius.circular(13))),
  331. height: 225,
  332. child: Column(
  333. crossAxisAlignment: CrossAxisAlignment.center,
  334. mainAxisAlignment: MainAxisAlignment.center,
  335. children: <Widget>[
  336. Padding(
  337. padding: EdgeInsets.fromLTRB(15, 15, 15, 13),
  338. child: Text(
  339. dialogTips,
  340. style:
  341. TextStyle(fontSize: 12, color: Color(0xff777777)),
  342. ),
  343. ),
  344. Divider(
  345. color: Color(0xffE5E5E5),
  346. ),
  347. InkWell(
  348. onTap: function,
  349. child: Container(
  350. height: 60,
  351. alignment: Alignment.center,
  352. child: Text(I18n.of(context).determine,
  353. style: TextStyle(
  354. fontSize: 18,
  355. color: Constants.ConfrimButtonColor)),
  356. ),
  357. ),
  358. Container(
  359. color: Color(0xffF2F2F2),
  360. height: 4,
  361. ),
  362. InkWell(
  363. onTap: () {
  364. Navigator.of(context).pop();
  365. },
  366. child: Container(
  367. height: 60,
  368. alignment: Alignment.center,
  369. child: Text(I18n.of(context).cancel,
  370. style: TextStyle(
  371. fontSize: 18, color: Color(0xff4B4B4B))),
  372. ),
  373. )
  374. ],
  375. ),
  376. );
  377. },
  378. );
  379. },
  380. child: Container(
  381. height: 40,
  382. margin: EdgeInsets.symmetric(horizontal: 40),
  383. alignment: Alignment.center,
  384. child: Text(
  385. title,
  386. style:
  387. TextStyle(color: Constants.ConfrimButtonColor, fontSize: 15),
  388. ),
  389. ),
  390. ));
  391. }
  392. ///群公告
  393. Widget groupAnnounce() {
  394. return InkWell(
  395. onTap: () {
  396. if (widget.groupInfoModel.describe == '' && !isHost) {
  397. showToast(I18n.of(context).only_host);
  398. return;
  399. }
  400. Navigator.of(context).push(
  401. new MaterialPageRoute(
  402. builder: (context) {
  403. return GroupAnnouncementPage(
  404. groupInfoModel: widget.groupInfoModel,
  405. );
  406. },
  407. ),
  408. );
  409. },
  410. child: Container(
  411. color: Colors.white,
  412. child: Column(
  413. children: <Widget>[
  414. Container(
  415. padding: EdgeInsets.symmetric(
  416. horizontal: Separate_Size, vertical: 12),
  417. color: Colors.white,
  418. child: Row(
  419. children: <Widget>[
  420. Column(
  421. crossAxisAlignment: CrossAxisAlignment.start,
  422. children: <Widget>[
  423. Padding(
  424. padding: EdgeInsets.only(top: 0, left: 4),
  425. child: Text(
  426. I18n.of(context).group_announcement,
  427. style: TextStyle(
  428. color: Colors.black, fontSize: 14),
  429. ),
  430. ),
  431. widget.groupInfoModel.describe == null ||
  432. widget.groupInfoModel.describe == ""
  433. ? Container()
  434. : Container(
  435. width: Screen.width - 55,
  436. padding: EdgeInsets.only(top: 3, left: 4),
  437. child: Text(
  438. widget.groupInfoModel.describe,
  439. maxLines: 1,
  440. overflow: TextOverflow.ellipsis,
  441. style: TextStyle(
  442. color: Color(0xff818181),
  443. fontSize: 11),
  444. ),
  445. ),
  446. ]),
  447. Expanded(
  448. child: SizedBox(),
  449. ),
  450. Padding(
  451. padding: EdgeInsets.only(bottom: 0),
  452. child: Icon(
  453. IconData(0xe63c, fontFamily: 'iconfont'),
  454. size: 20.0,
  455. color: Color(AppColors.TabIconNormal),
  456. ))
  457. ],
  458. )),
  459. Container(
  460. margin: EdgeInsets.symmetric(horizontal: 15),
  461. decoration: BoxDecoration(
  462. border: Border(
  463. bottom: Constants.GreyBorderSide,
  464. ),
  465. ),
  466. )
  467. ],
  468. )));
  469. }
  470. ///群成员显示
  471. Widget buildMember(
  472. Function addMember, Function deleteMember, Function seeMoreMember) {
  473. // List<GroupMemberModel> members = widget.groupInfoModel.getMembersInGroup();
  474. List<GroupMemberModel> members = [];
  475. for (int k = 0; k < widget.groupInfoModel.members.length; k++) {
  476. //只加入存在群的
  477. GroupMemberModel mo = widget.groupInfoModel.members[k];
  478. if (mo.inGroup == 1) {
  479. members.add(mo);
  480. }
  481. }
  482. members.sort((GroupMemberModel left, GroupMemberModel right) =>
  483. right.identity.compareTo(left.identity));
  484. print('群成员数量- ${members.length}');
  485. int length = members.length;
  486. int dex = isHost ? 2 : 1;
  487. int shouldShow = length > (10 - dex) ? 10 - dex : length;
  488. double size = Screen.width / 5;
  489. List<Widget> list = [];
  490. for (int index = 0; index < shouldShow; index++) {
  491. var member = members[index];
  492. var refName = Provider.of<RefNameProvider>(context)
  493. .getGroupRefName(widget.groupInfoModel.sessionId, member.memberId);
  494. list.add(GestureDetector(
  495. child: Container(
  496. child: Column(
  497. children: <Widget>[
  498. ClipRRect(
  499. borderRadius: BorderRadius.all(Radius.circular(8.0)),
  500. child: CachedNetworkImage(
  501. imageUrl: member.avtar,
  502. placeholder: (context, url) => Image.asset(
  503. Constants.DefaultHeadImgUrl,
  504. width: size - 30,
  505. height: size - 30,
  506. ),
  507. width: size - 30,
  508. height: size - 30,
  509. )),
  510. SizedBox(
  511. height: 5,
  512. ),
  513. Container(
  514. width: size - 30,
  515. alignment: Alignment.center,
  516. child: Text(
  517. refName,
  518. textAlign: TextAlign.center,
  519. style: TextStyle(fontSize: 11, color: Color(0xff818181)),
  520. maxLines: 1,
  521. overflow: TextOverflow.ellipsis,
  522. ),
  523. )
  524. ],
  525. ),
  526. width: size,
  527. height: size,
  528. ),
  529. behavior: HitTestBehavior.translucent,
  530. onTap: () {
  531. if (members[index].memberId != UserData().basicInfo.userId) {
  532. AppNavigator.pushProfileInfoPage(context, members[index].memberId,
  533. fromWhere: 2, addMode: 1);
  534. }
  535. },
  536. ));
  537. }
  538. list.add(GestureDetector(
  539. onTap: addMember,
  540. child: Container(
  541. width: size,
  542. height: size,
  543. child: Column(
  544. children: <Widget>[
  545. Container(
  546. alignment: Alignment.center,
  547. width: size - 30,
  548. height: size - 30,
  549. child: Text(
  550. '+',
  551. textScaleFactor: 1.0,
  552. style: TextStyle(fontSize: 30, color: Color(0xffB1B1B1)),
  553. ),
  554. decoration: BoxDecoration(
  555. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  556. borderRadius: BorderRadius.all(Radius.circular(6))),
  557. )
  558. ],
  559. ),
  560. ),
  561. ));
  562. if (isHost) {
  563. list.add(Container(
  564. width: size,
  565. height: size,
  566. child: Column(
  567. children: <Widget>[
  568. GestureDetector(
  569. onTap: deleteMember,
  570. child: Container(
  571. alignment: Alignment.center,
  572. width: size - 30,
  573. height: size - 30,
  574. child: Container(
  575. color: Color(0xffB1B1B1),
  576. width: 20,
  577. height: 2.6,
  578. ),
  579. decoration: BoxDecoration(
  580. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  581. borderRadius: BorderRadius.all(Radius.circular(6))),
  582. ),
  583. )
  584. ],
  585. ),
  586. ));
  587. }
  588. return Container(
  589. color: Color(0xffFAFAFA),
  590. child: Column(
  591. crossAxisAlignment: CrossAxisAlignment.start,
  592. children: <Widget>[
  593. SizedBox(
  594. height: 5,
  595. ),
  596. Wrap(
  597. children: list,
  598. crossAxisAlignment: WrapCrossAlignment.start,
  599. alignment: WrapAlignment.start,
  600. ),
  601. length > (10 - dex)
  602. ? GestureDetector(
  603. onTap: seeMoreMember,
  604. child: Container(
  605. height: 35,
  606. child: Row(
  607. mainAxisAlignment: MainAxisAlignment.center,
  608. children: <Widget>[
  609. Text(
  610. I18n.of(context).show_more_member,
  611. textScaleFactor: 1.0,
  612. style: TextStyle(color: Color(0xff818181)),
  613. ),
  614. Padding(
  615. padding: EdgeInsets.only(bottom: 1.5),
  616. child: Icon(
  617. IconData(0xe63c, fontFamily: 'iconfont'),
  618. size: 20.0,
  619. color: Color(AppColors.TabIconNormal),
  620. ))
  621. ],
  622. ),
  623. ),
  624. )
  625. : Container(),
  626. ],
  627. ),
  628. );
  629. }
  630. }