Hibok
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

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