RoomInfo.dart 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:shared_preferences/shared_preferences.dart';
  4. import 'package:url_launcher/url_launcher.dart';
  5. import '../styles/colors.dart';
  6. import 'dart:ui';
  7. import '../plugins/ScreenStramPlugin.dart';
  8. import '../net/HttpManager.dart';
  9. import '../net/Result.dart';
  10. import 'package:flutter_redux/flutter_redux.dart';
  11. import '../redux/AppState.dart';
  12. import '../model/HouseInfo.dart';
  13. import '../styles/totast.dart';
  14. import 'StartWindow.dart';
  15. import '../model/PlayerInfo.dart';
  16. import '../widget/VideoWidget.dart';
  17. import 'dart:async';
  18. import '../widget/Dialog.dart';
  19. import 'SecondRoomInfo.dart';
  20. import 'package:flutter/cupertino.dart';
  21. import 'UserGuid.dart';
  22. import 'VideoPlayer.dart';
  23. import './CompetitionNotice.dart';
  24. class RoomInfo extends StatefulWidget {
  25. RoomInfo(this.houseInfo, {Key key}) : super(key: key);
  26. final HouseInfo houseInfo; // 用来储存传递过来的值
  27. @override
  28. RoomInfoState createState() => RoomInfoState();
  29. }
  30. class RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin {
  31. TabController mController;
  32. Map roomInfo;
  33. HouseInfo houseInfo;
  34. bool isJoin = true;
  35. PlayerInfo playerInfo;
  36. bool isPop = false;
  37. bool showBack = false;
  38. Timer timer;
  39. List<List<String>> roomTipsList = [];
  40. ScrollController _tipController;
  41. String _myUrl;
  42. int tabIndex = 0;
  43. int myRank = 0;
  44. int myPoints = 0;
  45. //获取房间信息
  46. Future<void> getRoomInfo() async {
  47. Result res = await HttpManager.get('houseInfo/getOne', data: {'id': houseInfo.id});
  48. if (res.success) {
  49. setState(() {
  50. roomInfo = res.data;
  51. houseInfo = HouseInfo.fromJson(res.data);
  52. });
  53. } else {}
  54. checkJoinInfo();
  55. }
  56. //开始比赛
  57. Future<void> startGame() async {
  58. Toast.show(context, '加载中', -1, 'loading');
  59. Result res = await HttpManager.post('houseInfo/handBegin', data: {'id': houseInfo.id});
  60. Toast.hide();
  61. }
  62. //隔一秒检查是否开始
  63. Future<void> getNowStatus() async {
  64. Result res = await HttpManager.get('houseInfo/getPlayerNum', data: {'id': houseInfo.id});
  65. if (res.success) {
  66. if (houseInfo.statusFlag == 0 && res.data['statusFlag'] == 2) {
  67. showStart();
  68. // timer.cancel();
  69. }
  70. setState(() {
  71. houseInfo.playerNumber = res.data['playerNumber'];
  72. houseInfo.statusFlag = res.data['statusFlag'];
  73. houseInfo.bonus = res.data['bonus'];
  74. houseInfo.beginTime = res.data['beginTime'];
  75. });
  76. }
  77. }
  78. //开始比赛确认按钮
  79. Future<void> showStart() async {
  80. if (!isJoin) {
  81. return;
  82. }
  83. bool result = await Navigator.of(context).push<bool>(
  84. PageRouteBuilder(
  85. opaque: false,
  86. transitionDuration: Duration(milliseconds: 300),
  87. transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
  88. return FadeTransition(
  89. opacity: CurvedAnimation(parent: animation, curve: Curves.linear),
  90. child: child,
  91. );
  92. },
  93. pageBuilder: (BuildContext context, _, __) {
  94. return StartWindow();
  95. },
  96. ),
  97. );
  98. Map<String, dynamic> data = {'id': playerInfo.id};
  99. bool success = true;
  100. if (result) {
  101. success = await ScreenStreamPlugin.start(playerInfo.id.toString());
  102. if (success) {
  103. data['statusFlag'] = 2;
  104. data['played'] = true;
  105. } else {
  106. data['statusFlag'] = 6;
  107. data['played'] = false;
  108. }
  109. } else {
  110. data['statusFlag'] = 6;
  111. data['played'] = false;
  112. }
  113. Result res = await HttpManager.post('playerInfo/update', data: data);
  114. // MyDialog.showDialog(context, '自动启动游戏失败,请手动切换到游戏app开始竞赛', submitText: '知道了');
  115. // Timer(Duration(seconds: 10), () {
  116. // showSucessInfo();
  117. // });
  118. // return;
  119. if (res.success) {
  120. if (data['statusFlag'] == 2) {
  121. const url = 'pubgmhd1106467070://';
  122. if (await canLaunch(url)) {
  123. Timer(Duration(seconds: 1), () async {
  124. await launch(url);
  125. showSucessInfo();
  126. });
  127. } else {
  128. showCustomDialog(context, '自动启动游戏失败,请手动切换到游戏app开始竞赛', submitText: '知道了');
  129. Timer(Duration(seconds: 10), () {
  130. showSucessInfo();
  131. });
  132. }
  133. } else {
  134. showBackDialog(success ? 1 : 0);
  135. }
  136. }
  137. }
  138. //开始录屏提示框
  139. void showSucessInfo() {
  140. showCustomDialog(context, '您已经完成比赛了吗,确认完成,那就点击下方完成竞赛按钮,上传本次成绩,祝您赢取大奖', title: '完成比赛', submitText: '我已完成比赛', onsubmit: () async {
  141. HttpManager.post('playerInfo/update', data: {'id': playerInfo.id, 'statusFlag': 3});
  142. bool success = await ScreenStreamPlugin.stop();
  143. Timer(Duration(seconds: 1), () {
  144. getEndTips();
  145. });
  146. setState(() {
  147. playerInfo.statusFlag = 3;
  148. });
  149. });
  150. }
  151. Future<void> getEndTips() async {
  152. Result res = await HttpManager.get('playerInfo/endNum', data: {'houseId': houseInfo.id});
  153. if (res.success) {
  154. int time = houseInfo.beginTime + 1 * 3600 * 1000 - DateTime.now().millisecondsSinceEpoch;
  155. var nowTime = (time ~/ 1000 ~/ 60) % 60;
  156. setState(() {
  157. roomTipsList.add(['你已完成本次比赛,当前完成人数 ', res.data.toString(), '人,比赛需要等待所有人完成后方可结算奖励', '', ',你可以先去参加其他竞赛,稍后在“个人中心-我的战绩”中可以查看本次竞赛排名及领取奖励']);
  158. });
  159. }
  160. }
  161. //未确认比赛弹窗
  162. void showBackDialog(type) {
  163. showCustomDialog(context, (type == 1 ? '由于您未在十秒内点击开始按钮' : '由于您未授权录屏') + ',系统已经判定您放弃比赛,谢谢您的参与。', title: '很遗憾');
  164. }
  165. //检查加入信息
  166. Future<void> checkJoinInfo() async {
  167. Result res = await HttpManager.get('playerInfo/getOne', data: {'userId': StoreProvider.of<AppState>(context).state.userInfo.id, 'houseId': houseInfo.id});
  168. if (res.success) {
  169. if (res.data == null) {
  170. setState(() {
  171. isJoin = false;
  172. });
  173. if (houseInfo.statusFlag == 0) {
  174. if (houseInfo.scoreType == 0) {
  175. roomTipsList.add([
  176. '上方奖金为当前本次竞赛的总奖金,根据当前人数的增加,奖金也就越多,竞赛的第一名获得${houseInfo.houseLevel.firstRatio}%,第二名获得${houseInfo.houseLevel.secondRatio}%,第三名获得${houseInfo.houseLevel.thirdRatio}%,其他名次算作失败没有奖励,祝你取得好成绩。注:奖金池的${houseInfo.houseLevel.feeRatio}%为平台方运营服务费, 奖金池的${houseInfo.houseLevel.poolRatio}%流入赛季总奖金。'
  177. ]);
  178. } else {
  179. roomTipsList.add([
  180. '同房间内的玩家进行竞赛,所有吃上鸡的玩家均可获得奖金,即平分总奖金池的${houseInfo.houseLevel.avgRatio}%。注:奖金池的${houseInfo.houseLevel.feeRatio}%为平台方运营服务费, 奖金池的${houseInfo.houseLevel.poolRatio}%流入赛季总奖金。'
  181. ]);
  182. }
  183. }
  184. } else {
  185. playerInfo = PlayerInfo.fromJson(res.data);
  186. myPoints = playerInfo.points;
  187. if (houseInfo.statusFlag == 4) {
  188. _myUrl = await ScreenStreamPlugin.getVideo(playerInfo.id.toString());
  189. print('本地视频' + playerInfo.id.toString());
  190. print(_myUrl);
  191. Result rankRes = await HttpManager.get('playerInfo/userRank', data: {'id': playerInfo.id});
  192. if (rankRes.success) {
  193. myRank = rankRes.data;
  194. }
  195. }
  196. setState(() {
  197. isJoin = true;
  198. });
  199. if (houseInfo.statusFlag == 0) {
  200. if (houseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
  201. roomTipsList.add(['房间创建成功,待人数满员时会自动开启比赛,请在此页面耐心等待其他人的加入,退出房间则视为自动放弃比赛,已支付金币概不退换,快快点击右上角分享给好友加入战局吧']);
  202. } else {
  203. // roomTipsList.add([
  204. // '请在此页面耐心等待,竞赛即将开始,届时玩家有10秒的时间进行确认,点击确认方可正式进入竞赛,若没有点击,则视为自动放弃此次竞赛,已支付金币概不退换'
  205. // ]);
  206. }
  207. // Timer(Duration(seconds: 1), () {
  208. // roomTipsList.add([
  209. // '游戏开始后会有弹窗提示授权进行录屏的操作,',
  210. // '请一定点击“确定”或“允许”此操作',
  211. // ',系统会自动跳转打开游戏app,若长时间没有自动跳转,请手动打开游戏app进行比赛,在游戏比赛结束后,请',
  212. // '一定要点击查看游戏最后的��数名次结算页面',
  213. // ',返回游戏主页,最后再切换到我们竞赛app中,点击完成比赛,方可成功上传本次成绩。从游戏开始一小时之内必须返回全民App点击完成比赛,否则判定游戏失败,祝你取得好成绩。'
  214. // ]);
  215. // changeScroll();
  216. // });
  217. } else if (houseInfo.statusFlag != 4) {
  218. if (playerInfo.statusFlag == 3 || playerInfo.statusFlag == 8 || playerInfo.statusFlag == 9) {
  219. getEndTips();
  220. }
  221. }
  222. }
  223. }
  224. if (isJoin && houseInfo.statusFlag != 4) {
  225. timer = Timer.periodic(Duration(seconds: 1), (timer) {
  226. getNowStatus();
  227. });
  228. }
  229. }
  230. //加入房间
  231. Future<void> joinRoom() async {
  232. Toast.show(context, '加载中', -1, 'loading');
  233. Result res = await HttpManager.post('houseInfo/join', data: {'houseId': houseInfo.id, 'userId': StoreProvider.of<AppState>(context).state.userInfo.id});
  234. Toast.hide();
  235. if (res.success) {
  236. Toast.show(context, '加入成功', 1500, 'success');
  237. checkJoinInfo();
  238. } else {
  239. Toast.show(context, res.error, 1500, 'info');
  240. }
  241. }
  242. //获取分秒
  243. String getSecondsMIn(int time) {
  244. if (time == null) {
  245. return '';
  246. } else {
  247. return ((time ~/ 1000 ~/ 60) % 60).toString() + '分' + (time ~/ 1000 % 60).toString() + '秒';
  248. }
  249. }
  250. @override
  251. void initState() {
  252. super.initState();
  253. houseInfo = widget.houseInfo;
  254. mController = TabController(
  255. length: 2,
  256. vsync: this,
  257. );
  258. mController.addListener(() {
  259. setState(() {
  260. tabIndex = mController.index;
  261. });
  262. print(tabIndex);
  263. });
  264. _tipController = ScrollController();
  265. roomInfo = {};
  266. Future.delayed(Duration.zero, () async {
  267. getRoomInfo();
  268. final prefs = await SharedPreferences.getInstance();
  269. final bool showGuid3 = prefs.getBool('showGuid3') ?? true;
  270. if (showGuid3) {
  271. await prefs.setBool('showGuid3', false);
  272. await showUserGuide3(context);
  273. }
  274. });
  275. }
  276. @override
  277. void dispose() {
  278. super.dispose();
  279. mController.dispose();
  280. if (timer != null) {
  281. timer.cancel();
  282. }
  283. }
  284. @override
  285. Widget build(BuildContext context) {
  286. ScreenUtil.instance = ScreenUtil(width: 375, height: 667)..init(context);
  287. int status = 0;
  288. if (houseInfo != null) {
  289. status = houseInfo.statusFlag;
  290. }
  291. return WillPopScope(
  292. child: Scaffold(
  293. appBar: AppBar(
  294. title: Container(
  295. child: TabBar(
  296. controller: mController,
  297. labelColor: PRIMARY_COLOR,
  298. unselectedLabelColor: Color(0xCCFFFFFF),
  299. labelStyle: TextStyle(fontSize: 16.0),
  300. indicatorColor: PRIMARY_COLOR,
  301. indicatorWeight: 3,
  302. indicatorSize: TabBarIndicatorSize.label,
  303. tabs: <Widget>[
  304. Tab(text: '房间信息'),
  305. Tab(text: '参赛成员'),
  306. ],
  307. ),
  308. ),
  309. centerTitle: true,
  310. elevation: 0,
  311. ),
  312. body: Container(
  313. color: BG_SUB_COLOR,
  314. child: TabBarView(
  315. controller: mController,
  316. children: [_firstPage(), SecondPage(houseInfo)],
  317. )),
  318. floatingActionButton: _joinBtn(),
  319. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  320. ),
  321. onWillPop: () {
  322. if (houseInfo == null || (houseInfo.statusFlag != 0) || !isJoin) {
  323. if (timer != null) {
  324. timer.cancel();
  325. }
  326. isPop = true;
  327. Toast.hide();
  328. Navigator.of(context).pop();
  329. return Future.value(false);
  330. } else {
  331. showCustomDialog(context, '比赛即将开始,确定离开房间?', isCancel: true, onsubmit: () {
  332. Navigator.of(context).pop();
  333. });
  334. }
  335. return Future.value(false);
  336. },
  337. );
  338. }
  339. Widget _firstPage() {
  340. int statuFlag = 0;
  341. if (houseInfo != null) {
  342. if (houseInfo.statusFlag != null) {
  343. statuFlag = houseInfo.statusFlag;
  344. }
  345. }
  346. return LayoutBuilder(
  347. builder: (BuildContext context, BoxConstraints viewportConstraints) {
  348. return Container(
  349. child: RefreshIndicator(
  350. color: PRIMARY_COLOR,
  351. backgroundColor: Colors.white,
  352. displacement: 10,
  353. onRefresh: () async {
  354. await Future.delayed(const Duration(seconds: 1));
  355. },
  356. child: SingleChildScrollView(
  357. controller: _tipController,
  358. physics: AlwaysScrollableScrollPhysics(),
  359. child: Column(
  360. children: <Widget>[
  361. houseInfo != null ? VideoWidget(videoSrc: houseInfo.video) : Container(),
  362. // Image.network(topImg, width: double.infinity),
  363. Container(
  364. height: 60,
  365. padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
  366. child: Row(
  367. children: <Widget>[
  368. Expanded(
  369. child: Text(
  370. houseInfo.houseName,
  371. style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
  372. ),
  373. ),
  374. Row(
  375. mainAxisAlignment: MainAxisAlignment.center,
  376. children: <Widget>[
  377. Image.asset(
  378. 'images/icon_renshu.png',
  379. width: 20,
  380. ),
  381. Text(
  382. (houseInfo != null ? (houseInfo.playerNumber ?? 0).toString() : '0') +
  383. '/' +
  384. (houseInfo != null ? houseInfo.maxNumber.toString() : '0'),
  385. style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Color(0xFFB1B2C0)),
  386. ),
  387. ],
  388. )
  389. ],
  390. ),
  391. ),
  392. Container(
  393. height: 40,
  394. margin: EdgeInsets.fromLTRB(15, 0, 15, 0),
  395. color: Color(0x1A1990F8),
  396. child: Row(
  397. children: <Widget>[
  398. Expanded(
  399. flex: 1,
  400. child: CupertinoButton(
  401. padding: EdgeInsets.all(0),
  402. onPressed: () {
  403. if (houseInfo == null || (houseInfo.statusFlag != 0) || !isJoin) {
  404. if (timer != null) {
  405. timer.cancel();
  406. }
  407. isPop = true;
  408. Toast.hide();
  409. Navigator.of(context).pop();
  410. return Future.value(false);
  411. } else {
  412. showCustomDialog(context, '比赛即将开始,确定离开房间?', isCancel: true, onsubmit: () {
  413. Navigator.of(context).pop();
  414. });
  415. }
  416. },
  417. child: Text(
  418. '返回锦标赛',
  419. style: TextStyle(color: PRIMARY_COLOR, fontSize: 14, fontWeight: FontWeight.bold),
  420. ),
  421. ),
  422. ),
  423. Container(
  424. width: 1,
  425. height: 12,
  426. color: PRIMARY_COLOR,
  427. ),
  428. Expanded(
  429. flex: 1,
  430. child: CupertinoButton(
  431. padding: EdgeInsets.all(0),
  432. onPressed: () {
  433. showNotice(context);
  434. },
  435. child: Text(
  436. '竞赛须知',
  437. style: TextStyle(color: PRIMARY_COLOR, fontSize: 14, fontWeight: FontWeight.bold),
  438. ),
  439. ),
  440. ),
  441. ],
  442. ),
  443. ),
  444. // Container(
  445. // height: 40,
  446. // margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
  447. // decoration: BoxDecoration(
  448. // color: Color(0x1AFFFF00),
  449. // border: Border.all(
  450. // width: 1,
  451. // color: Colors.yellow,
  452. // )),
  453. // child: Row(
  454. // mainAxisAlignment: MainAxisAlignment.spaceAround,
  455. // children: <Widget>[
  456. // Text('积分 加成+0%', style: TextStyle(color: Colors.yellow, fontSize: 12)),
  457. // Text('保底 0积分', style: TextStyle(color: Colors.yellow, fontSize: 12)),
  458. // ],
  459. // ),
  460. // ),
  461. statuFlag != 4
  462. ? TipsListContent(tipsList: roomTipsList, houseInfo: houseInfo)
  463. : RankContent(
  464. roomId: houseInfo.id.toString(),
  465. ),
  466. Container(
  467. width: double.infinity,
  468. height: 78,
  469. )
  470. ],
  471. ))),
  472. );
  473. },
  474. );
  475. }
  476. Widget _joinBtn() {
  477. int joinMoney = 0;
  478. int statusFlag = houseInfo != null ? houseInfo.statusFlag : 1;
  479. int playerStatus = playerInfo != null ? playerInfo.statusFlag : 0;
  480. if (!isJoin && statusFlag == 0) {
  481. return Container(
  482. color: BG_SUB_COLOR,
  483. width: ScreenUtil().setWidth(375),
  484. height: 48 + ScreenUtil().setHeight(40),
  485. padding: EdgeInsets.only(top: ScreenUtil().setHeight(20), bottom: ScreenUtil().setHeight(20), left: 15, right: 15),
  486. child: RaisedButton(
  487. textColor: Colors.white,
  488. child: Row(
  489. mainAxisAlignment: MainAxisAlignment.center,
  490. children: <Widget>[
  491. Container(
  492. margin: EdgeInsets.only(left: 20),
  493. child: Text(
  494. '加入房间',
  495. style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
  496. ))
  497. ],
  498. ),
  499. onPressed: () => joinRoom()),
  500. );
  501. } else if (!isJoin && statusFlag == 2) {
  502. return Container(
  503. width: double.infinity,
  504. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  505. height: 88,
  506. child: RaisedButton(
  507. disabledColor: Color(0xFF914244),
  508. disabledTextColor: Color(0xFF252532),
  509. child: Text(
  510. '房间已经开始,加入通道关闭',
  511. style: TextStyle(fontSize: 16),
  512. ),
  513. onPressed: null,
  514. ),
  515. );
  516. } else if (isJoin && statusFlag == 0) {
  517. int _time;
  518. if (houseInfo != null) {
  519. _time = houseInfo.createTime + 600000 - DateTime.now().millisecondsSinceEpoch;
  520. }
  521. if (houseInfo != null && houseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
  522. return Container(
  523. width: double.infinity,
  524. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  525. height: 88,
  526. child: RaisedButton(
  527. child: Text.rich(TextSpan(children: [
  528. TextSpan(
  529. text: '开始比赛',
  530. style: TextStyle(fontSize: 16),
  531. ),
  532. TextSpan(
  533. text: '(${getSecondsMIn(_time)}秒后将自动开始)',
  534. style: TextStyle(fontSize: 12),
  535. )
  536. ])),
  537. onPressed: () {
  538. showCustomDialog(context, '确认要开始比赛吗?', isCancel: true, onsubmit: () {
  539. print('开始');
  540. startGame();
  541. });
  542. },
  543. ),
  544. );
  545. } else {
  546. return Container(
  547. width: double.infinity,
  548. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  549. height: 88,
  550. child: RaisedButton(
  551. disabledColor: Color(0xFF1990F8),
  552. disabledTextColor: Color(0xFF252532),
  553. child: Text(
  554. '预计' + getSecondsMIn(_time) + '后开始',
  555. style: TextStyle(fontSize: 16),
  556. ),
  557. onPressed: null,
  558. ),
  559. );
  560. }
  561. } else if (isJoin && statusFlag == 8) {
  562. return Container(
  563. width: double.infinity,
  564. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  565. height: 88,
  566. child: RaisedButton(
  567. disabledColor: Color(0xFF1990F8),
  568. disabledTextColor: Color(0xFF252532),
  569. child: Text(
  570. '正在努力解析视频中',
  571. style: TextStyle(fontSize: 16),
  572. ),
  573. onPressed: null,
  574. ),
  575. );
  576. } else if (isJoin && (statusFlag == 2 || statusFlag == 3)) {
  577. int _time;
  578. if (houseInfo != null) {
  579. _time = houseInfo.beginTime + 3600000 - DateTime.now().millisecondsSinceEpoch;
  580. }
  581. return Container(
  582. width: double.infinity,
  583. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  584. height: 88,
  585. child: RaisedButton(
  586. disabledColor: Color(0xFF1990F8),
  587. disabledTextColor: Color(0xFF252532),
  588. child: Text(
  589. '最迟在' + getSecondsMIn(_time) + '后结算',
  590. style: TextStyle(fontSize: 16),
  591. ),
  592. onPressed: null,
  593. ),
  594. );
  595. } else if (statusFlag == 4 && tabIndex == 0) {
  596. return Container(
  597. width: double.infinity,
  598. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  599. height: 88,
  600. child: RaisedButton(
  601. disabledColor: Color(0xFF1990F8),
  602. disabledTextColor: Color(0xFF15151D),
  603. child: Text(
  604. '已结束',
  605. style: TextStyle(fontSize: 16),
  606. ),
  607. onPressed: null,
  608. ),
  609. );
  610. } else if (statusFlag == 4 && tabIndex == 1) {
  611. return Builder(
  612. builder: (context) {
  613. return Container(
  614. height: 48,
  615. color: SUB_COLOR,
  616. child: Row(
  617. children: <Widget>[
  618. Container(
  619. width: 57,
  620. child: Center(
  621. child: Container(
  622. width: 22,
  623. height: 22,
  624. color: PRIMARY_COLOR,
  625. child: Center(
  626. child: Text(
  627. myRank.toString(),
  628. style: TextStyle(fontSize: 12, color: Colors.white),
  629. ),
  630. )),
  631. )),
  632. Container(
  633. width: 30,
  634. height: 30,
  635. margin: EdgeInsets.only(right: 10),
  636. child: CircleAvatar(
  637. backgroundImage: NetworkImage(StoreProvider.of<AppState>(context).state.userInfo.icon),
  638. ),
  639. ),
  640. Expanded(
  641. flex: 1,
  642. child: Text(
  643. StoreProvider.of<AppState>(context).state.userInfo.nickname,
  644. style: TextStyle(
  645. fontSize: 14,
  646. color: Colors.white,
  647. ),
  648. ),
  649. ),
  650. _myUrl != null
  651. ? Container(
  652. width: 68,
  653. height: 24,
  654. margin: EdgeInsets.only(right: 10),
  655. child: OutlineButton(
  656. textColor: BG_SUB_COLOR,
  657. borderSide: BorderSide(color: BG_SUB_COLOR),
  658. padding: EdgeInsets.all(0),
  659. highlightColor: PRIMARY_COLOR.withOpacity(0.8),
  660. highlightedBorderColor: BG_SUB_COLOR,
  661. child: Text(
  662. '查看回放',
  663. style: TextStyle(fontSize: 12),
  664. ),
  665. onPressed: () {
  666. Navigator.push(context, CupertinoPageRoute(builder: (context) => VideoPlayerPage(videoUrl: _myUrl, fileType: 'file')));
  667. },
  668. ),
  669. )
  670. : Container()
  671. ],
  672. ),
  673. );
  674. },
  675. );
  676. } else {
  677. return Container();
  678. }
  679. }
  680. }
  681. //房间的提示信息
  682. class TipsListContent extends StatelessWidget {
  683. TipsListContent({Key key, this.tipsList, this.houseInfo}) : super(key: key);
  684. final List<List<String>> tipsList;
  685. final HouseInfo houseInfo;
  686. @override
  687. Widget build(BuildContext context) {
  688. return Container(
  689. margin: EdgeInsets.only(top: 15),
  690. width: double.infinity,
  691. child: Column(
  692. children: _list(),
  693. ),
  694. );
  695. }
  696. List<Widget> _list() {
  697. List<Widget> myList = [];
  698. for (int i = 0; i < tipsList.length; i++) {
  699. myList.add(Tips(content: tipsList[i], showTongzhi: (tipsList[i].length == 1 && i == 0) ? true : false, houseInfo: houseInfo));
  700. }
  701. return myList;
  702. }
  703. }
  704. class Tips extends StatelessWidget {
  705. Tips({Key key, this.content, this.showTongzhi, this.houseInfo}) : super(key: key);
  706. final List<String> content;
  707. final bool showTongzhi;
  708. final HouseInfo houseInfo;
  709. @override
  710. Widget build(BuildContext context) {
  711. return Container(
  712. padding: EdgeInsets.all(15),
  713. margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
  714. color: Color(0xFF293354),
  715. child: Column(
  716. children: <Widget>[
  717. content.length == 1
  718. ? Text(
  719. content[0],
  720. style: TextStyle(color: Colors.white, fontSize: 13),
  721. )
  722. : _textList(),
  723. showTongzhi
  724. ? FlatButton(
  725. padding: EdgeInsets.all(0),
  726. textColor: PRIMARY_COLOR,
  727. highlightColor: Colors.transparent,
  728. splashColor: Colors.transparent,
  729. child: Text(
  730. '查看竞赛须知',
  731. style: TextStyle(
  732. decoration: TextDecoration.underline,
  733. ),
  734. ),
  735. onPressed: () {
  736. showNotice(context);
  737. },
  738. )
  739. : Container()
  740. ],
  741. ));
  742. }
  743. Widget _textList() {
  744. return Text.rich(TextSpan(
  745. style: TextStyle(color: Colors.white, fontSize: 13),
  746. children: [
  747. TextSpan(text: content[0]),
  748. TextSpan(
  749. text: content[1],
  750. style: TextStyle(color: PRIMARY_COLOR, fontSize: 13, fontWeight: FontWeight.bold),
  751. ),
  752. TextSpan(text: content[2]),
  753. TextSpan(text: content[3]),
  754. TextSpan(text: content[4])
  755. ],
  756. ));
  757. }
  758. }
  759. //比赛结束排名
  760. class RankContent extends StatefulWidget {
  761. RankContent({Key key, this.roomId}) : super(key: key);
  762. final String roomId; // 用来储存传递过来的值
  763. @override
  764. RankContentState createState() => RankContentState();
  765. }
  766. class RankContentState extends State<RankContent> {
  767. List<PlayerInfo> topList = [];
  768. Future<void> getTopList() async {
  769. Toast.show(context, '加载中', -1, 'loading');
  770. Result res = await HttpManager.get('playerInfo/rankPage', data: {'houseId': widget.roomId, 'currentPage': 1, 'pageNumber': 3});
  771. Toast.hide();
  772. List<PlayerInfo> list = [];
  773. if (res.success) {
  774. for (var item in res.data['pp']) {
  775. PlayerInfo jonPlayer = PlayerInfo.fromJson(item);
  776. list.add(jonPlayer);
  777. }
  778. } else {}
  779. setState(() {
  780. topList = list;
  781. });
  782. }
  783. @override
  784. void initState() {
  785. super.initState();
  786. Future.delayed(Duration.zero, () {
  787. getTopList();
  788. });
  789. }
  790. @override
  791. Widget build(BuildContext context) {
  792. return Container(
  793. width: double.infinity,
  794. height: 180,
  795. margin: EdgeInsets.only(top: 15),
  796. child: Row(
  797. mainAxisAlignment: MainAxisAlignment.center,
  798. crossAxisAlignment: CrossAxisAlignment.end,
  799. children: <Widget>[_rankItem(2), _rankItem(1), _rankItem(3)],
  800. ),
  801. );
  802. }
  803. Widget _rankItem(int _num) {
  804. if (_num > topList.length) {
  805. return Container(
  806. width: 107,
  807. height: 60,
  808. );
  809. }
  810. List colorList = [
  811. [Color(0xFFD48E00), Color(0xFFFECF01)],
  812. [Color(0xFFC5C5C5), Color(0xFFE3E3E3)],
  813. [Color(0xFFE77023), Color(0xFFF89E58)]
  814. ];
  815. return Container(
  816. padding: EdgeInsets.only(left: 15, right: 15, top: _num == 1 ? 0 : 15),
  817. width: 107,
  818. child: Column(
  819. crossAxisAlignment: CrossAxisAlignment.center,
  820. children: <Widget>[
  821. Container(
  822. child: Stack(
  823. children: <Widget>[
  824. Positioned(
  825. top: 0,
  826. left: _num == 1 ? 19 : 14,
  827. child: Center(
  828. child: Image.asset(
  829. 'images/icon_paihangbang_0' + '$_num.png',
  830. width: 32,
  831. ),
  832. ),
  833. ),
  834. Container(
  835. margin: EdgeInsets.only(top: 27, bottom: 20),
  836. width: _num == 1 ? 70 : 60,
  837. height: _num == 1 ? 70 : 60,
  838. decoration: BoxDecoration(
  839. gradient: LinearGradient(colors: colorList[_num - 1], begin: Alignment.topLeft, end: Alignment.bottomRight),
  840. borderRadius: BorderRadius.all(Radius.circular(100)),
  841. ),
  842. child: Center(
  843. child: Container(
  844. width: _num == 1 ? 60 : 50,
  845. height: _num == 1 ? 60 : 50,
  846. child: CircleAvatar(backgroundImage: NetworkImage(topList[_num - 1].userInfo.icon)),
  847. )),
  848. ),
  849. Positioned(
  850. bottom: 0,
  851. child: Center(
  852. child: Image.asset(
  853. 'images/ph_yinpai_no' + '$_num.png',
  854. width: 67,
  855. ),
  856. ),
  857. ),
  858. ],
  859. ),
  860. ),
  861. Text(
  862. topList[_num - 1].userInfo.nickname,
  863. style: TextStyle(
  864. color: Color(0xFFFDC372),
  865. fontSize: 12,
  866. ),
  867. overflow: TextOverflow.ellipsis,
  868. textAlign: TextAlign.center,
  869. ),
  870. SizedBox(
  871. height: 5,
  872. ),
  873. Row(
  874. mainAxisAlignment: MainAxisAlignment.center,
  875. children: <Widget>[
  876. Image.asset('images/icon_jifen.png', width: 20),
  877. Text('×' + (topList[_num - 1].points != null ? topList[_num - 1].points.toString() : '0'), style: TextStyle(color: PRIMARY_COLOR, fontSize: 12))
  878. ],
  879. )
  880. ],
  881. ),
  882. );
  883. }
  884. }