import 'package:flutter/material.dart'; import 'package:flutter_picker/flutter_picker.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/cupertino.dart'; import 'package:file_picker/file_picker.dart'; import '../styles/colors.dart'; import 'dart:io'; import 'dart:async'; import 'dart:convert'; import 'dart:ui'; import '../styles/totast.dart'; import '../pages/RoomInfo.dart'; import 'package:flutter_redux/flutter_redux.dart'; import '../redux/AppState.dart'; import '../net/HttpManager.dart'; import '../net/Result.dart'; import 'package:dio/dio.dart'; import '../model/GameInfo.dart'; import '../model/HouseLevel.dart'; import '../plugins/ScreenStramPlugin.dart'; import '../widget/Dialog.dart'; import '../widget/LinearButton.dart'; class OpenRoom extends StatefulWidget { OpenRoom({Key key, this.roomFlag}) : super(key: key); final String roomFlag; // 用来储存传递过来的值 @override OpenRoomState createState() => OpenRoomState(); } class OpenRoomState extends State { TextStyle titleStyle = TextStyle(color: Colors.white, fontSize: 14); TextStyle valStyle = TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500); Map editRoomInfo = {'gameId': 1, 'houseLevel': 1, 'maxNumber': 5, 'scoreType': 0}; List gameList = []; List levelList = []; Future getFilePath() async { File file = await FilePicker.getFile(type: FileType.ANY); if (file == null) { return; } print(file.statSync()); Toast.show(context, '加载中', -1, 'loading'); Result res = await HttpManager.post('assets/uploadFile', data: { 'file': UploadFileInfo(file, file.path), }); Toast.hide(); if (res.success) { setState(() { editRoomInfo['video'] = res.data[0]; }); } } Future showSysDialog(id) async { Toast.show(context, '加载中', -1, 'loading'); Result res = await HttpManager.get('alertMessage/getOne', data: {'id': id}); Toast.hide(); if (res.success) { MyDialog.showDialog(context, res.data['remark']); } } Future saveInfo() async { if (!StoreProvider.of(context).state.userInfo.createFlag) { showSysDialog(1); return; } if (!editRoomInfo.containsKey('gameId')) { Toast.show(context, '请选择游戏', 1500, 'info'); return; } if (editRoomInfo['houseName'] == null || editRoomInfo['houseName'] == '') { Toast.show(context, '请输入房间标题', 1500, 'info'); return; } // if (!editRoomInfo.containsKey('houseLevel')) { // Toast.show(context, '请选择房间等级', 1500, 'info'); // return; // } if (editRoomInfo['houseType'] == '1' && (editRoomInfo['gameHouseId'] == null || editRoomInfo['gameHouseId'] == '')) { Toast.show(context, '请录入游戏房间号', 1500, 'info'); return; } if (editRoomInfo['houseType'] == '1' && (editRoomInfo['gameHousePassword'] == null || editRoomInfo['gameHousePassword'] == '')) { Toast.show(context, '请录入游戏房间密码', 1500, 'info'); return; } if (StoreProvider.of(context).state.userInfo.moneyCoin != null) { HouseLevel chooseLevelInfo = HouseLevel.empty(); for (var item in levelList) { if (item.id.toString() == editRoomInfo['houseLevel'].toString()) { chooseLevelInfo = item; } } if (StoreProvider.of(context).state.userInfo.moneyCoin < chooseLevelInfo.entryCoin) { return; } } else { return; } bool hasPermission = await ScreenStreamPlugin.checkPermission(); if (!hasPermission) { showDialog( context: context, builder: (context) => AlertDialog( title: Text('需要悬浮窗权限'), contentTextStyle: TextStyle(color: Colors.black87), content: Text('请在点击确定后,勾选"允许显示在其他应用的上层"'), actions: [ FlatButton( child: Text('确定'), onPressed: () { Navigator.of(context).pop(); ScreenStreamPlugin.requestPermission(); }, ), ], ), ); return; } editRoomInfo['createUser'] = StoreProvider.of(context).state.userInfo.id; editRoomInfo['userId'] = StoreProvider.of(context).state.userInfo.id; Toast.show(context, '加载中', -1, 'loading'); Result res = await HttpManager.post('houseInfo/save', data: editRoomInfo); Toast.hide(); if (res.success) { // HttpManager.post('houseInfo/join', data: { // 'houseId': res.data, // 'userId': StoreProvider.of(context).state.userInfo.id // }); Toast.show(context, '创建成功', 1500, 'success'); Future.delayed(Duration(milliseconds: 1500), () { Navigator.pushReplacement(context, CupertinoPageRoute(builder: (context) => RoomInfo(roomId: res.data.toString()))); }); } else { Toast.show(context, res.error, 1500, 'info'); } } Future getInfo() async { Toast.show(context, '加载中', -1, 'loading'); Result res = await HttpManager.get('gameInfo/all'); if (res.success) { List _list = []; for (var item in res.data) { _list.add(GameInfo.fromJson(item)); } setState(() { gameList = _list; if (res.data.length > 0) { editRoomInfo['gameId'] = res.data[0]['id']; String name = StoreProvider.of(context).state.userInfo.nickname; editRoomInfo['houseName'] = (name.length > 5 ? name.substring(0, 5) : name) + '的' + res.data[0]['shortName'] + '房间'; editRoomInfo['houseAbstract'] = res.data[0]['profile'] ?? ''; } }); } else {} Result res2 = await HttpManager.get('houseLevel/all'); Toast.hide(); if (res2.success) { List _list = []; for (var item in res2.data) { _list.add(HouseLevel.fromJson(item)); } setState(() { levelList = _list; if (levelList.isNotEmpty) { editRoomInfo['houseLevel'] = res2.data[0]['id']; } }); } else {} } @override void initState() { super.initState(); editRoomInfo['houseType'] = widget.roomFlag; Future.delayed(Duration.zero, () { getInfo(); }); } @override Widget build(BuildContext context) { GameInfo chooseGameInfo = GameInfo.empty(); for (var item in gameList) { if (item.id.toString() == editRoomInfo['gameId'].toString()) { chooseGameInfo = item; } } HouseLevel chooseLevelInfo = HouseLevel.empty(); for (var item in levelList) { if (item.id.toString() == editRoomInfo['houseLevel'].toString()) { chooseLevelInfo = item; } } return WillPopScope( child: Scaffold( appBar: AppBar( title: Text('发起赛事'), centerTitle: true, elevation: 0, // actions: [ // Container( // width: 60, // child: FlatButton( // highlightColor: PRIMARY_COLOR, // padding: EdgeInsets.only(right: 0), // child: Text('规则', // style: TextStyle(color: Colors.white, fontSize: 13)), // onPressed: () {}, // ), // ) // ], ), body: Container( color: Color(0xFF2E3049), width: double.infinity, height: double.infinity, child: SingleChildScrollView( child: Container( child: Column( children: [ Container( width: double.infinity, color: Color(0xFF1D1E2E), height: 210, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 160, height: 38, child: LinearButton( radius: 38.0, colorList: [Color(0xFF3A3E61), Color(0xFF3A3E61)], childWidget: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(right: 8), child: Image.asset( 'images/icon_shipin.png', width: 20, )), Text('上传图片或视频', style: titleStyle) ], ), onTapHomeMenu: () { getFilePath(); }, ), ), Padding( padding: EdgeInsets.only(top: 12), child: Text( editRoomInfo.containsKey('video') ? '已选择' : '不上传则自动使用官方默认视频', style: TextStyle(color: Color(0xFF9BA0AE), fontSize: 13), ), ) ], ), ), //房间标题 // Container( // height: 60, // color: BG_COLOR, // padding: // EdgeInsets.symmetric(horizontal: 15, vertical: 8), // child: TextField( // textAlign: TextAlign.end, // style: valStyle, // maxLength: 10, // decoration: InputDecoration( // hintText: '请输入房间标题', // hintStyle: TextStyle( // color: Color(0xFF727785), fontSize: 13), // prefixIcon: Padding( // padding: EdgeInsets.symmetric(vertical: 12), // child: Text('房间标题', style: titleStyle), // ), // border: InputBorder.none, // counterStyle: TextStyle(fontSize: 0)), // onChanged: (value) { // editRoomInfo['houseName'] = value; // }, // ), // ), ChooseContent( title: '选择游戏', val: chooseGameInfo.gameName, onTapHomeMenu: () { showPicker(context); }, ), Container( margin: EdgeInsets.symmetric(horizontal: 15), height: 1, color: BG_SUB_COLOR, ), InputContent( title: '房间标题', value: editRoomInfo['houseName'], onTextChange: (value) { editRoomInfo['houseName'] = value; }), Container( margin: EdgeInsets.symmetric(horizontal: 15), height: 1, color: BG_SUB_COLOR, ), // //房间简介 // InputContent( // title: '房间简介', // value: editRoomInfo['houseAbstract'], // onTextChange: (value) { // editRoomInfo['houseAbstract'] = value; // }), // Container( // height: 60, // color: BG_COLOR, // padding: // EdgeInsets.symmetric(horizontal: 15, vertical: 8), // child: TextField( // textAlign: TextAlign.end, // style: valStyle, // maxLength: 15, // decoration: InputDecoration( // hintText: '请输入房间简介', // hintStyle: TextStyle( // color: Color(0xFF727785), fontSize: 13), // prefixIcon: Padding( // padding: EdgeInsets.symmetric(vertical: 12), // child: Text('房间简介', style: titleStyle), // ), // border: InputBorder.none, // counterStyle: TextStyle(fontSize: 0)), // onChanged: (value) { // editRoomInfo['houseAbstract'] = value; // }, // ), // ), //房间等级 // ChooseContent( // title: '房间等级', // chooseLevelInfo: chooseLevelInfo, // isLevel: true, // onTapHomeMenu: () { // showLevelPicker(context); // }, // ), Container( margin: EdgeInsets.symmetric(horizontal: 15), height: 1, color: BG_SUB_COLOR, ), //房间人数 ChooseContent( title: '房卡人数', val: editRoomInfo['maxNumber'].toString() + '人次房卡', icon: Image.asset('images/icon_yiwen.png'), onTapHomeMenu: () { showNumPicker(context); }, ), Container( margin: EdgeInsets.symmetric(horizontal: 15), height: 1, color: BG_SUB_COLOR, ), //房间人数 ChooseContent( title: '胜利条件', val: editRoomInfo['scoreType'] == 0 ? '评分' : '吃鸡', onTapHomeMenu: () { showScoreType(context); }, ), _bottomWidget(), ], ), ), ), ), floatingActionButton: Padding( padding: EdgeInsets.fromLTRB(15, 39, 15, 10), child: LinearButton( onTapHomeMenu: () { saveInfo(); }, childWidget: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(right: 6), child: Image.asset('images/icon_renci.png'), ), Text( '×${editRoomInfo["maxNumber"]}', style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), ), Padding( padding: EdgeInsets.only(left: 20), child: Text( '创建房间', style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500), ), ) ], ), ), ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, ), onWillPop: () { Toast.hide(); Navigator.pop(context); return Future.value(false); }, ); } Widget _bottomWidget() { if (widget.roomFlag == '1') return Column( children: [ Container( height: 10, color: BG_SUB_COLOR, ), //游戏房间号 Container( height: 60, color: BG_COLOR, padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: TextField( textAlign: TextAlign.end, style: valStyle, maxLength: 15, decoration: InputDecoration( hintText: '请输入游戏房间号', hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13), prefixIcon: Padding( padding: EdgeInsets.symmetric(vertical: 12), child: Text('游戏房间号', style: titleStyle), ), border: InputBorder.none, counterStyle: TextStyle(fontSize: 0)), onChanged: (value) { editRoomInfo['gameHouseId'] = value; }, ), ), Container( height: 1, color: BG_SUB_COLOR, ), //游戏中房间密�� Container( height: 60, color: BG_COLOR, padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: TextField( textAlign: TextAlign.end, style: valStyle, maxLength: 10, decoration: InputDecoration( hintText: '请输入密码', hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13), prefixIcon: Padding( padding: EdgeInsets.symmetric(vertical: 12), child: Text('游戏中房间密码', style: titleStyle), ), border: InputBorder.none, counterStyle: TextStyle(fontSize: 0)), onChanged: (value) { editRoomInfo['gameHousePassword'] = value; }, ), ), ], ); else { return Container(); } } void showPicker(BuildContext context) { List _list = []; for (var item in gameList) { _list.add(item.gameName); } String PickerData = json.encode(_list); Picker( confirmText: '确定', cancelText: '取消', adapter: PickerDataAdapter(pickerdata: JsonDecoder().convert(PickerData)), changeToFirst: true, textAlign: TextAlign.left, columnPadding: const EdgeInsets.all(8.0), onConfirm: (Picker picker, List value) { setState(() { editRoomInfo['gameId'] = gameList[value[0]].id; editRoomInfo['houseName'] = StoreProvider.of(context).state.userInfo.nickname + '的' + gameList[value[0]].shortName + '房间'; editRoomInfo['houseAbstract'] = gameList[value[0]].profile ?? ''; }); }).showModal(this.context); } void showNumPicker(BuildContext context) { List _list = []; List _listName = []; List _member = [5, 10, 15, 20, 25, 50, 100]; for (var item in _member) { _list.add(item); _listName.add(item.toString() + '人次房卡'); } String pickerData = json.encode(_listName); Picker( confirmText: '确定', cancelText: '取消', adapter: PickerDataAdapter(pickerdata: JsonDecoder().convert(pickerData)), changeToFirst: true, textAlign: TextAlign.left, columnPadding: const EdgeInsets.all(8.0), onConfirm: (Picker picker, List value) { setState(() { editRoomInfo['maxNumber'] = _list[value[0]]; }); }).showModal(this.context); } void showScoreType(BuildContext context) { List _list = ['评分', '吃鸡']; String PickerData = json.encode(_list); Picker( confirmText: '确定', cancelText: '取消', adapter: PickerDataAdapter(pickerdata: JsonDecoder().convert(PickerData)), changeToFirst: true, textAlign: TextAlign.left, columnPadding: const EdgeInsets.all(8.0), onConfirm: (Picker picker, List value) { setState(() { editRoomInfo['scoreType'] = _list[value[0]] == '评分' ? 0 : 1; }); }).showModal(this.context); } void showLevelPicker(BuildContext context) { List _list = []; for (var item in levelList) { _list.add(item.levelName); } String PickerData = json.encode(_list); Picker( confirmText: '确定', cancelText: '取消', adapter: PickerDataAdapter(pickerdata: JsonDecoder().convert(PickerData)), changeToFirst: true, textAlign: TextAlign.left, columnPadding: const EdgeInsets.all(8.0), onConfirm: (Picker picker, List value) { setState(() { editRoomInfo['houseLevel'] = levelList[value[0]].id; }); }).showModal(this.context); } } typedef void OnTapHomeMenu(); typedef ValueChanged = void Function(T value); class ChooseContent extends StatelessWidget { ChooseContent({Key key, this.title, this.val, this.chooseLevelInfo, this.isLevel = false, this.icon, this.onTapHomeMenu}) : super(key: key); final String title; final String val; final OnTapHomeMenu onTapHomeMenu; final HouseLevel chooseLevelInfo; final Image icon; final bool isLevel; GlobalKey anchorKey = GlobalKey(); @override Widget build(BuildContext context) { return Container( child: InkWell( child: Container( height: 60, padding: EdgeInsets.symmetric(horizontal: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: TextStyle(fontSize: 14, color: Colors.white)), icon != null ? InkWell( onTap: () { //弹出 RenderBox renderBox = anchorKey.currentContext.findRenderObject(); var offset = renderBox.localToGlobal(Offset.zero); print(offset.dx.toString() + ',' + offset.dy.toString()); Navigator.of(context).push(PageRouteBuilder( opaque: false, transitionDuration: Duration(milliseconds: 300), transitionsBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation, Widget child) { return FadeTransition( opacity: CurvedAnimation(parent: animation, curve: Curves.linear), child: child, ); }, pageBuilder: (BuildContext context, _, __) { return FloatTextContent(dx: offset.dx, dy: offset.dy); })); }, child: Padding(padding: EdgeInsets.all(9), child: icon, key: anchorKey)) : Container(), Expanded( flex: 1, child: isLevel ? Row( mainAxisAlignment: MainAxisAlignment.end, children: [ chooseLevelInfo.icon != null ? Image.network( chooseLevelInfo.icon, width: 22, ) : Container(), Text( chooseLevelInfo.levelName ?? '', style: TextStyle(color: Color(0xFFF9D881)), ), Padding( padding: EdgeInsets.only(left: 20, right: 2), child: Image.asset('images/icon_jinbi_da_bai.png', width: 20), ), Text( '×' + (chooseLevelInfo.entryCoin ?? 0).toString(), style: TextStyle(color: Colors.white, fontSize: 15, fontWeight: FontWeight.w500), ) ], ) : Text(val ?? '', style: TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500), textAlign: TextAlign.right), ), Image.asset('images/icon_inter.png', width: 24) ], ), ), onTap: onTapHomeMenu, )); } } class InputContent extends StatefulWidget { InputContent({Key key, this.title, this.value, this.onTextChange}) : super(key: key); final String title; final String value; final ValueChanged onTextChange; @override InputContentState createState() => InputContentState(); } class InputContentState extends State { TextEditingController _controller; @override void initState() { super.initState(); _controller = TextEditingController(); } @override void didUpdateWidget(InputContent oldWidget) { super.didUpdateWidget(oldWidget); _controller.text = widget.value ?? ''; } @override Widget build(BuildContext context) { return Container( height: 60, padding: EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: TextField( controller: _controller, textAlign: TextAlign.end, style: TextStyle(fontSize: 15, color: Colors.white, fontWeight: FontWeight.w500), maxLength: 10, decoration: InputDecoration( hintText: '请输入' + widget.title, hintStyle: TextStyle(color: Color(0xFF727785), fontSize: 13), prefixIcon: Padding( padding: EdgeInsets.symmetric(vertical: 12), child: Text(widget.title, style: TextStyle(fontSize: 14, color: Colors.white)), ), border: InputBorder.none, counterStyle: TextStyle(fontSize: 0)), onChanged: widget.onTextChange, ), ); } } class FloatTextContent extends StatelessWidget { final num dx; final num dy; FloatTextContent({this.dx, this.dy}); @override Widget build(BuildContext context) { return GestureDetector( onTap: () { Navigator.of(context).pop(); }, child: Container( color: Colors.transparent, child: Stack( children: [ Positioned( left: dx + 31, top: dy + 9, child: Container( padding: EdgeInsets.all(10), decoration: BoxDecoration( borderRadius: BorderRadius.only(topRight: Radius.circular(8), bottomLeft: Radius.circular(8), bottomRight: Radius.circular(8)), color: Color(0xFF3A3E61), ), constraints: BoxConstraints(maxWidth: 241), child: Text('房主可以选择不同人次的房卡进行开始比赛,同步消耗自己相应的参赛名额,比如选择50人次房卡,系统从我的账号上扣除50人次参赛名额,房间内最多可进入50人参加比赛', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w400, decoration: TextDecoration.none)), ), ) ], ), ), ); } }