RoomInfo.dart 37 KB

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