Hibok
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

590 行
19 KiB

  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:chat/data/constants.dart';
  3. import 'package:chat/generated/i18n.dart';
  4. import 'package:chat/home/InformUser.dart';
  5. import 'package:chat/models/ref_name_provider.dart';
  6. import 'package:chat/utils/CustomUI.dart';
  7. import 'package:chat/utils/MessageBox.dart';
  8. import 'package:chat/utils/MessageMgr.dart';
  9. import 'package:chat/utils/PicSwiper.dart';
  10. import 'package:chat/utils/app_navigator.dart';
  11. import 'package:chat/utils/local_notification_util.dart';
  12. import 'package:chat/utils/msgHandler.dart';
  13. import 'package:flutter/material.dart';
  14. import 'package:oktoast/oktoast.dart';
  15. import 'package:provider/provider.dart';
  16. import '../utils/HttpUtil.dart';
  17. import 'package:dio/dio.dart';
  18. import "../data/UserData.dart";
  19. import '../utils/TokenMgr.dart';
  20. class ProgramDetailPage extends StatefulWidget {
  21. @required
  22. final int programId;
  23. ProgramDetailPage({Key key, this.programId}) : super(key: key);
  24. @override
  25. _ProgramDetailPageState createState() => new _ProgramDetailPageState();
  26. }
  27. class _ProgramDetailPageState extends State<ProgramDetailPage> {
  28. GlobalKey<ScaffoldState> registKey = new GlobalKey();
  29. List fabulousList = [];
  30. bool isMyself = false;
  31. List evaluateList = [];
  32. List enrollList = [];
  33. bool showAllContent = false;
  34. bool isMan = false;
  35. bool isProgram = false;
  36. Map programInfo = {};
  37. bool isLoadingFish = false;
  38. bool isNonContent = false;
  39. bool isJoin = false;
  40. msgRefresh(data) {
  41. getData();
  42. }
  43. msgUpdateDy(data) {
  44. setState(() {
  45. isNonContent = data;
  46. });
  47. }
  48. @override
  49. void initState() {
  50. super.initState();
  51. MessageMgr().on('delete_program', msgDeleteProgram);
  52. MessageMgr().on('update_dy', msgUpdateDy);
  53. MessageMgr().on('refresh_list', msgRefreshList);
  54. getData();
  55. LocalNotificationUtil().cleanAllNotifications();
  56. }
  57. msgRefreshList(data) {
  58. getData();
  59. }
  60. msgDeleteProgram(data) {
  61. Navigator.of(context).pop();
  62. }
  63. Future getData() async {
  64. Map data = {
  65. "userId": UserData().basicInfo.userId,
  66. "id": widget.programId,
  67. };
  68. data['sign'] = TokenMgr().getSign(data);
  69. Response res = await HttpUtil().post('station/evaluate/detail',
  70. data: data, failback: () => Navigator.of(context).pop());
  71. var resData = res.data;
  72. print(resData);
  73. if (resData['code'] == 0) {
  74. if (resData['data']['FabulousList'] != null)
  75. fabulousList = resData['data']['FabulousList'];
  76. if (resData['data']['EvaluateList'] != null) {
  77. evaluateList = resData['data']['EvaluateList'];
  78. }
  79. enrollList = resData['data']['EnrollList'];
  80. isMyself = resData['data']['UserId'] == UserData().basicInfo.userId;
  81. isMan = resData['data']['Sex'] == 1;
  82. isProgram = resData['data']['Type'] == 0;
  83. programInfo = resData['data'];
  84. programInfo['Id'] = widget.programId;
  85. isNonContent = resData['data']['EvaluateStatus'] == 1;
  86. isJoin = resData['data']['IsEnroll'] == 1;
  87. isLoadingFish = true;
  88. setState(() {});
  89. } else {
  90. showToast(resData['msg']);
  91. }
  92. }
  93. @override
  94. Widget build(BuildContext context) {
  95. Widget appBar = new AppBar(
  96. //backgroundColor: AppColors.NewAppbarBgColor,
  97. title: new Text(
  98. isProgram
  99. ? I18n.of(context).program_details
  100. : I18n.of(context).dynamic_details,
  101. textScaleFactor: 1.0,
  102. style: TextStyle(color: AppColors.NewAppbarTextColor),
  103. ),
  104. elevation: 1,
  105. leading: CustomUI.buildCustomLeading(context),
  106. centerTitle: true,
  107. );
  108. var content = new Scaffold(
  109. key: registKey,
  110. appBar: appBar,
  111. //backgroundColor: Colors.white,
  112. body: SafeArea(
  113. child: Center(
  114. child: Container(
  115. height: MediaQuery.of(context).size.height,
  116. width: MediaQuery.of(context).size.width,
  117. child: _buildBody(),
  118. ),
  119. ),
  120. ));
  121. return CustomUI.buildPageLoading(context, content, !isLoadingFish);
  122. }
  123. Widget _buildBottomSheetItem(str, height, callback) {
  124. return InkWell(
  125. child: Container(
  126. height: height,
  127. decoration:
  128. BoxDecoration(border: Border(bottom: Constants.GreyBorderSide)),
  129. alignment: Alignment.center,
  130. child: Text(
  131. str,
  132. textScaleFactor: 1.0,
  133. style: TextStyle(fontSize: 18, color: Constants.BlackTextColor),
  134. ),
  135. ),
  136. onTap: callback,
  137. );
  138. }
  139. Widget _buildReply(data) {
  140. const TextColor = Constants.BlackTextColor;
  141. const BlueColor = Constants.GreyTextColor;
  142. bool isWriter =
  143. programInfo['UserId'] == UserData().basicInfo.userId; //是否发布者
  144. bool isReplyer = data['UserId'] == UserData().basicInfo.userId; //是否评论者
  145. replay() {
  146. Navigator.of(context).pop();
  147. CustomUI.showContentDialog(
  148. registKey.currentContext, programInfo['Id'], data['Pid'], 1, (data) {
  149. programInfo['EvaluateNum']++;
  150. evaluateList.add(data);
  151. setState(() {});
  152. },
  153. replyUserId: data['UserId'],
  154. replyUserName: Provider.of<RefNameProvider>(context)
  155. .getRefName(data['UserId'], data['NickName']),
  156. isMyself: isMyself);
  157. }
  158. inform() async {
  159. var resdata = {
  160. "reportuserId": UserData().basicInfo.userId,
  161. "userid": data['UserId'],
  162. };
  163. resdata['sign'] = TokenMgr().getSign(resdata);
  164. resdata['type'] = 4;
  165. resdata['objectId'] = data['Pid'];
  166. resdata['reason'] = 0;
  167. resdata["imgurl"] = '';
  168. resdata["explain"] = '';
  169. Response res = await HttpUtil().post('report/user/insert', data: resdata);
  170. Map resData = res.data;
  171. showToast(resData['msg']);
  172. if (resData['code'] == 0) {
  173. Navigator.of(context).pop();
  174. }
  175. }
  176. delete() async {
  177. var resdata = {
  178. "userId": UserData().basicInfo.userId,
  179. "pId": data['Pid'],
  180. };
  181. resdata['sign'] = TokenMgr().getSign(resdata);
  182. Response res = await HttpUtil()
  183. .post('station/delete/evaluate', data: resdata, isShowLoading: true);
  184. Map resData = res.data;
  185. if (resData['code'] == 0) {
  186. Navigator.of(context).pop();
  187. programInfo['EvaluateNum']--;
  188. getData();
  189. }
  190. }
  191. double fontSize = 14;
  192. //1.不是发布者
  193. //1.1是评论者则没有选项
  194. //1.2不是评论者则有回复和举报
  195. //2.是发布者
  196. //2.1是评论者则有删除
  197. //2.2不是评论者则有删除,回复和举报
  198. return InkWell(
  199. onTap: !isWriter && isReplyer
  200. ? null
  201. : () {
  202. double height = 50.0;
  203. List<Widget> list = [];
  204. if (!isWriter && !isReplyer)
  205. list = [
  206. _buildBottomSheetItem(
  207. I18n.of(context).reply, height, replay),
  208. _buildBottomSheetItem(
  209. I18n.of(context).report, height, inform),
  210. ];
  211. if (isWriter && isReplyer)
  212. list = [
  213. _buildBottomSheetItem(
  214. I18n.of(context).delete, height, delete),
  215. ];
  216. if (isWriter && !isReplyer)
  217. list = [
  218. _buildBottomSheetItem(
  219. I18n.of(context).delete, height, delete),
  220. _buildBottomSheetItem(
  221. I18n.of(context).reply, height, replay),
  222. _buildBottomSheetItem(
  223. I18n.of(context).report, height, inform),
  224. ];
  225. //回复不能回复自己 ,只有发布者才能删除评论
  226. showModalBottomSheet(
  227. context: registKey.currentContext,
  228. builder: (BuildContext context) {
  229. return new Container(
  230. height: height * list.length,
  231. child: Column(
  232. children: list,
  233. ),
  234. );
  235. },
  236. ).then((val) {});
  237. },
  238. child: Container(
  239. padding: EdgeInsets.only(bottom: 3),
  240. child: RichText(
  241. text: TextSpan(
  242. children: data['ReplyUserId'] == 0
  243. ? [
  244. TextSpan(
  245. text: Provider.of<RefNameProvider>(context)
  246. .getRefName(data['UserId'], data['NickName']),
  247. style: TextStyle(
  248. fontSize: fontSize,
  249. textBaseline: TextBaseline.alphabetic,
  250. color: BlueColor,
  251. fontWeight: FontWeight.w500),
  252. ),
  253. TextSpan(
  254. text: ': ${data['Content']}',
  255. style: TextStyle(
  256. color: TextColor,
  257. textBaseline: TextBaseline.alphabetic,
  258. fontSize: fontSize),
  259. )
  260. ]
  261. : [
  262. TextSpan(
  263. text: Provider.of<RefNameProvider>(context)
  264. .getRefName(data['UserId'], data['NickName']),
  265. style: TextStyle(
  266. fontSize: fontSize,
  267. textBaseline: TextBaseline.alphabetic,
  268. color: BlueColor,
  269. fontWeight: FontWeight.w500),
  270. ),
  271. TextSpan(
  272. text: ' ${I18n.of(context).reply} ',
  273. style: TextStyle(
  274. fontSize: fontSize,
  275. textBaseline: TextBaseline.alphabetic,
  276. color: TextColor,
  277. fontWeight: FontWeight.w500),
  278. ),
  279. TextSpan(
  280. text: data['ReplyNickName'],
  281. style: TextStyle(
  282. fontSize: fontSize,
  283. textBaseline: TextBaseline.alphabetic,
  284. color: BlueColor,
  285. fontWeight: FontWeight.w500),
  286. ),
  287. TextSpan(
  288. text: ': ${data['Content']}',
  289. style: TextStyle(
  290. color: TextColor,
  291. textBaseline: TextBaseline.alphabetic,
  292. fontSize: fontSize),
  293. )
  294. ]),
  295. ),
  296. ));
  297. }
  298. Widget _buildJoinItem(data) {
  299. Widget basicInfo = Row(children: <Widget>[
  300. Padding(
  301. padding: EdgeInsets.only(left: 10, right: 5),
  302. child: Stack(
  303. children: <Widget>[
  304. Padding(
  305. padding: EdgeInsets.only(right: 10),
  306. child: ClipRRect(
  307. borderRadius: BorderRadius.circular(6.0),
  308. child: CachedNetworkImage(
  309. height: 45,
  310. width: 45,
  311. imageUrl:
  312. data['Headimgurl'] == null ? "" : data['Headimgurl'],
  313. placeholder: CustomUI.buildImgLoding,
  314. fit: BoxFit.cover,
  315. ),
  316. ),
  317. ),
  318. Positioned(
  319. right: 5,
  320. bottom: 0,
  321. child: Container(
  322. padding: EdgeInsets.only(bottom: 1.3, left: 0.5),
  323. decoration: BoxDecoration(
  324. color: Colors.white,
  325. borderRadius: BorderRadius.all(Radius.circular(20))),
  326. child: Icon(
  327. IconData(
  328. !isMan ? 0xe639 : 0xe638,
  329. fontFamily: 'iconfont',
  330. ),
  331. color: !isMan
  332. ? const Color(0xff0072ff)
  333. : const Color(0xffff0486),
  334. size: 12,
  335. ),
  336. ))
  337. ],
  338. )),
  339. Expanded(
  340. child: Column(
  341. crossAxisAlignment: CrossAxisAlignment.start,
  342. children: <Widget>[
  343. Container(
  344. child: RichText(
  345. text: TextSpan(children: [
  346. TextSpan(
  347. text: Provider.of<RefNameProvider>(context)
  348. .getRefName(data['UserId'], data['NickName']),
  349. style:
  350. TextStyle(fontSize: 14, color: Constants.BlackTextColor)),
  351. TextSpan(
  352. text: I18n.of(context).signed_up.replaceFirst('/s1', ''),
  353. style:
  354. TextStyle(fontSize: 13, color: Constants.GreyTextColor)),
  355. ])),
  356. ),
  357. Text(
  358. '${data['CreateTime']}',
  359. textScaleFactor: 1.0,
  360. style: TextStyle(color: Constants.LightGreyTextColor, fontSize: 12),
  361. ),
  362. ],
  363. )),
  364. InkWell(
  365. onTap: () {
  366. Navigator.of(context).push(
  367. new MaterialPageRoute(
  368. builder: (context) {
  369. return InformUserPage(
  370. isMan: !isMan,
  371. userId: data['UserId'],
  372. );
  373. },
  374. ),
  375. );
  376. },
  377. child: Container(
  378. padding: EdgeInsets.only(left: 10, right: 10, bottom: 10),
  379. alignment: Alignment.topRight,
  380. child: Text(
  381. I18n.of(context).report,
  382. textScaleFactor: 1.0,
  383. style: TextStyle(color: Constants.BlackTextColor),
  384. )))
  385. ]);
  386. Widget img = Container(
  387. child: Row(
  388. children: <Widget>[
  389. InkWell(
  390. onTap: () {
  391. Navigator.of(context).push(
  392. new MaterialPageRoute(
  393. builder: (context) {
  394. return PicSwiper(
  395. id: 0, pics: [PicSwiperItem(data['ImgUrl'], id: 0)]);
  396. },
  397. ),
  398. );
  399. },
  400. child: Container(
  401. margin: EdgeInsets.only(top: 10, left: 60),
  402. height: 80,
  403. width: 100,
  404. decoration:
  405. BoxDecoration(borderRadius: BorderRadius.circular(2.0)),
  406. child: ClipRRect(
  407. borderRadius: BorderRadius.circular(8),
  408. child: CachedNetworkImage(
  409. imageUrl: data['ImgUrl'] == null ? "" : data['ImgUrl'],
  410. placeholder: CustomUI.buildImgLoding,
  411. fit: BoxFit.cover,
  412. ),
  413. ))),
  414. Expanded(
  415. child: Container(
  416. height: 90,
  417. alignment: Alignment.bottomRight,
  418. child: InkWell(
  419. child: Container(
  420. margin: EdgeInsets.only(right: 10),
  421. decoration: BoxDecoration(
  422. color: const Color(0xFF547CFF),
  423. borderRadius: BorderRadius.all(Radius.circular(5))),
  424. padding:
  425. EdgeInsets.only(left: 15, right: 15, top: 5, bottom: 5),
  426. child: Text(
  427. !isMan
  428. ? I18n.of(context).talk_him
  429. : I18n.of(context).contact_her,
  430. textScaleFactor: 1.0,
  431. style: TextStyle(color: Colors.white, fontSize: 13),
  432. ),
  433. ),
  434. onTap: () {
  435. int fdId = data['UserId'];
  436. int sessionId = UserData().getSessionId(fdId);
  437. MsgHandler.updateActiveSesstion(sessionId);
  438. AppNavigator.pushChatPage(context, fdId);
  439. },
  440. ),
  441. ),
  442. )
  443. ],
  444. ),
  445. );
  446. return Container(
  447. padding: EdgeInsets.only(top: 10, bottom: 10),
  448. decoration: BoxDecoration(
  449. color: Colors.grey[100],
  450. borderRadius: BorderRadius.all(Radius.circular(10))),
  451. margin: EdgeInsets.only(top: 10),
  452. width: MediaQuery.of(context).size.width * 0.95,
  453. child: Column(
  454. children: <Widget>[basicInfo, img],
  455. ));
  456. }
  457. Widget _buildJoinList() {
  458. if (enrollList == null || enrollList.length == 0) {
  459. return Container();
  460. }
  461. return isMyself
  462. ? Container(
  463. child: Column(
  464. children: enrollList.map((data) {
  465. return _buildJoinItem(data);
  466. }).toList(),
  467. ),
  468. )
  469. : Container();
  470. }
  471. Widget _buildContent() {
  472. if (evaluateList == null || evaluateList.length == 0) {
  473. return Container();
  474. }
  475. const maxNum = 2;
  476. Widget button = InkWell(
  477. highlightColor: Colors.transparent,
  478. radius: 0,
  479. onTap: () {
  480. setState(() {
  481. showAllContent = !showAllContent;
  482. });
  483. },
  484. child: Padding(
  485. padding: EdgeInsets.only(top: 5, bottom: 5),
  486. child: Row(
  487. children: <Widget>[
  488. Text(
  489. !showAllContent
  490. ? I18n.of(context).expand
  491. : I18n.of(context).collapse,
  492. textScaleFactor: 1.0,
  493. style: TextStyle(fontSize: 12, color: Colors.grey),
  494. ),
  495. Icon(
  496. !showAllContent
  497. ? Icons.keyboard_arrow_down
  498. : Icons.keyboard_arrow_up,
  499. size: 18,
  500. color: Colors.grey,
  501. )
  502. ],
  503. ),
  504. ),
  505. );
  506. List<Widget> list = [];
  507. int showNum = evaluateList.length;
  508. if (evaluateList.length >= maxNum && !showAllContent) {
  509. showNum = maxNum;
  510. }
  511. for (int i = 0; i < showNum; i++) {
  512. var data = evaluateList[i];
  513. list.add(_buildReply(data));
  514. }
  515. if (evaluateList.length > maxNum) {
  516. list.add(button);
  517. }
  518. return Container(
  519. margin: EdgeInsets.only(left: 23, top: 10, right: 8, bottom: 10),
  520. child: Column(
  521. crossAxisAlignment: CrossAxisAlignment.start,
  522. children: list,
  523. ));
  524. }
  525. Widget _buildBody() {
  526. return new ListView(
  527. children: isLoadingFish
  528. ? <Widget>[
  529. MessageBox(isDetail: true, programInfo: programInfo),
  530. // _buildBigImg(programInfo),
  531. // _buildImgList(),
  532. _buildContent(),
  533. _buildJoinList(),
  534. ]
  535. : [],
  536. );
  537. }
  538. @override
  539. void dispose() {
  540. registKey = null;
  541. MessageMgr().off('update_dy', msgUpdateDy);
  542. MessageMgr().off('delete_program', msgDeleteProgram);
  543. MessageMgr().off('refresh_list', msgRefreshList);
  544. super.dispose();
  545. }
  546. }