aslan-flutter/lib/chatvibe_features/webview/game_lx_webview_page.dart
2026-07-01 18:25:58 +08:00

189 lines
5.7 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';
class GameLxWebviewPage extends StatefulWidget {
final String url;
///安全高度
final double height;
final double width;
final String gameId;
const GameLxWebviewPage({
Key? key,
required this.url,
required this.height,
required this.width,
this.gameId = "",
}) : super(key: key);
@override
_GameLxWebviewPageState createState() => _GameLxWebviewPageState();
}
class _GameLxWebviewPageState extends State<GameLxWebviewPage> {
late WebViewController _controller;
bool _isLoading = true;
String gameLink = "";
String gameUrl = "";
@override
void initState() {
super.initState();
Provider.of<RtcProvider>(context, listen: false).closeFullGame = false;
if (widget.url.split("?").length > 1) {
gameLink = "${widget.url}&";
} else {
gameLink = "${widget.url}?";
}
gameUrl =
"${gameLink}uid=${AccountStorage().getCurrentUser()?.userProfile?.id}&token=${AccountStorage().token}&lang=${ATGlobalConfig.lang}&time=${DateTime.now().millisecondsSinceEpoch}";
_initializeWebViewController();
_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)
..loadRequest(Uri.parse(gameUrl)) // 游戏网址
..addJavaScriptChannel(
'pay',
onMessageReceived: (message) {
debugPrint('pay callback: ${message.message}');
// 实际支付处理逻辑
ATNavigatorUtils.push(
context,
WalletRoute.recharge,
replace: false,
);
},
)
..addJavaScriptChannel(
'closeGame',
onMessageReceived: (message) {
debugPrint('closeGame callback');
Navigator.of(context).pop();
},
)
..addJavaScriptChannel(
'loadComplete',
onMessageReceived: (message) {
debugPrint('game load complete');
setState(() {
_isLoading = false;
});
},
)
..setNavigationDelegate(
NavigationDelegate(
onPageFinished: (url) {
setState(() {
_isLoading = false;
});
},
onWebResourceError: (WebResourceError error) {
_onWebResourceError(error);
},
),
);
}
/// 调用游戏币更新
void updateCoin() {
_controller.runJavaScript('updateCoin();');
}
void _uploadGameRecord() {
ChatRoomRepository().ludoHistoryRecord(
widget.gameId,
widget.height > 0 ? "IN_ROOM" : "OUT_ROOM",
);
}
}