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

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