RoomInfo.dart 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  1. import 'dart:async';
  2. import 'dart:io';
  3. import 'dart:ui';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/painting.dart';
  6. import 'package:flutter_screenutil/flutter_screenutil.dart';
  7. import 'package:intl/intl.dart';
  8. import 'package:url_launcher/url_launcher.dart';
  9. import 'package:battery/battery.dart';
  10. import 'package:flutter_redux/flutter_redux.dart';
  11. import 'package:flutter/cupertino.dart';
  12. import '../styles/colors.dart';
  13. import 'package:screen_stream_plugin/screen_stream_plugin.dart';
  14. import '../net/HttpManager.dart';
  15. import '../net/Result.dart';
  16. import '../redux/AppState.dart';
  17. import '../model/HouseInfo.dart';
  18. import '../styles/totast.dart';
  19. import 'StartWindow.dart';
  20. import '../model/PlayerInfo.dart';
  21. import '../widget/VideoWidget.dart';
  22. import '../widget/Dialog.dart';
  23. import 'CompetitionInformation.dart';
  24. import 'SecondRoomInfo.dart';
  25. import 'VideoPlayer.dart';
  26. import '../model/UserInfo.dart';
  27. import '../widget/LinearButton.dart';
  28. import 'Appeal.dart';
  29. import 'ShoppingMall.dart';
  30. import '../redux/UserRedux.dart';
  31. class RoomInfo extends StatefulWidget {
  32. RoomInfo({Key key, this.roomId}) : super(key: key);
  33. final String roomId; // 用来储存传递过来的值
  34. @override
  35. RoomInfoState createState() => RoomInfoState();
  36. }
  37. class RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin {
  38. List<Map> tabList;
  39. TabController mController;
  40. Map roomInfo;
  41. HouseInfo houseInfo;
  42. Map colorInfo;
  43. bool isJoin = true;
  44. PlayerInfo playerInfo;
  45. bool isPop = false;
  46. bool showBack = false;
  47. Timer timer;
  48. List<List<Map>> roomTipsList = [];
  49. ScrollController _tipController;
  50. String _myUrl;
  51. int tabIndex = 0;
  52. UserInfo userInfo;
  53. int myRank = 0;
  54. String mymedal = '';
  55. bool canAppeal = false;
  56. int appealState = 0;
  57. bool showJiexie = false;
  58. bool showHelloWord = false;
  59. bool showWait = false;
  60. num race = 10;
  61. HttpServer server;
  62. //获取房间信息
  63. Future<void> getRoomInfo(type) async {
  64. print('现在时间:' + DateTime.now().millisecondsSinceEpoch.toString());
  65. Toast.show(context, '加载中', -1, 'loading');
  66. Result res = await HttpManager.get('houseInfo/getOne', data: {'id': widget.roomId});
  67. Toast.hide();
  68. if (res.success) {
  69. setState(() {
  70. roomInfo = res.data;
  71. houseInfo = HouseInfo.fromJson(res.data);
  72. });
  73. // showNotice();
  74. if (houseInfo.statusFlag == 0 && houseInfo.userId != StoreProvider.of<AppState>(context).state.userInfo.id) {
  75. showNotice();
  76. }
  77. if (houseInfo.statusFlag < 2 && type == 'first') {
  78. final battery = Battery();
  79. final batteryLevel = await battery.batteryLevel;
  80. await MyDialog.showDialog(context, (batteryLevel < 50 ? '系统检测到你的电量低于50%' : '') + ' 为了正常上传比赛结果,建议插上电源线保持电量充足', submitText: '知道了');
  81. }
  82. } else {}
  83. checkJoinInfo();
  84. }
  85. //开始比赛
  86. Future<void> startGame() async {
  87. Toast.show(context, '加载中', -1, 'loading');
  88. Result res = await HttpManager.post('houseInfo/handBegin', data: {'id': widget.roomId});
  89. Toast.hide();
  90. }
  91. //隔一秒检查是否开始
  92. Future<void> getNowStatus() async {
  93. print('检查执行');
  94. Result res = await HttpManager.get('houseInfo/getPlayerNum', data: {'id': widget.roomId});
  95. if (res.success) {
  96. if (houseInfo.statusFlag == 0 && res.data['statusFlag'] == 2) {
  97. showStart();
  98. // timer.cancel();
  99. }
  100. setState(() {
  101. houseInfo.playerNumber = res.data['playerNumber'];
  102. houseInfo.statusFlag = res.data['statusFlag'];
  103. houseInfo.bonus = res.data['bonus'];
  104. houseInfo.beginTime = res.data['beginTime'];
  105. });
  106. if (houseInfo.statusFlag == 4) {
  107. checkJoinInfo();
  108. } else if (!isJoin) {
  109. checkJoinInfo();
  110. }
  111. }
  112. }
  113. //开始比赛确认按钮
  114. Future<void> showStart() async {
  115. if (!isJoin) {
  116. return;
  117. }
  118. bool result = await Navigator.of(context).push<bool>(
  119. PageRouteBuilder(
  120. opaque: false,
  121. transitionDuration: Duration(milliseconds: 300),
  122. transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
  123. return FadeTransition(
  124. opacity: CurvedAnimation(parent: animation, curve: Curves.linear),
  125. child: child,
  126. );
  127. },
  128. pageBuilder: (BuildContext context, _, __) {
  129. return StartWindow();
  130. },
  131. ),
  132. );
  133. Map<String, dynamic> data = {'id': playerInfo.id};
  134. bool success = true;
  135. if (result) {
  136. success = await ScreenStreamPlugin.start(playerInfo.id.toString(), dialogMessage: '你是否已杀戮${playerInfo.needkill}人?');
  137. if (success) {
  138. data['beginTime'] = DateTime.now().millisecondsSinceEpoch;
  139. data['statusFlag'] = 2;
  140. data['played'] = true;
  141. } else {
  142. data['statusFlag'] = 6;
  143. data['played'] = false;
  144. }
  145. } else {
  146. data['statusFlag'] = 6;
  147. data['played'] = false;
  148. }
  149. Toast.show(context, '加载中', -1, 'loading');
  150. Result res = await HttpManager.post('playerInfo/update', data: data);
  151. Toast.hide();
  152. // MyDialog.showDialog(context, '自动启动游戏失败,请手动切换到游戏app开始竞赛', submitText: '知道了');
  153. // Timer(Duration(seconds: 10), () {
  154. // showSucessInfo();
  155. // });
  156. // return;
  157. if (res.success) {
  158. if (data['statusFlag'] == 2) {
  159. const url = 'pubgmhd1106467070://';
  160. if (await canLaunch(url)) {
  161. Timer(Duration(seconds: 1), () async {
  162. await launch(url);
  163. showSucessInfo(3);
  164. });
  165. } else {
  166. MyDialog.showDialog(context, '自动启动游戏失败,请手动切换到游戏app开始竞赛', submitText: '知道了');
  167. Timer(Duration(seconds: 10), () {
  168. showSucessInfo(3);
  169. });
  170. throw 'Could not launch $url';
  171. }
  172. } else {
  173. showBackDialog(success ? 1 : 0);
  174. }
  175. }
  176. }
  177. //开始录屏提示框
  178. void showSucessInfo(status) {
  179. MyDialog.showDialog(context, '',
  180. textList: [
  181. {"value": '您已经完成杀戮目标了吗?确定请点击', "isImportant": false},
  182. {"value": '“我已完成比赛”', "isImportant": true},
  183. {"value": '按钮。上传本次成绩,最后的名次稍后公布。祝您取得好成绩!', "isImportant": false}
  184. ],
  185. title: '完成比赛',
  186. submitText: '我已完成比赛', onsubmit: () async {
  187. HttpManager.post('playerInfo/gameOver', data: {'id': playerInfo.id, 'statusFlag': status, 'endTime': DateTime.now().millisecondsSinceEpoch});
  188. bool success = await ScreenStreamPlugin.stop();
  189. Timer(Duration(seconds: 1), () {
  190. getEndTips();
  191. });
  192. setState(() {
  193. playerInfo.statusFlag = 3;
  194. });
  195. });
  196. }
  197. Future<void> getEndTips() async {
  198. Result res = await HttpManager.get('playerInfo/endNum', data: {'houseId': widget.roomId});
  199. if (res.success) {
  200. int time = houseInfo.beginTime + 1 * 3600 * 1000 - DateTime.now().millisecondsSinceEpoch;
  201. var nowTime = (time ~/ 1000 ~/ 60) % 60;
  202. setState(() {
  203. showHelloWord = false;
  204. roomTipsList.add([
  205. {"value": '你已完成本次比赛,当前完成人数 ', "type": 0},
  206. {"value": res.data.toString(), "type": 1},
  207. {"value": '人,比赛需要等待其他人完成后方可结算奖励,你可以先去参加其他竞赛,稍后会有', "type": 0},
  208. {"value": '邮件', "type": 1},
  209. {"value": '提醒你本次竞赛结果以及领取奖励,请注意查看', "type": 0},
  210. {"value": '首页左上角邮件提醒', "type": 1},
  211. {"value": '哦', "type": 0}
  212. ]);
  213. showWait = true;
  214. changeScroll();
  215. });
  216. }
  217. }
  218. //未确认比赛弹窗
  219. void showBackDialog(type) {
  220. MyDialog.showDialog(context, (type == 1 ? '由于您未在十秒内点击开始按钮' : '由于您未授权录屏') + ',系统已经判定您放弃比赛,谢谢您的参与。', title: '很遗憾');
  221. }
  222. //检查加入信息
  223. Future<void> checkJoinInfo() async {
  224. Result res = await HttpManager.get('playerInfo/getOne', data: {'userId': StoreProvider.of<AppState>(context).state.userInfo.id, 'houseId': widget.roomId});
  225. if (res.success) {
  226. if (res.data == null) {
  227. setState(() {
  228. isJoin = false;
  229. });
  230. if (houseInfo.statusFlag == 0) {
  231. if (houseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
  232. // roomTipsList.add([{
  233. // "value":'房间创建成功,待人数满员时会自动开启比赛,房主也可以手动开启比赛,同时,你也可以加入本次比赛',
  234. // "type":0
  235. // }]);
  236. changeScroll();
  237. }
  238. if (!showHelloWord) {
  239. setState(() {
  240. showHelloWord = true;
  241. });
  242. // if (isJoin) {
  243. // roomTipsList.add([{
  244. // "value":'亲爱的玩家:',
  245. // }]);
  246. // }
  247. changeScroll();
  248. }
  249. }
  250. } else {
  251. // if (houseInfo.statusFlag == 0) {
  252. // roomTipsList
  253. // .add(['待倒计时结束或人数满员时会自动开启比赛,请在此页面耐心等待其他人的加入,加入房间后再次退出则视为自动放弃比赛。', '由于部分手机在低电量情况下无法在后台正常运行竞赛APP,为了你比赛数据的正常获取,请保持手机电量在50%以上', '', '', '']);
  254. // }
  255. playerInfo = PlayerInfo.fromJson(res.data);
  256. if (playerInfo.medal != null) {
  257. mymedal = res.data['medal'];
  258. }
  259. if (houseInfo.statusFlag == 4) {
  260. _myUrl = await ScreenStreamPlugin.getVideo(playerInfo.id.toString());
  261. print('本地视频' + playerInfo.id.toString());
  262. print(_myUrl);
  263. Result rankRes = await HttpManager.get('playerInfo/userRank', data: {'id': playerInfo.id});
  264. if (rankRes.success) {
  265. myRank = rankRes.data + 1;
  266. }
  267. }
  268. setState(() {
  269. isJoin = true;
  270. });
  271. if (houseInfo.statusFlag == 0) {
  272. // if (houseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
  273. // roomTipsList.add(['房间创建成功,待人数满员时会自动开启比赛,房主也可以手动开启比赛,请在此页面耐心等待其他人的加入,加入房间后再次退出则视为自动放弃比赛,已支付金币概不退换,快快点击右上角分享给好友加入战局吧']);
  274. // changeScroll();
  275. // } else {
  276. // roomTipsList.add([
  277. // '请在此页面耐心等待,竞赛即将开始,届时玩家有10秒的时间进行确认,点击确认方可正式进入竞赛,若没有点击,则视为自动放弃此次竞赛,已支付金币概不退换'
  278. // ]);
  279. // changeScroll();
  280. // }
  281. // Timer(Duration(seconds: 1), () {
  282. // roomTipsList.add([
  283. // '游戏开始后会有弹窗提示授权进行录屏的操作,',
  284. // '请一定点击“确定”或“允许”此操作',
  285. // ',系统会自动跳转打开游戏app,若长时间没有自动跳转,请手动打开游戏app进行比赛,在游戏比赛结束后,请',
  286. // '���定要点击查看游戏最后的��数名次结算页面',
  287. // ',返回游戏主页,最后再切换到我们竞赛app中,点击完成比赛,方可成功上传本次成绩。从游戏开始一小时之内必须返回全民App点击完成比赛,否则判定游戏失败,祝你取得好成绩。'
  288. // ]);
  289. // changeScroll();
  290. // });
  291. } else if (houseInfo.statusFlag != 4) {
  292. if (playerInfo.statusFlag == 3 || playerInfo.statusFlag == 8 || playerInfo.statusFlag == 9) {
  293. getEndTips();
  294. }
  295. }
  296. }
  297. }
  298. if (isJoin && houseInfo.statusFlag != 4 || houseInfo.statusFlag == 0) {
  299. print('检查1');
  300. if (timer != null) {
  301. timer.cancel();
  302. }
  303. timer = Timer.periodic(Duration(seconds: 1), (timer) {
  304. print('检查');
  305. if (houseInfo.statusFlag == 4) {
  306. timer.cancel();
  307. } else {
  308. getNowStatus();
  309. }
  310. });
  311. }
  312. if (isJoin && houseInfo.statusFlag == 4) {
  313. setState(() {
  314. showJiexie = true;
  315. });
  316. //申诉
  317. HttpManager.get('appealInfo/getOne', data: {
  318. 'userId': StoreProvider.of<AppState>(context).state.userInfo.id,
  319. 'playerInfoId': playerInfo.id,
  320. }).then((res) {
  321. if (res.success && res.data != null) {
  322. setState(() {
  323. canAppeal = true;
  324. appealState = 1;
  325. });
  326. } else {
  327. setState(() {
  328. canAppeal = true;
  329. appealState = 0;
  330. });
  331. }
  332. });
  333. }
  334. if (houseInfo.statusFlag == 2 && playerInfo.beginTime != null && playerInfo.endTime == null) {
  335. showSucessInfo(9);
  336. }
  337. }
  338. //加入房间
  339. Future<void> joinRoom() async {
  340. UserInfo myUser;
  341. Toast.show(context, '加载中', -1, 'loading');
  342. Result res2 = await HttpManager.get('userInfo/getUserInfo');
  343. if (res2.success) {
  344. StoreProvider.of<AppState>(context).dispatch(UpdateUserAction(UserInfo.fromJson(res2.data)));
  345. myUser = UserInfo.fromJson(res2.data);
  346. } else {}
  347. Toast.hide();
  348. if (myUser.moneyTicket < houseInfo.houseLevel.entryCoin) {
  349. MyDialog.showDialog(context, '门票不足不能加入', onsubmit: () async {
  350. Result res = await HttpManager.get('systemVariable/get', data: {'name': "iosPayHide"});
  351. if (Platform.isIOS && res.data != null && res.data == 'true') {
  352. MyDialog.showDialog(context, 'ios充值暂未开放');
  353. } else {
  354. Navigator.push(context, CupertinoPageRoute(builder: (context) => ShoppingMall()));
  355. }
  356. });
  357. return;
  358. }
  359. MyDialog.showDialog(context, '加入房间后再次退出则示为自动放弃比赛', submitText: '确认加入', isCancel: true, onsubmit: () async {
  360. Toast.show(context, '加载中', -1, 'loading');
  361. Result res = await HttpManager.post('houseInfo/join', data: {'houseId': widget.roomId, 'userId': StoreProvider.of<AppState>(context).state.userInfo.id});
  362. Toast.hide();
  363. if (res.success) {
  364. bool hasPermission = await ScreenStreamPlugin.checkPermission();
  365. if (!hasPermission) {
  366. showDialog(
  367. context: context,
  368. builder: (context) => AlertDialog(
  369. title: Text('需要悬浮窗权限'),
  370. contentTextStyle: TextStyle(color: Colors.black87),
  371. content: Text('请在点击确定后,勾选"允许显示在其他应用的上层"'),
  372. actions: <Widget>[
  373. FlatButton(
  374. child: Text('确定'),
  375. onPressed: () {
  376. Navigator.of(context).pop();
  377. ScreenStreamPlugin.requestPermission();
  378. },
  379. ),
  380. ],
  381. ),
  382. );
  383. return;
  384. } else {
  385. Toast.show(context, '加入成功', 1500, 'success');
  386. }
  387. } else {
  388. Toast.show(context, res.error, 1500, 'info');
  389. }
  390. });
  391. }
  392. //展示通知
  393. void showNotice() {
  394. Navigator.of(context).push(PageRouteBuilder(
  395. opaque: false,
  396. transitionDuration: Duration(milliseconds: 300),
  397. transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
  398. return FadeTransition(
  399. opacity: CurvedAnimation(parent: animation, curve: Curves.linear),
  400. child: child,
  401. );
  402. },
  403. pageBuilder: (BuildContext context, _, __) {
  404. return CompetitionInformation(houseInfo: houseInfo);
  405. }));
  406. }
  407. //改变滚动条
  408. void changeScroll() {
  409. Timer(Duration(seconds: 1), () {
  410. _tipController.animateTo(context.size.height, duration: Duration(milliseconds: 1500), curve: Curves.ease);
  411. });
  412. }
  413. //获取分秒
  414. String getSecondsMIn(int time) {
  415. if (time == null) {
  416. return '';
  417. } else {
  418. return ((time ~/ 1000 ~/ 60) % 60).toString() + '分' + (time ~/ 1000 % 60).toString() + '秒';
  419. }
  420. }
  421. @override
  422. void initState() {
  423. super.initState();
  424. tabList = [
  425. {'title': '房间信息', 'value': 1},
  426. {'title': '人员列表', 'value': 2}
  427. ];
  428. mController = TabController(
  429. length: tabList.length,
  430. vsync: this,
  431. );
  432. mController.addListener(() {
  433. setState(() {
  434. tabIndex = mController.index;
  435. });
  436. print(tabIndex);
  437. });
  438. _tipController = ScrollController();
  439. roomInfo = {};
  440. colorInfo = {
  441. '黄金': Color(0xFFF9D881),
  442. '白银': Color(0xFFAFCAD8),
  443. '青铜': Color(0xFFE18D50),
  444. };
  445. Future.delayed(Duration.zero, () async {
  446. Result res2 = await HttpManager.get('systemVariable/get', data: {'name': "ticketPrice"});
  447. if (res2.success) {
  448. print(res2.data);
  449. setState(() {
  450. race = double.parse(res2.data);
  451. });
  452. }
  453. // showSucessInfo(3);
  454. getRoomInfo('first');
  455. userInfo = StoreProvider.of<AppState>(context).state.userInfo;
  456. // showStart();
  457. });
  458. if (timer != null) {
  459. timer.cancel();
  460. }
  461. HttpServer.bind(InternetAddress.anyIPv4, 8899).then((s) {
  462. server = s;
  463. s.listen((HttpRequest request) {
  464. request.response.write('rtmp://202.79.174.56:1935/myapp/${playerInfo.id}?playerInfoId=${playerInfo.id}');
  465. request.response.close();
  466. });
  467. });
  468. }
  469. @override
  470. void dispose() {
  471. super.dispose();
  472. mController.dispose();
  473. if (timer != null) {
  474. timer.cancel();
  475. }
  476. if (server != null) {
  477. server.close(force: true);
  478. }
  479. }
  480. @override
  481. Widget build(BuildContext context) {
  482. ScreenUtil.instance = ScreenUtil(width: 375, height: 667)..init(context);
  483. int status = 0;
  484. if (houseInfo != null) {
  485. status = houseInfo.statusFlag;
  486. }
  487. return WillPopScope(
  488. child: Scaffold(
  489. appBar: AppBar(
  490. title: Container(
  491. child: TabBar(
  492. controller: mController,
  493. labelColor: Color(0xFFD4504B),
  494. unselectedLabelColor: Colors.white.withOpacity(0.5),
  495. labelStyle: TextStyle(fontSize: 16.0),
  496. indicatorColor: Color(0xFFC44D4B),
  497. indicatorWeight: 3,
  498. indicatorSize: TabBarIndicatorSize.label,
  499. tabs: tabList.map((item) {
  500. return Tab(
  501. text: item['title'],
  502. );
  503. }).toList(),
  504. ),
  505. ),
  506. centerTitle: true,
  507. elevation: 0,
  508. actions: <Widget>[
  509. Container(
  510. padding: EdgeInsets.only(right: 30, left: 20),
  511. child: Container(
  512. width: 24,
  513. ))
  514. ],
  515. ),
  516. body: Container(
  517. color: Color(0xFF2E3049),
  518. child: TabBarView(
  519. controller: mController,
  520. children: [_firstPage(), SecondPage(roomId: widget.roomId, status: status, houseInfo: houseInfo)],
  521. )),
  522. floatingActionButton: _joinBtn(),
  523. floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
  524. ),
  525. onWillPop: () {
  526. if (houseInfo == null || (houseInfo.statusFlag != 0) || !isJoin) {
  527. if (timer != null) {
  528. timer.cancel();
  529. }
  530. isPop = true;
  531. Toast.hide();
  532. Navigator.of(context).pop(true);
  533. return Future.value(false);
  534. } else {
  535. Toast.show(context, '比赛即将开始,暂不能离开房间', 1500, 'info');
  536. }
  537. return Future.value(false);
  538. },
  539. );
  540. }
  541. Widget _firstPage() {
  542. Map houseLevelInfo = roomInfo.isNotEmpty ? roomInfo['houseLevelInfo'] : {};
  543. String levelName = houseLevelInfo.containsKey('levelName') ? houseLevelInfo['levelName'] : '黄金';
  544. int joinMoney = houseLevelInfo.containsKey('feeRatio') && roomInfo.containsKey('bonus') ? houseLevelInfo['feeRatio'] * roomInfo['bonus'] : 0;
  545. String topImg = 'http://images.liqucn.com/img/h22/h70/img_localize_8e824debdd9ee29522690f36680e2d8e_600x337.png';
  546. int statuFlag = 0;
  547. if (houseInfo != null) {
  548. if (houseInfo.video != null) {
  549. topImg = houseInfo.video;
  550. }
  551. if (houseInfo.statusFlag != null) {
  552. statuFlag = houseInfo.statusFlag;
  553. }
  554. }
  555. String timeStr = '';
  556. int _time;
  557. if (houseInfo == null) {
  558. } else if (houseInfo.statusFlag == 0) {
  559. //房价未开始比赛
  560. _time = houseInfo.createTime + 600000 - DateTime.now().millisecondsSinceEpoch;
  561. timeStr = '最迟 ${getSecondsMIn(_time)} 后自动开始比赛';
  562. }
  563. // else if (isJoin && (houseInfo.statusFlag == 2 || houseInfo.statusFlag == 3)) {
  564. // _time = houseInfo.beginTime + 3600000 - DateTime.now().millisecondsSinceEpoch;
  565. // timeStr = '最迟 ${getSecondsMIn(_time)} 后结算';
  566. // }
  567. List jiangpaiImg = ['images/jiangpai_huangjin.png', 'images/jiangpai_baiyin.png', 'images/jiangpai_qingtong.png', 'images/jiangpai_bojin.png'];
  568. String img = '';
  569. if (playerInfo != null) {
  570. if (playerInfo.medal == 'platinum') {
  571. img = jiangpaiImg[3];
  572. } else if (playerInfo.medal == 'gold') {
  573. img = jiangpaiImg[0];
  574. } else if (playerInfo.medal == 'silver') {
  575. img = jiangpaiImg[1];
  576. } else if (playerInfo.medal == 'bronze') {
  577. img = jiangpaiImg[2];
  578. }
  579. }
  580. return LayoutBuilder(
  581. builder: (BuildContext context, BoxConstraints viewportConstraints) {
  582. return Container(
  583. child: RefreshIndicator(
  584. color: PRIMARY_COLOR,
  585. backgroundColor: Colors.white,
  586. displacement: 10,
  587. onRefresh: () async {
  588. await Future.delayed(const Duration(seconds: 1));
  589. },
  590. child: houseInfo != null
  591. ? SingleChildScrollView(
  592. controller: _tipController,
  593. physics: AlwaysScrollableScrollPhysics(),
  594. child: Column(
  595. children: <Widget>[
  596. houseInfo != null ? VideoWidget(videoSrc: houseInfo.video) : Container(),
  597. // Image.network(topImg, width: double.infinity),
  598. Container(
  599. padding: EdgeInsets.all(15),
  600. child: Row(
  601. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  602. children: <Widget>[
  603. Container(
  604. child: Text(
  605. houseInfo != null ? houseInfo.houseName : '',
  606. style: TextStyle(color: Colors.white, fontSize: 20, fontWeight: FontWeight.w600),
  607. ),
  608. ),
  609. Container(
  610. width: 66,
  611. child: LinearButton(
  612. btntext: '竞赛须知',
  613. btnHeight: 28.0,
  614. textColor: Color(0xFF2E3049),
  615. textSize: 12.0,
  616. colorList: [Color(0xFFFFB726), Color(0xFFFFB726)],
  617. onTapHomeMenu: () {
  618. showNotice();
  619. },
  620. ),
  621. )
  622. // Container(
  623. // width: 5,
  624. // ),
  625. // houseInfo != null ? ScoreType(houseInfo.scoreType) : Container(),
  626. // Image.network(
  627. // houseLevelInfo.containsKey('icon')
  628. // ? houseLevelInfo['icon']
  629. // : '',
  630. // width: 14,
  631. // ),
  632. // Text(
  633. // houseLevelInfo.containsKey('levelName')
  634. // ? houseLevelInfo['levelName']
  635. // : '',
  636. // style:
  637. // TextStyle(color: colorInfo[levelName]),
  638. // )
  639. ],
  640. )),
  641. Container(
  642. padding: EdgeInsets.symmetric(horizontal: 15),
  643. child: Row(
  644. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  645. children: <Widget>[
  646. Text(
  647. '本次任务:游戏中最短时间内杀戮${houseInfo.killnumber}人',
  648. style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Color(0xFFFFB726)),
  649. ),
  650. Row(
  651. children: <Widget>[
  652. Image.asset(
  653. 'images/icon_renshu.png',
  654. ),
  655. Text(
  656. (houseInfo != null ? (houseInfo.playerNumber ?? 0).toString() : '0') +
  657. '/' +
  658. (houseInfo != null ? houseInfo.maxNumber.toString() : '0'),
  659. style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFFB1B2C0)),
  660. ),
  661. ],
  662. ),
  663. // Row(
  664. // children: <Widget>[
  665. // Image.asset(
  666. // 'images/house2.png',
  667. // ),
  668. // Text(
  669. // 'X${houseInfo.bonus}',
  670. // style: TextStyle(fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xFFB1B2C0)),
  671. // ),
  672. // ],
  673. // ),
  674. // Container(
  675. // width: 30,
  676. // ),
  677. // Container(
  678. // width: 10,
  679. // ),
  680. ],
  681. ),
  682. ),
  683. Container(
  684. padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
  685. margin: EdgeInsets.fromLTRB(15, 7, 15, 0),
  686. decoration: BoxDecoration(color: Color(0xFF23253C), borderRadius: BorderRadius.all(Radius.circular(4))),
  687. child: Column(
  688. crossAxisAlignment: CrossAxisAlignment.start,
  689. children: <Widget>[
  690. Row(
  691. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  692. children: <Widget>[
  693. Column(
  694. children: <Widget>[
  695. Row(
  696. children: <Widget>[
  697. Image.asset('images/icon_jifen.png'),
  698. Text(
  699. 'x${houseInfo.bonus * houseInfo.houseLevel.firstRatio / 100}/${houseInfo.maxNumber * race * houseInfo.houseLevel.entryCoin * houseInfo.houseLevel.firstRatio / 100}',
  700. style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
  701. )
  702. ],
  703. ),
  704. Container(
  705. height: 3,
  706. ),
  707. Text('第一名', style: TextStyle(fontSize: 12, color: Color(0xFFB1B2C0)))
  708. ],
  709. ),
  710. Column(
  711. children: <Widget>[
  712. Row(
  713. children: <Widget>[
  714. Image.asset('images/icon_jifen.png'),
  715. Text(
  716. 'x${houseInfo.bonus * houseInfo.houseLevel.secondRatio / 100}/${houseInfo.maxNumber * race * houseInfo.houseLevel.entryCoin * houseInfo.houseLevel.secondRatio / 100}',
  717. style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
  718. )
  719. ],
  720. ),
  721. Container(
  722. height: 3,
  723. ),
  724. Text('第二名', style: TextStyle(fontSize: 12, color: Color(0xFFB1B2C0)))
  725. ],
  726. ),
  727. Column(
  728. children: <Widget>[
  729. Row(
  730. children: <Widget>[
  731. Image.asset('images/icon_jifen.png'),
  732. Text(
  733. 'x${houseInfo.bonus * houseInfo.houseLevel.thirdRatio / 100}/${houseInfo.maxNumber * race * houseInfo.houseLevel.entryCoin * houseInfo.houseLevel.thirdRatio / 100}',
  734. style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500),
  735. )
  736. ],
  737. ),
  738. Container(
  739. height: 3,
  740. ),
  741. Text('第三名', style: TextStyle(fontSize: 12, color: Color(0xFFB1B2C0)))
  742. ],
  743. )
  744. ],
  745. ),
  746. Container(
  747. height: 10,
  748. ),
  749. Text(
  750. '注:上方显示数值���前三名的“当前奖励/最高奖励”',
  751. style: TextStyle(color: Colors.white30, fontSize: 12),
  752. )
  753. ],
  754. )),
  755. timeStr != ''
  756. ? Container(
  757. decoration: BoxDecoration(
  758. color: Color(0xFF3E3348),
  759. borderRadius: BorderRadius.all(Radius.circular(4)),
  760. ),
  761. margin: EdgeInsets.fromLTRB(15, 15, 15, 0),
  762. padding: EdgeInsets.symmetric(vertical: 10),
  763. height: 40,
  764. width: double.infinity,
  765. child: Text(timeStr,
  766. textAlign: TextAlign.center, style: TextStyle(fontSize: 15, color: Color(0xFFD4504B), fontWeight: FontWeight.w500)),
  767. )
  768. : Container(),
  769. statuFlag != 4 && showWait
  770. ? Container(
  771. width: double.infinity,
  772. margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
  773. padding: EdgeInsets.symmetric(vertical: 10),
  774. height: 40,
  775. decoration: BoxDecoration(color: Color(0xFF3E3348), borderRadius: BorderRadius.all(Radius.circular(4))),
  776. child: Text(
  777. '你已完成比赛,等待游戏解析中',
  778. style: TextStyle(
  779. color: Color(0xFFD4504B),
  780. fontSize: 15,
  781. ),
  782. textAlign: TextAlign.center,
  783. ))
  784. : Container(),
  785. statuFlag != 4 && showHelloWord
  786. ? Container(
  787. width: double.infinity,
  788. padding: EdgeInsets.all(15),
  789. margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
  790. decoration: BoxDecoration(
  791. // gradient: LinearGradient(colors: [Color(0xFF464B6A), Color(0xFF35395E)], begin: Alignment.topCenter, end: Alignment.bottomCenter),
  792. color: Color(0xFF3A3E61),
  793. borderRadius:
  794. BorderRadius.only(topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8))),
  795. child: DefaultTextStyle(
  796. style: TextStyle(
  797. color: Colors.white,
  798. fontSize: 13.0,
  799. ),
  800. child: Column(
  801. crossAxisAlignment: CrossAxisAlignment.start,
  802. children: <Widget>[
  803. Text('亲爱的玩家:'),
  804. Text('欢迎来到有奖杀戮的世界!'),
  805. Text(
  806. '请保持手机电量在50%以上',
  807. style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xFFFFB726)),
  808. ),
  809. Text.rich(TextSpan(children: [
  810. TextSpan(text: '倒计时结束或人数满员时会'),
  811. TextSpan(
  812. text: '自动',
  813. style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xFFFFB726)),
  814. ),
  815. TextSpan(text: '开启比赛!请在此等候其他玩家加入')
  816. ])),
  817. Text.rich(TextSpan(children: [
  818. TextSpan(text: '完成本房间任务目标后,'),
  819. TextSpan(
  820. text: Platform.isIOS ? '切记立刻返回应用' : '切记立刻点击悬浮窗',
  821. style: TextStyle(fontWeight: FontWeight.w600, color: Color(0xFFFFB726)),
  822. ),
  823. TextSpan(text: '回到房间')
  824. ])),
  825. ],
  826. ),
  827. ))
  828. : Container(),
  829. statuFlag != 4
  830. ? TipsListContent(tipsList: roomTipsList, houseInfo: houseInfo)
  831. : Container(
  832. child: playerInfo != null && showJiexie
  833. ? Column(
  834. children: <Widget>[
  835. // ( playerInfo.statusFlag!=7&&playerInfo.statusFlag!=9&&!playerInfo.dataError)?
  836. Container(
  837. width: double.infinity,
  838. margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10),
  839. padding: EdgeInsets.symmetric(vertical: 10),
  840. height: 40,
  841. decoration: BoxDecoration(color: Color(0xFF3E3348), borderRadius: BorderRadius.all(Radius.circular(4))),
  842. child: Text(
  843. playerInfo.statusFlag == 7 ||
  844. playerInfo.statusFlag == 9 ||
  845. playerInfo.dataError ||
  846. playerInfo.statusFlag == 6 ||
  847. playerInfo.killNumber < playerInfo.needkill
  848. ? (playerInfo.statusFlag == 6 ? '很遗憾您本次未参赛' : '很遗憾您本次任务失败,下次加油!')
  849. : (playerInfo.houseRank < 4 ? '恭喜您,您获得了第${playerInfo.houseRank}名!' : '很遗憾您未能进入前三名,下次加油!'),
  850. style: TextStyle(
  851. color: Color(0xFFD4504B),
  852. fontSize: 15,
  853. ),
  854. textAlign: TextAlign.center,
  855. ),
  856. ),
  857. (playerInfo.statusFlag != 7 &&
  858. playerInfo.statusFlag != 9 &&
  859. !playerInfo.dataError &&
  860. playerInfo.statusFlag != 6 &&
  861. playerInfo.killNumber >= playerInfo.needkill)
  862. ? Container(
  863. margin: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
  864. padding: EdgeInsets.all(15),
  865. height: 140,
  866. decoration: BoxDecoration(
  867. color: Color(0xFF3A3E61),
  868. borderRadius: BorderRadius.only(
  869. topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8))),
  870. child: Column(
  871. crossAxisAlignment: CrossAxisAlignment.start,
  872. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  873. children: <Widget>[
  874. Text('比赛结果', style: TextStyle(color: Colors.white54, fontSize: 13)),
  875. Row(
  876. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  877. children: <Widget>[
  878. Text("参数成员 ", style: TextStyle(color: Colors.white, fontSize: 14)),
  879. Text("${houseInfo.playerNumber}人 ",
  880. style: TextStyle(color: Color(0xFFFFB726), fontWeight: FontWeight.w500, fontSize: 14))
  881. ],
  882. ),
  883. Row(
  884. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  885. children: <Widget>[
  886. Text("我的排名 ", style: TextStyle(color: Colors.white, fontSize: 14)),
  887. Text('${playerInfo.houseRank}',
  888. style: TextStyle(color: Color(0xFFFFB726), fontWeight: FontWeight.w500, fontSize: 14))
  889. ],
  890. ),
  891. Row(
  892. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  893. children: <Widget>[
  894. Text("获得积分 ", style: TextStyle(color: Colors.white, fontSize: 14)),
  895. Row(
  896. children: <Widget>[
  897. Image.asset('images/icon_jifen.png'),
  898. Text('x${playerInfo.bonus}',
  899. style: TextStyle(color: Color(0xFFFFB726), fontWeight: FontWeight.w500, fontSize: 14))
  900. ],
  901. )
  902. ],
  903. )
  904. ],
  905. ),
  906. )
  907. : playerInfo.statusFlag == 6
  908. ? Container(
  909. margin: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
  910. padding: EdgeInsets.all(15),
  911. // height: 239,
  912. width: double.infinity,
  913. decoration: BoxDecoration(
  914. color: Color(0xFF3A3E61),
  915. borderRadius: BorderRadius.only(
  916. topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8))),
  917. child: Column(
  918. crossAxisAlignment: CrossAxisAlignment.start,
  919. children: <Widget>[
  920. Text(
  921. '造成此情况等原因可能是:',
  922. style: TextStyle(color: Colors.white54, fontSize: 13),
  923. ),
  924. Container(
  925. height: 10,
  926. ),
  927. Text(
  928. '1、倒计时结束内未点击开始',
  929. style: TextStyle(color: Colors.white, fontSize: 13),
  930. ),
  931. ],
  932. ),
  933. )
  934. : Container(
  935. margin: EdgeInsets.symmetric(vertical: 10, horizontal: 15),
  936. padding: EdgeInsets.all(15),
  937. // height: 239,
  938. width: double.infinity,
  939. decoration: BoxDecoration(
  940. color: Color(0xFF3A3E61),
  941. borderRadius: BorderRadius.only(
  942. topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8))),
  943. child: Column(
  944. crossAxisAlignment: CrossAxisAlignment.start,
  945. children: <Widget>[
  946. Text(
  947. '造成此情况等原因可能是:',
  948. style: TextStyle(color: Colors.white54, fontSize: 13),
  949. ),
  950. Container(
  951. height: 10,
  952. ),
  953. Text(
  954. '1、游戏中杀戮人数未到房间任务要求',
  955. style: TextStyle(color: Colors.white, fontSize: 13),
  956. ),
  957. Text(
  958. '2、没有实际进行游戏比赛 ',
  959. style: TextStyle(color: Colors.white, fontSize: 13),
  960. ),
  961. Text(
  962. '3、使用作弊手段进行游戏 ',
  963. style: TextStyle(color: Colors.white, fontSize: 13),
  964. ),
  965. Text(
  966. '4、手机性能或电量过低,在运行和平精英游戏时自动将我们平台APP从后台进程中退掉 ',
  967. style: TextStyle(color: Colors.white, fontSize: 13),
  968. ),
  969. Text(
  970. '5、游戏时间过长,没有在最大时间内返回平台APP点击结束游戏 ',
  971. style: TextStyle(color: Colors.white, fontSize: 13),
  972. ),
  973. ],
  974. ),
  975. )
  976. ],
  977. )
  978. : Container(),
  979. ),
  980. Container(
  981. width: double.infinity,
  982. height: 78,
  983. )
  984. ],
  985. ),
  986. )
  987. : Container()),
  988. );
  989. },
  990. );
  991. }
  992. Widget _joinBtn() {
  993. int joinMoney = houseInfo != null ? houseInfo.houseLevel.entryCoin : 0;
  994. int statusFlag = houseInfo != null ? houseInfo.statusFlag : 1;
  995. int playerStatus = playerInfo != null ? playerInfo.statusFlag : 0;
  996. List jiangpaiImg = ['金牌', '银牌', '铜牌', '铂金'];
  997. String img = '';
  998. if (mymedal != null) {
  999. if (mymedal == 'platinum') {
  1000. img = jiangpaiImg[3];
  1001. } else if (mymedal == 'gold') {
  1002. img = jiangpaiImg[0];
  1003. } else if (mymedal == 'silver') {
  1004. img = jiangpaiImg[1];
  1005. } else if (mymedal == 'bronze') {
  1006. img = jiangpaiImg[2];
  1007. }
  1008. }
  1009. int entryCoin = houseInfo != null ? houseInfo.houseLevel.entryCoin : 0;
  1010. if (!isJoin && statusFlag == 0 && houseInfo.userId == StoreProvider.of<AppState>(context).state.userInfo.id) {
  1011. return Container(
  1012. padding: EdgeInsets.symmetric(vertical: 15, horizontal: 10),
  1013. child: Row(
  1014. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  1015. children: <Widget>[
  1016. Container(
  1017. width: 165,
  1018. child: LinearButton(
  1019. colorList: [Color(0xFF4F5386), Color(0xFF4F5386)],
  1020. childWidget: Row(
  1021. mainAxisAlignment: MainAxisAlignment.center,
  1022. children: <Widget>[
  1023. Image.asset(
  1024. 'images/icon_menpiao.png',
  1025. ),
  1026. Container(
  1027. margin: EdgeInsets.only(left: 6),
  1028. child: Text(
  1029. '×${entryCoin}',
  1030. style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
  1031. ),
  1032. ),
  1033. Container(
  1034. margin: EdgeInsets.only(left: 5),
  1035. child: Text(
  1036. '加入比赛',
  1037. style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
  1038. ))
  1039. ],
  1040. ),
  1041. onTapHomeMenu: () => joinRoom(),
  1042. ),
  1043. ),
  1044. Container(
  1045. width: 165,
  1046. child: LinearButton(
  1047. btntext: '开始竞赛',
  1048. onTapHomeMenu: () {
  1049. MyDialog.showDialog(context, '确认要开始比赛吗?', isCancel: true, onsubmit: () {
  1050. print('开始');
  1051. startGame();
  1052. });
  1053. },
  1054. ),
  1055. )
  1056. ],
  1057. ),
  1058. );
  1059. } else if (!isJoin && statusFlag == 0) {
  1060. return Container(
  1061. color: BG_SUB_COLOR,
  1062. width: ScreenUtil().setWidth(375),
  1063. height: 48 + ScreenUtil().setHeight(40),
  1064. padding: EdgeInsets.only(top: ScreenUtil().setHeight(20), bottom: ScreenUtil().setHeight(20), left: 15, right: 15),
  1065. child: LinearButton(
  1066. childWidget: Row(
  1067. mainAxisAlignment: MainAxisAlignment.center,
  1068. children: <Widget>[
  1069. Image.asset(
  1070. 'images/icon_menpiao.png',
  1071. width: 20,
  1072. ),
  1073. Container(
  1074. margin: EdgeInsets.only(left: 6),
  1075. child: Text(
  1076. '×${entryCoin}',
  1077. style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
  1078. ),
  1079. ),
  1080. Container(
  1081. margin: EdgeInsets.only(left: 20),
  1082. child: Text(
  1083. '加入比赛',
  1084. style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
  1085. ))
  1086. ],
  1087. ),
  1088. onTapHomeMenu: () => joinRoom(),
  1089. ),
  1090. );
  1091. } else if (!isJoin && statusFlag == 2) {
  1092. return Container(
  1093. width: double.infinity,
  1094. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1095. height: 88,
  1096. child: LinearButton(btntext: '房间已经开始,加入通道关闭', colorList: [Color(0xFFB34A4A), Color(0xFFB34A4A)], textColor: Color(0xFF252532))
  1097. // RaisedButton(
  1098. // disabledColor: Color(0xFFD4504B),
  1099. // disabledTextColor: Color(0xFF252532),
  1100. // child: Text(
  1101. // '房间已经开始,加入通道关闭',
  1102. // style: TextStyle(fontSize: 16),
  1103. // ),
  1104. // onPressed: null,
  1105. // ),
  1106. );
  1107. } else if (isJoin && statusFlag == 0) {
  1108. int _time;
  1109. if (houseInfo != null) {
  1110. _time = houseInfo.createTime + 600000 - DateTime.now().millisecondsSinceEpoch;
  1111. }
  1112. if (houseInfo != null && houseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
  1113. return Container(
  1114. width: double.infinity,
  1115. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1116. height: 88,
  1117. child: LinearButton(
  1118. childWidget: Center(
  1119. child: Text.rich(TextSpan(children: [
  1120. TextSpan(
  1121. text: '开始比赛',
  1122. style: TextStyle(fontSize: 16, color: Colors.white),
  1123. ),
  1124. // TextSpan(
  1125. // text: '(${getSecondsMIn(_time)}秒后将自动开始)',
  1126. // style: TextStyle(fontSize: 12),
  1127. // )
  1128. ])),
  1129. ),
  1130. onTapHomeMenu: () {
  1131. MyDialog.showDialog(context, '确认要开始比赛吗?', isCancel: true, onsubmit: () {
  1132. print('开始');
  1133. startGame();
  1134. });
  1135. },
  1136. )
  1137. // RaisedButton(
  1138. // child: Text.rich(TextSpan(children: [
  1139. // TextSpan(
  1140. // text: '开始比赛',
  1141. // style: TextStyle(fontSize: 16),
  1142. // ),
  1143. // TextSpan(
  1144. // text: '(${getSecondsMIn(_time)}秒后将自动开始)',
  1145. // style: TextStyle(fontSize: 12),
  1146. // )
  1147. // ])),
  1148. // onPressed: () {
  1149. // MyDialog.showDialog(context, '确认要开始比赛吗?', isCancel: true,
  1150. // onsubmit: () {
  1151. // print('开始');
  1152. // startGame();
  1153. // });
  1154. // },
  1155. // ),
  1156. );
  1157. } else {
  1158. return Container(
  1159. width: double.infinity,
  1160. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1161. height: 88,
  1162. child: LinearButton(btntext: '等待开始中', colorList: [Color(0xFFB34A4A), Color(0xFFB34A4A)], textColor: Color(0xFF252532)));
  1163. }
  1164. } else if (isJoin && statusFlag == 8) {
  1165. return Container(
  1166. width: double.infinity,
  1167. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1168. height: 88,
  1169. child: LinearButton(btntext: '正在努力解析视频中', colorList: [Color(0xFFB34A4A), Color(0xFFB34A4A)], textColor: Color(0xFF252532))
  1170. // RaisedButton(
  1171. // disabledColor: Color(0xFFD4504B),
  1172. // disabledTextColor: Color(0xFF252532),
  1173. // child: Text(
  1174. // '正在努力解析视频中',
  1175. // style: TextStyle(fontSize: 16),
  1176. // ),
  1177. // onPressed: null,
  1178. // ),
  1179. );
  1180. } else if (isJoin && (statusFlag == 2 || statusFlag == 3)) {
  1181. int _time;
  1182. if (houseInfo != null) {
  1183. _time = houseInfo.beginTime + 1800000 - DateTime.now().millisecondsSinceEpoch;
  1184. }
  1185. return Container(
  1186. width: double.infinity,
  1187. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1188. height: 88,
  1189. child: LinearButton(btntext: '预计还有 ' + getSecondsMIn(_time) + ' 结算游戏', colorList: [Color(0xFFB34A4A), Color(0xFFB34A4A)], textColor: Color(0xFF252532)),
  1190. );
  1191. } else if (statusFlag == 4 && tabIndex == 0) {
  1192. if (isJoin &&
  1193. canAppeal &&
  1194. appealState == 0 &&
  1195. playerInfo != null &&
  1196. (playerInfo.statusFlag == 9 ||
  1197. playerInfo.statusFlag == 7 ||
  1198. playerInfo.dataError ||
  1199. playerInfo.statusFlag == 6 ||
  1200. playerInfo.killNumber < playerInfo.needkill)) {
  1201. return Container(
  1202. width: double.infinity,
  1203. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1204. height: 88,
  1205. child: LinearButton(
  1206. btntext: '申诉结果',
  1207. colorList: [Color(0xFFAF4946), Color(0xFFAF4946)],
  1208. textColor: Colors.white,
  1209. onTapHomeMenu: () async {
  1210. final success = await Navigator.push(context, CupertinoPageRoute(builder: (context) => Appeal(playerInfo)));
  1211. if (success != null && success) {
  1212. Toast.show(context, '提交成功', 1500, 'success');
  1213. setState(() {
  1214. appealState = 1;
  1215. });
  1216. }
  1217. },
  1218. ));
  1219. } else if (isJoin && canAppeal && appealState == 1) {
  1220. return Container(
  1221. width: double.infinity,
  1222. padding: EdgeInsets.symmetric(horizontal: 15, vertical: 20),
  1223. height: 88,
  1224. child: LinearButton(btntext: '已提交申诉', colorList: [Color(0xFFB34A4A), Color(0xFFB34A4A)], textColor: Color(0xFF252532)));
  1225. } else {
  1226. return Container();
  1227. }
  1228. } else if (statusFlag == 4 && tabIndex == 1) {
  1229. return Container(
  1230. height: 48,
  1231. child: LinearButton(
  1232. childWidget: Padding(
  1233. padding: EdgeInsets.symmetric(vertical: 9, horizontal: 20),
  1234. child: Row(
  1235. children: <Widget>[
  1236. Container(
  1237. width: 30,
  1238. height: 30,
  1239. margin: EdgeInsets.only(right: 10),
  1240. child: CircleAvatar(
  1241. backgroundImage: NetworkImage(userInfo.icon),
  1242. ),
  1243. ),
  1244. Expanded(
  1245. flex: 1,
  1246. child: Text(
  1247. userInfo.nickname,
  1248. style: TextStyle(
  1249. fontSize: 14,
  1250. color: Color(0xFF252532),
  1251. ),
  1252. ),
  1253. ),
  1254. _myUrl != null
  1255. ? Container(
  1256. width: 68,
  1257. height: 24,
  1258. margin: EdgeInsets.only(right: 10),
  1259. child: OutlineButton(
  1260. textColor: BG_SUB_COLOR,
  1261. borderSide: BorderSide(color: BG_SUB_COLOR),
  1262. padding: EdgeInsets.all(0),
  1263. highlightColor: PRIMARY_COLOR.withOpacity(0.8),
  1264. highlightedBorderColor: BG_SUB_COLOR,
  1265. child: Text(
  1266. '查看回放',
  1267. style: TextStyle(fontSize: 12),
  1268. ),
  1269. onPressed: () =>
  1270. {Navigator.push(context, CupertinoPageRoute(builder: (context) => VideoPlayerPage(videoUrl: _myUrl, fileType: 'file')))},
  1271. ),
  1272. )
  1273. : Container(),
  1274. playerInfo != null
  1275. ? Text(
  1276. (playerInfo.statusFlag == 7 ||
  1277. playerInfo.statusFlag == 9 ||
  1278. playerInfo.dataError ||
  1279. playerInfo.statusFlag == 6 ||
  1280. playerInfo.killNumber < playerInfo.needkill)
  1281. ? '任务失败'
  1282. : '${playerInfo.houseRank}',
  1283. style: TextStyle(fontSize: 14, color: Color(0xFF252532), fontWeight: FontWeight.w500),
  1284. )
  1285. : Container()
  1286. ],
  1287. ),
  1288. ),
  1289. ),
  1290. );
  1291. } else {
  1292. return Container();
  1293. }
  1294. }
  1295. }
  1296. //房间的提示信息
  1297. class TipsListContent extends StatelessWidget {
  1298. TipsListContent({Key key, this.tipsList, this.houseInfo}) : super(key: key);
  1299. final List<List<Map>> tipsList;
  1300. final HouseInfo houseInfo;
  1301. @override
  1302. Widget build(BuildContext context) {
  1303. return Container(
  1304. // margin: EdgeInsets.only(top: 15),
  1305. width: double.infinity,
  1306. child: Column(
  1307. children: _list(),
  1308. ),
  1309. );
  1310. }
  1311. List<Widget> _list() {
  1312. List<Widget> myList = [];
  1313. for (int i = 0; i < tipsList.length; i++) {
  1314. myList.add(Tips(content: tipsList[i], showTongzhi: (tipsList[i].length == 1 && i == 0) ? true : false, houseInfo: houseInfo));
  1315. }
  1316. return myList;
  1317. }
  1318. }
  1319. class Tips extends StatelessWidget {
  1320. Tips({Key key, this.content, this.showTongzhi, this.houseInfo}) : super(key: key);
  1321. final List<Map> content;
  1322. final bool showTongzhi;
  1323. final HouseInfo houseInfo;
  1324. @override
  1325. Widget build(BuildContext context) {
  1326. return Container(
  1327. padding: EdgeInsets.all(15),
  1328. margin: EdgeInsets.fromLTRB(15, 10, 15, 0),
  1329. decoration: BoxDecoration(
  1330. // gradient: LinearGradient(colors: [Color(0xFF464B6A), Color(0xFF35395E)], begin: Alignment.topCenter, end: Alignment.bottomCenter),
  1331. color: Color(0xFF3A3E61),
  1332. borderRadius: BorderRadius.only(topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8))),
  1333. child: Column(
  1334. children: <Widget>[
  1335. _textList(),
  1336. ],
  1337. ));
  1338. }
  1339. Widget _textList() {
  1340. List<TextSpan> list = [];
  1341. for (var item in content) {
  1342. list.add(TextSpan(
  1343. text: item['value'],
  1344. style:
  1345. item['type'] == 0 ? TextStyle(color: Colors.white, fontSize: 13) : TextStyle(fontWeight: FontWeight.w600, color: Color(0xFFFFB726), fontSize: 13),
  1346. ));
  1347. }
  1348. return Text.rich(TextSpan(children: list));
  1349. }
  1350. }
  1351. //比赛结束排名
  1352. class RankContent extends StatefulWidget {
  1353. RankContent({Key key, this.roomId}) : super(key: key);
  1354. final String roomId; // 用来储存传递过来的值
  1355. @override
  1356. RankContentState createState() => RankContentState();
  1357. }
  1358. class RankContentState extends State<RankContent> {
  1359. List<PlayerInfo> topList = [];
  1360. Future<void> getTopList() async {
  1361. Toast.show(context, '加载中', -1, 'loading');
  1362. Result res = await HttpManager.get('playerInfo/rankPage', data: {'houseId': widget.roomId, 'currentPage': 1, 'pageNumber': 3});
  1363. Toast.hide();
  1364. List<PlayerInfo> list = [];
  1365. if (res.success) {
  1366. for (var item in res.data['pp']) {
  1367. PlayerInfo jonPlayer = PlayerInfo.fromJson(item);
  1368. list.add(jonPlayer);
  1369. }
  1370. } else {}
  1371. setState(() {
  1372. topList = list;
  1373. });
  1374. }
  1375. @override
  1376. void initState() {
  1377. super.initState();
  1378. Future.delayed(Duration.zero, () {
  1379. getTopList();
  1380. });
  1381. }
  1382. @override
  1383. Widget build(BuildContext context) {
  1384. return Container(
  1385. width: double.infinity,
  1386. height: 180,
  1387. margin: EdgeInsets.only(top: 15),
  1388. child: Row(
  1389. mainAxisAlignment: MainAxisAlignment.center,
  1390. crossAxisAlignment: CrossAxisAlignment.end,
  1391. children: <Widget>[_rankItem(2), _rankItem(1), _rankItem(3)],
  1392. ),
  1393. );
  1394. }
  1395. Widget _rankItem(int _num) {
  1396. if (_num > topList.length) {
  1397. return Container(
  1398. width: 107,
  1399. height: 60,
  1400. );
  1401. }
  1402. List colorList = [
  1403. [Color(0xFFD48E00), Color(0xFFFECF01)],
  1404. [Color(0xFFC5C5C5), Color(0xFFE3E3E3)],
  1405. [Color(0xFFE77023), Color(0xFFF89E58)]
  1406. ];
  1407. List imgList = ['images/jiangpai_huangjin.png', 'images/jiangpai_baiyin.png', 'images/jiangpai_qingtong.png', 'images/jiangpai_bojin.png'];
  1408. String img = '';
  1409. if (topList[_num - 1].medal == 'platinum') {
  1410. img = imgList[3];
  1411. } else if (topList[_num - 1].medal == 'gold') {
  1412. img = imgList[0];
  1413. } else if (topList[_num - 1].medal == 'silver') {
  1414. img = imgList[1];
  1415. } else if (topList[_num - 1].medal == 'bronze') {
  1416. img = imgList[2];
  1417. }
  1418. return Container(
  1419. padding: EdgeInsets.only(left: 15, right: 15, top: _num == 1 ? 0 : 15),
  1420. width: 107,
  1421. child: Column(
  1422. crossAxisAlignment: CrossAxisAlignment.center,
  1423. children: <Widget>[
  1424. Container(
  1425. child: Stack(
  1426. children: <Widget>[
  1427. Container(
  1428. margin: EdgeInsets.only(top: 17, bottom: 20),
  1429. width: _num == 1 ? 70 : 60,
  1430. height: _num == 1 ? 70 : 60,
  1431. decoration: BoxDecoration(
  1432. gradient: LinearGradient(colors: colorList[_num - 1], begin: Alignment.topLeft, end: Alignment.bottomRight),
  1433. borderRadius: BorderRadius.all(Radius.circular(100)),
  1434. ),
  1435. child: Center(
  1436. child: Container(
  1437. width: _num == 1 ? 60 : 50,
  1438. height: _num == 1 ? 60 : 50,
  1439. child: CircleAvatar(backgroundImage: NetworkImage(topList[_num - 1].userInfo.icon)),
  1440. )),
  1441. ),
  1442. Positioned(
  1443. bottom: 0,
  1444. child: Center(
  1445. child: Image.asset(
  1446. 'images/ph_yinpai_no' + '$_num.png',
  1447. width: 67,
  1448. ),
  1449. ),
  1450. ),
  1451. Positioned(
  1452. top: 0,
  1453. left: 19,
  1454. child: Center(
  1455. child: img != ''
  1456. ? Image.asset(
  1457. img,
  1458. )
  1459. : Container(),
  1460. ),
  1461. )
  1462. ],
  1463. ),
  1464. ),
  1465. Text(
  1466. topList[_num - 1].userInfo.nickname,
  1467. style: TextStyle(
  1468. color: Color(0xFFFDC372),
  1469. fontSize: 12,
  1470. ),
  1471. overflow: TextOverflow.ellipsis,
  1472. textAlign: TextAlign.center,
  1473. ),
  1474. // SizedBox(
  1475. // height: 5,
  1476. // ),
  1477. // Row(
  1478. // mainAxisAlignment: MainAxisAlignment.center,
  1479. // children: <Widget>[
  1480. // Image.asset('images/icon_jinbi_xiao_hong.png', width: 20),
  1481. // Text('×' + (topList[_num - 1].bonus != null ? topList[_num - 1].bonus.toString() : '0'), style: TextStyle(color: PRIMARY_COLOR, fontSize: 12))
  1482. // ],
  1483. // )
  1484. ],
  1485. ),
  1486. );
  1487. }
  1488. }