Hibok
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

1163 lignes
42 KiB

  1. import 'package:chat/data/UserData.dart';
  2. import 'package:chat/data/WebData.dart';
  3. import 'package:chat/data/constants.dart';
  4. import 'package:chat/generated/i18n.dart';
  5. import 'package:chat/home/InformUser.dart';
  6. import 'package:chat/home/ProfilePage.dart';
  7. import 'package:chat/home/ProgramDetail.dart';
  8. import 'package:chat/models/ref_name_provider.dart';
  9. import 'package:chat/utils/CustomUI.dart';
  10. import 'package:chat/utils/HttpUtil.dart';
  11. import 'package:chat/utils/MessageMgr.dart';
  12. import 'package:chat/utils/PicSwiper.dart';
  13. import 'package:chat/utils/TokenMgr.dart';
  14. import 'package:chat/utils/screen.dart';
  15. import 'package:dio/dio.dart';
  16. import 'package:flutter/material.dart';
  17. import 'package:cached_network_image/cached_network_image.dart';
  18. import 'package:flutter_screenutil/flutter_screenutil.dart';
  19. import 'package:image_picker/image_picker.dart';
  20. import 'package:oktoast/oktoast.dart';
  21. import 'package:chat/utils/PopUpMenu.dart' as myPopUp;
  22. import 'package:provider/provider.dart';
  23. import 'package:url_launcher/url_launcher.dart';
  24. const BlackIconColor = const Color(0xFF4D4D4F);
  25. class MessageBox extends StatefulWidget {
  26. final programInfo;
  27. final bool isDetail;
  28. MessageBox({
  29. Key key,
  30. @required this.programInfo,
  31. this.isDetail: false,
  32. }) : super(key: key);
  33. _MessageBoxState createState() => _MessageBoxState();
  34. }
  35. class _MessageBoxState extends State<MessageBox> {
  36. bool isMyself = false;
  37. bool isProgram = false;
  38. bool isCloseContent = false;
  39. bool isShowAll = false;
  40. //List fabulousList = [];
  41. @override
  42. Widget build(BuildContext context) {
  43. initValue();
  44. return _buildMessageBox(widget.programInfo);
  45. }
  46. @override
  47. void initState() {
  48. super.initState();
  49. }
  50. void initValue() {
  51. isMyself = widget.programInfo['UserId'] == UserData().basicInfo.userId;
  52. isProgram = widget.programInfo['Type'] == 0;
  53. isCloseContent = widget.programInfo['EvaluateStatus'] == 1;
  54. widget.programInfo['EvaluateList'] =
  55. widget.programInfo['EvaluateList'] == null
  56. ? []
  57. : widget.programInfo['EvaluateList'];
  58. widget.programInfo['FabulousList'] =
  59. widget.programInfo['FabulousList'] == null
  60. ? []
  61. : widget.programInfo['FabulousList'];
  62. }
  63. void _selectValue(str, userId, isProgram) async {
  64. if (str == 'inform') {
  65. Navigator.of(context).push(
  66. new MaterialPageRoute(
  67. builder: (context) {
  68. return InformUserPage(
  69. isMan: widget.programInfo['Sex'] == 1,
  70. programId: widget.programInfo['Id'],
  71. isProgram: isProgram,
  72. userId: userId,
  73. );
  74. },
  75. ),
  76. );
  77. } else if (str == 'black') {
  78. HttpUtil().blackUser(userId, () {});
  79. } else if (str == 'noContent') {
  80. var data = {
  81. "userId": UserData().basicInfo.userId,
  82. "type": 1,
  83. "id": userId,
  84. };
  85. data['sign'] = TokenMgr().getSign(data);
  86. Response res =
  87. await HttpUtil().post('station/settings/program', data: data);
  88. var resData = res.data;
  89. if (resData['code'] == 0) {
  90. showToast(resData['msg']);
  91. widget.programInfo['EvaluateStatus'] = 1;
  92. MessageMgr().emit('update_dy', true);
  93. setState(() {});
  94. }
  95. } else if (str == 'delete') {
  96. var data = {
  97. "userId": UserData().basicInfo.userId,
  98. "type": 2,
  99. "id": userId,
  100. };
  101. data['sign'] = TokenMgr().getSign(data);
  102. Response res =
  103. await HttpUtil().post('station/settings/program', data: data);
  104. var resData = res.data;
  105. if (resData['code'] == 0) {
  106. showToast(resData['msg']);
  107. if (isProgram) {
  108. UserData().isCanProgram = true;
  109. }
  110. MessageMgr().emit('delete_program', userId);
  111. }
  112. } else if (str == 'openContent') {
  113. var data = {
  114. "userId": UserData().basicInfo.userId,
  115. "type": 3,
  116. "id": userId,
  117. };
  118. data['sign'] = TokenMgr().getSign(data);
  119. Response res =
  120. await HttpUtil().post('station/settings/program', data: data);
  121. var resData = res.data;
  122. if (resData['code'] == 0) {
  123. showToast(resData['msg']);
  124. widget.programInfo['EvaluateStatus'] = 0;
  125. MessageMgr().emit('update_dy', false);
  126. setState(() {});
  127. }
  128. }
  129. }
  130. Widget _iconButton(code, iconColor, text, callback,
  131. {textColor = BlackIconColor, double iconSize = 18}) {
  132. return InkWell(
  133. onTap: callback,
  134. child: Container(
  135. alignment: Alignment.center,
  136. width: Screen.width / 4,
  137. margin: EdgeInsets.only(bottom: 5),
  138. child: Column(
  139. crossAxisAlignment: CrossAxisAlignment.center,
  140. mainAxisAlignment: MainAxisAlignment.end,
  141. children: <Widget>[
  142. Container(
  143. child: Icon(
  144. IconData(
  145. code,
  146. fontFamily: 'iconfont',
  147. ),
  148. color: iconColor,
  149. size: iconSize,
  150. )),
  151. Container(
  152. constraints: BoxConstraints(minHeight: 15),
  153. ///防止中文数字高度不一样,界面发生变化
  154. padding: EdgeInsets.only(top: 2, left: 1.5),
  155. child: fixedText(text,
  156. color: textColor,
  157. fontSize: 9.67,
  158. fontWeight: FontWeight.normal))
  159. ],
  160. )));
  161. }
  162. Widget _iconRow(code, str, size) {
  163. return Container(
  164. margin: EdgeInsets.only(top: 3),
  165. constraints: BoxConstraints(minHeight: 20),
  166. child: Row(
  167. crossAxisAlignment: CrossAxisAlignment.center,
  168. children: <Widget>[
  169. Container(
  170. margin: EdgeInsets.only(right: 5),
  171. child: Icon(
  172. IconData(
  173. code,
  174. fontFamily: 'iconfont',
  175. ),
  176. color: BlackIconColor,
  177. size: size,
  178. )),
  179. Expanded(
  180. child: Container(
  181. child: extendedText(
  182. str,
  183. selectionEnabled: false,
  184. color: Constants.BlackTextColor,
  185. emojisize: 17.0,
  186. fontSize: ScreenUtil().setSp(14),
  187. //fontWeight: FontWeight.w500,
  188. ))),
  189. ],
  190. ),
  191. );
  192. }
  193. void _sendPicture(callback) async {
  194. if (await CustomUI.showPhotoPermissionSetting(context)) {
  195. var tempFile = await ImagePicker.pickImage(source: ImageSource.gallery);
  196. if (tempFile != null) {
  197. Map data = {"type": 4, "userId": UserData().basicInfo.userId};
  198. data['sign'] = TokenMgr().getSign(data);
  199. Response res = await HttpUtil().uploadFile(
  200. tempFile, data, 'upload/file/postflie', 'image',
  201. isShowLoading: true);
  202. var resData = res.data;
  203. if (resData['code'] == 0) {
  204. Navigator.of(context).pop();
  205. callback(resData['msg']);
  206. }
  207. }
  208. }
  209. }
  210. Widget _buildIconButtonList(data) {
  211. bool isStop = data['Status'] == 1;
  212. //bool isSameSex = data['Sex'] == UserData().basicInfo.sex;
  213. //bool isMan = data['Sex'] == 1;
  214. bool isAd = data['Type'] == 2;
  215. Widget likeButton = _iconButton(
  216. 0xe65b,
  217. data['IsFabulous'] > 0 ? Constants.BlueTextColor : BlackIconColor,
  218. // data['FabulousNum'] > 0
  219. // ? data['FabulousNum'].toString()
  220. // : I18n.of(context).thumbs_up3,
  221. I18n.of(context).thumbs_up3,
  222. isStop
  223. ? () {
  224. showToast(I18n.of(context).has_ended);
  225. }
  226. : data['IsFabulous'] > 0
  227. ? () {
  228. showToast(I18n.of(context).already_praised);
  229. }
  230. : () async {
  231. if (isAd) {
  232. Map rdata = {
  233. "userId": UserData().basicInfo.userId,
  234. "adId": data['Id'],
  235. };
  236. rdata['sign'] = TokenMgr().getSign(rdata);
  237. Response res = await HttpUtil().post('adActivity/give/like',
  238. data: rdata, isShowLoading: true);
  239. var resData = res.data;
  240. if (resData['code'] == 0) {
  241. setState(() {
  242. data['FabulousNum']++;
  243. data['IsFabulous']++;
  244. widget.programInfo['FabulousList'].add({
  245. "UserId": UserData().basicInfo.userId,
  246. "Headimgurl": UserData().basicInfo.headimgurl
  247. });
  248. });
  249. }
  250. } else {
  251. Map rdata = {
  252. "userId": UserData().basicInfo.userId,
  253. "id": data['Id'],
  254. };
  255. rdata['sign'] = TokenMgr().getSign(rdata);
  256. Response res = await HttpUtil().post('station/give/like',
  257. data: rdata, isShowLoading: true);
  258. var resData = res.data;
  259. if (resData['code'] == 0) {
  260. setState(() {
  261. data['FabulousNum']++;
  262. data['IsFabulous']++;
  263. widget.programInfo['FabulousList'].add({
  264. "UserId": UserData().basicInfo.userId,
  265. "Headimgurl": UserData().basicInfo.headimgurl
  266. });
  267. });
  268. }
  269. }
  270. },
  271. textColor:
  272. data['IsFabulous'] > 0 ? Constants.BlueTextColor : BlackIconColor,
  273. );
  274. // var str = data['EvaluateNum'] > 0
  275. // ? data['EvaluateNum'].toString()
  276. // : I18n.of(context).comment;
  277. Widget contentButton = _iconButton(
  278. 0xe65d,
  279. isCloseContent && !isMyself
  280. ? BlackIconColor.withOpacity(0.5)
  281. : BlackIconColor,
  282. // !isCloseContent
  283. // ? (isMyself ? str : I18n.of(context).comment)
  284. // : isMyself ? str : I18n.of(context).comment_closed,
  285. !isCloseContent
  286. ? I18n.of(context).comment
  287. : I18n.of(context).comment_closed,
  288. isStop
  289. ? () {
  290. showToast(I18n.of(context).has_ended);
  291. }
  292. : (isCloseContent)
  293. ? () {
  294. showToast(I18n.of(context).comment_closed);
  295. }
  296. :
  297. // isSameSex && !isMyself
  298. // ? () {
  299. // showToast(isMan
  300. // ? I18n.of(context).men_cant2
  301. // : I18n.of(context).ms_cant2);
  302. // }
  303. // :
  304. () {
  305. CustomUI.showContentDialog(context, data['Id'], 0, 0,
  306. (data) {
  307. widget.programInfo['EvaluateNum']++;
  308. widget.programInfo['EvaluateList'].insert(0, data);
  309. data['Id'] = widget.programInfo['Id'];
  310. if (!isAd && widget.isDetail)
  311. MessageMgr().emit('refresh_list', data);
  312. setState(() {});
  313. }, isAd: isAd, isMyself: isMyself);
  314. },
  315. textColor: isCloseContent && !isMyself
  316. ? BlackIconColor.withOpacity(0.5)
  317. : BlackIconColor);
  318. Widget stopJoin = _iconButton(
  319. 0xe65e,
  320. BlackIconColor,
  321. !isStop
  322. ? I18n.of(context).end_registration
  323. : I18n.of(context).has_ended,
  324. isStop
  325. ? null
  326. : () async {
  327. CustomUI.buildOneConfirm(context, I18n.of(context).end_choose,
  328. I18n.of(context).determine, () async {
  329. Map rdata = {
  330. "userId": UserData().basicInfo.userId,
  331. "id": data['Id'],
  332. };
  333. rdata['sign'] = TokenMgr().getSign(rdata);
  334. Response res = await HttpUtil()
  335. .post('station/fin/inscriptions', data: rdata);
  336. var resData = res.data;
  337. if (resData['code'] == 0) {
  338. Navigator.of(context).pop();
  339. UserData().isCanProgram = true;
  340. showToast(resData['msg']);
  341. MessageMgr().emit('refresh_list');
  342. widget.programInfo['Status'] = 1;
  343. setState(() {});
  344. }
  345. });
  346. },
  347. iconSize: 18);
  348. Widget joinButton = _iconButton(
  349. 0xe624,
  350. data['IsEnroll'] > 0 ? Colors.red : BlackIconColor,
  351. isMyself
  352. ? '${I18n.of(context).view_registration}(${data['EnrollNum']})'
  353. : '${I18n.of(context).sign_up2}(${data['EnrollNum']})',
  354. isMyself
  355. ? null
  356. :
  357. // isSameSex
  358. // ? () {
  359. // showToast(isMan
  360. // ? I18n.of(context).men_cant
  361. // : I18n.of(context).ms_cant);
  362. // }
  363. // :
  364. (data['IsEnroll'] > 0
  365. ? () {
  366. showToast(I18n.of(context).alreay_join);
  367. }
  368. : () async {
  369. if ((UserData().isMan() && !UserData().isVip)) {
  370. showToast(I18n.of(context).cannot_join);
  371. return;
  372. }
  373. if ((!UserData().isMan() &&
  374. !UserData().basicInfo.isAttestation)) {
  375. CustomUI.buildNotTrue(context);
  376. return;
  377. }
  378. CustomUI.buildOneConfirm(
  379. context,
  380. I18n.of(context).need_photo2,
  381. I18n.of(context).choose_photo, () {
  382. _sendPicture((url) async {
  383. Map rdata = {
  384. "userId": UserData().basicInfo.userId,
  385. "id": data['Id'],
  386. };
  387. rdata['sign'] = TokenMgr().getSign(rdata);
  388. rdata['imgUrl'] = url;
  389. Response res = await HttpUtil()
  390. .post('station/program/enroll', data: rdata);
  391. var resData = res.data;
  392. if (resData['code'] == 0) {
  393. showToast(resData['msg']);
  394. setState(() {
  395. data['EnrollNum']++;
  396. data['IsEnroll']++;
  397. });
  398. }
  399. });
  400. });
  401. }),
  402. iconSize: 18);
  403. return Container(
  404. width: double.infinity,
  405. alignment: Alignment.center,
  406. height: 47,
  407. child: Row(
  408. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  409. crossAxisAlignment: CrossAxisAlignment.center,
  410. children: isProgram
  411. ? (isMyself
  412. ? [likeButton, contentButton, joinButton, stopJoin]
  413. : [likeButton, contentButton, joinButton])
  414. : [likeButton, contentButton],
  415. ),
  416. );
  417. }
  418. //动态消息框
  419. Widget _buildMessageBox(data) {
  420. bool isAd = data['Type'] == 2;
  421. return InkWell(
  422. onTap: () async {
  423. if (isAd) {
  424. if (await canLaunch(data['HopeObject'])) {
  425. await launch(data['HopeObject']);
  426. } else {
  427. throw 'Could not launch ${data['HopeObject']}';
  428. }
  429. return;
  430. }
  431. if (widget.isDetail) return;
  432. Navigator.of(context).push(
  433. new MaterialPageRoute(
  434. builder: (context) {
  435. return ProgramDetailPage(
  436. programId: data['Id'],
  437. );
  438. },
  439. ),
  440. );
  441. },
  442. child: Container(
  443. margin: EdgeInsets.only(top: 10),
  444. decoration: BoxDecoration(
  445. color: Colors.white,
  446. border: Border(
  447. top: Constants.GreyBorderSide,
  448. bottom: Constants.GreyBorderSide)),
  449. child: Column(
  450. children: <Widget>[
  451. _buildUserInfo(data),
  452. _buildTimebox(data),
  453. _buildImgSet(data),
  454. _buildImgList(data),
  455. widget.isDetail ? Container() : _buildDivder(),
  456. _buildIconButtonList(data),
  457. //_buildContent(),
  458. ],
  459. ),
  460. ));
  461. }
  462. Widget _buildDivder() {
  463. return Container(
  464. height: 1,
  465. margin: EdgeInsets.symmetric(horizontal: 21),
  466. decoration:
  467. BoxDecoration(border: Border(top: Constants.GreyBorderSide)));
  468. }
  469. // Widget _buildContent() {
  470. // if (widget.programInfo['EvaluateList'].length == 0) {
  471. // return Container();
  472. // }
  473. // List<Widget> list = [];
  474. // var size = widget.programInfo['EvaluateList'].length >= 2
  475. // ? 2
  476. // : widget.programInfo['EvaluateList'].length;
  477. // for (int i = 0; i < size; i++) {
  478. // var data = widget.programInfo['EvaluateList'][i];
  479. // list.add(_buildReply(data));
  480. // }
  481. // return Container(
  482. // decoration: BoxDecoration(
  483. // borderRadius: BorderRadius.only(
  484. // bottomLeft: Radius.circular(10),
  485. // bottomRight: Radius.circular(10))),
  486. // child: Column(
  487. // children: <Widget>[
  488. // Container(
  489. // padding: EdgeInsets.zero,
  490. // margin:
  491. // EdgeInsets.only(left: 20, right: 20, top: 11.5, bottom: 14),
  492. // height: 0.1,
  493. // decoration: BoxDecoration(
  494. // border: Border(top: BorderSide(color: Color(0xFFF1F1F1)))),
  495. // ),
  496. // Container(
  497. // margin: EdgeInsets.only(left: 24),
  498. // decoration: BoxDecoration(
  499. // borderRadius: BorderRadius.only(
  500. // bottomLeft: Radius.circular(10),
  501. // bottomRight: Radius.circular(10))),
  502. // child: Row(
  503. // crossAxisAlignment: CrossAxisAlignment.start,
  504. // children: <Widget>[
  505. // Column(
  506. // crossAxisAlignment: CrossAxisAlignment.start,
  507. // children: list,
  508. // )
  509. // ],
  510. // ))
  511. // ],
  512. // ));
  513. // }
  514. // Widget _buildReply(data) {
  515. // var content = ": ${data['Content'] == null ? '' : data['Content']} ";
  516. // return Container(
  517. // padding: EdgeInsets.only(left: 0, bottom: 3),
  518. // width: Screen.width - 30,
  519. // child: RichText(
  520. // text: TextSpan(
  521. // children: data['ReplyUserId'] == 0
  522. // ? [
  523. // TextSpan(
  524. // text: Provider.of<RefNameProvider>(context)
  525. // .getRefName(data['UserId'], data['NickName']),
  526. // style: TextStyle(
  527. // fontSize: 12.5,
  528. // textBaseline: TextBaseline.alphabetic,
  529. // color: const Color(0xFF739BBC),
  530. // fontWeight: FontWeight.w500),
  531. // ),
  532. // TextSpan(
  533. // text: content,
  534. // style: TextStyle(
  535. // color: Constants.GreyTextColor,
  536. // textBaseline: TextBaseline.alphabetic,
  537. // fontSize: 12.5),
  538. // )
  539. // ]
  540. // : [
  541. // TextSpan(
  542. // text: WebData().subUserName(
  543. // Provider.of<RefNameProvider>(context)
  544. // .getRefName(data['UserId'], data['NickName'])),
  545. // style: TextStyle(
  546. // fontSize: 12.5,
  547. // textBaseline: TextBaseline.alphabetic,
  548. // color: const Color(0xFF739BBC),
  549. // fontWeight: FontWeight.w500),
  550. // ),
  551. // TextSpan(
  552. // text: ' ${I18n.of(context).reply} ',
  553. // style: TextStyle(
  554. // fontSize: 12.5,
  555. // textBaseline: TextBaseline.alphabetic,
  556. // color: Constants.GreyTextColor,
  557. // fontWeight: FontWeight.w500),
  558. // ),
  559. // TextSpan(
  560. // text: WebData().subUserName(data['ReplyNickName']),
  561. // style: TextStyle(
  562. // fontSize: 12.5,
  563. // textBaseline: TextBaseline.alphabetic,
  564. // color: const Color(0xFF739BBC),
  565. // fontWeight: FontWeight.w500),
  566. // ),
  567. // TextSpan(
  568. // text: content,
  569. // style: TextStyle(
  570. // color: Constants.GreyTextColor,
  571. // textBaseline: TextBaseline.alphabetic,
  572. // fontSize: 12.5),
  573. // )
  574. // ]),
  575. // ),
  576. // );
  577. // }
  578. Widget _buildTimebox(data) {
  579. return Container(
  580. padding: EdgeInsets.only(left: 15),
  581. child: Column(
  582. crossAxisAlignment: CrossAxisAlignment.start,
  583. children: <Widget>[
  584. isProgram
  585. ? _iconRow(0xe636,
  586. WebData().getProgramName(context, data['ProgramType']), 16.0)
  587. : Container(),
  588. isProgram
  589. ? _iconRow(
  590. 0xe635,
  591. '${data['AboutTime'].split(' ')[0]} ${WebData().getDateString(context, data['timeQuantum'])}',
  592. 16.0)
  593. : Container(),
  594. isProgram
  595. ? _iconRow(
  596. 0xe617,
  597. '${I18n.of(context).expect_lover}:${WebData().getLovePeople(data['HopeObject'])}',
  598. 16.0)
  599. : Container(),
  600. _buildTextContent(data),
  601. ],
  602. ),
  603. );
  604. }
  605. bool isExpansion(String text) {
  606. double width = Screen.width - 25;
  607. TextPainter _textPainter = TextPainter(
  608. maxLines: 2,
  609. text: TextSpan(
  610. text: text, style: TextStyle(fontSize: 16.0, color: Colors.black)),
  611. textDirection: TextDirection.ltr)
  612. ..layout(maxWidth: width, minWidth: width);
  613. if (_textPainter.didExceedMaxLines) {
  614. //这里判断 文本是否截断
  615. return true;
  616. } else {
  617. return false;
  618. }
  619. }
  620. Widget _buildTextContent(data) {
  621. if (data['Content'] == null || data['Content'] == '') {
  622. return Container();
  623. }
  624. bool showAllContent = isExpansion(data['Content']);
  625. return Container(
  626. margin: EdgeInsets.only(right: 10, top: 5),
  627. child: Column(
  628. crossAxisAlignment: CrossAxisAlignment.start,
  629. children: <Widget>[
  630. extendedText(
  631. data['Content'],
  632. selectionEnabled: false,
  633. color: Constants.BlackTextColor,
  634. emojisize: 17.0,
  635. maxLines: isShowAll ? 10 : 2,
  636. fontSize: ScreenUtil().setSp(14),
  637. fontWeight: FontWeight.w500,
  638. ),
  639. showAllContent
  640. ? InkWell(
  641. onTap: () {
  642. setState(() {
  643. isShowAll = !isShowAll;
  644. });
  645. },
  646. child: Container(
  647. padding: EdgeInsets.only(top: 5),
  648. child: Row(
  649. children: <Widget>[
  650. Text(
  651. !isShowAll
  652. ? I18n.of(context).expand
  653. : I18n.of(context).collapse,
  654. textScaleFactor: 1.0,
  655. style: TextStyle(
  656. fontSize: 15,
  657. color: Constants.BlueTextColor),
  658. ),
  659. Icon(
  660. !isShowAll
  661. ? Icons.keyboard_arrow_down
  662. : Icons.keyboard_arrow_up,
  663. size: 24,
  664. color: Constants.BlueTextColor),
  665. ],
  666. )))
  667. : Container(),
  668. ]));
  669. }
  670. Widget _buildBigImg(int id, List imgList, width, height) {
  671. return InkWell(
  672. onTap: () {
  673. Navigator.of(context).push(
  674. new MaterialPageRoute(
  675. builder: (context) {
  676. return PicSwiper(
  677. id: id,
  678. pics: imgList
  679. .map<PicSwiperItem>(
  680. (f) => PicSwiperItem(f, id: imgList.indexOf(f)))
  681. .toList(),
  682. );
  683. },
  684. ),
  685. );
  686. },
  687. child: Container(
  688. height: height,
  689. width: width,
  690. child: CachedNetworkImage(
  691. imageUrl: imgList[id] == null ? "" : imgList[id],
  692. placeholder: CustomUI.buildImgLoding,
  693. fit: BoxFit.cover,
  694. ),
  695. ));
  696. }
  697. Widget _buildImgSet(data) {
  698. double height = 254.5;
  699. List imgList = (data['ImgUrl'] == '' || data['ImgUrl'] == null)
  700. ? []
  701. : data['ImgUrl'].split('|');
  702. Widget result;
  703. switch (imgList.length) {
  704. case 1:
  705. result = _buildBigImg(0, imgList, Screen.width, height);
  706. break;
  707. case 2:
  708. double paddingWidth = 3;
  709. double imgWidth = (Screen.width - paddingWidth) / 2;
  710. result = Row(
  711. children: <Widget>[
  712. _buildBigImg(0, imgList, imgWidth, height),
  713. SizedBox(
  714. width: paddingWidth,
  715. ),
  716. _buildBigImg(1, imgList, imgWidth, height)
  717. ],
  718. );
  719. break;
  720. case 3:
  721. double paddingWidth = 3;
  722. double imgWidth = (Screen.width - paddingWidth) / 2;
  723. double imgHeight = (height - paddingWidth) / 2;
  724. result = Row(
  725. children: <Widget>[
  726. _buildBigImg(0, imgList, imgWidth, height),
  727. SizedBox(width: paddingWidth),
  728. Column(
  729. children: <Widget>[
  730. _buildBigImg(1, imgList, imgWidth, imgHeight),
  731. SizedBox(height: paddingWidth),
  732. _buildBigImg(2, imgList, imgWidth, imgHeight),
  733. ],
  734. ),
  735. ],
  736. );
  737. break;
  738. case 4:
  739. double paddingWidth = 3;
  740. double imgWidth = (Screen.width - paddingWidth) / 2;
  741. double imgHeight = (height - paddingWidth) / 2;
  742. result = Row(
  743. children: <Widget>[
  744. Column(
  745. children: <Widget>[
  746. _buildBigImg(0, imgList, imgWidth, imgHeight),
  747. SizedBox(height: paddingWidth),
  748. _buildBigImg(1, imgList, imgWidth, imgHeight),
  749. ],
  750. ),
  751. SizedBox(width: paddingWidth),
  752. Column(
  753. children: <Widget>[
  754. _buildBigImg(2, imgList, imgWidth, imgHeight),
  755. SizedBox(height: paddingWidth),
  756. _buildBigImg(3, imgList, imgWidth, imgHeight),
  757. ],
  758. ),
  759. ],
  760. );
  761. break;
  762. default:
  763. result = Container();
  764. }
  765. return Padding(padding: EdgeInsets.only(top: 5), child: result);
  766. }
  767. Widget _buildImg(data) {
  768. double width = 25;
  769. return InkWell(
  770. onTap: data['UserId'] == UserData().basicInfo.userId
  771. ? null
  772. : () {
  773. Navigator.of(context).push(
  774. new MaterialPageRoute(
  775. builder: (context) {
  776. return ProfilePage(
  777. userId: data['UserId'],
  778. );
  779. },
  780. ),
  781. );
  782. },
  783. child: Container(
  784. decoration: BoxDecoration(borderRadius: BorderRadius.circular(2.0)),
  785. width: width,
  786. height: width,
  787. child: ClipRRect(
  788. borderRadius: BorderRadius.circular(30),
  789. child: CachedNetworkImage(
  790. imageUrl: data['Headimgurl'] == null ? '' : data['Headimgurl'],
  791. placeholder: (context, url) => Image.asset(
  792. Constants.DefaultHeadImgUrl,
  793. width: width,
  794. height: width,
  795. ),
  796. fit: BoxFit.cover,
  797. ),
  798. )));
  799. }
  800. Widget _buildImgList(programInfo) {
  801. int pictureNum = programInfo['FabulousList'].length >= 3
  802. ? 3
  803. : programInfo['FabulousList'].length;
  804. List<Widget> list = [
  805. Container(height: 30, width: 30, margin: EdgeInsets.only(top: 10))
  806. ];
  807. if (pictureNum != 0) {
  808. list.add(_buildImg(programInfo['FabulousList'][0]));
  809. for (int i = 1; i < pictureNum; i++) {
  810. list.add(Positioned(
  811. left: 15.0 * i,
  812. child: _buildImg(programInfo['FabulousList'][i]),
  813. ));
  814. }
  815. if (programInfo['FabulousList'].length > 3) {
  816. list.add(Positioned(
  817. left: 70,
  818. child: Container(
  819. alignment: Alignment.center,
  820. decoration: BoxDecoration(
  821. color: Colors.grey[400],
  822. borderRadius: BorderRadius.circular(20.0)),
  823. width: 25,
  824. height: 25,
  825. child: Text(
  826. '+${programInfo['FabulousList'].length - pictureNum}',
  827. textScaleFactor: 1.0,
  828. style: TextStyle(color: Colors.white, fontSize: 13),
  829. ))));
  830. }
  831. }
  832. return Container(
  833. height: 37.5,
  834. padding: EdgeInsets.only(top: 0, left: 15, right: 23),
  835. child: Row(
  836. mainAxisAlignment: MainAxisAlignment.end,
  837. crossAxisAlignment: CrossAxisAlignment.center,
  838. children: <Widget>[
  839. Expanded(
  840. child: Stack(
  841. alignment: Alignment.centerLeft,
  842. children: list,
  843. ),
  844. ),
  845. Container(
  846. child: Text(
  847. I18n.of(context)
  848. .content_num
  849. .replaceFirst('/s1', programInfo['EvaluateNum'].toString()),
  850. style: TextStyle(fontSize: 12, color: BlackIconColor),
  851. ),
  852. ),
  853. ],
  854. ));
  855. }
  856. Widget _buildUserInfo(data) {
  857. Color greColor = Color(0xFF5A5A5A);
  858. Widget otherPop = myPopUp.PopupMenuButton<String>(
  859. offset: Offset(-10, 40),
  860. child: Container(
  861. margin: EdgeInsets.only(right: 10),
  862. padding: EdgeInsets.only(left: 8, right: 8, top: 0, bottom: 0),
  863. decoration: BoxDecoration(
  864. //border: Border.all(color: greColor),
  865. borderRadius: BorderRadius.all(Radius.circular(8))),
  866. child: Icon(
  867. IconData(0xe621, fontFamily: Constants.IconFontFamily),
  868. color: greColor,
  869. size: 12,
  870. )),
  871. onSelected: (str) {
  872. _selectValue(str, data['UserId'], isProgram);
  873. },
  874. itemBuilder: (BuildContext context) => <myPopUp.PopupMenuEntry<String>>[
  875. myPopUp.PopupMenuItem<String>(
  876. value: 'inform',
  877. child: Container(
  878. margin: EdgeInsets.only(top: 10, bottom: 10),
  879. child: fixedText(I18n.of(context).anonymous_report,
  880. fontSize: 14, color: Constants.BlackTextColor)),
  881. )
  882. ],
  883. );
  884. Widget myPop = myPopUp.PopupMenuButton<String>(
  885. offset: Offset(0, 40),
  886. padding: EdgeInsets.zero,
  887. child: Container(
  888. //margin: EdgeInsets.only(right: 10),
  889. padding: EdgeInsets.only(left: 18, right: 18, top: 3, bottom: 3),
  890. decoration: BoxDecoration(
  891. //border: Border.all(color: greColor),
  892. borderRadius: BorderRadius.all(Radius.circular(8))),
  893. child: Icon(
  894. IconData(0xe621, fontFamily: Constants.IconFontFamily),
  895. color: greColor,
  896. size: 12,
  897. )),
  898. onSelected: (str) {
  899. _selectValue(str, data['Id'], isProgram);
  900. },
  901. itemBuilder: (BuildContext context) => <myPopUp.PopupMenuEntry<String>>[
  902. !isCloseContent
  903. ? myPopUp.PopupMenuItem<String>(
  904. value: 'noContent',
  905. child: Container(
  906. margin: EdgeInsets.only(top: 10, bottom: 10),
  907. child: fixedText(I18n.of(context).prohibit_comments,
  908. fontSize: 15, color: Constants.BlackTextColor)))
  909. : myPopUp.PopupMenuItem<String>(
  910. value: 'openContent',
  911. child: Container(
  912. margin: EdgeInsets.only(top: 10, bottom: 10),
  913. child: fixedText(I18n.of(context).open_comments,
  914. fontSize: 15, color: Constants.BlackTextColor))),
  915. const myPopUp.PopupMenuDivider(
  916. height: 1,
  917. ),
  918. myPopUp.PopupMenuItem<String>(
  919. value: 'delete',
  920. child: Container(
  921. margin: EdgeInsets.only(top: 10, bottom: 10),
  922. child: fixedText(I18n.of(context).delete,
  923. fontSize: 15, color: Constants.BlackTextColor)),
  924. ),
  925. ],
  926. );
  927. bool isMan = data['Sex'] == 1;
  928. bool isVip = data['IsMember'] > 0;
  929. bool isSVIP = data['IsMember'] == 2;
  930. bool isAd = data['Type'] == 2;
  931. double imgHeight = 45.6;
  932. return Container(
  933. margin: EdgeInsets.only(top: 5, bottom: 10),
  934. child: Stack(children: <Widget>[
  935. InkWell(
  936. onTap: () async {
  937. if (isAd) {
  938. if (await canLaunch(data['HopeObject'])) {
  939. await launch(data['HopeObject']);
  940. } else {
  941. throw 'Could not launch ${data['HopeObject']}';
  942. }
  943. return;
  944. }
  945. if (data['UserId'] == UserData().basicInfo.userId) {
  946. return;
  947. }
  948. // if (data['Sex'] == UserData().basicInfo.sex) {
  949. // showToast(UserData().isMan()
  950. // ? I18n.of(context).cant_see
  951. // : I18n.of(context).cant_see2);
  952. // return;
  953. // }
  954. Navigator.of(context).push(
  955. new MaterialPageRoute(
  956. builder: (context) {
  957. return ProfilePage(
  958. userId: data['UserId'],
  959. );
  960. },
  961. ),
  962. );
  963. },
  964. child: Stack(
  965. children: <Widget>[
  966. Padding(
  967. padding: EdgeInsets.only(
  968. top: 8.5, right: 19, left: 15, bottom: 0),
  969. child: ClipRRect(
  970. borderRadius: BorderRadius.circular(imgHeight),
  971. child:
  972. data['HeadimgUrl'] == null || data['HeadimgUrl'] == ''
  973. ? Image.asset(
  974. Constants.DefaultHeadImgUrl,
  975. width: imgHeight,
  976. height: imgHeight,
  977. )
  978. : CachedNetworkImage(
  979. height: imgHeight,
  980. width: imgHeight,
  981. imageUrl: data['HeadimgUrl'],
  982. placeholder: (context, url) => Image.asset(
  983. Constants.DefaultHeadImgUrl,
  984. width: imgHeight,
  985. height: imgHeight,
  986. ),
  987. fit: BoxFit.cover,
  988. ),
  989. )),
  990. Positioned(
  991. right: 15,
  992. bottom: 0,
  993. child: Container(
  994. padding: EdgeInsets.only(bottom: 1.3, left: 0.5),
  995. decoration: BoxDecoration(
  996. color: Colors.white,
  997. borderRadius: BorderRadius.all(Radius.circular(20))),
  998. child: Icon(
  999. IconData(
  1000. isMan ? 0xe639 : 0xe638,
  1001. fontFamily: 'iconfont',
  1002. ),
  1003. color: isMan
  1004. ? const Color(0xff0072ff)
  1005. : const Color(0xffff0486),
  1006. size: 13,
  1007. ),
  1008. ))
  1009. ],
  1010. )),
  1011. Container(
  1012. margin: EdgeInsets.only(top: 3, left: imgHeight + 31),
  1013. child: Column(
  1014. crossAxisAlignment: CrossAxisAlignment.start,
  1015. children: <Widget>[
  1016. SizedBox(height: 5),
  1017. Row(
  1018. children: <Widget>[
  1019. Container(
  1020. child: Text(
  1021. data['NickName'] == null || data['NickName'] == ''
  1022. ? ''
  1023. : WebData().subUserName(
  1024. Provider.of<RefNameProvider>(context).getRefName(
  1025. data['UserId'], data['NickName'])),
  1026. textScaleFactor: 1.0,
  1027. style: TextStyle(
  1028. fontWeight: FontWeight.w500,
  1029. fontSize: 16,
  1030. ),
  1031. )),
  1032. data['IsAttestation'] == 1 && !isMan
  1033. ? Container(
  1034. margin: EdgeInsets.only(left: 5),
  1035. padding: EdgeInsets.only(
  1036. top: 2, bottom: 2, left: 5, right: 5),
  1037. alignment: Alignment.center,
  1038. decoration: BoxDecoration(
  1039. borderRadius: BorderRadius.circular(3),
  1040. color: Constants.PurpleBackgroundColor,
  1041. ),
  1042. child: Text(
  1043. 'Real',
  1044. textScaleFactor: 1.0,
  1045. style:
  1046. TextStyle(fontSize: 8, color: Colors.white),
  1047. ))
  1048. : Text(''),
  1049. isVip && isMan
  1050. ? Container(
  1051. margin: EdgeInsets.only(left: 5),
  1052. child:
  1053. isSVIP ? Constants.svipIcon : Constants.vipIcon)
  1054. : Container(),
  1055. Expanded(
  1056. child: Align(
  1057. alignment: Alignment.centerRight,
  1058. child: isAd
  1059. ? Container(
  1060. margin: EdgeInsets.only(right: 10),
  1061. padding: EdgeInsets.symmetric(
  1062. horizontal: 5.5, vertical: 2.5),
  1063. decoration: BoxDecoration(
  1064. borderRadius: BorderRadius.circular(3),
  1065. border: Border.all(color: Colors.grey)),
  1066. child: Text(I18n.of(context).ad,
  1067. style: TextStyle(
  1068. fontSize: 9, color: Colors.grey)),
  1069. )
  1070. : Container(),
  1071. ),
  1072. ),
  1073. !isAd
  1074. ? Container(
  1075. alignment: Alignment.centerRight,
  1076. child: isMyself ? myPop : otherPop)
  1077. : Container(),
  1078. ],
  1079. ),
  1080. SizedBox(height: 8),
  1081. Row(
  1082. children: <Widget>[
  1083. Text(
  1084. WebData().getLoginTime(context, data['CreateTime']),
  1085. style: TextStyle(
  1086. color: const Color(0xFF5C5C5C), fontSize: 12),
  1087. ),
  1088. Expanded(
  1089. child: isMyself
  1090. ? Align(
  1091. alignment: Alignment.centerRight,
  1092. child: Container(
  1093. margin: EdgeInsets.only(right: 10),
  1094. padding: EdgeInsets.only(
  1095. left: 4, right: 4, top: 3, bottom: 3),
  1096. decoration: BoxDecoration(
  1097. color: Colors.grey[200],
  1098. borderRadius: BorderRadius.circular(10.0),
  1099. ),
  1100. child: Text(
  1101. I18n.of(context).i_posted,
  1102. style: TextStyle(
  1103. fontSize: 10,
  1104. color: Colors.grey[600],
  1105. ),
  1106. ),
  1107. ))
  1108. : Container(),
  1109. )
  1110. ],
  1111. )
  1112. ],
  1113. )),
  1114. ]),
  1115. );
  1116. }
  1117. }