chat_page_view.dart 20 KB

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