Hibok
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

684 linhas
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. 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. textScaleFactor: 1.0,
  341. style:
  342. TextStyle(fontSize: 12, color: Color(0xff777777)),
  343. ),
  344. ),
  345. Divider(
  346. color: Color(0xffE5E5E5),
  347. ),
  348. InkWell(
  349. onTap: function,
  350. child: Container(
  351. height: 60,
  352. alignment: Alignment.center,
  353. child: Text(I18n.of(context).determine,
  354. textScaleFactor: 1.0,
  355. style: TextStyle(
  356. fontSize: 18,
  357. color: Constants.ConfrimButtonColor)),
  358. ),
  359. ),
  360. Container(
  361. color: Color(0xffF2F2F2),
  362. height: 4,
  363. ),
  364. InkWell(
  365. onTap: () {
  366. Navigator.of(context).pop();
  367. },
  368. child: Container(
  369. height: 60,
  370. alignment: Alignment.center,
  371. child: Text(I18n.of(context).cancel,
  372. textScaleFactor: 1.0,
  373. style: TextStyle(
  374. fontSize: 18, color: Color(0xff4B4B4B))),
  375. ),
  376. )
  377. ],
  378. ),
  379. );
  380. },
  381. );
  382. },
  383. child: Container(
  384. height: 40,
  385. margin: EdgeInsets.symmetric(horizontal: 40),
  386. alignment: Alignment.center,
  387. child: Text(
  388. title,
  389. textScaleFactor: 1.0,
  390. style:
  391. TextStyle(color: Constants.ConfrimButtonColor, fontSize: 15),
  392. ),
  393. ),
  394. ));
  395. }
  396. ///群公告
  397. Widget groupAnnounce() {
  398. return InkWell(
  399. onTap: () {
  400. if (widget.groupInfoModel.describe == '' && !isHost) {
  401. showToast(I18n.of(context).only_host);
  402. return;
  403. }
  404. Navigator.of(context).push(
  405. new MaterialPageRoute(
  406. builder: (context) {
  407. return GroupAnnouncementPage(
  408. groupInfoModel: widget.groupInfoModel,
  409. );
  410. },
  411. ),
  412. );
  413. },
  414. child: Container(
  415. color: Colors.white,
  416. child: Column(
  417. children: <Widget>[
  418. Container(
  419. padding: EdgeInsets.symmetric(
  420. horizontal: Separate_Size, vertical: 12),
  421. color: Colors.white,
  422. child: Row(
  423. children: <Widget>[
  424. Column(
  425. crossAxisAlignment: CrossAxisAlignment.start,
  426. children: <Widget>[
  427. Padding(
  428. padding: EdgeInsets.only(top: 0, left: 4),
  429. child: Text(
  430. I18n.of(context).group_announcement,
  431. textScaleFactor: 1.0,
  432. style: TextStyle(
  433. color: Colors.black, fontSize: 14),
  434. ),
  435. ),
  436. widget.groupInfoModel.describe == null ||
  437. widget.groupInfoModel.describe == ""
  438. ? Container()
  439. : Container(
  440. width: Screen.width - 55,
  441. padding: EdgeInsets.only(top: 3, left: 4),
  442. child: Text(
  443. widget.groupInfoModel.describe,
  444. textScaleFactor: 1.0,
  445. maxLines: 1,
  446. overflow: TextOverflow.ellipsis,
  447. style: TextStyle(
  448. color: Color(0xff818181),
  449. fontSize: 11),
  450. ),
  451. ),
  452. ]),
  453. Expanded(
  454. child: SizedBox(),
  455. ),
  456. Padding(
  457. padding: EdgeInsets.only(bottom: 0),
  458. child: Icon(
  459. IconData(0xe63c, fontFamily: 'iconfont'),
  460. size: 20.0,
  461. color: Color(AppColors.TabIconNormal),
  462. ))
  463. ],
  464. )),
  465. Container(
  466. margin: EdgeInsets.symmetric(horizontal: 15),
  467. decoration: BoxDecoration(
  468. border: Border(
  469. bottom: Constants.GreyBorderSide,
  470. ),
  471. ),
  472. )
  473. ],
  474. )));
  475. }
  476. ///群成员显示
  477. Widget buildMember(
  478. Function addMember, Function deleteMember, Function seeMoreMember) {
  479. // List<GroupMemberModel> members = widget.groupInfoModel.getMembersInGroup();
  480. List<GroupMemberModel> members = [];
  481. for (int k = 0; k < widget.groupInfoModel.members.length; k++) {
  482. //只加入存在群的
  483. GroupMemberModel mo = widget.groupInfoModel.members[k];
  484. if (mo.inGroup == 1) {
  485. members.add(mo);
  486. }
  487. }
  488. members.sort((GroupMemberModel left, GroupMemberModel right) =>
  489. right.identity.compareTo(left.identity));
  490. print('群成员数量- ${members.length}');
  491. int length = members.length;
  492. int dex = isHost ? 2 : 1;
  493. int shouldShow = length > (10 - dex) ? 10 - dex : length;
  494. double size = Screen.width / 5;
  495. List<Widget> list = [];
  496. for (int index = 0; index < shouldShow; index++) {
  497. var member = members[index];
  498. var refName = Provider.of<RefNameProvider>(context)
  499. .getGroupRefName(widget.groupInfoModel.sessionId, member.memberId);
  500. list.add(GestureDetector(
  501. child: Container(
  502. child: Column(
  503. children: <Widget>[
  504. ClipRRect(
  505. borderRadius: BorderRadius.all(Radius.circular(8.0)),
  506. child: CachedNetworkImage(
  507. imageUrl: member.avtar,
  508. placeholder: (context, url) => Image.asset(
  509. Constants.DefaultHeadImgUrl,
  510. width: size - 30,
  511. height: size - 30,
  512. ),
  513. width: size - 30,
  514. height: size - 30,
  515. )),
  516. SizedBox(
  517. height: 5,
  518. ),
  519. Container(
  520. width: size - 30,
  521. alignment: Alignment.center,
  522. child: Text(
  523. refName,
  524. textScaleFactor: 1.0,
  525. textAlign: TextAlign.center,
  526. style: TextStyle(fontSize: 11, color: Color(0xff818181)),
  527. maxLines: 1,
  528. overflow: TextOverflow.ellipsis,
  529. ),
  530. )
  531. ],
  532. ),
  533. width: size,
  534. height: size,
  535. ),
  536. behavior: HitTestBehavior.translucent,
  537. onTap: () {
  538. if (members[index].memberId != UserData().basicInfo.userId) {
  539. AppNavigator.pushProfileInfoPage(context, members[index].memberId,
  540. fromWhere: 2, addMode: 1);
  541. }
  542. },
  543. ));
  544. }
  545. list.add(GestureDetector(
  546. onTap: addMember,
  547. child: Container(
  548. width: size,
  549. height: size,
  550. child: Column(
  551. children: <Widget>[
  552. Container(
  553. alignment: Alignment.center,
  554. width: size - 30,
  555. height: size - 30,
  556. child: Text(
  557. '+',
  558. textScaleFactor: 1.0,
  559. style: TextStyle(fontSize: 30, color: Color(0xffB1B1B1)),
  560. ),
  561. decoration: BoxDecoration(
  562. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  563. borderRadius: BorderRadius.all(Radius.circular(6))),
  564. )
  565. ],
  566. ),
  567. ),
  568. ));
  569. if (isHost) {
  570. list.add(Container(
  571. width: size,
  572. height: size,
  573. child: Column(
  574. children: <Widget>[
  575. GestureDetector(
  576. onTap: deleteMember,
  577. child: Container(
  578. alignment: Alignment.center,
  579. width: size - 30,
  580. height: size - 30,
  581. child: Container(
  582. color: Color(0xffB1B1B1),
  583. width: 20,
  584. height: 2.6,
  585. ),
  586. decoration: BoxDecoration(
  587. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  588. borderRadius: BorderRadius.all(Radius.circular(6))),
  589. ),
  590. )
  591. ],
  592. ),
  593. ));
  594. }
  595. return Container(
  596. color: Color(0xffFAFAFA),
  597. child: Column(
  598. crossAxisAlignment: CrossAxisAlignment.start,
  599. children: <Widget>[
  600. SizedBox(
  601. height: 5,
  602. ),
  603. Wrap(
  604. children: list,
  605. crossAxisAlignment: WrapCrossAlignment.start,
  606. alignment: WrapAlignment.start,
  607. ),
  608. length > (10 - dex)
  609. ? GestureDetector(
  610. onTap: seeMoreMember,
  611. child: Container(
  612. height: 35,
  613. child: Row(
  614. mainAxisAlignment: MainAxisAlignment.center,
  615. children: <Widget>[
  616. Text(
  617. I18n.of(context).show_more_member,
  618. textScaleFactor: 1.0,
  619. style: TextStyle(color: Color(0xff818181)),
  620. ),
  621. Padding(
  622. padding: EdgeInsets.only(bottom: 1.5),
  623. child: Icon(
  624. IconData(0xe63c, fontFamily: 'iconfont'),
  625. size: 20.0,
  626. color: Color(AppColors.TabIconNormal),
  627. ))
  628. ],
  629. ),
  630. ),
  631. )
  632. : Container(),
  633. ],
  634. ),
  635. );
  636. }
  637. }