import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/shared/tools/sc_lk_dialog_util.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; class RoomGameEntryButton extends StatelessWidget { const RoomGameEntryButton({super.key}); @override Widget build(BuildContext context) { return SCDebounceWidget( onTap: () { showBottomInBottomDialog( context, const RoomGameBottomSheet(), barrierColor: Colors.black54, ); }, child: Container( width: 44.w, height: 44.w, alignment: Alignment.center, decoration: BoxDecoration( shape: BoxShape.circle, color: const Color(0xff09372E).withValues(alpha: 0.72), border: Border.all( color: Colors.white.withValues(alpha: 0.22), width: 1.w, ), boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.18), blurRadius: 10.w, offset: Offset(0, 4.w), ), ], ), child: Text( // 当前先用代码绘制的 `🎮` 作为语言房游戏入口占位, // 后续设计图到位后直接替换成正式 UI 图片资源即可。 '🎮', style: TextStyle(fontSize: 22.sp), ), ), ); } } class RoomGameBottomSheet extends StatelessWidget { const RoomGameBottomSheet({super.key}); static const int _itemsPerRow = 5; /// 静态占位数据,后续接入真实接口后直接替换这里的数据源即可。 static const List<_RoomGameItem> _mockGames = [ _RoomGameItem(name: 'Ludo', icon: Icons.casino_outlined), _RoomGameItem(name: 'Dice', icon: Icons.casino), _RoomGameItem(name: 'UNO', icon: Icons.style_outlined), _RoomGameItem(name: 'Quiz', icon: Icons.psychology_outlined), _RoomGameItem(name: 'Race', icon: Icons.sports_motorsports_outlined), _RoomGameItem(name: 'Poker', icon: Icons.style), _RoomGameItem(name: 'Lucky', icon: Icons.auto_awesome_outlined), _RoomGameItem(name: 'Bingo', icon: Icons.grid_on_outlined), _RoomGameItem(name: '2048', icon: Icons.apps_outlined), _RoomGameItem(name: 'Chess', icon: Icons.extension_outlined), _RoomGameItem(name: 'Keno', icon: Icons.confirmation_number_outlined), _RoomGameItem(name: 'Cards', icon: Icons.view_carousel_outlined), _RoomGameItem(name: 'Darts', icon: Icons.gps_fixed), _RoomGameItem(name: 'Puzzle', icon: Icons.interests_outlined), _RoomGameItem(name: 'Slots', icon: Icons.local_activity_outlined), _RoomGameItem(name: 'Spin', icon: Icons.blur_circular_outlined), _RoomGameItem(name: 'Snake', icon: Icons.route_outlined), _RoomGameItem(name: 'Party', icon: Icons.celebration_outlined), _RoomGameItem(name: 'Hero', icon: Icons.shield_outlined), _RoomGameItem(name: 'Arena', icon: Icons.sports_esports_outlined), ]; @override Widget build(BuildContext context) { final rowCount = (_mockGames.length / _itemsPerRow).ceil(); return SafeArea( top: false, child: ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(18.w), topRight: Radius.circular(18.w), ), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 16, sigmaY: 16), child: Container( width: ScreenUtil().screenWidth, height: ScreenUtil().screenHeight / 3, color: const Color(0xff09372E).withValues(alpha: 0.88), child: Column( children: [ SizedBox(height: 10.w), Container( width: 34.w, height: 4.w, decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.28), borderRadius: BorderRadius.circular(99.w), ), ), Padding( padding: EdgeInsets.fromLTRB(16.w, 14.w, 16.w, 10.w), child: Row( children: [ text( 'Games', fontSize: 16, fontWeight: FontWeight.w700, textColor: Colors.white, ), const Spacer(), text( 'Static mock data', fontSize: 11, textColor: Colors.white70, ), ], ), ), Expanded( child: ListView.builder( padding: EdgeInsets.fromLTRB(12.w, 0, 12.w, 20.w), itemCount: rowCount, itemBuilder: (context, rowIndex) { return Padding( padding: EdgeInsets.only(bottom: 12.w), child: Row( children: List.generate(_itemsPerRow, (columnIndex) { final itemIndex = rowIndex * _itemsPerRow + columnIndex; return Expanded( child: Padding( padding: EdgeInsets.symmetric(horizontal: 4.w), child: itemIndex < _mockGames.length ? _RoomGameTile( item: _mockGames[itemIndex], ) : const SizedBox.shrink(), ), ); }), ), ); }, ), ), ], ), ), ), ), ); } } class _RoomGameTile extends StatelessWidget { const _RoomGameTile({required this.item}); final _RoomGameItem item; @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ Container( width: 48.w, height: 48.w, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ const Color(0xff18F2B1).withValues(alpha: 0.26), Colors.white.withValues(alpha: 0.08), ], ), border: Border.all( color: Colors.white.withValues(alpha: 0.2), width: 1.w, ), ), alignment: Alignment.center, child: Icon( // 当前先用系统 Icon 占位,后续会替换成具体游戏 UI 图标/图片资源。 item.icon, size: 22.w, color: Colors.white, ), ), SizedBox(height: 6.w), text( item.name, fontSize: 11, textColor: Colors.white, fontWeight: FontWeight.w500, textAlign: TextAlign.center, maxLines: 1, ), ], ); } } class _RoomGameItem { const _RoomGameItem({required this.name, required this.icon}); final String name; final IconData icon; }