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.
 
 
 
 
 
 

685 satır
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(widget.groupInfoModel.sessionId, val);
  240. });
  241. }),
  242. SizedBox(
  243. height: 11,
  244. ),
  245. ///清除聊天记录
  246. _buildSettingWithConfirm(I18n.of(context).group_clean_chat_record,
  247. I18n.of(context).group_clean_chat_record, () {
  248. clearRecord();
  249. Navigator.of(context).pop();
  250. }),
  251. Padding(
  252. padding: EdgeInsets.symmetric(horizontal: Separate_Size),
  253. child: Divider(
  254. color: Color(0xffE5E5E5),
  255. height: 0.6,
  256. ),
  257. ),
  258. ///退出并删除按钮
  259. _buildSettingWithConfirm(I18n.of(context).quit_and_delete,
  260. I18n.of(context).quit_group_tips, () {
  261. print('退出群聊');
  262. quitGroup();
  263. MsgHandler.quitGroup(widget.groupInfoModel.sessionId);
  264. }),
  265. ],
  266. ),
  267. ),
  268. );
  269. }
  270. Widget _buildSetting(String title, String desc, Function func,
  271. {showRightIcon = true, showDivider = true, extendWidget}) {
  272. //版本
  273. return Container(
  274. padding: EdgeInsets.symmetric(horizontal: 10),
  275. child: FullWidthButton(
  276. showRightIcon: showRightIcon,
  277. title: title,
  278. description: desc,
  279. extendWidget: extendWidget,
  280. showDivider: showDivider,
  281. onPressed: func,
  282. ),
  283. decoration: BoxDecoration(
  284. color: Colors.white,
  285. ),
  286. );
  287. }
  288. Widget _buildSettingWithSwitch(
  289. bool switchValue, String title, Function onchang) {
  290. Widget left = new Text(
  291. title,
  292. textScaleFactor: 1.0,
  293. style: TextStyle(fontSize: 14, fontWeight: FontWeight.normal),
  294. );
  295. Widget right = new Expanded(
  296. child: new Container(
  297. alignment: Alignment.centerRight,
  298. padding: EdgeInsets.only(right: 8),
  299. child: new Switch(
  300. value: switchValue,
  301. activeTrackColor: Constants.ConfrimButtonColor.withOpacity(0.3),
  302. onChanged: onchang,
  303. )));
  304. return new Container(
  305. decoration: BoxDecoration(
  306. color: Colors.white,
  307. ),
  308. padding: EdgeInsets.only(left: 20),
  309. height: 53,
  310. child: new Row(
  311. children: <Widget>[left, right],
  312. ),
  313. );
  314. }
  315. Widget _buildSettingWithConfirm(
  316. String title, String dialogTips, Function function) {
  317. return Container(
  318. color: Colors.white,
  319. padding: EdgeInsets.only(top: 11, bottom: 11),
  320. child: InkWell(
  321. onTap: () {
  322. showModalBottomSheet(
  323. context: context,
  324. backgroundColor: Colors.transparent,
  325. builder: (BuildContext context) {
  326. return Container(
  327. decoration: BoxDecoration(
  328. color: Colors.white,
  329. borderRadius: BorderRadius.only(
  330. topLeft: Radius.circular(13),
  331. topRight: Radius.circular(13))),
  332. height: 225,
  333. child: Column(
  334. crossAxisAlignment: CrossAxisAlignment.center,
  335. mainAxisAlignment: MainAxisAlignment.center,
  336. children: <Widget>[
  337. Padding(
  338. padding: EdgeInsets.fromLTRB(15, 15, 15, 13),
  339. child: Text(
  340. dialogTips,
  341. textScaleFactor: 1.0,
  342. style:
  343. TextStyle(fontSize: 12, color: Color(0xff777777)),
  344. ),
  345. ),
  346. Divider(
  347. color: Color(0xffE5E5E5),
  348. ),
  349. InkWell(
  350. onTap: function,
  351. child: Container(
  352. height: 60,
  353. alignment: Alignment.center,
  354. child: Text(I18n.of(context).determine,
  355. textScaleFactor: 1.0,
  356. style: TextStyle(
  357. fontSize: 18,
  358. color: Constants.ConfrimButtonColor)),
  359. ),
  360. ),
  361. Container(
  362. color: Color(0xffF2F2F2),
  363. height: 4,
  364. ),
  365. InkWell(
  366. onTap: () {
  367. Navigator.of(context).pop();
  368. },
  369. child: Container(
  370. height: 60,
  371. alignment: Alignment.center,
  372. child: Text(I18n.of(context).cancel,
  373. textScaleFactor: 1.0,
  374. style: TextStyle(
  375. fontSize: 18, color: Color(0xff4B4B4B))),
  376. ),
  377. )
  378. ],
  379. ),
  380. );
  381. },
  382. );
  383. },
  384. child: Container(
  385. height: 40,
  386. margin: EdgeInsets.symmetric(horizontal: 40),
  387. alignment: Alignment.center,
  388. child: Text(
  389. title,
  390. textScaleFactor: 1.0,
  391. style:
  392. TextStyle(color: Constants.ConfrimButtonColor, fontSize: 15),
  393. ),
  394. ),
  395. ));
  396. }
  397. ///群公告
  398. Widget groupAnnounce() {
  399. return InkWell(
  400. onTap: () {
  401. if (widget.groupInfoModel.describe == '' && !isHost) {
  402. showToast(I18n.of(context).only_host);
  403. return;
  404. }
  405. Navigator.of(context).push(
  406. new MaterialPageRoute(
  407. builder: (context) {
  408. return GroupAnnouncementPage(
  409. groupInfoModel: widget.groupInfoModel,
  410. );
  411. },
  412. ),
  413. );
  414. },
  415. child: Container(
  416. color: Colors.white,
  417. child: Column(
  418. children: <Widget>[
  419. Container(
  420. padding: EdgeInsets.symmetric(
  421. horizontal: Separate_Size, vertical: 12),
  422. color: Colors.white,
  423. child: Row(
  424. children: <Widget>[
  425. Column(
  426. crossAxisAlignment: CrossAxisAlignment.start,
  427. children: <Widget>[
  428. Padding(
  429. padding: EdgeInsets.only(top: 0, left: 4),
  430. child: Text(
  431. I18n.of(context).group_announcement,
  432. textScaleFactor: 1.0,
  433. style: TextStyle(
  434. color: Colors.black, fontSize: 14),
  435. ),
  436. ),
  437. widget.groupInfoModel.describe == null ||
  438. widget.groupInfoModel.describe == ""
  439. ? Container()
  440. : Container(
  441. width: Screen.width - 55,
  442. padding: EdgeInsets.only(top: 3, left: 4),
  443. child: Text(
  444. widget.groupInfoModel.describe,
  445. textScaleFactor: 1.0,
  446. maxLines: 1,
  447. overflow: TextOverflow.ellipsis,
  448. style: TextStyle(
  449. color: Color(0xff818181),
  450. fontSize: 11),
  451. ),
  452. ),
  453. ]),
  454. Expanded(
  455. child: SizedBox(),
  456. ),
  457. Padding(
  458. padding: EdgeInsets.only(bottom: 0),
  459. child: Icon(
  460. IconData(0xe63c, fontFamily: 'iconfont'),
  461. size: 20.0,
  462. color: Color(AppColors.TabIconNormal),
  463. ))
  464. ],
  465. )),
  466. Container(
  467. margin: EdgeInsets.symmetric(horizontal: 15),
  468. decoration: BoxDecoration(
  469. border: Border(
  470. bottom: Constants.GreyBorderSide,
  471. ),
  472. ),
  473. )
  474. ],
  475. )));
  476. }
  477. ///群成员显示
  478. Widget buildMember(
  479. Function addMember, Function deleteMember, Function seeMoreMember) {
  480. // List<GroupMemberModel> members = widget.groupInfoModel.getMembersInGroup();
  481. List<GroupMemberModel> members = [];
  482. for (int k = 0; k < widget.groupInfoModel.members.length; k++) {
  483. //只加入存在群的
  484. GroupMemberModel mo = widget.groupInfoModel.members[k];
  485. if (mo.inGroup == 1) {
  486. members.add(mo);
  487. }
  488. }
  489. members.sort((GroupMemberModel left, GroupMemberModel right) =>
  490. right.identity.compareTo(left.identity));
  491. print('群成员数量- ${members.length}');
  492. int length = members.length;
  493. int dex = isHost ? 2 : 1;
  494. int shouldShow = length > (10 - dex) ? 10 - dex : length;
  495. double size = Screen.width / 5;
  496. List<Widget> list = [];
  497. for (int index = 0; index < shouldShow; index++) {
  498. var member = members[index];
  499. var refName = Provider.of<RefNameProvider>(context)
  500. .getGroupRefName(widget.groupInfoModel.sessionId, member.memberId);
  501. list.add(GestureDetector(
  502. child: Container(
  503. child: Column(
  504. children: <Widget>[
  505. ClipRRect(
  506. borderRadius: BorderRadius.all(Radius.circular(8.0)),
  507. child: CachedNetworkImage(
  508. imageUrl: member.avtar,
  509. placeholder: (context, url) => Image.asset(
  510. Constants.DefaultHeadImgUrl,
  511. width: size - 30,
  512. height: size - 30,
  513. ),
  514. width: size - 30,
  515. height: size - 30,
  516. )),
  517. SizedBox(
  518. height: 5,
  519. ),
  520. Container(
  521. width: size - 30,
  522. alignment: Alignment.center,
  523. child: Text(
  524. refName,
  525. textScaleFactor: 1.0,
  526. textAlign: TextAlign.center,
  527. style: TextStyle(fontSize: 11, color: Color(0xff818181)),
  528. maxLines: 1,
  529. overflow: TextOverflow.ellipsis,
  530. ),
  531. )
  532. ],
  533. ),
  534. width: size,
  535. height: size,
  536. ),
  537. behavior: HitTestBehavior.translucent,
  538. onTap: () {
  539. if (members[index].memberId != UserData().basicInfo.userId) {
  540. AppNavigator.pushProfileInfoPage(context, members[index].memberId,
  541. fromWhere: 2, addMode: !FriendListMgr().isMyFriend(members[index].memberId) ? 1 : 0);
  542. }
  543. },
  544. ));
  545. }
  546. list.add(GestureDetector(
  547. onTap: addMember,
  548. child: Container(
  549. width: size,
  550. height: size,
  551. child: Column(
  552. children: <Widget>[
  553. Container(
  554. alignment: Alignment.center,
  555. width: size - 30,
  556. height: size - 30,
  557. child: Text(
  558. '+',
  559. textScaleFactor: 1.0,
  560. style: TextStyle(fontSize: 30, color: Color(0xffB1B1B1)),
  561. ),
  562. decoration: BoxDecoration(
  563. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  564. borderRadius: BorderRadius.all(Radius.circular(6))),
  565. )
  566. ],
  567. ),
  568. ),
  569. ));
  570. if (isHost) {
  571. list.add(Container(
  572. width: size,
  573. height: size,
  574. child: Column(
  575. children: <Widget>[
  576. GestureDetector(
  577. onTap: deleteMember,
  578. child: Container(
  579. alignment: Alignment.center,
  580. width: size - 30,
  581. height: size - 30,
  582. child: Container(
  583. color: Color(0xffB1B1B1),
  584. width: 20,
  585. height: 2.6,
  586. ),
  587. decoration: BoxDecoration(
  588. border: Border.all(color: Color(0xffC3C3C3), width: 1.0),
  589. borderRadius: BorderRadius.all(Radius.circular(6))),
  590. ),
  591. )
  592. ],
  593. ),
  594. ));
  595. }
  596. return Container(
  597. color: Color(0xffFAFAFA),
  598. child: Column(
  599. crossAxisAlignment: CrossAxisAlignment.start,
  600. children: <Widget>[
  601. SizedBox(
  602. height: 5,
  603. ),
  604. Wrap(
  605. children: list,
  606. crossAxisAlignment: WrapCrossAlignment.start,
  607. alignment: WrapAlignment.start,
  608. ),
  609. length > (10 - dex)
  610. ? GestureDetector(
  611. onTap: seeMoreMember,
  612. child: Container(
  613. height: 35,
  614. child: Row(
  615. mainAxisAlignment: MainAxisAlignment.center,
  616. children: <Widget>[
  617. Text(
  618. I18n.of(context).show_more_member,
  619. textScaleFactor: 1.0,
  620. style: TextStyle(color: Color(0xff818181)),
  621. ),
  622. Padding(
  623. padding: EdgeInsets.only(bottom: 1.5),
  624. child: Icon(
  625. IconData(0xe63c, fontFamily: 'iconfont'),
  626. size: 20.0,
  627. color: Color(AppColors.TabIconNormal),
  628. ))
  629. ],
  630. ),
  631. ),
  632. )
  633. : Container(),
  634. ],
  635. ),
  636. );
  637. }
  638. }