417 lines
14 KiB
Dart
417 lines
14 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
import 'package:aslan/chatvibe_ui/components/at_debounce_widget.dart';
|
|
import 'package:aslan/chatvibe_core/constants/at_global_config.dart';
|
|
import 'package:aslan/chatvibe_core/routes/at_fluro_navigator.dart';
|
|
import 'package:aslan/chatvibe_data/sources/local/user_manager.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
import 'package:aslan/app_localizations.dart';
|
|
import 'package:aslan/chatvibe_ui/components/dialog/dialog_base.dart';
|
|
import 'package:aslan/chatvibe_data/sources/repositories/room_repository_imp.dart';
|
|
import 'package:aslan/chatvibe_domain/models/res/at_get_game_config_data.dart';
|
|
import 'package:aslan/chatvibe_managers/rtc_manager.dart';
|
|
import 'package:aslan/chatvibe_features/wallet/wallet_route.dart';
|
|
|
|
import '../../chatvibe_data/models/enum/at_game_mode_type.dart';
|
|
|
|
class GameBsWebviewPage extends StatefulWidget {
|
|
final String url;
|
|
|
|
///安全高度
|
|
final double height;
|
|
final double width;
|
|
final String gameMode;
|
|
final String gameId;
|
|
|
|
const GameBsWebviewPage({
|
|
Key? key,
|
|
required this.url,
|
|
required this.height,
|
|
required this.width,
|
|
this.gameMode = "",
|
|
this.gameId = "",
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
_GameBsWebviewPageState createState() => _GameBsWebviewPageState();
|
|
}
|
|
|
|
class _GameBsWebviewPageState extends State<GameBsWebviewPage> {
|
|
late WebViewController _controller;
|
|
double _progress = 0.0;
|
|
bool _isLoading = true;
|
|
|
|
final EventChannel _eventChannelPlugin = EventChannel('baishunChannel');
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
Provider.of<RtcProvider>(context, listen: false).closeFullGame = false;
|
|
// 初始化 WebViewController
|
|
_controller =
|
|
WebViewController()
|
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
..addJavaScriptChannel(
|
|
"baishunChannel",
|
|
onMessageReceived: (sjMessage) {},
|
|
)
|
|
..setNavigationDelegate(
|
|
NavigationDelegate(
|
|
onProgress: (int progress) {
|
|
setState(() {
|
|
_progress = progress / 100.0;
|
|
});
|
|
},
|
|
onPageStarted: (String url) {
|
|
setState(() {
|
|
_isLoading = true;
|
|
});
|
|
},
|
|
onPageFinished: (String url) {
|
|
_injectJavaScriptInterface();
|
|
},
|
|
onWebResourceError: (WebResourceError error) {
|
|
_onWebResourceError(error);
|
|
},
|
|
),
|
|
)
|
|
..loadRequest(Uri.parse(widget.url));
|
|
bindChannel();
|
|
_uploadGameRecord();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_controller.loadRequest(Uri.parse('about:blank'));
|
|
super.dispose();
|
|
}
|
|
|
|
void _injectJavaScriptInterface() async {}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return widget.height < 0
|
|
? SizedBox(
|
|
width: ScreenUtil().screenWidth,
|
|
height: ScreenUtil().screenHeight,
|
|
child: buidMainContent(),
|
|
)
|
|
: Column(
|
|
children: [
|
|
widget.gameMode == ATGameModeType.CHAT_ROOM.name
|
|
? Container()
|
|
: Row(
|
|
children: [
|
|
Spacer(),
|
|
ATDebounceWidget(
|
|
child: Icon(
|
|
Icons.close,
|
|
color:
|
|
ATGlobalConfig.businessLogicStrategy
|
|
.getGameWebViewCloseIconColor(),
|
|
size: 25.w,
|
|
),
|
|
onTap: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
SizedBox(width: 3.w),
|
|
],
|
|
),
|
|
SizedBox(height: 6.w),
|
|
AspectRatio(
|
|
aspectRatio: (750 / widget.height),
|
|
child: buidMainContent(),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget buidMainContent() {
|
|
return Scaffold(
|
|
backgroundColor:
|
|
ATGlobalConfig.businessLogicStrategy
|
|
.getGameWebViewScaffoldBackgroundColor(),
|
|
resizeToAvoidBottomInset: false,
|
|
body: SafeArea(
|
|
top: false,
|
|
child: Stack(
|
|
children: [
|
|
Selector<RtcProvider, bool>(
|
|
selector: (c, p) => p.closeFullGame,
|
|
shouldRebuild: (prev, next) => prev != next,
|
|
builder: (_, closeFullGame, __) {
|
|
if (closeFullGame) {
|
|
Navigator.of(context).removeRoute(ModalRoute.of(context)!);
|
|
}
|
|
return Container();
|
|
},
|
|
),
|
|
WebViewWidget(controller: _controller),
|
|
|
|
// 加载指示器
|
|
if (_isLoading)
|
|
Center(
|
|
child: CircularProgressIndicator(
|
|
valueColor: AlwaysStoppedAnimation<Color>(
|
|
ATGlobalConfig.businessLogicStrategy
|
|
.getWebViewPageProgressBarActiveColor(),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _progressBar(double progress, BuildContext context) {
|
|
return progress < 1.0
|
|
? LinearProgressIndicator(
|
|
value: progress,
|
|
backgroundColor:
|
|
ATGlobalConfig.businessLogicStrategy
|
|
.getGameWebViewProgressBarBackgroundColor(),
|
|
minHeight: 1.0,
|
|
valueColor: AlwaysStoppedAnimation<Color>(
|
|
ATGlobalConfig.businessLogicStrategy
|
|
.getWebViewPageProgressBarActiveColor(),
|
|
),
|
|
)
|
|
: const SizedBox.shrink();
|
|
}
|
|
|
|
void _onWebResourceError(WebResourceError error) {
|
|
print('_onWebResourceError:${error.description}');
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
// 可以在这里添加错误处理逻辑,比如显示错误页面
|
|
}
|
|
|
|
void bindChannel() {
|
|
if (Platform.isAndroid) {
|
|
_eventChannelPlugin.receiveBroadcastStream().listen((event) {
|
|
final obj = json.decode(event);
|
|
String jsFunName = obj['jsCallback'];
|
|
if (jsFunName.contains('getConfig')) {
|
|
print("BSGAME游戏调⽤getConfig main.dart");
|
|
ATGetGameConfigData _configData = ATGetGameConfigData(
|
|
appChannel: ATGlobalConfig.gameAppChannel,
|
|
appId: ATGlobalConfig.gameAppid,
|
|
userId: AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
|
|
gameMode:
|
|
widget.height < 0
|
|
? "3"
|
|
: (widget.gameMode == ATGameModeType.CHAT_ROOM.name
|
|
? "3"
|
|
: "2"),
|
|
language: ATGlobalConfig.lang == "ar" ? "7" : "2",
|
|
gsp: 101,
|
|
roomId:
|
|
Provider.of<RtcProvider>(
|
|
context,
|
|
listen: false,
|
|
).currenRoom?.roomProfile?.roomProfile?.id ??
|
|
"",
|
|
gameRoomId: "",
|
|
code: AccountStorage().getToken(),
|
|
role:
|
|
Provider.of<RtcProvider>(context, listen: false).isFz()
|
|
? "2"
|
|
: "0",
|
|
gameConfig: GameConfig(
|
|
sceneMode: 0,
|
|
currencyIcon:
|
|
"https://tkm-atu.oss-ap-southeast-1.aliyuncs.com/avatar/b1bc4425-0037-433b-bf00-6977620ff57e.png",
|
|
),
|
|
);
|
|
String jsUrl = jsFunName + "(${jsonEncode(_configData.toJson())})";
|
|
_controller!.runJavaScript(jsUrl);
|
|
} else if (jsFunName.contains('destroy')) {
|
|
print("BSGAME游戏调⽤destroy main.dart");
|
|
//关闭游戏TODO客⼾端
|
|
_controller.loadRequest(Uri.parse('about:blank'));
|
|
if (widget.gameMode == ATGameModeType.CHAT_ROOM) {
|
|
Provider.of<RtcProvider>(
|
|
context,
|
|
listen: false,
|
|
).roomMannyGameClose();
|
|
} else {
|
|
Navigator.of(context).pop();
|
|
}
|
|
super.dispose();
|
|
} else if (jsFunName.contains('gameRecharge')) {
|
|
print("BSGAME游戏调⽤gameRecharge main.dart");
|
|
//拉起⽀付商城TODO客⼾端
|
|
_showGameRecharge();
|
|
} else if (jsFunName.contains('gameLoaded')) {
|
|
print("BSGAME游戏调⽤gameLoaded main.dart");
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
//游戏加载完毕TODO客⼾端
|
|
} else if (jsFunName.contains('sendGameAction')) {
|
|
print("BSGAME游戏调⽤sendGameAction main.dart--${obj}");
|
|
String str = sendGameActionUtil(obj);
|
|
if (str.isNotEmpty) {
|
|
_controller.runJavaScript(str);
|
|
}
|
|
}
|
|
});
|
|
} else {
|
|
_controller.addJavaScriptChannel(
|
|
"getConfig",
|
|
onMessageReceived: (JavaScriptMessage jsonMessage) {
|
|
print("BSGAME 游戏调⽤getConfig main.dart ios");
|
|
final obj = json.decode(jsonMessage.message);
|
|
String jsFunName = obj['jsCallback'];
|
|
ATGetGameConfigData _configData = ATGetGameConfigData(
|
|
appChannel: ATGlobalConfig.gameAppChannel,
|
|
appId: ATGlobalConfig.gameAppid,
|
|
userId: AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
|
|
gameMode: widget.height < 0 ? "3" : "2",
|
|
language: ATGlobalConfig.lang == "ar" ? "7" : "2",
|
|
gsp: 101,
|
|
roomId:
|
|
Provider.of<RtcProvider>(
|
|
context,
|
|
listen: false,
|
|
).currenRoom?.roomProfile?.roomProfile?.id ??
|
|
"",
|
|
code: AccountStorage().getToken(),
|
|
gameConfig: GameConfig(
|
|
sceneMode: 0,
|
|
currencyIcon:
|
|
"https://tkm-atu.oss-ap-southeast-1.aliyuncs.com/avatar/b1bc4425-0037-433b-bf00-6977620ff57e.png",
|
|
),
|
|
);
|
|
String jsUrl = jsFunName + "(${jsonEncode(_configData.toJson())})";
|
|
_controller!.runJavaScript(jsUrl);
|
|
},
|
|
);
|
|
_controller.addJavaScriptChannel(
|
|
"destroy",
|
|
onMessageReceived: (JavaScriptMessage message) {
|
|
print("BSGAME 游戏调⽤destroy main.dart ios");
|
|
_controller.loadRequest(Uri.parse('about:blank'));
|
|
if (widget.gameMode == ATGameModeType.CHAT_ROOM) {
|
|
Provider.of<RtcProvider>(
|
|
context,
|
|
listen: false,
|
|
).roomMannyGameClose();
|
|
} else {
|
|
Navigator.of(context).pop();
|
|
}
|
|
super.dispose();
|
|
},
|
|
);
|
|
_controller.addJavaScriptChannel(
|
|
"gameRecharge",
|
|
onMessageReceived: (JavaScriptMessage message) {
|
|
print("BSGAME 游戏调⽤gameRecharge main.dart ios");
|
|
_showGameRecharge();
|
|
},
|
|
);
|
|
_controller.addJavaScriptChannel(
|
|
"gameLoaded",
|
|
onMessageReceived: (JavaScriptMessage message) {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
print("BSGAME 游戏调⽤gameLoaded main.dart ios");
|
|
},
|
|
);
|
|
_controller.addJavaScriptChannel(
|
|
"sendGameAction",
|
|
onMessageReceived: (JavaScriptMessage message) {
|
|
String str = sendGameActionUtil(message.message);
|
|
if (str.isNotEmpty) {
|
|
_controller.runJavaScript(str);
|
|
}
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
void _showGameRecharge() {
|
|
SmartDialog.dismiss(tag: "showConfirmDialog");
|
|
SmartDialog.show(
|
|
tag: "showConfirmDialog",
|
|
alignment: Alignment.center,
|
|
animationType: SmartAnimationType.fade,
|
|
builder: (_) {
|
|
return MsgDialog(
|
|
title: ATAppLocalizations.of(context)!.tips,
|
|
msg: ATAppLocalizations.of(context)!.balanceNotEnough,
|
|
btnText: ATAppLocalizations.of(context)!.confirm,
|
|
onEnsure: () {
|
|
SmartDialog.dismiss(tag: "showConfirmDialog");
|
|
ATNavigatorUtils.push(
|
|
context,
|
|
WalletRoute.recharge,
|
|
replace: false,
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
String sendGameActionUtil(message) {
|
|
String result = '';
|
|
int type = message['type'];
|
|
Map<String, dynamic> params = message['params'];
|
|
switch (type) {
|
|
case 13: //游戏开始
|
|
break;
|
|
case 14: //游戏结束
|
|
break;
|
|
case 15: //上下座
|
|
int optType = params['optType']; //0 上座,1 下座
|
|
String userId = params['userId']; //用户 id
|
|
int seat = params['seat']; ////座位位置
|
|
//如果不鉴权就直接把下面的消息返回
|
|
final Map<String, dynamic> map = {};
|
|
map["optType"] = optType;
|
|
map["userId"] = userId;
|
|
map["seat"] = seat;
|
|
final Map<String, dynamic> parentMap = {};
|
|
parentMap["type"] = 4; // 使用下标操作符添加数据
|
|
parentMap["params"] = map;
|
|
result = "gameActionUpdate(${json.encode(parentMap)})";
|
|
break;
|
|
case 17: //踢人
|
|
String userId = params['userId'];
|
|
int seat = params['seat'];
|
|
|
|
//如果不鉴权就直接把下面的消息返回
|
|
final Map<String, dynamic> map = {};
|
|
map["optResult"] = 0;
|
|
map["optUserId"] = AccountStorage().getCurrentUser()?.userProfile?.id;
|
|
map["userId"] = userId;
|
|
map["reason"] = seat;
|
|
final Map<String, dynamic> parentMap = {};
|
|
parentMap["type"] = 6; // 使用下标操作符添加数据
|
|
parentMap["params"] = map;
|
|
result = "gameActionUpdate(${json.encode(parentMap)})";
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void _uploadGameRecord() {
|
|
ChatRoomRepository().ludoHistoryRecord(
|
|
widget.gameId,
|
|
widget.height > 0 ? "IN_ROOM" : "OUT_ROOM",
|
|
);
|
|
}
|
|
}
|