chat_page_view.dart 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  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. if(!MyCookie().underReview)
  230. items.add(GestureDetector(
  231. child: Container(
  232. child: SvgPicture.asset(
  233. 'images/svg/发红包.svg',
  234. ),
  235. ),
  236. behavior: HitTestBehavior.translucent,
  237. onTap: () async {
  238. MyTools()
  239. .toPage(context, RedPacketPage(ChatData().chatWith), (then) {});
  240. },
  241. ));
  242. return items;
  243. }
  244. goodsInfo(GoodsBeanDataData goods) {
  245. if (goods == null) {
  246. return Container();
  247. } else {
  248. return Container(
  249. padding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
  250. color: Colors.white,
  251. child: Row(
  252. children: [
  253. Container(
  254. margin: EdgeInsets.only(right: 7),
  255. child: ClipRRect(
  256. child: MyViews().netImg(imgURL(goods.coverPath), 54, 54,
  257. placeholder: 'images/svg/goodsDefImg.svg'),
  258. borderRadius: BorderRadius.circular(4),
  259. ),
  260. ),
  261. Expanded(
  262. child: Container(
  263. constraints: BoxConstraints(minHeight: 54),
  264. child: Column(
  265. children: [
  266. Text(
  267. '${goods.title}',
  268. style: TextStyle(color: MyColors.c333333, fontSize: 13),
  269. maxLines: 2,
  270. overflow: TextOverflow.ellipsis,
  271. softWrap: true,
  272. ),
  273. Row(
  274. children: [
  275. MyViews()
  276. .myText('¥${goods.price}', MyColors.cFF4233, 12),
  277. Container(
  278. decoration: BoxDecoration(
  279. color: MyColors.cFF4233,
  280. borderRadius: BorderRadius.circular(7),
  281. ),
  282. height: 14,
  283. width: 40,
  284. child: MyViews()
  285. .myText('找货', Colors.white, 8, height: 1.0),
  286. alignment: Alignment.center,
  287. padding: EdgeInsets.only(top: 1),
  288. )
  289. ],
  290. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  291. ),
  292. ],
  293. crossAxisAlignment: CrossAxisAlignment.start,
  294. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  295. ),
  296. ),
  297. ),
  298. ],
  299. ),
  300. );
  301. }
  302. }
  303. chatItems(MessageBeanContent msg, BuildContext context) {
  304. return Container(
  305. padding: EdgeInsets.only(left: 14, right: 14, bottom: 11, top: 11),
  306. child: Column(
  307. children: [
  308. Visibility(
  309. child: MyViews().myText(msg.sentAt, MyColors.c999999, 10),
  310. visible: showTime(msg),
  311. ),
  312. Container(
  313. height: 13,
  314. ),
  315. Row(
  316. children: [
  317. msg.senderUid != MyCookie().getUID()
  318. ? headWidget(msg)
  319. : Expanded(
  320. child: Container(
  321. child: chatBubble(msg, context),
  322. alignment: Alignment.centerRight,
  323. )),
  324. Container(
  325. width: 8,
  326. ),
  327. msg.senderUid != MyCookie().getUID()
  328. ? Expanded(
  329. child: Container(
  330. child: chatBubble(msg, context),
  331. alignment: Alignment.centerLeft,
  332. ))
  333. : headWidget(msg),
  334. ],
  335. crossAxisAlignment: msg.senderUid != MyCookie().getUID()
  336. ? CrossAxisAlignment.start
  337. : CrossAxisAlignment.start,
  338. mainAxisAlignment: MainAxisAlignment.start,
  339. ),
  340. Visibility(
  341. child: Container(child: MyViews().myText('红包已自动存入', MyColors.c999999, 10),margin: EdgeInsets.only(top: 10),),
  342. visible: msg.type == chatMsgTypeRedPackage,
  343. )
  344. ],
  345. ),
  346. );
  347. }
  348. headWidget(MessageBeanContent msg) {
  349. return ClipRRect(
  350. child: msg.senderUid==0?Image.asset('images/app_logo.png',width: 40,height: 40,):MyViews().netImg(imgURL(msg.senderPic), 40, 40),
  351. borderRadius: BorderRadius.circular(20),
  352. );
  353. }
  354. chatBubble(MessageBeanContent msg, BuildContext context) {
  355. if (msg.type == chatMsgTypePic) {}
  356. return ClipRRect(
  357. borderRadius: BorderRadius.circular(4),
  358. child: Container(
  359. constraints: BoxConstraints(
  360. minHeight: 40, maxWidth: MediaQuery.of(context).size.width - 140),
  361. color: Colors.white,
  362. child: bubbleItem(msg, context),
  363. padding: EdgeInsets.symmetric(
  364. horizontal: msg.type == chatMsgTypeText ? 14 : 1,
  365. vertical: msg.type == chatMsgTypeText ? 10 : 1),
  366. ),
  367. );
  368. }
  369. // sendMessages(String content, bool isImg) async {
  370. // var now = new DateTime.now();
  371. // //http://172.16.104.14:4151/pub?topic=97231698
  372. // Response response = await Dio().post(
  373. // 'http://${MyCookie().server}:4151/pub?topic=${ChatData().chatWith.userUid}',
  374. // data: {
  375. // "type": "新消息",
  376. // "content": {
  377. // "sender": {
  378. // "pic": MyCookie().loginInformation.data.extra.picture,
  379. // "name": MyCookie().loginInformation.data.extra.name,
  380. // "id": MyCookie().loginInformation.data.extra.id,
  381. // "uid": MyCookie().getUID(),
  382. // },
  383. // "receiver": {
  384. // "pic": ChatData().chatWith.userPic,
  385. // "name": ChatData().chatWith.userName,
  386. // "id": ChatData().chatWith.userUid,
  387. // "uid": ChatData().chatWith.userUid,
  388. // },
  389. // "content": content,
  390. // "time": now.toString().substring(0, 19),
  391. // "type": isImg ? "图片" : "文字",
  392. // "uuid": getUUID()
  393. // }
  394. // });
  395. // if (response.data.toString() == 'OK') {
  396. // print(response.data.toString());
  397. // MsgDB msgDB =
  398. // MsgDB('table${MyCookie().getUID()}_${ChatData().chatWith.userUid}');
  399. // if (!msgDB.isTableExits) {
  400. // await msgDB.open();
  401. // }
  402. // NewMsgBeanEntity newMsg =
  403. // NewMsgBeanEntity().fromJson(json.decode(json.encode({
  404. // "type": "新消息",
  405. // "content": {
  406. // "sender": {
  407. // "pic": MyCookie().loginInformation.data.extra.picture,
  408. // "name": MyCookie().loginInformation.data.extra.name,
  409. // "id": MyCookie().loginInformation.data.extra.id,
  410. // "uid": MyCookie().getUID(),
  411. // },
  412. // "receiver": {
  413. // "pic": ChatData().chatWith.userPic,
  414. // "name": ChatData().chatWith.userName,
  415. // "id": ChatData().chatWith.userUid,
  416. // "uid": ChatData().chatWith.userUid,
  417. // },
  418. // "content": content,
  419. // "time": now.toString().substring(0, 19),
  420. // "type": isImg ? "图片" : "文字",
  421. // "uuid": getUUID(),
  422. // "shop": {},
  423. // "order": {},
  424. // "goods": {},
  425. // }
  426. // })));
  427. // await msgDB.addTableData([newMsg]);
  428. // EventBus().emit('hasNewMsg', newMsg);
  429. // EventBus().emit('hasNewMsgInMsgPage', newMsg);
  430. // }
  431. // }
  432. void sendImg(File img) {
  433. EasyLoading.show();
  434. upload(img, (re, hE) {
  435. if (!hE) {
  436. UploadImageBeanEntity data =
  437. UploadImageBeanEntity().fromJson(json.decode(re.data.toString()));
  438. sendMsg(chatMsgTypePic, ChatData().chatWith.userUid, data.data[0].path,
  439. (re, hE) async {
  440. if (!hE) {
  441. SendMessageBeanEntity entity = SendMessageBeanEntity()
  442. .fromJson(json.decode(re.data.toString()));
  443. MsgDB msgDB =
  444. MsgDB('table${MyCookie().getUID()}_${entity.data.receiverUid}');
  445. if (!msgDB.isTableExits) {
  446. await msgDB.open();
  447. }
  448. await msgDB.addTableData([entity.data]);
  449. EventBus().emit('hasNewMsg', entity.data);
  450. EventBus().emit('hasNewMsgInMsgPage', entity.data);
  451. }
  452. }, (e) {});
  453. }
  454. EasyLoading.dismiss();
  455. }, (e) {});
  456. }
  457. showTime(MessageBeanContent msg) {
  458. int index =
  459. ChatData().msges.indexWhere((element) => element.uuid == msg.uuid);
  460. if (index == ChatData().msges.length - 1) {
  461. return true;
  462. } else {
  463. return DateTime.parse(msg.sentAt).isAfter(
  464. DateTime.parse(ChatData().msges[index + 1].sentAt)
  465. .add(Duration(minutes: 2)));
  466. }
  467. }
  468. bubbleItem(MessageBeanContent msg, BuildContext context) {
  469. if (msg.type == chatMsgTypeText) {
  470. return MyViews().myText(msg.content, MyColors.c333333, 15);
  471. } else if (msg.type == chatMsgTypePic) {
  472. return GestureDetector(
  473. child: AsperctRaioImage.network(imgURL(msg.content),
  474. builder: (context, snapshot, url) {
  475. return MyViews().netImg(
  476. imgURL(msg.content),
  477. (snapshot.data.height.toDouble() / 5) /
  478. (snapshot.data.width.toDouble() / 5) *
  479. 150,
  480. 150,
  481. placeholder: 'images/svg/goodsDefImg.svg');
  482. }),
  483. onTap: () {
  484. MyTools().toPage(
  485. context, PictureDisplayPage(imgURL(msg.content)), (then) {});
  486. },
  487. behavior: HitTestBehavior.translucent,
  488. );
  489. } else if (msg.type == chatMsgTypeRedPackage) {
  490. return Container(
  491. decoration: BoxDecoration(
  492. color: Colors.white,
  493. borderRadius: BorderRadius.circular(4),
  494. ),
  495. padding: EdgeInsets.all(14),
  496. child: Row(
  497. children: [
  498. SvgPicture.asset(
  499. 'images/svg/红包.svg',
  500. width: 29,
  501. height: 34,
  502. ),
  503. Container(
  504. margin: EdgeInsets.only(left: 7),
  505. child: Column(
  506. children: [
  507. MyViews().myText(
  508. msg.content.split('!@#')[0], MyColors.c333333, 14),
  509. MyViews().myText('收款人:${msg.content.split('!@#')[1]}',
  510. MyColors.c333333, 11),
  511. ],
  512. crossAxisAlignment: CrossAxisAlignment.start,
  513. ),
  514. )
  515. ],
  516. ),
  517. );
  518. }
  519. }
  520. }