513 lines
16 KiB
Dart
513 lines
16 KiB
Dart
import 'dart:async';
|
||
import 'dart:io';
|
||
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||
import 'package:game/network/NetworkConfig.dart';
|
||
import 'package:game/tools/shop/shop_page.dart';
|
||
import 'package:lottie/lottie.dart';
|
||
|
||
import '../beans/game_token_bean.dart';
|
||
import '../beans/queue_bean.dart';
|
||
import '../beans/reconnect_bean.dart';
|
||
import '../common/EventBusUtil.dart';
|
||
import '../common/Global.dart';
|
||
import '../common/func.dart';
|
||
import '../dialog/line_up_dialog.dart';
|
||
import '../dialog/reconnect_dialog.dart';
|
||
import 'game/game_page.dart';
|
||
import 'home/my_home_page.dart';
|
||
import 'home_model.dart';
|
||
import 'me/my_page.dart';
|
||
|
||
class HomePage extends StatefulWidget {
|
||
const HomePage({super.key});
|
||
|
||
@override
|
||
State<HomePage> createState() => _HomePageState();
|
||
}
|
||
|
||
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
|
||
final pageController = PageController();
|
||
|
||
GlobalKey<LineUpDialogState> lineUpDialogKey = GlobalKey();
|
||
|
||
List<StatefulWidget> bodyList = [];
|
||
|
||
int currentIndex = 0;
|
||
late StreamSubscription<StartGames> _startGamesEvent;
|
||
late StreamSubscription<TabSwitch> _tabSwitchEvent;
|
||
late StreamSubscription<RefreshUserdata> _refreshUserEvent;
|
||
|
||
late StreamSubscription subscription;
|
||
final HomeModel _viewModel = HomeModel();
|
||
late Timer _timer;
|
||
late BuildContext lineUpContext;
|
||
|
||
late ReconnectBean reconnectBean;
|
||
|
||
DateTime? _lastPressTime;
|
||
|
||
@override
|
||
void initState() {
|
||
// TODO: implement initState
|
||
super.initState();
|
||
|
||
if (NetworkConfig.isChecking) {
|
||
bodyList = [MyHomePage(), GamePage(), MyPage()];
|
||
} else {
|
||
bodyList = [MyHomePage(), GamePage(), ShopPage(), MyPage()];
|
||
}
|
||
|
||
///eventBus
|
||
///启动游戏
|
||
_startGamesEvent = EventBusUtil.listen((event) {
|
||
if (NetworkConfig.token == "") {
|
||
Navigator.pushNamed(context, "/LoginPage");
|
||
return;
|
||
}
|
||
|
||
final DateTime now = DateTime.now();
|
||
if (_lastPressTime != null && now.difference(_lastPressTime!) < Duration(seconds: 2)) {
|
||
// 两次点击时间间隔小于2秒,拦截第二次点击
|
||
print('Button pressed again within 2 seconds. Ignoring the second press.');
|
||
return;
|
||
}
|
||
// 更新最后一次点击时间
|
||
setState(() {
|
||
_lastPressTime = now;
|
||
});
|
||
|
||
FunctionUtil.loading();
|
||
NetworkConfig.gameId = event.gameId;
|
||
print("_startGamesEvent");
|
||
_viewModel.playGame(event.gameId);
|
||
});
|
||
|
||
///tab切换
|
||
_tabSwitchEvent = EventBusUtil.listen((event) {
|
||
if (NetworkConfig.token == "") {
|
||
Navigator.pushNamed(context, "/LoginPage");
|
||
return;
|
||
}
|
||
setState(() {
|
||
currentIndex = event.index;
|
||
});
|
||
pageController.jumpToPage(event.index);
|
||
});
|
||
|
||
///刷新用户信息
|
||
_refreshUserEvent = EventBusUtil.listen((event) {
|
||
_viewModel.getUserInfo();
|
||
});
|
||
|
||
subscription = _viewModel.streamController.stream.listen((event) {
|
||
String code = event['code'];
|
||
if (code.isNotEmpty) {
|
||
switch (code) {
|
||
case "getToken":
|
||
GameTokenBean gameTokenBean = event['data'];
|
||
Map<String, dynamic> gameMap = {
|
||
"gameToken": gameTokenBean.token,
|
||
"BsUrl": NetworkConfig.configBean?.bsUrl,
|
||
"channelId": NetworkConfig.configBean?.channelId,
|
||
"userToken": NetworkConfig.token,
|
||
"signKey": NetworkConfig.signKey,
|
||
"Channel": NetworkConfig.Channel,
|
||
"Version": NetworkConfig.Version,
|
||
};
|
||
|
||
///传值初始化游戏token
|
||
invokeNativeMethod("initData", gameMap);
|
||
_viewModel.getMyScList();
|
||
break;
|
||
|
||
///启动游戏
|
||
case "playGame":
|
||
EasyLoading.dismiss();
|
||
Map<String, dynamic> gameMap = {
|
||
"gameId": event['gameId'],
|
||
"playGameData": "${event['data']}",
|
||
"isReconPlay": "false",
|
||
};
|
||
invokeNativeMethod("playGame", gameMap);
|
||
break;
|
||
|
||
///游戏错误
|
||
case "gameError":
|
||
EasyLoading.showToast("网络异常,请稍后再试");
|
||
_viewModel.cancelQueue(event['gameId']);
|
||
break;
|
||
|
||
///线路不足游戏开始排队
|
||
case "gameQueue":
|
||
EasyLoading.dismiss();
|
||
QueueBean queueBean = event['data'];
|
||
String gameId = event['gameId'];
|
||
// FunctionUtil.bottomNoSheetDialog(
|
||
// context,
|
||
// LineUpDialog(
|
||
// lineUpDialogKey,
|
||
// num: queueBean.queue_pos!,
|
||
// onTap: () {
|
||
// _viewModel.cancelQueue(gameId);
|
||
// // lineUpDialogKey.currentState?.setNum(3);
|
||
// },
|
||
// ));
|
||
|
||
showDialog(
|
||
context: context,
|
||
barrierDismissible: false,
|
||
builder: (BuildContext context) {
|
||
lineUpContext = context;
|
||
return LineUpDialog(
|
||
lineUpDialogKey,
|
||
num: queueBean.queue_pos!,
|
||
onTap: () {
|
||
_timer.cancel();
|
||
_viewModel.cancelQueue(gameId);
|
||
},
|
||
);
|
||
});
|
||
|
||
//调用排队
|
||
_timer = Timer.periodic(const Duration(milliseconds: 5000), (as) {
|
||
print("playGameQueue");
|
||
_viewModel.playGameQueue(NetworkConfig.gameId);
|
||
});
|
||
break;
|
||
|
||
///游戏排队队列
|
||
case "playGameQueue":
|
||
QueueBean queueBean = event['data'];
|
||
|
||
lineUpDialogKey.currentState?.setNum(queueBean.queue_pos);
|
||
|
||
break;
|
||
|
||
case "cancelQueue":
|
||
_timer.cancel();
|
||
break;
|
||
|
||
///排队成功 开始游戏
|
||
case "gameQueueSuccess":
|
||
Navigator.pop(lineUpContext);
|
||
_timer.cancel();
|
||
_viewModel.playGame(NetworkConfig.gameId);
|
||
break;
|
||
|
||
///可重连游戏
|
||
case "getMyScList":
|
||
reconnectBean = event['data'];
|
||
|
||
///重连弹窗
|
||
FunctionUtil.popDialog2(
|
||
context,
|
||
ReconnectDialog(
|
||
reconnectBean: reconnectBean,
|
||
onTap: (gameId, type) {
|
||
if (type == 1) {
|
||
FunctionUtil.loading();
|
||
_viewModel.reconPlayGame(gameId);
|
||
} else {
|
||
_viewModel.exitPlayGame(gameId);
|
||
}
|
||
},
|
||
));
|
||
break;
|
||
|
||
///重连游戏
|
||
case "reconPlayGame":
|
||
EasyLoading.dismiss();
|
||
Map<String, dynamic> gameMap = {
|
||
"gameId": event['gameId'],
|
||
"playGameData": "${event['data']}",
|
||
"isReconPlay": "true",
|
||
};
|
||
invokeNativeMethod("playGame", gameMap);
|
||
break;
|
||
|
||
case "reconPlayGameError":
|
||
EasyLoading.showToast(event['data']);
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
_viewModel.getToken();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
// TODO: implement dispose
|
||
_startGamesEvent.cancel();
|
||
_tabSwitchEvent.cancel();
|
||
_timer.cancel();
|
||
_refreshUserEvent.cancel();
|
||
subscription.cancel();
|
||
super.dispose();
|
||
}
|
||
|
||
void onPageChanged(int index) {
|
||
// streamSink.add(index);
|
||
if (NetworkConfig.token == "") {
|
||
Navigator.pushNamed(context, "/LoginPage");
|
||
return;
|
||
}
|
||
setState(() {
|
||
currentIndex = index;
|
||
});
|
||
pageController.jumpToPage(index);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final size = MediaQuery.of(context).size;
|
||
final h74 = size.width / 4.864864864864865;
|
||
return WillPopScope(
|
||
onWillPop: doubleClickBack,
|
||
child: Scaffold(
|
||
backgroundColor: Color(0xFF17181A),
|
||
body: Stack(
|
||
children: [
|
||
PageView(
|
||
controller: pageController,
|
||
// onPageChanged: onPageChanged,
|
||
children: bodyList,
|
||
physics: NeverScrollableScrollPhysics(), // 禁止滑动
|
||
)
|
||
],
|
||
),
|
||
bottomNavigationBar: BottomAppBar(
|
||
elevation: 0,
|
||
color: const Color(0xFF171B23),
|
||
child: bottomItem(context),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
///底部导航item
|
||
bottomItem(context) {
|
||
final size = MediaQuery.of(context).size;
|
||
final w47 = size.width / 7.659574468085106;
|
||
return NetworkConfig.isChecking
|
||
? Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
///首页
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(0);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 0
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_home.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(
|
||
width: w47,
|
||
height: w47,
|
||
image: const AssetImage('assets/images/ic_home.png'),
|
||
))
|
||
],
|
||
),
|
||
),
|
||
|
||
///游戏列表
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(1);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 1
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_game.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(width: w47, height: w47, image: const AssetImage('assets/images/ic_game.png')),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
|
||
///我的
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(2);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 2
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_me.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(
|
||
width: w47,
|
||
height: w47,
|
||
image: const AssetImage('assets/images/ic_me.png'),
|
||
),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
],
|
||
)
|
||
: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
///首页
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(0);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 0
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_home.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(
|
||
width: w47,
|
||
height: w47,
|
||
image: const AssetImage('assets/images/ic_home.png'),
|
||
))
|
||
],
|
||
),
|
||
),
|
||
|
||
///游戏列表
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(1);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 1
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_game.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(width: w47, height: w47, image: const AssetImage('assets/images/ic_game.png')),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
|
||
///商城
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(2);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 2
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_shop.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(width: w47, height: w47, image: const AssetImage('assets/images/ic_shop.png')),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
|
||
///我的
|
||
GestureDetector(
|
||
onTap: () {
|
||
onPageChanged(3);
|
||
},
|
||
child: Stack(
|
||
children: [
|
||
currentIndex == 3
|
||
? SizedBox(
|
||
width: w47,
|
||
height: w47,
|
||
child: Lottie.asset(
|
||
'assets/animation/an_me.json',
|
||
repeat: false,
|
||
),
|
||
)
|
||
: Container(
|
||
margin: const EdgeInsets.only(top: 5),
|
||
child: Image(
|
||
width: w47,
|
||
height: w47,
|
||
image: const AssetImage('assets/images/ic_me.png'),
|
||
),
|
||
)
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
int last = 0;
|
||
|
||
Future<bool> doubleClickBack() async {
|
||
int now = DateTime.now().millisecondsSinceEpoch;
|
||
|
||
if (now - last > 2500) {
|
||
last = DateTime.now().millisecondsSinceEpoch;
|
||
EasyLoading.showToast("再按一次退出");
|
||
return Future.value(false);
|
||
} else {
|
||
_viewModel.exitApp();
|
||
SystemNavigator.pop();
|
||
exit(0);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 获取原生的值
|
||
invokeNativeMethod(String method, Map<String, dynamic> map) async {
|
||
dynamic args;
|
||
try {
|
||
args = await Global.method.invokeMethod(method, map);
|
||
} on PlatformException catch (e) {}
|
||
}
|