post_widget.dart 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. import 'dart:convert';
  2. import 'dart:math';
  3. import 'package:cached_network_image/cached_network_image.dart';
  4. import 'package:flutter/cupertino.dart';
  5. import 'package:flutter/material.dart';
  6. import 'package:flutter/services.dart';
  7. import 'package:provider/provider.dart';
  8. import 'package:sport/bean/post.dart';
  9. import 'package:sport/bean/post_user.dart';
  10. import 'package:sport/pages/social/gallery_photo_view.dart';
  11. import 'package:sport/pages/social/post_detail_page.dart';
  12. import 'package:sport/pages/social/post_share_page.dart';
  13. import 'package:sport/pages/social/share_webview.dart';
  14. import 'package:sport/provider/social_detail_model.dart';
  15. import 'package:sport/router/navigator_util.dart';
  16. import 'package:sport/services/api/inject_api.dart';
  17. import 'package:sport/utils/DateFormat.dart';
  18. import 'package:sport/utils/toast.dart';
  19. import 'package:sport/widgets/dialog/alert_dialog.dart';
  20. import 'package:sport/widgets/dialog/bindphone_dialog.dart';
  21. import 'package:sport/widgets/dialog/modal_bottom_action.dart';
  22. import 'package:sport/widgets/dialog/request_dialog.dart';
  23. import 'package:sport/widgets/image.dart';
  24. import 'package:sport/widgets/menu_share_bottom.dart';
  25. import 'package:sport/widgets/misc.dart';
  26. import 'package:sport/widgets/space.dart';
  27. import 'chat_page.dart';
  28. class PostWidget extends StatefulWidget {
  29. final SocialDetailModel model;
  30. final Post post;
  31. final bool isSelf;
  32. final bool jump; // 头像是否可点击
  33. final String keyword; // 头像是否可点击
  34. final bool highlight; // 头像是否可点击
  35. final bool showForum; // 头像是否可点击
  36. final bool showTopButton; // 头像是否可点击
  37. final Function callback; // 头像是否可点击
  38. PostWidget(this.post, this.model, this.isSelf,
  39. {this.jump = true, this.highlight = false, this.keyword, this.showForum = false, this.showTopButton = false, this.callback});
  40. @override
  41. State<StatefulWidget> createState() => _PostWidgetState();
  42. }
  43. class _PostWidgetState extends State<PostWidget> with InjectApi {
  44. @override
  45. Widget build(BuildContext context) {
  46. return widget.post.isDelete == true ? Container() : _buildPostDetailWidget(context, widget.post, widget.isSelf);
  47. }
  48. void go(Post post, bool comment) async {
  49. print("${post.toJson()}----------------------------------------");
  50. var result = await Navigator.push(context, MaterialPageRoute(builder: (context) {
  51. return PostDetailPage(post, comment, widget.model.list);
  52. }));
  53. if (result == true) {
  54. _delete(widget.model, post);
  55. }
  56. }
  57. bool isExpansion(String text) {
  58. TextPainter _textPainter = TextPainter(maxLines: 3, text: TextSpan(text: text, style: TextStyle(fontSize: 16.0)), textDirection: TextDirection.ltr)
  59. ..layout(maxWidth: MediaQuery.of(context).size.width - 24);
  60. if (_textPainter.didExceedMaxLines) {
  61. return true;
  62. } else {
  63. return false;
  64. }
  65. }
  66. Widget _highlightName(String content) {
  67. String keyword = widget.keyword;
  68. var list = content.split(keyword);
  69. List<InlineSpan> texts = [];
  70. for (int i = 0; i < list.length; i++) {
  71. texts.add(TextSpan(text: list[i]));
  72. if (i < list.length - 1) texts.add(TextSpan(text: keyword, style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor)));
  73. }
  74. return RichText(
  75. text: TextSpan(style: Theme.of(context).textTheme.subtitle1, children: texts),
  76. );
  77. }
  78. Widget _highlightContent(String content, {int maxLines}) {
  79. String keyword = widget.keyword;
  80. var list = content.split(keyword);
  81. List<InlineSpan> texts = [];
  82. for (int i = 0; i < list.length; i++) {
  83. texts.add(TextSpan(text: list[i]));
  84. if (i < list.length - 1)
  85. texts.add(TextSpan(text: keyword, style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16, color: Theme.of(context).accentColor)));
  86. }
  87. return RichText(
  88. maxLines: maxLines,
  89. text: TextSpan(style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16), children: texts),
  90. );
  91. }
  92. Widget _postWidget(Post post) {
  93. double width = MediaQuery.of(context).size.width - 24 - 22;
  94. // if(post.quoteData != null) print("[post:]${post.toJson()}-------------------------");
  95. // print("[post:]${post.toJson()}----------------------------------------");
  96. return Column(
  97. crossAxisAlignment: CrossAxisAlignment.start,
  98. children: <Widget>[
  99. RichText(
  100. maxLines: 3,
  101. overflow: TextOverflow.ellipsis,
  102. text: TextSpan(style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16), children: <InlineSpan>[
  103. TextSpan(text: '${post.nickname}:', style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor)),
  104. TextSpan(text: '${post.content}', style: Theme.of(context).textTheme.subtitle1),
  105. ]),
  106. ),
  107. if (post.images.length > 0)
  108. GridView.count(
  109. physics: new NeverScrollableScrollPhysics(),
  110. shrinkWrap: true,
  111. padding: EdgeInsets.only(top: 15),
  112. childAspectRatio: post.images.length == 1 ? max(16 / 10, post.images[0].getImageAspectRatio()) : 1,
  113. crossAxisSpacing: 10.0,
  114. crossAxisCount: min(3, post.images.length),
  115. children: post.images
  116. .asMap()
  117. .keys
  118. .take(min(3, post.images.length))
  119. .map((i) => GestureDetector(
  120. onTap: () => open(context, i, post.images),
  121. child: i < 2
  122. ? post.images.length == 1
  123. ? Row(
  124. mainAxisSize: MainAxisSize.min,
  125. children: <Widget>[
  126. ClipRRect(
  127. borderRadius: BorderRadius.circular(6),
  128. child: Stack(
  129. children: <Widget>[
  130. CachedNetworkImage(
  131. alignment: Alignment.centerLeft,
  132. imageUrl: post.images[i].thumbnail,
  133. fit: BoxFit.cover,
  134. width: post.images[i].getWidth(width),
  135. ),
  136. if (post.images[i].isLongImage())
  137. Positioned(
  138. bottom: 4,
  139. right: 4,
  140. child: Container(
  141. padding: EdgeInsets.symmetric(horizontal: 8, vertical: 2),
  142. decoration:
  143. BoxDecoration(color: Colors.black.withOpacity(.8), borderRadius: BorderRadius.all(Radius.circular(20))),
  144. child: Text(
  145. "长图",
  146. style: Theme.of(context).textTheme.bodyText1.copyWith(color: Colors.white),
  147. ),
  148. ),
  149. )
  150. ],
  151. ))
  152. ],
  153. )
  154. : ClipRRect(
  155. borderRadius: BorderRadius.circular(6),
  156. child: CachedNetworkImage(alignment: Alignment.centerLeft, imageUrl: post.images[i].thumbnail, fit: BoxFit.cover))
  157. : ClipRRect(
  158. borderRadius: BorderRadius.circular(6),
  159. child: Stack(
  160. fit: StackFit.expand,
  161. children: <Widget>[
  162. CachedNetworkImage(
  163. imageUrl: post.images[i].thumbnail,
  164. fit: BoxFit.cover,
  165. ),
  166. if (post.images.length - 3 > 0)
  167. Container(
  168. color: Color(0x80000000),
  169. child: Center(
  170. child: Text(
  171. "+${post.images.length - 3}",
  172. style: TextStyle(color: Colors.white, fontSize: 16),
  173. ),
  174. ),
  175. )
  176. ],
  177. ))))
  178. .toList()),
  179. if(post.quoteData != null)
  180. _postLink(post.quoteData,color: Colors.white),
  181. ],
  182. );
  183. }
  184. Widget _postLink(String quote,{Color color}){
  185. var data = json.decode(quote);
  186. return Container(
  187. padding: EdgeInsets.all(8.0),
  188. color:color !=null? color:Color(0xfff5f5f5),
  189. child: Row(
  190. crossAxisAlignment: CrossAxisAlignment.start,
  191. mainAxisSize: MainAxisSize.max,
  192. children: <Widget>[
  193. CachedNetworkImage(
  194. imageUrl: avatarList[4],
  195. width: 60.0,
  196. height: 60.0,
  197. ),
  198. Space(
  199. width: 5.0,
  200. ),
  201. Expanded(
  202. child: RichText(
  203. maxLines: 3,
  204. overflow: TextOverflow.ellipsis,
  205. text: TextSpan(style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16), children: <InlineSpan>[
  206. TextSpan(text: '${data["username"]["value"]}:', style: Theme.of(context).textTheme.subtitle1.copyWith(color: Theme.of(context).accentColor)),
  207. TextSpan(text: '分享了他的运动记录,快来围观吧~', style: Theme.of(context).textTheme.subtitle1),
  208. ]),
  209. ),
  210. ),]),
  211. );
  212. }
  213. _delete(SocialDetailModel model, Post post) {
  214. model.list.removeWhere((element) => element.id == post.id);
  215. setState(() {
  216. post.isDelete = true;
  217. });
  218. }
  219. _deleteF(SocialDetailModel model, Post post) async {
  220. if (await showDialog(
  221. context: context,
  222. builder: (context) => CustomAlertDialog(title: '确定删除帖子?', ok: () => Navigator.of(context).pop(true)),
  223. ) ==
  224. true) {
  225. await request(context, () async {
  226. await model.api.postDelSubject(post.id);
  227. ToastUtil.show("删除成功");
  228. _delete(model, post);
  229. });
  230. }
  231. }
  232. Widget _buildPostDetailWidget(BuildContext context, Post post, bool isSelf) {
  233. SocialDetailModel model = widget.model;
  234. double width = MediaQuery.of(context).size.width - 24;
  235. return Column(
  236. children: <Widget>[
  237. GestureDetector(
  238. behavior: HitTestBehavior.opaque,
  239. onTap: () {
  240. go(post, false);
  241. // NavigatorUtil.goSocialPostDetail(context, post)
  242. },
  243. onLongPress: () async {
  244. await showActionDialog(context, {
  245. if (isSelf == false)
  246. "举报帖子": () async {
  247. await request(context, () async {
  248. await model.api.postForumReport(subjectId: post.id).catchError((onError) {});
  249. ToastUtil.show("举报成功");
  250. });
  251. },
  252. if (isSelf == false)
  253. "屏蔽此条": () async {
  254. await request(context, () async {
  255. await model.api.postForumBlockObject(post.id, "subject").catchError((onError) {});
  256. ToastUtil.show("屏蔽成功");
  257. _delete(model, post);
  258. });
  259. },
  260. "复制文字": () {
  261. Clipboard.setData(ClipboardData(text: post.content));
  262. ToastUtil.show("已复制到粘贴板");
  263. }
  264. });
  265. },
  266. child: Padding(
  267. padding: const EdgeInsets.symmetric(vertical: 12.0),
  268. child: Column(
  269. crossAxisAlignment: CrossAxisAlignment.start,
  270. children: <Widget>[
  271. Row(
  272. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  273. children: <Widget>[
  274. GestureDetector(
  275. onTap: widget.jump
  276. ? () => NavigatorUtil.goSocialUserDetail(context, PostUser(id: post.userId, name: post.nickname, avatar: post.avatar))
  277. : null,
  278. child: Row(
  279. children: <Widget>[
  280. Space(
  281. width: 12,
  282. ),
  283. CircleAvatar(backgroundImage: userAvatarProvider(post.avatar), radius: 18),
  284. Space(
  285. width: 8,
  286. ),
  287. Column(
  288. crossAxisAlignment: CrossAxisAlignment.start,
  289. children: <Widget>[
  290. Row(
  291. children: <Widget>[
  292. widget.highlight
  293. ? _highlightName(post.nickname)
  294. : Text(
  295. post.nickname,
  296. style: Theme.of(context).textTheme.subtitle1.copyWith(fontWeight: FontWeight.w600),
  297. ),
  298. if (post?.followStatus == "friends")
  299. Container(
  300. margin: EdgeInsets.only(left: 4.0),
  301. width: 27.0,
  302. height: 14.0,
  303. decoration: BoxDecoration(
  304. // color: Colors.white,
  305. // borderRadius: BorderRadius.all(Radius.circular(2)),
  306. // border: Border.all(
  307. // color: Theme.of(context).accentColor,
  308. // width: .5,
  309. // )
  310. image: DecorationImage(
  311. image: AssetImage("lib/assets/img/bbs_icon_friend.png")
  312. ),
  313. ),
  314. // padding: EdgeInsets.fromLTRB(4, 0, 4, 2),
  315. // margin: EdgeInsets.fromLTRB(6.0, 0, 6, 0),
  316. // child: Text(
  317. // "好友",
  318. // style: Theme.of(context).textTheme.subtitle2.copyWith(color: Theme.of(context).accentColor, fontSize: 11),
  319. // )
  320. ),
  321. if(post?.isOfficial == "1")
  322. Container(
  323. margin: EdgeInsets.only(left: 4.0),
  324. width: 27.0,
  325. height: 14.0,
  326. decoration: BoxDecoration(
  327. image: DecorationImage(
  328. image: AssetImage("lib/assets/img/bbs_icon_official.png")
  329. ),
  330. ),
  331. ),
  332. ],
  333. ),
  334. Space(
  335. height: 4,
  336. ),
  337. Text(DateFormat.formatTime(post.createTime), style: Theme.of(context).textTheme.bodyText1)
  338. ],
  339. ),
  340. ],
  341. )),
  342. widget.showForum && isSelf
  343. ? PopupMenuButton(
  344. icon: Image.asset(
  345. "lib/assets/img/bbs_btn_more.png",
  346. height: 12,
  347. fit: BoxFit.fitHeight,
  348. ),
  349. onSelected: (action) async {
  350. switch (action) {
  351. case "delete":
  352. if (await showDialog(
  353. context: context,
  354. builder: (context) => CustomAlertDialog(title: '确定删除此条?', ok: () => Navigator.of(context).pop(true)),
  355. ) ==
  356. true) {
  357. await request(context, () async {
  358. await model.api.postDelSubject(post.id);
  359. ToastUtil.show("删除成功");
  360. _delete(model, post);
  361. });
  362. }
  363. break;
  364. case "top":
  365. await request(context, () async {
  366. if (post.isUserTop == "1") {
  367. var resp = await model.api.unsetUserTopSubjects(post.id).catchError((onError) {});
  368. if (resp?.code == 0) {
  369. ToastUtil.show("取消置顶成功");
  370. post.isUserTop = "0";
  371. }
  372. } else {
  373. var resp = await model.api.setUserTopSubjects(post.id).catchError((onError) {});
  374. if (resp?.code == 0) {
  375. ToastUtil.show("置顶成功");
  376. post.isUserTop = "1";
  377. }
  378. }
  379. widget.callback?.call();
  380. // setState(() {});
  381. });
  382. break;
  383. }
  384. },
  385. itemBuilder: (_) => divideMenus([
  386. menuItemCenter("delete", "删除此条"),
  387. if (widget.showTopButton == true) menuItemCenter("top", post.isUserTop == "1" ? "取消置顶" : "置顶帖子"),
  388. ]),
  389. )
  390. : IconButton(
  391. icon: Image.asset("lib/assets/img/btn_close_invitation.png"),
  392. onPressed: () async {
  393. if (isSelf == false) {
  394. if (await showDialog(
  395. context: context,
  396. builder: (context) => CustomAlertDialog(title: '是否屏蔽此条帖子', ok: () => Navigator.of(context).pop(true)),
  397. ) ==
  398. true) {
  399. await request(context, () async {
  400. await model.api.postForumBlockObject(post.id, "subject").catchError((onError) {});
  401. ToastUtil.show("屏蔽成功");
  402. _delete(model, post);
  403. });
  404. }
  405. } else {
  406. _deleteF(model, post);
  407. }
  408. },
  409. )
  410. ],
  411. ),
  412. Padding(
  413. padding: const EdgeInsets.symmetric(horizontal: 12.0),
  414. child: Column(
  415. crossAxisAlignment: CrossAxisAlignment.start,
  416. children: <Widget>[
  417. Padding(
  418. padding: const EdgeInsets.only(top: 6.0),
  419. child: Column(
  420. crossAxisAlignment: CrossAxisAlignment.start,
  421. children: <Widget>[
  422. post.isExpansion ?? false == false
  423. ? widget.highlight
  424. ? _highlightContent(post.content, maxLines: 3)
  425. : Text(post.content,
  426. maxLines: 3, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16))
  427. : widget.highlight
  428. ? _highlightContent(post.content)
  429. : Text(post.content, style: Theme.of(context).textTheme.subtitle1.copyWith(fontSize: 16)),
  430. if (isExpansion(post.content))
  431. GestureDetector(
  432. onTap: () {
  433. post.isExpansion = !(post.isExpansion ?? true);
  434. setState(() {});
  435. },
  436. child: Padding(
  437. padding: const EdgeInsets.only(top: 5.0),
  438. child: Row(
  439. children: <Widget>[
  440. Text(
  441. post.isExpansion ?? false == false ? "全部" : "收起",
  442. style: Theme.of(context).textTheme.bodyText1,
  443. strutStyle: fixedLine,
  444. ),
  445. SizedBox(
  446. width: 4,
  447. ),
  448. post.isExpansion ?? false == false ? arrowBottom() : arrowTop()
  449. ],
  450. ),
  451. )),
  452. ],
  453. ),
  454. ),
  455. if (post.images.length > 0)
  456. GridView.count(
  457. physics: new NeverScrollableScrollPhysics(),
  458. shrinkWrap: true,
  459. padding: const EdgeInsets.only(top: 12.0),
  460. childAspectRatio: post.images.length == 1 ? max(16 / 10, post.images[0].getImageAspectRatio()) : 1,
  461. crossAxisSpacing: 10.0,
  462. crossAxisCount: min(3, post.images.length),
  463. children: post.images
  464. .asMap()
  465. .keys
  466. .take(min(3, post.images.length))
  467. .map((i) => GestureDetector(
  468. onTap: () => i < 2 ? open(context, i, post.images) : go(post, false),
  469. child: i < 2
  470. ? post.images.length == 1
  471. ? Row(
  472. mainAxisSize: MainAxisSize.min,
  473. children: <Widget>[
  474. ClipRRect(
  475. borderRadius: BorderRadius.circular(6),
  476. child: Stack(
  477. children: <Widget>[
  478. CachedNetworkImage(
  479. alignment: Alignment.centerLeft,
  480. imageUrl: post.images[i].thumbnail,
  481. fit: BoxFit.cover,
  482. width: post.images[i].getWidth(width),
  483. ),
  484. if (post.images[i].isLongImage())
  485. Positioned(
  486. bottom: 4,
  487. right: 4,
  488. child: Container(
  489. padding: EdgeInsets.symmetric(horizontal: 8, vertical: 2),
  490. decoration: BoxDecoration(
  491. color: Colors.black.withOpacity(.8), borderRadius: BorderRadius.all(Radius.circular(20))),
  492. child: Text(
  493. "长图",
  494. style: Theme.of(context).textTheme.bodyText1.copyWith(color: Colors.white),
  495. ),
  496. ),
  497. )
  498. ],
  499. ))
  500. ],
  501. )
  502. : ClipRRect(
  503. borderRadius: BorderRadius.circular(6),
  504. child:
  505. CachedNetworkImage(alignment: Alignment.centerLeft, imageUrl: post.images[i].thumbnail, fit: BoxFit.cover))
  506. : ClipRRect(
  507. borderRadius: BorderRadius.circular(6),
  508. child: Stack(
  509. fit: StackFit.expand,
  510. children: <Widget>[
  511. CachedNetworkImage(
  512. imageUrl: post.images[i].thumbnail,
  513. fit: BoxFit.cover,
  514. ),
  515. if (post.images.length - 3 > 0)
  516. Container(
  517. color: Color(0x80000000),
  518. child: Center(
  519. child: Text(
  520. "+${post.images.length - 3}",
  521. style: TextStyle(color: Colors.white, fontSize: 16),
  522. ),
  523. ),
  524. )
  525. ],
  526. ))))
  527. .toList()),
  528. ],
  529. ),
  530. ),
  531. if (post.quoteSubject != null)
  532. GestureDetector(
  533. behavior: HitTestBehavior.opaque,
  534. onTap: () {
  535. go(post.quoteSubject, false);
  536. },
  537. child: Container(
  538. padding: EdgeInsets.all(11.0),
  539. margin: EdgeInsets.symmetric(horizontal: 12.0, vertical: 5.0),
  540. decoration: BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(10)), color: Color(0xfff5f5f5)),
  541. child: _postWidget(post.quoteSubject),
  542. ),
  543. ),
  544. Row(
  545. children: <Widget>[
  546. // Expanded(child:Text('${post.toJson()}')),
  547. if(post.gameName != null && post.gameName != "" )
  548. Container(
  549. padding: EdgeInsets.fromLTRB(12.0, 12.0, 6.0, 0.0),
  550. alignment: Alignment.centerLeft,
  551. child: Container(
  552. padding: EdgeInsets.only(left: 6.0,right: 6.0,bottom: 2.0,top: 1.0),
  553. decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(4.0)),color: Color(0xffF1F1F1)),
  554. child: Text(post.gameName,style: TextStyle(color: Color(0xff999999),fontSize: 12.0),strutStyle: StrutStyle(forceStrutHeight: true),),
  555. ),
  556. ),
  557. if (widget.post.isUserTop == '1')
  558. Padding(
  559. padding: post.gameName != null && post.gameName != "" ? EdgeInsets.fromLTRB(0.0, 12.0, 12.0, 0.0) : EdgeInsets.fromLTRB(12.0, 12.0, 12.0, 0.0) ,
  560. child: Container(
  561. child: Text(
  562. "已置顶",
  563. style: TextStyle(fontSize: 12 , color: Color(0xff5498FF)),
  564. strutStyle: fixedLine,
  565. ),
  566. padding: EdgeInsets.only(left: 6.0,right: 6.0,bottom: 2.0,top: 1.0),
  567. decoration: BoxDecoration(
  568. borderRadius: BorderRadius.circular(2),
  569. border: Border.all(
  570. color: Color(0xff5498FF),
  571. width: .5,
  572. ),
  573. ),
  574. ),
  575. )
  576. ],
  577. ),
  578. if(post.quoteData != null)
  579. GestureDetector(
  580. behavior: HitTestBehavior.opaque,
  581. onTap: () {
  582. var data = json.decode(post.quoteData);
  583. print("$data------------------------------");
  584. NavigatorUtil.goPage(context, (context) => WebViewSharePage(data['url']["value"],hash: data['hash']["value"],));
  585. },
  586. child: Container(
  587. padding: EdgeInsets.all(11.0),
  588. margin: EdgeInsets.symmetric(horizontal: 12.0, vertical: 5.0),
  589. decoration: BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(10)), color: Color(0xfff5f5f5)),
  590. child: _postLink(post.quoteData),
  591. ),
  592. ),
  593. Space(
  594. height: 15,
  595. ),
  596. Row(
  597. children: <Widget>[
  598. Expanded(
  599. child: GestureDetector(
  600. behavior: HitTestBehavior.opaque,
  601. onTap: () {
  602. // NavigatorUtil.goPage(context, (context) => PostSharePage(post));
  603. menuShareBottom(context,"social",post: post);
  604. },
  605. child: Container(
  606. padding: const EdgeInsets.symmetric(horizontal: 5.0),
  607. child: Center(
  608. child: Row(
  609. mainAxisSize: MainAxisSize.min,
  610. children: <Widget>[
  611. Image.asset("lib/assets/img/bbslist_icon_share.png"),
  612. SizedBox(
  613. width: 5,
  614. ),
  615. Text(
  616. "转发",
  617. strutStyle: fixedLine,
  618. style: Theme.of(context).textTheme.bodyText1,
  619. ),
  620. ],
  621. ),
  622. ),
  623. ),
  624. ),
  625. ),
  626. Expanded(
  627. child: GestureDetector(
  628. behavior: HitTestBehavior.opaque,
  629. onTap: () async {
  630. if (await showBindPhoneDialog(context) == true) {
  631. go(post, true);
  632. }
  633. },
  634. child: Container(
  635. padding: const EdgeInsets.symmetric(horizontal: 5.0),
  636. child: Center(
  637. child: Row(
  638. mainAxisSize: MainAxisSize.min,
  639. children: <Widget>[
  640. Image.asset("lib/assets/img/bbslist_icon_reply.png"),
  641. SizedBox(
  642. width: 5,
  643. ),
  644. Text(
  645. post.commentCount == 0 ? "回复" : "${post.commentCount}",
  646. strutStyle: fixedLine,
  647. style: Theme.of(context).textTheme.bodyText1,
  648. ),
  649. ],
  650. ),
  651. ),
  652. ),
  653. ),
  654. ),
  655. Expanded(
  656. child: GestureDetector(
  657. behavior: HitTestBehavior.opaque,
  658. onTap: () async {
  659. await (post.isLiked ? model.api.postForumUnLike(post.id, "subject_id") : model.api.postForumLike(post.id, "subject_id"));
  660. setState(() {
  661. post.toggleLike();
  662. });
  663. },
  664. child: Container(
  665. padding: const EdgeInsets.symmetric(horizontal: 5.0),
  666. child: Center(
  667. child: SizedBox(
  668. height: 19,
  669. child: Row(
  670. crossAxisAlignment: CrossAxisAlignment.end,
  671. mainAxisSize: MainAxisSize.min,
  672. children: <Widget>[
  673. Image.asset(
  674. "lib/assets/img/bbslist_icon_like${post.isLiked ? 'd' : ''}.png",
  675. ),
  676. SizedBox(
  677. width: 5,
  678. ),
  679. Text(
  680. post.likeCount == 0 ? "点赞" : "${post.likeCount}",
  681. strutStyle: fixedLine,
  682. style: Theme.of(context).textTheme.bodyText1,
  683. ),
  684. ],
  685. ),
  686. ),
  687. ),
  688. ),
  689. ),
  690. ),
  691. ],
  692. ),
  693. ],
  694. ),
  695. ),
  696. ),
  697. // if (widget.showForum)
  698. // Padding(
  699. // padding: const EdgeInsets.only(bottom: 12.0, left: 12.0),
  700. // child: Row(
  701. // children: <Widget>[
  702. //// Container(
  703. //// child: Text("来自${widget.post.forumName}", style: Theme.of(context).textTheme.bodyText1),
  704. //// padding: EdgeInsets.fromLTRB(8, 0, 8, 1),
  705. //// decoration: BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadius.all(Radius.circular(20)), color: Color(0xfff1f1f1)),
  706. //// ),
  707. //// Space(
  708. //// width: 10,
  709. //// ),
  710. // ],
  711. // ),
  712. // ),
  713. Divider(
  714. height: 1,
  715. ),
  716. ],
  717. );
  718. }
  719. }