chat_page_view.dart 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. import 'dart:convert';
  2. import 'dart:io';
  3. import 'package:bbyyy/beans/goods_bean_entity.dart';
  4. import 'package:bbyyy/beans/message_bean_entity.dart';
  5. import 'package:bbyyy/beans/send_message_bean_entity.dart';
  6. import 'package:bbyyy/beans/upload_image_bean_entity.dart';
  7. import 'package:bbyyy/https/my_request.dart';
  8. import 'package:bbyyy/https/url.dart';
  9. import 'package:bbyyy/msgDB/my_msg_db.dart';
  10. import 'package:bbyyy/my_tools/AsperctRaioImage.dart';
  11. import 'package:bbyyy/my_tools/const.dart';
  12. import 'package:bbyyy/my_tools/easy_loading/easy_loading.dart';
  13. import 'package:bbyyy/my_tools/event_bus.dart';
  14. import 'package:bbyyy/my_tools/my_colors.dart';
  15. import 'package:bbyyy/my_tools/my_cookie.dart';
  16. import 'package:bbyyy/my_tools/my_tools.dart';
  17. import 'package:bbyyy/my_tools/my_views.dart';
  18. import 'package:bbyyy/paegs/chat_page/chat_data.dart';
  19. import 'package:bbyyy/paegs/picture_display_page/picture_display_page.dart';
  20. import 'package:bbyyy/paegs/red_packet_page/red_packet_page.dart';
  21. import 'package:flutter/material.dart';
  22. import 'package:flutter/services.dart';
  23. import 'package:flutter_svg/svg.dart';
  24. class ChatPageView {
  25. TextEditingController textEditingController = TextEditingController();
  26. var showM = false;
  27. var showS = false;
  28. inputBox(BuildContext context, FocusNode focusNode) {
  29. return StatefulBuilder(builder: (c, s) {
  30. return SafeArea(
  31. top: false,
  32. child: Container(
  33. child: Material(
  34. color: MyColors.cf8f8f8,
  35. child: Column(
  36. children: <Widget>[
  37. Container(
  38. constraints: BoxConstraints(
  39. maxHeight: 144.0,
  40. minHeight: 50,
  41. ),
  42. padding: EdgeInsets.only(left: 0, right: 13),
  43. child: Row(
  44. children: <Widget>[
  45. Expanded(
  46. flex: 280,
  47. child: Container(
  48. constraints: BoxConstraints(
  49. minHeight: 30,
  50. ),
  51. margin: EdgeInsets.only(
  52. top: 10, bottom: 10, left: 14, right: 8.0),
  53. decoration: BoxDecoration(
  54. color: Colors.white,
  55. borderRadius: BorderRadius.circular(2.0)),
  56. child: TextField(
  57. controller: textEditingController,
  58. focusNode: focusNode,
  59. cursorColor: MyColors.cFF4233,
  60. cursorWidth: 1.0,
  61. onTap: () {
  62. s(() {
  63. showM = false;
  64. EventBus().emit('s2b');
  65. });
  66. },
  67. decoration: InputDecoration(
  68. border: InputBorder.none,
  69. disabledBorder: InputBorder.none,
  70. enabledBorder: InputBorder.none,
  71. focusedBorder: InputBorder.none,
  72. isDense: true,
  73. contentPadding:
  74. const EdgeInsets.fromLTRB(8, 4.5, 8, 4.5)),
  75. maxLines: null,
  76. style: TextStyle(
  77. color: Colors.black,
  78. fontSize: 16,
  79. height: 1.3,
  80. letterSpacing: 0.2),
  81. keyboardType: TextInputType.multiline,
  82. onChanged: (t) {
  83. s(() {
  84. if (t.length > 0) {
  85. showS = true;
  86. } else {
  87. showS = false;
  88. }
  89. });
  90. },
  91. ),
  92. ),
  93. ),
  94. Expanded(
  95. child: showS
  96. ? GestureDetector(
  97. child: Container(
  98. height: 30,
  99. width: 52,
  100. margin: EdgeInsets.only(bottom: 10),
  101. alignment: Alignment.center,
  102. decoration: BoxDecoration(
  103. borderRadius:
  104. BorderRadius.all(Radius.circular(15)),
  105. color: MyColors.cFF4233),
  106. child: Text(
  107. '发送',
  108. style: TextStyle(
  109. color: Colors.white, fontSize: 15),
  110. ),
  111. ),
  112. onTap: () {
  113. // s(() {
  114. // sendMessages(
  115. // textEditingController.text.toString(),
  116. // false);
  117. // textEditingController.clear();
  118. // showS = false;
  119. // });
  120. sendMsg(
  121. chatMsgTypeText,
  122. ChatData().chatWith.userUid,
  123. textEditingController.text.toString(),
  124. (re, hE) async {
  125. if (!hE) {
  126. SendMessageBeanEntity entity =
  127. SendMessageBeanEntity.fromJson(
  128. json.decode(re.data.toString()));
  129. MsgDB msgDB = MsgDB(
  130. 'table${MyCookie().getUID()}_${entity.data.receiverUid}');
  131. if (!msgDB.isTableExits) {
  132. await msgDB.open();
  133. }
  134. await msgDB.addTableData([entity.data]);
  135. EventBus().emit('hasNewMsg', entity.data);
  136. EventBus().emit(
  137. 'hasNewMsgInMsgPage', entity.data);
  138. }
  139. }, (e) {});
  140. s(() {
  141. textEditingController.clear();
  142. showS = false;
  143. });
  144. },
  145. behavior: HitTestBehavior.translucent,
  146. )
  147. : GestureDetector(
  148. child: Container(
  149. child: SvgPicture.asset(
  150. 'images/svg/功能(发图片什么的).svg',
  151. height: 28,
  152. width: 28,
  153. ),
  154. margin: EdgeInsets.only(bottom: 10),
  155. ),
  156. onTap: () {
  157. s(() {
  158. showM = !showM;
  159. if (showM) {
  160. MyTools().hideKeyboard(context);
  161. }
  162. });
  163. },
  164. behavior: HitTestBehavior.translucent,
  165. ),
  166. flex: 58,
  167. ),
  168. ],
  169. crossAxisAlignment: CrossAxisAlignment.end,
  170. ),
  171. ),
  172. Visibility(
  173. child: Column(
  174. children: <Widget>[
  175. Divider(
  176. height: 0.5,
  177. color: MyColors.cE1E1E1,
  178. ),
  179. Container(
  180. height: 100,
  181. child: SingleChildScrollView(
  182. child: moreItem(context, focusNode, s),
  183. ),
  184. ),
  185. ],
  186. ),
  187. visible: showM,
  188. )
  189. ],
  190. mainAxisSize: MainAxisSize.min,
  191. ),
  192. elevation: 0,
  193. ),
  194. color: MyColors.cf3f3f3,
  195. ),
  196. );
  197. });
  198. }
  199. moreItem(BuildContext context, FocusNode focusNode, StateSetter s) {
  200. return Container(
  201. height: 100,
  202. child: GridView(
  203. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  204. crossAxisCount: 5, //横轴三个子widget
  205. childAspectRatio: 1,
  206. crossAxisSpacing: 20,
  207. mainAxisSpacing: 10 //宽高比为1时,子widget
  208. ),
  209. children: getItems(context, focusNode, s),
  210. padding: EdgeInsets.only(left: 14, right: 20, top: 8, bottom: 8),
  211. ),
  212. );
  213. }
  214. getItems(BuildContext context, FocusNode focusNode, StateSetter s) {
  215. List<Widget> items = [];
  216. items.add(GestureDetector(
  217. child: Container(
  218. child: SvgPicture.asset(
  219. 'images/svg/图片.svg',
  220. ),
  221. ),
  222. behavior: HitTestBehavior.translucent,
  223. onTap: () async {
  224. File img = await selectPicturesIndividually();
  225. if (img != null) {
  226. sendImg(img);
  227. }
  228. },
  229. ));
  230. if (!MyCookie().underReview)
  231. items.add(GestureDetector(
  232. child: Container(
  233. child: SvgPicture.asset(
  234. 'images/svg/发红包.svg',
  235. ),
  236. ),
  237. behavior: HitTestBehavior.translucent,
  238. onTap: () async {
  239. MyTools()
  240. .toPage(context, RedPacketPage(ChatData().chatWith), (then) {});
  241. },
  242. ));
  243. return items;
  244. }
  245. goodsInfo(GoodsBeanDataData goods) {
  246. if (goods == null) {
  247. return Container();
  248. } else {
  249. return Container(
  250. padding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
  251. color: Colors.white,
  252. child: Row(
  253. children: [
  254. Container(
  255. margin: EdgeInsets.only(right: 7),
  256. child: ClipRRect(
  257. child: MyViews().netImg(imgURL(goods.coverPath), 54, 54,
  258. placeholder: 'images/svg/goodsDefImg.svg'),
  259. borderRadius: BorderRadius.circular(4),
  260. ),
  261. ),
  262. Expanded(
  263. child: Container(
  264. constraints: BoxConstraints(minHeight: 54),
  265. child: Column(
  266. children: [
  267. Text(
  268. '${goods.title}',
  269. style: TextStyle(color: MyColors.c333333, fontSize: 13),
  270. maxLines: 2,
  271. overflow: TextOverflow.ellipsis,
  272. softWrap: true,
  273. ),
  274. Row(
  275. children: [
  276. MyViews()
  277. .myText('¥${goods.price}', MyColors.cFF4233, 12),
  278. Container(
  279. decoration: BoxDecoration(
  280. color: MyColors.cFF4233,
  281. borderRadius: BorderRadius.circular(7),
  282. ),
  283. height: 14,
  284. width: 40,
  285. child: MyViews()
  286. .myText('找货', Colors.white, 8, height: 1.0),
  287. alignment: Alignment.center,
  288. padding: EdgeInsets.only(top: 1),
  289. )
  290. ],
  291. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  292. ),
  293. ],
  294. crossAxisAlignment: CrossAxisAlignment.start,
  295. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  296. ),
  297. ),
  298. ),
  299. ],
  300. ),
  301. );
  302. }
  303. }
  304. chatItems(MessageBeanContent msg, BuildContext context) {
  305. return Container(
  306. padding: EdgeInsets.only(left: 14, right: 14, bottom: 11, top: 11),
  307. child: Column(
  308. children: [
  309. Visibility(
  310. child: MyViews().myText(msg.sentAt, MyColors.c999999, 10),
  311. visible: showTime(msg),
  312. ),
  313. Container(
  314. height: 13,
  315. ),
  316. Row(
  317. children: [
  318. msg.senderUid != MyCookie().getUID()
  319. ? headWidget(msg)
  320. : Expanded(
  321. child: Container(
  322. child: chatBubble(msg, context),
  323. alignment: Alignment.centerRight,
  324. )),
  325. Container(
  326. width: 8,
  327. ),
  328. msg.senderUid != MyCookie().getUID()
  329. ? Expanded(
  330. child: Container(
  331. child: chatBubble(msg, context),
  332. alignment: Alignment.centerLeft,
  333. ))
  334. : headWidget(msg),
  335. ],
  336. crossAxisAlignment: msg.senderUid != MyCookie().getUID()
  337. ? CrossAxisAlignment.start
  338. : CrossAxisAlignment.start,
  339. mainAxisAlignment: MainAxisAlignment.start,
  340. ),
  341. Visibility(
  342. child: Container(
  343. child: MyViews().myText('红包已自动存入', MyColors.c999999, 10),
  344. margin: EdgeInsets.only(top: 10),
  345. ),
  346. visible: msg.type == chatMsgTypeRedPackage,
  347. )
  348. ],
  349. ),
  350. );
  351. }
  352. headWidget(MessageBeanContent msg) {
  353. return ClipRRect(
  354. child: msg.senderUid == 0
  355. ? Image.asset(
  356. 'images/app_logo.png',
  357. width: 40,
  358. height: 40,
  359. )
  360. : MyViews().netImg(imgURL(msg.senderPic), 40, 40),
  361. borderRadius: BorderRadius.circular(20),
  362. );
  363. }
  364. chatBubble(MessageBeanContent msg, BuildContext context) {
  365. if (msg.type == chatMsgTypePic) {}
  366. return ClipRRect(
  367. borderRadius: BorderRadius.circular(4),
  368. child: Container(
  369. constraints: BoxConstraints(
  370. minHeight: 40, maxWidth: MediaQuery.of(context).size.width - 140),
  371. color: Colors.white,
  372. child: bubbleItem(msg, context),
  373. padding: EdgeInsets.symmetric(
  374. horizontal: msg.type == chatMsgTypeText ? 14 : 1,
  375. vertical: msg.type == chatMsgTypeText ? 10 : 1),
  376. ),
  377. );
  378. }
  379. // sendMessages(String content, bool isImg) async {
  380. // var now = new DateTime.now();
  381. // //http://172.16.104.14:4151/pub?topic=97231698
  382. // Response response = await Dio().post(
  383. // 'http://${MyCookie().server}:4151/pub?topic=${ChatData().chatWith.userUid}',
  384. // data: {
  385. // "type": "新消息",
  386. // "content": {
  387. // "sender": {
  388. // "pic": MyCookie().loginInformation.data.extra.picture,
  389. // "name": MyCookie().loginInformation.data.extra.name,
  390. // "id": MyCookie().loginInformation.data.extra.id,
  391. // "uid": MyCookie().getUID(),
  392. // },
  393. // "receiver": {
  394. // "pic": ChatData().chatWith.userPic,
  395. // "name": ChatData().chatWith.userName,
  396. // "id": ChatData().chatWith.userUid,
  397. // "uid": ChatData().chatWith.userUid,
  398. // },
  399. // "content": content,
  400. // "time": now.toString().substring(0, 19),
  401. // "type": isImg ? "图片" : "文字",
  402. // "uuid": getUUID()
  403. // }
  404. // });
  405. // if (response.data.toString() == 'OK') {
  406. // print(response.data.toString());
  407. // MsgDB msgDB =
  408. // MsgDB('table${MyCookie().getUID()}_${ChatData().chatWith.userUid}');
  409. // if (!msgDB.isTableExits) {
  410. // await msgDB.open();
  411. // }
  412. // NewMsgBeanEntity newMsg =
  413. // NewMsgBeanEntity.fromJson(json.decode(json.encode({
  414. // "type": "新消息",
  415. // "content": {
  416. // "sender": {
  417. // "pic": MyCookie().loginInformation.data.extra.picture,
  418. // "name": MyCookie().loginInformation.data.extra.name,
  419. // "id": MyCookie().loginInformation.data.extra.id,
  420. // "uid": MyCookie().getUID(),
  421. // },
  422. // "receiver": {
  423. // "pic": ChatData().chatWith.userPic,
  424. // "name": ChatData().chatWith.userName,
  425. // "id": ChatData().chatWith.userUid,
  426. // "uid": ChatData().chatWith.userUid,
  427. // },
  428. // "content": content,
  429. // "time": now.toString().substring(0, 19),
  430. // "type": isImg ? "图片" : "文字",
  431. // "uuid": getUUID(),
  432. // "shop": {},
  433. // "order": {},
  434. // "goods": {},
  435. // }
  436. // })));
  437. // await msgDB.addTableData([newMsg]);
  438. // EventBus().emit('hasNewMsg', newMsg);
  439. // EventBus().emit('hasNewMsgInMsgPage', newMsg);
  440. // }
  441. // }
  442. void sendImg(File img) {
  443. EasyLoading.show();
  444. upload(img, (re, hE) {
  445. if (!hE) {
  446. UploadImageBeanEntity data =
  447. UploadImageBeanEntity.fromJson(json.decode(re.data.toString()));
  448. sendMsg(chatMsgTypePic, ChatData().chatWith.userUid, data.data[0].path,
  449. (re, hE) async {
  450. if (!hE) {
  451. SendMessageBeanEntity entity = SendMessageBeanEntity.fromJson(json.decode(re.data.toString()));
  452. MsgDB msgDB =
  453. MsgDB('table${MyCookie().getUID()}_${entity.data.receiverUid}');
  454. if (!msgDB.isTableExits) {
  455. await msgDB.open();
  456. }
  457. await msgDB.addTableData([entity.data]);
  458. EventBus().emit('hasNewMsg', entity.data);
  459. EventBus().emit('hasNewMsgInMsgPage', entity.data);
  460. }
  461. }, (e) {});
  462. }
  463. EasyLoading.dismiss();
  464. }, (e) {});
  465. }
  466. showTime(MessageBeanContent msg) {
  467. int index =
  468. ChatData().msges.indexWhere((element) => element.uuid == msg.uuid);
  469. if (index == ChatData().msges.length - 1) {
  470. return true;
  471. } else {
  472. return DateTime.parse(msg.sentAt).isAfter(
  473. DateTime.parse(ChatData().msges[index + 1].sentAt)
  474. .add(Duration(minutes: 2)));
  475. }
  476. }
  477. bubbleItem(MessageBeanContent msg, BuildContext context) {
  478. if (msg.type == chatMsgTypeText) {
  479. return GestureDetector(
  480. onLongPress: (){
  481. showToast('已复制到剪切板');
  482. Clipboard.setData(ClipboardData(text: '${msg.content}'));
  483. },
  484. child: MyViews().myText(msg.content, MyColors.c333333, 15));
  485. } else if (msg.type == chatMsgTypePic) {
  486. return GestureDetector(
  487. child: AsperctRaioImage.network(imgURL(msg.content),
  488. builder: (context, snapshot, url) {
  489. return MyViews().netImg(
  490. imgURL(msg.content),
  491. (snapshot.data.height.toDouble() / 5) /
  492. (snapshot.data.width.toDouble() / 5) *
  493. 150,
  494. 150,
  495. placeholder: 'images/svg/goodsDefImg.svg');
  496. }),
  497. onTap: () {
  498. MyTools().toPage(
  499. context, PictureDisplayPage(imgURL(msg.content)), (then) {});
  500. },
  501. behavior: HitTestBehavior.translucent,
  502. );
  503. } else if (msg.type == chatMsgTypeRedPackage) {
  504. return Container(
  505. decoration: BoxDecoration(
  506. color: Colors.white,
  507. borderRadius: BorderRadius.circular(4),
  508. ),
  509. padding: EdgeInsets.all(14),
  510. child: Row(
  511. children: [
  512. SvgPicture.asset(
  513. 'images/svg/红包.svg',
  514. width: 29,
  515. height: 34,
  516. ),
  517. Container(
  518. margin: EdgeInsets.only(left: 7),
  519. child: Column(
  520. children: [
  521. MyViews().myText(
  522. msg.content.split('!@#')[0], MyColors.c333333, 14),
  523. MyViews().myText('收款人:${msg.content.split('!@#')[1]}',
  524. MyColors.c333333, 11),
  525. ],
  526. crossAxisAlignment: CrossAxisAlignment.start,
  527. ),
  528. )
  529. ],
  530. ),
  531. );
  532. }
  533. }
  534. }