import 'dart:ui' as ui; import 'package:aslan/app_localizations.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_core/utilities/at_banner_utils.dart'; import 'package:aslan/chatvibe_core/utilities/at_loading_manager.dart'; import 'package:aslan/chatvibe_data/sources/repositories/config_repository_imp.dart'; import 'package:aslan/chatvibe_domain/models/res/at_get_list_game_config_res.dart'; import 'package:aslan/chatvibe_domain/models/res/at_index_banner_res.dart'; import 'package:aslan/chatvibe_features/index/main_route.dart'; import 'package:aslan/chatvibe_managers/app_general_manager.dart'; import 'package:aslan/chatvibe_ui/components/appbar/chatvibe_appbar.dart'; import 'package:aslan/chatvibe_ui/components/at_compontent.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../../../chatvibe_data/models/enum/at_game_origin_type.dart'; import '../../../chatvibe_data/sources/repositories/room_repository_imp.dart'; import '../../../chatvibe_domain/models/res/at_game_ranking_res.dart'; /// Game页面 class ATIndexGamePage extends StatefulWidget { const ATIndexGamePage({super.key}); @override State createState() => _ATIndexGamePageState(); } class _ATIndexGamePageState extends State { static const Color _panelBorderColor = Color(0xffEDB745); static const Color _titleTextColor = Color(0xcc000000); List games = []; int _currentIndex = 0; final RefreshController _refreshController = RefreshController( initialRefresh: false, ); List gameRecords = []; @override void initState() { super.initState(); loadGames(); } @override void dispose() { _refreshController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Stack( children: [ Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.transparent, appBar: ChatVibeStandardAppBar( title: ATAppLocalizations.of(context)!.game, actions: [], showBackButton: false, // leading: Transform.translate( // offset: Offset(ATGlobalConfig.lang == "ar" ? -22.w : 22.w, 0), // child: Transform.scale( // scale: 1.43, // child: GestureDetector( // child: Consumer( // builder: (context, ref, child) { // return netImage( // url: // AccountStorage() // .getCurrentUser() // ?.userProfile // ?.userAvatar ?? // "", // defaultImg: // ATGlobalConfig.businessLogicStrategy // .getMePageDefaultAvatarImage(), // width: 32.w, // height: 32.w, // shape: BoxShape.circle, // ); // }, // ), // onTap: () { // ATNavigatorUtils.push( // context, // "${MainRoute.person}?isMe=true&tageId=${AccountStorage().getCurrentUser()?.userProfile?.id}", // ); // }, // ), // ), // ), ), body: SmartRefresher( enablePullDown: true, enablePullUp: false, controller: _refreshController, onRefresh: () { loadGames(); }, onLoading: () {}, child: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Selector>( selector: (_, provider) => List.unmodifiable( provider.gameBanners, ), builder: (context, gameBanners, child) { return _banner(gameBanners); }, ), SizedBox(height: 5.w), _buildPlayLogSection(context), SizedBox(height: 12.w), _buildAllGamesSection(context), SizedBox(height: 20.w), ], ), ), ), ), ], ); } Widget _buildPlayLogSection(BuildContext context) { return _buildPanel( child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildSectionHeader(ATAppLocalizations.of(context)!.playLog), SizedBox(height: 10.w), Container( height: 50.w, padding: EdgeInsets.symmetric(horizontal: 12.w), child: gameRecords.isEmpty ? _buildCompactEmpty(context) : LayoutBuilder( builder: (context, constraints) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: ConstrainedBox( constraints: BoxConstraints( minWidth: constraints.maxWidth, ), child: Row( spacing: 5.w, mainAxisAlignment: MainAxisAlignment.start, children: List.generate(gameRecords.length, ( index, ) { return _buildPlayLogItem(gameRecords[index]); }), ), ), ); }, ), ), SizedBox(height: 10.w), ], ), ); } Widget _buildAllGamesSection(BuildContext context) { return _buildPanel( child: Column( mainAxisSize: MainAxisSize.min, children: [ _buildSectionHeader( ATAppLocalizations.of(context)!.allGames, showIndicator: true, ), SizedBox(height: 10.w), games.isEmpty ? Padding( padding: EdgeInsets.only(bottom: 10.w), child: _buildCompactEmpty(context), ) : GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: EdgeInsets.fromLTRB(10.w, 0, 10.w, 10.w), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, childAspectRatio: 1, mainAxisSpacing: 5.w, crossAxisSpacing: 5.w, ), itemCount: games.length, itemBuilder: (context, index) { return _buildGameGridItem(games[index]); }, ), ], ), ); } Widget _buildPanel({required Widget child}) { return Container( width: double.infinity, margin: EdgeInsets.symmetric(horizontal: 10.w), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: _panelBorderColor, width: 1.w), borderRadius: BorderRadius.circular(12.w), ), child: ClipRRect(borderRadius: BorderRadius.circular(1.w), child: child), ); } Widget _buildSectionHeader(String title, {bool showIndicator = false}) { return Container( height: 31.w, width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 10.w), child: Stack( alignment: AlignmentDirectional.centerStart, children: [ Text( title, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: _titleTextColor, fontSize: 16.sp, fontWeight: FontWeight.w600, decoration: TextDecoration.none, ), ), if (showIndicator) PositionedDirectional( start: 31.w, bottom: 1.w, child: Container( width: 15.w, height: 3.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(22.w), color: const Color(0xffFF9500), ), ), ), ], ), ); } Widget _buildPlayLogItem(ATGetListGameConfigRes game) { return GestureDetector( onTap: () { openGame(game.gameOrigin ?? "", game.gameCode ?? "", game.id ?? ""); }, child: netImage( url: game.cover ?? "", width: 50.w, height: 50.w, fit: BoxFit.cover, borderRadius: BorderRadius.circular(7.w), border: Border.all(color: _panelBorderColor, width: 1.w), ), ); } Widget _buildGameGridItem(Records game) { return GestureDetector( onTap: () { openGame(game.gameOrigin ?? "", game.gameUrl ?? "", game.gameId ?? ""); }, child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 105.w, height: 105.w, child: Stack( fit: StackFit.expand, clipBehavior: Clip.none, children: [ netImage( url: game.gameCover ?? "", fit: BoxFit.cover, borderRadius: BorderRadius.circular(14.w), border: Border.all(color: _panelBorderColor, width: 2.w), ), if (game.latest ?? false) PositionedDirectional( start: 4.w, bottom: 2.w, child: Image.asset( ATGlobalConfig.businessLogicStrategy.getGameNewTagImage(), height: 22.w, ), ), ], ), ), ], ), ); } Widget _buildCompactEmpty(BuildContext context) { return Center( child: Text( ATAppLocalizations.of(context)!.noData, style: TextStyle( color: Colors.black38, fontSize: 12.sp, fontWeight: FontWeight.w500, decoration: TextDecoration.none, ), ), ); } _banner(List gameBanners) { return gameBanners.isEmpty ? Container() : Stack( alignment: AlignmentDirectional.bottomCenter, children: [ Container( margin: EdgeInsets.symmetric(horizontal: 17.w), child: CarouselSlider( options: CarouselOptions( height: 98.w, autoPlay: true, // 启用自动播放 enlargeCenterPage: false, // 居中放大当前页面 enableInfiniteScroll: true, // 启用无限循环 autoPlayAnimationDuration: Duration(milliseconds: 800), // 自动播放动画时长 viewportFraction: 1, // 视口分数 onPageChanged: (index, reason) { _currentIndex = index; setState(() {}); }, ), items: gameBanners.map((item) { return GestureDetector( child: netImage( url: item.cover ?? "", height: 98.w, width: ScreenUtil().screenWidth * 0.9, fit: BoxFit.contain, borderRadius: BorderRadius.circular(12.w), ), onTap: () { print('ads:${item.toJson()}'); ATBannerUtils.openBanner(item, context); }, ); }).toList(), ), ), Row( mainAxisAlignment: MainAxisAlignment.center, children: gameBanners.asMap().entries.map((entry) { return Container( width: 6.0, height: 6.0, margin: EdgeInsets.symmetric( vertical: 15.0, horizontal: 4.0, ), decoration: BoxDecoration( shape: BoxShape.circle, color: _currentIndex == entry.key ? Colors.blue : Colors.white, ), ); }).toList(), ), ], ); ; } void loadGames() { ATLoadingManager.exhibitOperation(); games.clear(); gameRecords.clear(); Future.wait([ ChatRoomRepository().gameLudoHistoryRecent("OUT_ROOM"), ConfigRepositoryImp().gameRanking(1, "WEEK", size: 110), ]) .then((result) { gameRecords = result[0] as List ?? []; games = (result[1] as ATGameRankingRes).records ?? []; _refreshController.refreshCompleted(); _refreshController.loadComplete(); if (mounted) setState(() {}); ATLoadingManager.veilRoutine(); }) .catchError((e) { _refreshController.loadNoData(); _refreshController.refreshCompleted(); if (mounted) setState(() {}); ATLoadingManager.veilRoutine(); }); Provider.of(context, listen: false).loadMainBanner(); } void openGame(String gameOrigin, String gameUrl, String gameId) { if (gameOrigin == ATGameOriginType.LINGXIAN.name) { ATNavigatorUtils.push( context, "${MainRoute.gameLxWebviewPage}?url=${Uri.encodeComponent(gameUrl)}&gameId=$gameId&height=-1&width=-1", replace: false, ); } else if (gameOrigin == ATGameOriginType.BAISHUN.name) { ATNavigatorUtils.push( context, "${MainRoute.gameBsWebviewPage}?url=${Uri.encodeComponent(gameUrl)}&gameId=$gameId&height=-1&width=-1", replace: false, ); } else if (gameOrigin == ATGameOriginType.HOTGAME.name) { ATNavigatorUtils.push( context, "${MainRoute.gameRyWebviewPage}?url=${Uri.encodeComponent(gameUrl)}&gameId=$gameId&height=-1&width=-1", replace: false, ); } else if (gameOrigin == ATGameOriginType.YOMI.name) { ATNavigatorUtils.push( context, "${MainRoute.gameYmWebviewPage}?url=${Uri.encodeComponent(gameUrl)}&gameId=$gameId&height=-1&width=-1", replace: false, ); } } }