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.
 
 
 
 
 
 

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