229 lines
6.6 KiB
Dart
229 lines
6.6 KiB
Dart
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter/services.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:aslan/chatvibe_core/constants/at_global_config.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/chatvibe_ui/components/at_debounce_widget.dart';
|
||
import 'package:aslan/chatvibe_core/routes/at_fluro_navigator.dart';
|
||
import 'package:aslan/chatvibe_data/sources/repositories/room_repository_imp.dart';
|
||
import 'package:aslan/chatvibe_managers/rtc_manager.dart';
|
||
import 'package:aslan/chatvibe_features/wallet/wallet_route.dart';
|
||
import 'package:aslan/chatvibe_features/webview/bridge/at_js_bridge.dart';
|
||
|
||
class GameRyWebviewPage extends StatefulWidget {
|
||
final String url;
|
||
|
||
///安全高度
|
||
final double height;
|
||
final double width;
|
||
final String gameId;
|
||
|
||
const GameRyWebviewPage({
|
||
Key? key,
|
||
required this.url,
|
||
required this.height,
|
||
required this.width,
|
||
this.gameId = "",
|
||
}) : super(key: key);
|
||
|
||
@override
|
||
_GameRyWebviewPageState createState() => _GameRyWebviewPageState();
|
||
}
|
||
|
||
class _GameRyWebviewPageState extends State<GameRyWebviewPage> {
|
||
late WebViewController _controller;
|
||
bool _isLoading = true;
|
||
String gameLink = "";
|
||
String gameUrl = "";
|
||
late final ATJSBridge _bridge;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
Provider.of<RtcProvider>(context, listen: false).closeFullGame = false;
|
||
_bridge = ATJSBridge();
|
||
if (widget.url.split("?").length > 1) {
|
||
gameLink = "${widget.url}&";
|
||
} else {
|
||
gameLink = "${widget.url}?";
|
||
}
|
||
|
||
gameUrl =
|
||
"${gameLink}sdk=atu&uid=${AccountStorage().getCurrentUser()?.userProfile?.id}&token=${AccountStorage().token}&lang=${ATGlobalConfig.lang}";
|
||
_initializeWebViewController();
|
||
_bridge.initialize(_controller);
|
||
_uploadGameRecord();
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_controller.loadRequest(Uri.parse('about:blank'));
|
||
super.dispose();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return widget.height < 0
|
||
? SizedBox(
|
||
width: ScreenUtil().screenWidth,
|
||
height: ScreenUtil().screenHeight,
|
||
child: buidMainContent(),
|
||
)
|
||
: Column(
|
||
children: [
|
||
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(),
|
||
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.getGameWebViewLoadingIndicatorColor()),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
void _onWebResourceError(WebResourceError error) {
|
||
print('_onWebResourceError:${error.description}');
|
||
// 可以在这里添加错误处理逻辑,比如显示错误页面
|
||
}
|
||
|
||
void _initializeWebViewController() {
|
||
_controller =
|
||
WebViewController()
|
||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||
..setNavigationDelegate(
|
||
NavigationDelegate(
|
||
onPageStarted: (url) {
|
||
setState(() => _isLoading = true);
|
||
},
|
||
onPageFinished: (url) {
|
||
setState(() => _isLoading = false);
|
||
_injectBridgeScript();
|
||
},
|
||
onWebResourceError: (error) {
|
||
print('Web资源错误: ${error.description}');
|
||
_onWebResourceError(error);
|
||
},
|
||
),
|
||
)
|
||
..addJavaScriptChannel(
|
||
'ATJSBridge',
|
||
onMessageReceived: (JavaScriptMessage message) {
|
||
_bridge.handleMessage(message.message);
|
||
},
|
||
);
|
||
|
||
_bridge.initialize(_controller);
|
||
|
||
// 注册quit和recharge方法
|
||
_registerHandlers();
|
||
|
||
// 加载URL
|
||
_controller.loadRequest(Uri.parse(gameUrl));
|
||
}
|
||
|
||
void _registerHandlers() {
|
||
// 注册quit方法
|
||
_bridge.registerHandler('quit', (data) async {
|
||
Navigator.of(context).pop();
|
||
});
|
||
|
||
// 注册recharge方法
|
||
_bridge.registerHandler('recharge', (data) async {
|
||
ATNavigatorUtils.push(context, WalletRoute.recharge, replace: false);
|
||
});
|
||
}
|
||
|
||
void _injectBridgeScript() {
|
||
_controller.runJavaScript('''
|
||
// 确保window.quit是一个对象,并有postMessage方法
|
||
window.quit = window.quit || {};
|
||
|
||
window.quit.postMessage = function(message) {
|
||
// 构造发送给Flutter的消息
|
||
const payload = {
|
||
type: 'call',
|
||
handlerName: 'quit',
|
||
data: message,
|
||
callId: 'web_' + Date.now()
|
||
};
|
||
|
||
// 通过JavaScriptChannel发送消息
|
||
if (window.JSBridge) {
|
||
window.JSBridge.postMessage(JSON.stringify(payload));
|
||
}
|
||
};
|
||
|
||
window.recharge = window.recharge || {};
|
||
|
||
window.recharge.postMessage = function(message) {
|
||
// 构造发送给Flutter的消息
|
||
const payload = {
|
||
type: 'call',
|
||
handlerName: 'recharge',
|
||
data: message,
|
||
callId: 'web_' + Date.now()
|
||
};
|
||
|
||
// 通过JavaScriptChannel发送消息
|
||
if (window.JSBridge) {
|
||
window.JSBridge.postMessage(JSON.stringify(payload));
|
||
}
|
||
};
|
||
|
||
console.log('Flutter JS Bridge 初始化完成 - 支持window.quit.postMessage');
|
||
''');
|
||
}
|
||
|
||
void _uploadGameRecord() {
|
||
ChatRoomRepository().ludoHistoryRecord(
|
||
widget.gameId,
|
||
widget.height > 0 ? "IN_ROOM" : "OUT_ROOM",
|
||
);
|
||
}
|
||
}
|