x1ongzhu il y a 6 ans
Parent
commit
d8c07b8cb3
5 fichiers modifiés avec 297 ajouts et 26 suppressions
  1. 32 0
      lib/Constants.dart
  2. 95 3
      lib/pages/RoomInfo.dart
  3. 168 22
      lib/pages/RoomInfoDetail.dart
  4. 1 1
      lib/pages/openRoom.dart
  5. 1 0
      pubspec.yaml

+ 32 - 0
lib/Constants.dart

@@ -20,3 +20,35 @@ abstract class HouseStatus {
   // 解析完成
   static const int ANALYSIS = 8;
 }
+
+abstract class PlayerStatus {
+  // 加入
+  static const int JOIN = 0;
+
+  // 准备
+  static const int READY = 1;
+
+  // 开始
+  static const int START = 2;
+
+  // 结束
+  static const int END = 3;
+
+  // 结算
+  static const int SETTLEMENT = 4;
+
+  // 领取奖励
+  static const int RECEIVE = 5;
+
+  // 未比赛
+  static const int NO_MATCH = 6;
+
+  // 比赛超时
+  static const int OVERTIME = 7;
+
+  // 解析完成
+  static const int PROCESSED = 8;
+
+  // 解析失败
+  static const int PROCESSED_FAIL = 9;
+}

+ 95 - 3
lib/pages/RoomInfo.dart

@@ -1,8 +1,17 @@
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:url_launcher/url_launcher.dart';
+import 'package:wanna_battle/model/PlayerInfo.dart';
 import 'package:wanna_battle/pages/RoomInfoDetail.dart';
 import '../model/HouseInfo.dart';
 import '../Constants.dart';
 import '../styles/colors.dart';
+import '../net/HttpManager.dart';
+import '../net/Result.dart';
+import '../plugins/ScreenStramPlugin.dart';
+import './StartWindow.dart';
+import '../widget/Dialog.dart';
 
 class RoomInfo extends StatefulWidget {
   final HouseInfo houseInfo;
@@ -14,14 +23,15 @@ class RoomInfo extends StatefulWidget {
 }
 
 class _RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin {
-  HouseInfo houseInfo;
+  HouseInfo mHouseInfo;
+  PlayerInfo mPlayerInfo;
   TabController tabController;
   RoomInfoDetail roomInfoDetail;
 
   @override
   void initState() {
     super.initState();
-    houseInfo = widget.houseInfo;
+    mHouseInfo = widget.houseInfo;
     tabController = TabController(
       length: 2,
       vsync: this,
@@ -72,7 +82,12 @@ class _RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin
             children: [
               Builder(
                 builder: (context) {
-                  roomInfoDetail = RoomInfoDetail(houseInfo);
+                  roomInfoDetail = RoomInfoDetail(
+                    mHouseInfo,
+                    onStart: () {
+                      showStart();
+                    },
+                  );
                   return roomInfoDetail;
                 },
               ),
@@ -86,4 +101,81 @@ class _RoomInfoState extends State<RoomInfo> with SingleTickerProviderStateMixin
       },
     );
   }
+
+  Future<void> refreshData() async {}
+
+  Future<void> showStart() async {
+    if (mPlayerInfo == null) {
+      return;
+    }
+    bool result = await Navigator.of(context).push<bool>(
+      PageRouteBuilder(
+        opaque: false,
+        transitionDuration: Duration(milliseconds: 300),
+        transitionsBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation, Widget child) {
+          return FadeTransition(
+            opacity: CurvedAnimation(parent: animation, curve: Curves.linear),
+            child: child,
+          );
+        },
+        pageBuilder: (BuildContext context, _, __) {
+          return StartWindow();
+        },
+      ),
+    );
+    final Map<String, dynamic> data = {'id': mPlayerInfo.id};
+    bool success = true;
+    if (result) {
+      success = await ScreenStreamPlugin.start(mPlayerInfo.id.toString());
+      if (success) {
+        data['statusFlag'] = 2;
+      } else {
+        data['statusFlag'] = 6;
+      }
+    } else {
+      data['statusFlag'] = 6;
+    }
+    final Result res = await HttpManager.post('playerInfo/update', data: data);
+    if (res.success) {
+      if (data['statusFlag'] == 2) {
+        const url = 'pubgmhd1106467070://';
+        if (await canLaunch(url)) {
+          Timer(Duration(seconds: 1), () async {
+            await launch(url);
+            showSucessInfo();
+          });
+        } else {
+          showCustomDialog(context, '自动启动游戏失败,请手动切换到游戏app开始竞赛', submitText: '知道了');
+          Timer(Duration(seconds: 10), () {
+            showSucessInfo();
+          });
+
+          throw 'Could not launch $url';
+        }
+      } else {
+        showStartFailDialog(success ? 1 : 0);
+      }
+    }
+  }
+
+  void showSucessInfo() {
+    showCustomDialog(
+      context,
+      '您已经完成比赛了吗,确认完成,那就点击下方完成竞赛按钮,上传本次成绩,祝您赢取大奖',
+      title: '完成比赛',
+      submitText: '我已完成比赛',
+      onsubmit: () async {
+        HttpManager.post('playerInfo/update', data: {'id': mPlayerInfo.id, 'statusFlag': 3});
+        bool success = await ScreenStreamPlugin.stop();
+        setState(() {
+          mPlayerInfo.statusFlag = 3;
+        });
+        refreshData();
+      },
+    );
+  }
+
+  void showStartFailDialog(type) {
+    showCustomDialog(context, type == 1 ? '由于您未在十秒内点击开始按钮' : '由于您未授权录屏' ',系统已经判定您放弃比赛,谢谢您的参与。', title: '很遗憾');
+  }
 }

+ 168 - 22
lib/pages/RoomInfoDetail.dart

@@ -1,17 +1,29 @@
+import 'dart:async';
+
 import 'package:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
-import 'package:wanna_battle/Constants.dart';
-import 'package:wanna_battle/styles/colors.dart';
-import 'package:wanna_battle/styles/totast.dart';
+import 'package:flutter_html/flutter_html.dart';
+import 'package:flutter_redux/flutter_redux.dart';
+import 'package:url_launcher/url_launcher.dart';
+import 'package:wanna_battle/redux/AppState.dart';
+import '../Constants.dart';
+import '../styles/colors.dart';
+import '../styles/totast.dart';
 import '../widget/VideoWidget.dart';
 import '../model/HouseInfo.dart';
 import '../widget/Dialog.dart';
 import './CompetitionNotice.dart';
+import '../model/PlayerInfo.dart';
+import 'StartWindow.dart';
+import '../net/Result.dart';
+import '../net/HttpManager.dart';
+import '../plugins/ScreenStramPlugin.dart';
 
 class RoomInfoDetail extends StatefulWidget {
-  RoomInfoDetail(this.houseInfo, {Key key}) : super(key: key);
+  RoomInfoDetail(this.houseInfo, {Key key, this.onStart}) : super(key: key);
 
   final HouseInfo houseInfo;
+  final VoidCallback onStart;
   _RoomInfoDetailState state;
 
   void setHouseInfo(HouseInfo houseInfo) {
@@ -26,12 +38,14 @@ class RoomInfoDetail extends StatefulWidget {
 }
 
 class _RoomInfoDetailState extends State<RoomInfoDetail> {
-  HouseInfo houseInfo;
+  HouseInfo mHouseInfo;
+  PlayerInfo mPlayerInfo;
+  int finishedPlayerNum;
 
   @override
   void initState() {
     super.initState();
-    houseInfo = widget.houseInfo;
+    mHouseInfo = widget.houseInfo;
   }
 
   @override
@@ -41,7 +55,7 @@ class _RoomInfoDetailState extends State<RoomInfoDetail> {
         children: <Widget>[
           ListView(
             children: <Widget>[
-              houseInfo != null ? VideoWidget(videoSrc: houseInfo.video) : Container(),
+              mHouseInfo != null ? VideoWidget(videoSrc: mHouseInfo.video) : Container(),
               Container(
                 height: 60,
                 padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
@@ -49,7 +63,7 @@ class _RoomInfoDetailState extends State<RoomInfoDetail> {
                   children: <Widget>[
                     Expanded(
                       child: Text(
-                        houseInfo.houseName,
+                        mHouseInfo.houseName,
                         style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
                       ),
                     ),
@@ -61,9 +75,7 @@ class _RoomInfoDetailState extends State<RoomInfoDetail> {
                           width: 20,
                         ),
                         Text(
-                          (houseInfo != null ? (houseInfo.playerNumber ?? 0).toString() : '0') +
-                              '/' +
-                              (houseInfo != null ? houseInfo.maxNumber.toString() : '0'),
+                          (mHouseInfo?.playerNumber ?? 0).toString() + '/' + (mHouseInfo?.maxNumber ?? 0).toString(),
                           style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Color(0xFFB1B2C0)),
                         ),
                       ],
@@ -128,34 +140,168 @@ class _RoomInfoDetailState extends State<RoomInfoDetail> {
                   ],
                 ),
               ),
+              Container(
+                margin: EdgeInsets.fromLTRB(15, 20, 15, 0),
+                color: SUB_COLOR,
+                padding: EdgeInsets.all(15),
+                child: Text.rich(
+                  tipText(),
+                  style: TextStyle(color: Colors.white, fontSize: 13),
+                ),
+              )
             ],
           ),
           Align(
             alignment: Alignment.bottomCenter,
-            child: SafeArea(
-              child: Container(
-                height: 48,
-                margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
-                color: PRIMARY_COLOR,
-              ),
-            ),
+            child: SafeArea(child: roomBtn()),
           )
         ],
       ),
     );
   }
 
-  Widget tip() {
-    switch (houseInfo.statusFlag) {
+  TextSpan tipText() {
+    switch (mHouseInfo.statusFlag) {
       case HouseStatus.WAIT:
       case HouseStatus.READY:
+        return TextSpan(
+            text: '待倒计时结束或人数满员时会自动开启比赛,房主也可以手动开启比赛,请在此页面耐心等待其他人的加入,'
+                '加入房间后再次退出则视为自动放弃比赛,快快点击右上角分享给好友加入战局吧');
+
+      case HouseStatus.START:
+      case HouseStatus.END:
+      case HouseStatus.ANALYSIS:
+        final time = mHouseInfo.beginTime + 3600000 - DateTime.now().millisecondsSinceEpoch;
+        return TextSpan(children: <TextSpan>[
+          TextSpan(text: (mPlayerInfo?.statusFlag ?? 0 == PlayerStatus.END) ? '你已完成本次比赛,当前完成人数' : '当前完成人数'),
+          TextSpan(text: '${finishedPlayerNum ?? 0}'),
+          TextSpan(text: '比赛需要等待所有人完成后方可结算积分<br>最迟结算时间还剩'),
+          TextSpan(text: '${getCountDown(time)}'),
+          TextSpan(text: ',你可以先去参加其他竞赛,稍后在“个人中心-我的战绩”中可以查看本次竞赛排名及积分详情')
+        ]);
+        break;
+        
+      case HouseStatus.SETTLEMENT:
+        return TextSpan(text: '当前比赛已结束,可在参赛成员列表可查看当前比赛详细排名情况');
+    }
+    return TextSpan(text: '');
+  }
+
+  Widget roomBtn() {
+    switch (mHouseInfo.statusFlag) {
+      case HouseStatus.WAIT:
+      case HouseStatus.READY:
+        {
+          if (mHouseInfo.createUser == StoreProvider.of<AppState>(context).state.userInfo.id.toString()) {
+            return startBtn();
+          } else {
+            return countDownBtn();
+          }
+        }
+        break;
+      case HouseStatus.START:
+      case HouseStatus.END:
+        {
+          final time = mHouseInfo.beginTime + 3600000 - DateTime.now().millisecondsSinceEpoch;
+          return statusBtn(time > 0 ? ('最迟在' + getCountDown(time) + '后结算') : '等待结算');
+        }
+        break;
+      case HouseStatus.SETTLEMENT:
+        return statusBtn('已结束');
+        break;
+      case HouseStatus.ANALYSIS:
+        return statusBtn('结算中...');
+      default:
+        return statusBtn('已结束', color: Color(0xFF4F5C87));
+    }
+  }
+
+  Widget startBtn() {
+    final time = mHouseInfo.createTime + 600000 - DateTime.now().millisecondsSinceEpoch;
+    return Container(
+      margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
+      child: SizedBox(
+        height: 48,
+        width: double.infinity,
+        child: FlatButton(
+          color: PRIMARY_COLOR,
+          child: Text.rich(
+            TextSpan(children: [
+              TextSpan(
+                text: '开始比赛 ',
+                style: TextStyle(fontSize: 16),
+              ),
+              TextSpan(
+                text: '(${getCountDown(time)}后将自动开始)',
+                style: TextStyle(fontSize: 12, fontWeight: FontWeight.normal),
+              )
+            ]),
+            style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold),
+          ),
+          onPressed: () {
+            if (widget.onStart != null) {
+              widget.onStart();
+            }
+          },
+        ),
+      ),
+    );
+  }
+
+  Widget countDownBtn() {
+    final time = mHouseInfo.createTime + 600000 - DateTime.now().millisecondsSinceEpoch;
+    String text = '';
+    if (time >= 0) {
+      text = '预计${getCountDown(time)}后开始比赛';
+    } else {
+      text = '即将开始比赛';
     }
-    return Container();
+    return Container(
+      margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
+      height: 48,
+      color: PRIMARY_COLOR,
+      child: Center(
+        child: Text(
+          text,
+          style: TextStyle(
+            color: Color(0xFF252532),
+            fontSize: 16,
+            fontWeight: FontWeight.bold,
+          ),
+        ),
+      ),
+    );
+  }
+
+  Widget statusBtn(text, {Color color = PRIMARY_COLOR}) {
+    return Container(
+      margin: EdgeInsets.fromLTRB(15, 0, 15, 10),
+      height: 48,
+      color: color,
+      child: Center(
+        child: Text(
+          text,
+          style: TextStyle(
+            color: Color(0xFF252532),
+            fontSize: 16,
+            fontWeight: FontWeight.bold,
+          ),
+        ),
+      ),
+    );
   }
 
   void setHouseInfo(HouseInfo houseInfo) {
     setState(() {
-      this.houseInfo = houseInfo;
+      mHouseInfo = houseInfo;
     });
   }
+
+  String getCountDown(int time) {
+    if (time == null) {
+      return '';
+    } else {
+      return ((time ~/ 1000 ~/ 60) % 60).toString() + '分' + (time ~/ 1000 % 60).toString() + '秒';
+    }
+  }
 }

+ 1 - 1
lib/pages/openRoom.dart

@@ -459,7 +459,7 @@ class OpenRoomState extends State<OpenRoom> {
             height: 1,
             color: BG_SUB_COLOR,
           ),
-          //游戏中房间密��
+          //游戏中房间密
           Container(
             height: 60,
             color: BG_COLOR,

+ 1 - 0
pubspec.yaml

@@ -40,6 +40,7 @@ dependencies:
   gradient_text: ^1.0.2
   sprintf: ^4.0.2
   flutter_html: ^0.10.1+hotfix.1
+  flutter_html_view: "^0.3.1"
 
 dev_dependencies:
   build_runner: ^1.1.1