Hibok
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

791 Zeilen
25 KiB

  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:chat/data/translate_hk_data_mgr.dart';
  4. import 'package:chat/home/audio_chat_view.dart';
  5. import 'package:chat/utils/screen.dart';
  6. import 'package:chat/utils/upload_util.dart';
  7. import 'package:chat/utils/white_opacity_anim.dart';
  8. import 'package:fixnum/fixnum.dart';
  9. import 'package:cached_network_image/cached_network_image.dart';
  10. import 'package:chat/chat/translate_state.dart';
  11. import 'package:chat/data/UserData.dart';
  12. import 'package:chat/data/chat_data_mgr.dart';
  13. import 'package:chat/data/constants.dart';
  14. import 'package:chat/generated/i18n.dart';
  15. import 'package:chat/home/add_friend.dart';
  16. import 'package:chat/models/ChatMsg.dart';
  17. import 'package:chat/models/UserInfo.dart';
  18. import 'package:chat/models/keyboard_provider.dart';
  19. import 'package:chat/models/ref_name_provider.dart';
  20. import 'package:chat/models/voucher_change.dart';
  21. import 'package:chat/proto/all.pbserver.dart';
  22. import 'package:chat/utils/CustomUI.dart';
  23. import 'package:chat/utils/HttpUtil.dart';
  24. import 'package:chat/utils/MessageMgr.dart';
  25. import 'package:chat/utils/TokenMgr.dart';
  26. import 'package:chat/utils/analyze_utils.dart';
  27. import 'package:chat/utils/app_navigator.dart';
  28. import 'package:chat/utils/blacklist_mgr.dart';
  29. import 'package:chat/utils/count_down_button.dart';
  30. import 'package:chat/utils/friend_list_mgr.dart';
  31. import 'package:chat/utils/msgHandler.dart';
  32. import 'package:chat/utils/net_state_widget.dart';
  33. import 'package:chat/utils/sound_util.dart';
  34. import 'package:chat/utils/sp_utils.dart';
  35. import 'package:chat/utils/sql_util.dart';
  36. import 'package:dio/dio.dart';
  37. import 'package:extended_text/extended_text.dart';
  38. import 'package:flutter/cupertino.dart';
  39. import 'package:flutter/material.dart';
  40. import 'package:flutter/services.dart';
  41. import 'package:oktoast/oktoast.dart';
  42. import 'package:provider/provider.dart';
  43. import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
  44. import '../r.dart';
  45. import 'ChatPageItem.dart';
  46. import 'input_bar.dart';
  47. import 'package:chat/utils/PopUpMenu.dart' as myPop;
  48. import 'package:chat/models/money_change.dart';
  49. class ChatPage extends StatefulWidget {
  50. final int friendId;
  51. final int enterType; // 0默认 1图片
  52. final dynamic enterContent;
  53. final bool isTranslateButler;
  54. ChatPage(
  55. {Key key,
  56. this.friendId,
  57. this.enterType = 0,
  58. this.enterContent,
  59. this.isTranslateButler = false})
  60. : super(key: key);
  61. _ChatPageState createState() => _ChatPageState();
  62. }
  63. class _ChatPageState extends State<ChatPage> {
  64. final ItemScrollController itemScrollController = ItemScrollController();
  65. final ItemPositionsListener itemPositionListener =
  66. ItemPositionsListener.create();
  67. //ScrollController _scrollCtrl = ScrollController();
  68. MessageMgr msgMgr = MessageMgr();
  69. UserInfo friendInfo;
  70. List<MsgModel> msgList;
  71. KeyboardIndexProvider _keyboardIndexProvider = KeyboardIndexProvider();
  72. TextEditingController nickNameController = new TextEditingController();
  73. //统计聊天时长
  74. int startTime;
  75. bool isTranslateButler;
  76. bool isTranslateButlerFinish=false;///翻译管家是否已经结束
  77. int jumpTime;
  78. @override
  79. void dispose() {
  80. var endTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
  81. AnalyzeUtils.commitChatDuration(startTime, endTime);
  82. MessageMgr().off('Send CoinBag', _sendCoin);
  83. msgMgr.off('New Chat Message', receiveMsg);
  84. msgMgr.off('Keyboard Hide', dealWithKeyboardHide);
  85. msgMgr.off('Delete Select Message', _deleteItem);
  86. msgMgr.off(MessageMgr.TRANSLATE_HK_END_CHAT, translateHKChatEnd);
  87. msgMgr.off('Jump to Msg', jumpToMsg);
  88. MsgHandler.curActiveSession = 0;
  89. SoundUtils().stop();
  90. nickNameController.dispose();
  91. super.dispose();
  92. }
  93. jumpToMsg(time) {
  94. //var screenItemNums = itemPositionListener.itemPositions.value.length;
  95. int jumIndex = 0;
  96. jumpTime = time;
  97. for (int i = 0; i < msgList.length; i++) {
  98. if (time == msgList[i].time) {
  99. jumIndex = i - 1; // - screenItemNums + 2;
  100. break;
  101. }
  102. }
  103. if (jumIndex < 0) {
  104. jumIndex = 0;
  105. }
  106. if (jumIndex > msgList.length - 1) {
  107. jumIndex = msgList.length - 1;
  108. }
  109. setState(() {
  110. itemScrollController.scrollTo(
  111. index: jumIndex, duration: new Duration(microseconds: 1));
  112. });
  113. }
  114. @override
  115. void initState() {
  116. super.initState();
  117. print('init chatpage');
  118. getDefaultSetting();
  119. getUserInfo();
  120. isTranslateButler = widget.isTranslateButler;
  121. ///todo 这里再判断是否还在服务时间
  122. startTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
  123. msgList = ChatDataMgr().getRecord();
  124. msgMgr.on('New Chat Message', receiveMsg);
  125. msgMgr.on('Keyboard Hide', dealWithKeyboardHide);
  126. msgMgr.on('Send CoinBag', _sendCoin);
  127. msgMgr.on('Delete Select Message', _deleteItem);
  128. msgMgr.on(MessageMgr.TRANSLATE_HK_END_CHAT, translateHKChatEnd);
  129. msgMgr.on('Jump to Msg', jumpToMsg);
  130. }
  131. translateHKChatEnd(args){
  132. setState(() {
  133. isTranslateButlerFinish=true;
  134. });
  135. }
  136. void _sendFile(File file) async {
  137. // File file = await FilePicker.getFile();
  138. int fileSize = file.lengthSync();
  139. print('选择的文件 ${file.path} 大小 $fileSize');
  140. if (fileSize > 33 * 1024 * 1024) {
  141. showToast(I18n.of(context).max_file.replaceFirst('/s1', 33.toString()));
  142. return;
  143. }
  144. var fileName = file.path.split('/').last;
  145. print('fileName $fileName');
  146. var ext = '';
  147. var extList = fileName.split('.');
  148. if (extList.length > 1) {
  149. ext = extList.last;
  150. }
  151. print('ext $ext');
  152. var fileMsg = FileChat.create();
  153. fileMsg.type = ext;
  154. fileMsg.size = fileSize;
  155. fileMsg.name = fileName;
  156. var msg = MsgHandler.createSendMsg(
  157. ChatType.FileChatType, fileMsg.writeToBuffer(),
  158. friendId: widget.friendId,
  159. localFile: file.path,
  160. channelType: ChatChannelType.Session);
  161. sendMsg(msg);
  162. }
  163. _sendCoin(args) async {
  164. var res = await _checkCoinBeforeSend(args['amount']);
  165. if (res != null) {
  166. args['redNo'] = res['redNo'];
  167. args['friendId'] = widget.friendId;
  168. var msg = MsgHandler.createCoinBagMsg(args);
  169. sendMsg(msg);
  170. }
  171. }
  172. //校验
  173. _checkCoinBeforeSend(int amount) async {
  174. Map data = {
  175. "userId": UserData().basicInfo.userId,
  176. "rUserId": friendInfo.userId,
  177. "price": amount,
  178. };
  179. data['sign'] = TokenMgr().getSign(data);
  180. Response res = await HttpUtil().post('red/packet/send', data: data);
  181. if (res == null) {
  182. return null;
  183. }
  184. Map resData = res.data;
  185. if (resData['code'] == 0) {
  186. print(resData['data']);
  187. return resData['data'];
  188. }
  189. return null;
  190. }
  191. void getDefaultSetting() async {
  192. bool soundPlayMode =
  193. (await SPUtils.getBool(Constants.SOUND_PLAY_MODE)) ?? false;
  194. _keyboardIndexProvider.init(soundPlayMode);
  195. }
  196. dealWithKeyboardHide(args) {
  197. if (_keyboardIndexProvider.curKeyboardIndex == 0) {
  198. hideKeyBoard();
  199. }
  200. }
  201. getUserInfo() async {
  202. //先从本地获取用户信息
  203. friendInfo = await HttpUtil().getFriendInfo(widget.friendId, true);
  204. //如果是新的聊天,向服务器发送创建会话消息
  205. if (msgList.length == 0) {
  206. MsgHandler.getActiveSesstion(
  207. [friendInfo.userId, UserData().basicInfo.userId]);
  208. }
  209. if (mounted) {
  210. setState(() {});
  211. }
  212. WidgetsBinding.instance.addPostFrameCallback((_) {
  213. if (widget.enterType == 1) {
  214. print('接收到的:${widget.enterContent}');
  215. _sendFile(File(widget.enterContent));
  216. } else if (widget.enterType == 2) {
  217. //转发消息
  218. MsgModel originMsg = widget.enterContent;
  219. MsgModel msg = MsgHandler.createSendMsg(
  220. ChatType.valueOf(originMsg.msgType), originMsg.msgContent);
  221. msg.extraInfo = originMsg.extraInfo;
  222. if (originMsg.extraFile == null ||
  223. originMsg.extraFile.contains('http')) {
  224. msg.extraFile = originMsg.extraFile;
  225. } else {
  226. msg.extraFile = UploadUtil().getFullUrl(
  227. originMsg.extraFile, originMsg.sessionId, originMsg.channelType);
  228. }
  229. msg.localFile = originMsg.localFile;
  230. msg.friendId = widget.friendId;
  231. if (msg.localFile != null) {
  232. msg.state = MsgState.Uploaded;
  233. }
  234. sendMsg(msg);
  235. }
  236. });
  237. }
  238. @override
  239. Widget build(BuildContext context) {
  240. print('build chatpage');
  241. if (friendInfo == null) {
  242. return Scaffold(
  243. backgroundColor: const Color(0xFFE2E9F1),
  244. body: SafeArea(
  245. child: Center(
  246. child: CircularProgressIndicator(),
  247. ),
  248. ),
  249. );
  250. }
  251. List<Widget> actions = [];
  252. int voucher = Provider.of<VoucherChangeProvider>(context).voucher;
  253. actions.add(Row(
  254. children: <Widget>[
  255. CustomUI.buildImageLabel("assets/images/voucher.png", voucher,
  256. imgOpc: 0.5, imgHeight: 13),
  257. CustomUI.buildImageLabel(
  258. R.assetsImagesCoin, Provider.of<MoneyChangeProvider>(context).money,
  259. isLeft: false)
  260. ],
  261. ));
  262. actions.add(TranslateSateWidget(friendId: friendInfo.userId));
  263. actions.add(Container(
  264. margin: EdgeInsets.only(top: 1),
  265. child: myPop.PopupMenuButton(
  266. icon: Icon(
  267. Icons.more_horiz,
  268. size: 24,
  269. ),
  270. offset: Offset(0, 100),
  271. onSelected: (int index) {
  272. if (index == 2) {
  273. AppNavigator.pushInformUserPage(
  274. context, friendInfo.sex == 1, friendInfo.userId);
  275. } else if (index == 1) {
  276. Navigator.of(context).push(
  277. new MaterialPageRoute(
  278. builder: (context) {
  279. return AddFriendPage(
  280. userId: friendInfo.userId,
  281. pageType: SendMessagePageType.Remark,
  282. originalName: Provider.of<RefNameProvider>(context)
  283. .getRefName(
  284. friendInfo.userId, friendInfo.nickName));
  285. },
  286. ),
  287. );
  288. }
  289. },
  290. itemBuilder: (BuildContext context) {
  291. return <myPop.PopupMenuItem<int>>[
  292. myPop.PopupMenuItem(
  293. child: Container(
  294. alignment: Alignment.center,
  295. color: Colors.white,
  296. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  297. child: Text(I18n.of(context).anonymous_report,
  298. textScaleFactor: 1.0,
  299. maxLines: 1,
  300. style: TextStyle(
  301. color: Color(AppColors.AppBarColor), fontSize: 12)),
  302. ),
  303. value: 2,
  304. ),
  305. myPop.PopupMenuItem(
  306. child: Container(
  307. decoration: BoxDecoration(
  308. border: Border(
  309. top: BorderSide(width: 1, color: Colors.grey[300])),
  310. color: Colors.white,
  311. ),
  312. alignment: Alignment.center,
  313. padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
  314. child: Text(I18n.of(context).Remark,
  315. textScaleFactor: 1.0,
  316. maxLines: 1,
  317. style: TextStyle(
  318. color: Color(AppColors.AppBarColor), fontSize: 12)),
  319. ),
  320. value: 1,
  321. ),
  322. ];
  323. })));
  324. return Stack(
  325. children: <Widget>[
  326. MultiProvider(
  327. providers: [
  328. ChangeNotifierProvider(create: (_) => _keyboardIndexProvider),
  329. Provider<bool>.value(value: false),
  330. Provider<int>.value(value: widget.friendId),
  331. ],
  332. child: GestureDetector(
  333. onTap: hideKeyBoard,
  334. child: ExtendedTextSelectionPointerHandler(
  335. ///选择文字,消除弹窗
  336. builder: (states) {
  337. return Listener(
  338. child: Scaffold(
  339. resizeToAvoidBottomInset: false,
  340. backgroundColor: const Color(0xFFE2E9F1),
  341. appBar: AppBar(
  342. title: Text(
  343. '${Provider.of<RefNameProvider>(context).getRefName(friendInfo.userId, friendInfo.nickName)}',
  344. textScaleFactor: 1.0,
  345. style: TextStyle(
  346. color: Constants.BlackTextColor,
  347. fontSize: 16.47),
  348. ),
  349. leading: CustomUI.buildCustomLeading(context,onTap:(){
  350. if(isTranslateButler && !isTranslateButlerFinish){
  351. if(UserData().isTranslateUser){
  352. showToast('翻译服务未结束不能主动结束');
  353. }else{
  354. CustomUI.buildTowConfirm(
  355. context,
  356. '是否提前结束翻译管家服务?',
  357. I18n.of(context).confirm,
  358. (){
  359. setState(() {
  360. isTranslateButlerFinish=true;
  361. });
  362. MsgHandler.sendEndTransHKOrderReq();
  363. Navigator.of(context).pop();
  364. },
  365. '取消',
  366. (){ Navigator.of(context).pop();});
  367. }
  368. }else{
  369. Navigator.of(context).pop();
  370. }
  371. }), //todo
  372. titleSpacing: -10,
  373. centerTitle: false,
  374. elevation: 1,
  375. actions: actions),
  376. body: SafeArea(
  377. child: Column(
  378. children: <Widget>[
  379. NetStateWidget(),
  380. (isTranslateButler&!isTranslateButlerFinish)
  381. ? _buildTranslationButler()
  382. : Container(),
  383. Expanded(child: _buildMessageList()),
  384. InputBar(sendMsg: sendMsg,isTranslateHK: isTranslateButler,),
  385. ],
  386. ))),
  387. behavior: HitTestBehavior.translucent,
  388. onPointerDown: (value) {
  389. for (var state in states) {
  390. if (!state.containsPosition(value.position)) {
  391. //clear other selection
  392. state.clearSelection();
  393. }
  394. }
  395. },
  396. onPointerMove: (value) {
  397. //clear other selection
  398. for (var state in states) {
  399. if (!state.containsPosition(value.position)) {
  400. //clear other selection
  401. state.clearSelection();
  402. }
  403. }
  404. },
  405. );
  406. },
  407. ))),
  408. isTranslateButler ? getAudioChatView() : Container(),
  409. isTranslateButler ? zoomAudioButton() : Container()
  410. ],
  411. );
  412. }
  413. Widget getAudioChatView() {
  414. if (friendInfo == null || isTranslateButlerFinish) {
  415. return Container();
  416. }
  417. return isActive == null
  418. ? Container()
  419. : Offstage(
  420. offstage: !isShowAudio,
  421. child: AudioChatPage(
  422. userInfo: friendInfo,
  423. isTranslateButler: true,
  424. isReplay: !TranslateHKMgr().isUser,
  425. translateButlerCloseCallBack: audioChatPageCallBack,
  426. ),
  427. );
  428. }
  429. audioChatPageCallBack(int args) {
  430. switch (args) {
  431. case 1:
  432. setState(() {
  433. isShowAudio = !isShowAudio;
  434. isShowZoomButton = true;
  435. });
  436. break;
  437. case 2:
  438. setState(() {
  439. isActive = false;
  440. });
  441. break;
  442. }
  443. }
  444. bool isShowAudio = false;
  445. ///控住连麦窗口是否显示
  446. bool isActive = true;
  447. ///控制连麦是否关闭
  448. bool isShowZoomButton = true;
  449. GlobalKey mykey = GlobalKey();
  450. double dx = Screen.width , dy = Screen.height/2;
  451. double zoomButtonSize = 60;
  452. void dragEvent(DragUpdateDetails details) {
  453. final RenderObject box = context.findRenderObject();
  454. // 获得自定义Widget的大小,用来计算Widget的中心锚点
  455. dx = details.globalPosition.dx - mykey.currentContext.size.width / 2;
  456. dy = details.globalPosition.dy - mykey.currentContext.size.height / 2;
  457. // print('dx $dx dy $dy screen width:${Screen.width}');
  458. if (dx > Screen.width - zoomButtonSize) {
  459. dx = Screen.width - zoomButtonSize;
  460. } else if (dx < 0) {
  461. dx = 0;
  462. }
  463. if (dy > Screen.height - zoomButtonSize) {
  464. dy = Screen.height - zoomButtonSize;
  465. } else if (dy < 0) {
  466. dy = 0;
  467. }
  468. setState(() {});
  469. }
  470. Widget zoomAudioButton() {
  471. if (friendInfo == null || !isShowZoomButton) {
  472. return Container();
  473. }
  474. Widget button = Container(
  475. key: mykey,
  476. width: 57,
  477. height: 74,
  478. child: Card(child: Align(child: Icon(
  479. IconData(0xe67d, fontFamily: Constants.IconFontFamily),
  480. color: Color(0xFF008AFF),
  481. size: 35.0,
  482. ),alignment: Alignment.center,),),
  483. );
  484. return GestureDetector(
  485. onHorizontalDragUpdate: dragEvent,
  486. onVerticalDragUpdate: dragEvent,
  487. onTap: (){
  488. setState(() {
  489. isShowAudio = !isShowAudio;
  490. isShowZoomButton = !isShowZoomButton;
  491. });
  492. },
  493. child: Container(
  494. child: Transform.translate(
  495. offset: Offset(dx, dy),
  496. child: Align(
  497. alignment: Alignment.topLeft,
  498. child: button,
  499. ),
  500. ),
  501. ),
  502. );
  503. }
  504. Widget _buildTranslationButler() {
  505. bool hasHeadImg = true;
  506. if (friendInfo.headimgurl == null || friendInfo.headimgurl.length == 0) {
  507. hasHeadImg = false;
  508. }
  509. /// 5H币/1分钟
  510. String coinTIme = I18n.of(context).translation_butler_coin_time;
  511. coinTIme = coinTIme.replaceAll('/s1', '5');
  512. coinTIme = coinTIme.replaceAll('/s2', '1');
  513. return Container(
  514. padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
  515. color: Colors.white,
  516. child: Row(
  517. children: <Widget>[
  518. ClipRRect(
  519. borderRadius: BorderRadius.circular(8),
  520. child: hasHeadImg
  521. ? CachedNetworkImage(
  522. imageUrl: friendInfo.headimgurl,
  523. placeholder: (context, url) => Image.asset(
  524. Constants.DefaultHeadImgUrl,
  525. width: 54,
  526. height: 54,
  527. ),
  528. width: 54,
  529. height: 54,
  530. )
  531. : SizedBox(
  532. width: 54,
  533. height: 54,
  534. child: Image.asset(R.assetsImagesDefaultNorAvatar))),
  535. Padding(
  536. padding: EdgeInsets.only(left: 10),
  537. child: Container(
  538. child: Column(
  539. crossAxisAlignment: CrossAxisAlignment.start,
  540. children: <Widget>[
  541. Text(
  542. I18n.of(context).translation_butler,
  543. textScaleFactor: 1.0,
  544. overflow: TextOverflow.ellipsis,
  545. maxLines: 1,
  546. style: TextStyle(
  547. color: AppColors.NewAppbarTextColor, fontSize: 15),
  548. ),
  549. SizedBox(
  550. height: 5,
  551. ),
  552. Text(
  553. coinTIme,
  554. textScaleFactor: 1.0,
  555. maxLines: 1,
  556. style: TextStyle(color: Color(0xFF797979), fontSize: 13),
  557. )
  558. ],
  559. ),
  560. constraints: BoxConstraints(maxWidth: 135),
  561. ),
  562. ),
  563. TranslateHKMgr().isUser?Expanded(
  564. child: Container(
  565. constraints: BoxConstraints(maxWidth: 130),
  566. width: double.maxFinite,
  567. child: CountDownButton(
  568. I18n.of(context).translation_butler_end_service,
  569. () {
  570. // Navigator.of(context).pop();
  571. },
  572. countDownTime: 60*5,
  573. align: Alignment.centerRight,
  574. onPress: () {
  575. MsgHandler.sendEndTransHKOrderReq();
  576. // Navigator.of(context).pop();
  577. },
  578. ),
  579. // alignment: Alignment(1,0),
  580. )):Container(),
  581. ],
  582. ),
  583. );
  584. }
  585. Widget _buildMessageList() {
  586. return Container(
  587. alignment: Alignment.topCenter,
  588. child: msgList.length == 0
  589. ? Padding(
  590. padding: EdgeInsets.all(8),
  591. child: Text(
  592. I18n.of(context).chat_tips,
  593. textAlign: TextAlign.center,
  594. textScaleFactor: 1.0,
  595. style: TextStyle(color: Colors.grey, fontSize: 12),
  596. ))
  597. : NotificationListener(
  598. child: Scrollbar(
  599. child: ScrollablePositionedList.builder(
  600. physics: new ClampingScrollPhysics(),
  601. itemCount: msgList.length,
  602. itemBuilder: _buildItem,
  603. itemScrollController: itemScrollController,
  604. itemPositionsListener: itemPositionListener,
  605. //padding: EdgeInsets.all(8.0),
  606. reverse: true,
  607. hitCallback: hideKeyBoard,
  608. )),
  609. onNotification: (notification) {
  610. if (notification is ScrollNotification) {
  611. // var offset = notification.metrics.pixels;
  612. // print('滚动事件 offset $offset');
  613. }
  614. return true;
  615. },
  616. ),
  617. );
  618. }
  619. hideKeyBoard() {
  620. _keyboardIndexProvider.changeSelectIndex(-1);
  621. }
  622. readOnly() {
  623. _keyboardIndexProvider.changeReadOnlyKey(true);
  624. }
  625. sendMsg(MsgModel msg) {
  626. print('对方是否拉黑你 ${friendInfo.isBlackened}');
  627. if (BlacklistMgr.isBlack(friendInfo.userId)) {
  628. return;
  629. }
  630. print('chat page session id:${msg.sessionId}');
  631. if (!friendInfo.isCanStrangerNews &&
  632. !FriendListMgr().isMyFriend(friendInfo.userId)) {
  633. showToast(I18n.of(context).stranger_close_tips);
  634. return;
  635. }
  636. MsgHandler.insertMsgToDB(msg);
  637. MsgHandler.sendChatMsg(msg);
  638. if (mounted) {
  639. setState(() {});
  640. itemScrollController.jumpTo(index: 0);
  641. }
  642. }
  643. MsgModel msg;
  644. int count = 0;
  645. testBig(MsgModel msg) async {
  646. for (int k = 0; k < 100; k++) {
  647. msg.msgContent = utf8.encode('测试$count');
  648. Int64 time = Int64((DateTime.now()).millisecondsSinceEpoch);
  649. msg.time = time.toInt();
  650. MsgHandler.insertMsgToDB(msg);
  651. MsgHandler.sendChatMsg(msg);
  652. await Future.delayed(Duration(milliseconds: 500), () {});
  653. count++;
  654. }
  655. count = 0;
  656. print('发送完毕');
  657. showToast('发送完毕');
  658. }
  659. void receiveMsg(args) {
  660. if (mounted) {
  661. setState(() {});
  662. }
  663. }
  664. _deleteItem(msg) {
  665. MessageMgr().emit('Cancel Request', msg);
  666. print('#### 开始删除--');
  667. msgList.remove(msg);
  668. setState(() {});
  669. SqlUtil().deleteSigleRecordWith(msg.sessionId, msg.time);
  670. }
  671. Widget _buildItem(BuildContext context, int index) {
  672. var lastMsgTime;
  673. if (index < msgList.length - 1) {
  674. lastMsgTime = msgList[index + 1].time;
  675. }
  676. MsgModel msg = msgList[index];
  677. if (msg.time == jumpTime) {
  678. return WhiteOpacityAnim(
  679. key: Key(msg.time.toString()),
  680. child: ChatPageItem(
  681. key: Key(msg.time.toString()),
  682. msg: msg,
  683. hideKeyboard: readOnly,
  684. friendInfo: friendInfo,
  685. lastMsgTime: lastMsgTime),
  686. animFinishCallback: () {
  687. jumpTime = null;
  688. },
  689. );
  690. } else {
  691. return ChatPageItem(
  692. key: Key(msg.time.toString()),
  693. msg: msg,
  694. hideKeyboard: readOnly,
  695. friendInfo: friendInfo,
  696. lastMsgTime: lastMsgTime);
  697. }
  698. }
  699. }