import 'package:cached_network_image/cached_network_image.dart'; import 'package:dating_touchme_app/controller/discover/room_controller.dart'; import 'package:dating_touchme_app/controller/global.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/live/gift_product_model.dart'; import 'package:dating_touchme_app/model/rtc/rtc_channel_detail.dart'; import 'package:dating_touchme_app/widget/live/live_room_gift_item.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class LiveGiftPopup extends StatefulWidget { const LiveGiftPopup({ super.key, required this.activeGift, required this.giftNum, required this.giftList, required this.changeActive, this.showHeader = true, this.targetUserId, this.type, }); final ValueNotifier activeGift; final ValueNotifier giftNum; final List giftList; // 支持 List 或 List final void Function(int) changeActive; final bool showHeader; // 是否显示头部(用户选择部分) final int? targetUserId; // 预设的目标用户ID final int? type; @override State createState() => _LiveGiftPopupState(); } class _LiveGiftPopupState extends State { // 选中的用户ID(单选) int? _selectedUserId; // 标记是否已经尝试过设置默认选中 bool _hasTriedSetDefault = false; @override void initState() { super.initState(); // 如果传入了目标用户ID,直接设置 if (widget.targetUserId != null) { _selectedUserId = widget.targetUserId; } else if (widget.showHeader) { // 如果没有传入目标用户ID且显示头部,默认选中主持人 _initDefaultSelectedUser(); } // 默认选择第一个礼物 if (widget.giftList.isNotEmpty && widget.activeGift.value == null) { widget.activeGift.value = 0; } } /// 初始化默认选中的用户(主持人) void _initDefaultSelectedUser() { try { final roomController = Get.isRegistered() ? Get.find() : null; if (roomController != null) { final rtcChannelDetail = roomController.rtcChannelDetail.value; // 默认选中主持人(anchorInfo) if (rtcChannelDetail?.anchorInfo != null) { final anchorInfo = rtcChannelDetail!.anchorInfo!; // 获取当前用户ID,排除本人 final currentUserId = GlobalData().userId ?? GlobalData().userData?.id; // 如果主持人不是本人,则默认选中 if (anchorInfo.userId != currentUserId && anchorInfo.miId != currentUserId) { // 使用 uid 作为选中标识 if (anchorInfo.uid != null) { setState(() { _selectedUserId = anchorInfo.uid; }); } } } } } catch (e) { print('初始化默认选中用户失败: $e'); } } // 切换用户选中状态(单选模式) void _toggleUserSelection(int userId) { setState(() { if (_selectedUserId == userId) { // 如果点击的是已选中的用户,则取消选中 _selectedUserId = null; } else { // 否则选中该用户(自动取消之前的选中) _selectedUserId = userId; } }); } // 处理赠送礼物 Future _handleSendGift(int type) async { // 检查是否选中了礼物 final activeIndex = widget.activeGift.value; if (activeIndex == null || activeIndex < 0 || activeIndex >= widget.giftList.length) { SmartDialog.showToast('请先选择礼物'); return; } // 检查是否选中了接收用户(如果showHeader为false,则必须有targetUserId) if (widget.showHeader) { // 如果显示头部,需要检查是否选中了用户 if (_selectedUserId == null || _selectedUserId == 0) { SmartDialog.showToast('请先选择接收礼物的用户'); return; } } else { // 如果不显示头部,应该使用targetUserId,但如果targetUserId也没有,则检查_selectedUserId if (widget.targetUserId == null && (_selectedUserId == null || _selectedUserId == 0)) { SmartDialog.showToast('请先选择接收礼物的用户'); return; } } // 获取选中的礼物 final giftItem = widget.giftList[activeIndex]; GiftProductModel? gift; if (giftItem is GiftProductModel) { gift = giftItem; } else if (giftItem is Map) { // 如果是 Map,需要从 RoomController 的 giftProducts 中查找 SmartDialog.showToast('礼物数据格式错误'); return; } else { SmartDialog.showToast('礼物数据格式错误'); return; } // 获取 RoomController final roomController = Get.isRegistered() ? Get.find() : null; if (roomController == null) { SmartDialog.showToast('房间控制器未初始化'); return; } // 发送礼物 await roomController.sendGift(gift: gift, targetUserId: _selectedUserId ?? 0, type: type); SmartDialog.dismiss(); } @override Widget build(BuildContext context) { return Material( color: Colors.transparent, child: Container( color: const Color.fromRGBO(41, 31, 61, 1), height: 363.w, child: Column( children: [ if (widget.showHeader) _buildHeader(), Expanded( child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: Radius.circular(9.w), ), color: const Color.fromRGBO(22, 19, 28, 1), ), child: Column( children: [ _buildGiftSwiper(), _buildBottomBar(), ], ), ), ), ], ), ), ); } Widget _buildHeader() { // 获取 RoomController(在 Obx 外部获取,避免重复查找) final roomController = Get.isRegistered() ? Get.find() : null; if (roomController == null) { return Container( height: 53.w, padding: EdgeInsets.symmetric(horizontal: 10.w), child: Row( children: [ Text( "送给: ", style: TextStyle(fontSize: 13.w, color: Colors.white), ), ], ), ); } return Obx(() { // 直接访问响应式变量,让 Obx 能够正确监听变化 final rtcChannelDetail = roomController.rtcChannelDetail.value; // 获取当前用户ID final currentUserId = GlobalData().userId ?? GlobalData().userData?.id; // 构建用户列表(anchorInfo, maleInfo, femaleInfo) final List userList = []; if (rtcChannelDetail?.anchorInfo != null) { userList.add(rtcChannelDetail!.anchorInfo!); } if (rtcChannelDetail?.maleInfo != null) { userList.add(rtcChannelDetail!.maleInfo!); } if (rtcChannelDetail?.femaleInfo != null) { userList.add(rtcChannelDetail!.femaleInfo!); } // 移除本人 final filteredUserList = userList.where((user) { // 通过 userId 或 miId 判断是否是本人 return user.userId != currentUserId && user.miId != currentUserId; }).toList(); // 最多显示3个用户 final displayUsers = filteredUserList.take(3).toList(); // 如果还没有选中用户,且主持人存在且不是本人,默认选中主持人 if (!_hasTriedSetDefault && _selectedUserId == null && rtcChannelDetail?.anchorInfo != null) { final anchorInfo = rtcChannelDetail!.anchorInfo!; if (anchorInfo.userId != currentUserId && anchorInfo.miId != currentUserId && anchorInfo.uid != null) { _hasTriedSetDefault = true; WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted && _selectedUserId == null) { setState(() { _selectedUserId = anchorInfo.uid; }); } }); } } return Container( height: 53.w, padding: EdgeInsets.symmetric(horizontal: 10.w), child: Row( children: [ Row( children: [ Text( "送给: ", style: TextStyle(fontSize: 13.w, color: Colors.white), ), SizedBox(width: 6.w), ...displayUsers.asMap().entries.map((entry) { final index = entry.key; final user = entry.value; final isSelected = _selectedUserId == user.uid; return GestureDetector( onTap: () => _toggleUserSelection(user.uid ?? 0), child: Padding( padding: EdgeInsets.only(right: 10.w), child: Stack( children: [ ClipRRect( borderRadius: BorderRadius.all( Radius.circular(index == 0 ? 68.w : 34.w), ), child: Container( width: 34.w, height: 34.w, decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(index == 0 ? 68.w : 34.w), ), border: Border.all( width: index == 0 ? 2 : 1, color: const Color.fromRGBO(117, 98, 249, 1), ), ), child: user.profilePhoto.isNotEmpty ? CachedNetworkImage( imageUrl: user.profilePhoto, width: 34.w, height: 34.w, fit: BoxFit.cover, placeholder: (context, url) => Container( width: 34.w, height: 34.w, color: Colors.grey[300], child: Center( child: SizedBox( width: 16.w, height: 16.w, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.grey[600], ), ), ), ), errorWidget: (context, url, error) => Image.asset( Assets.imagesUserAvatar, width: 32.w, height: 32.w, ), ) : Image.asset( Assets.imagesUserAvatar, width: 32.w, height: 32.w, ), ), ), if (isSelected) Positioned( bottom: 0, right: 2.w, child: Container( width: 12.w, height: 12.w, decoration: BoxDecoration( borderRadius: BorderRadius.all( Radius.circular(12.w), ), color: const Color.fromRGBO(117, 98, 249, 1), ), child: Center( child: Image.asset( Assets.imagesCheck, width: 6.w, height: 4.w, ), ), ), ), ], ), ), ); }), ], ), ], ), ); }); } Widget _buildGiftSwiper() { if (widget.giftList.isEmpty) { return Expanded( child: Center( child: Text( '暂无礼物', style: TextStyle(fontSize: 14.w, color: Colors.white70), ), ), ); } return Expanded( child: ValueListenableBuilder( valueListenable: widget.activeGift, builder: (context, active, _) { return GridView.builder( padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 10.w), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, // 每行4个 crossAxisSpacing: 7.w, mainAxisSpacing: 7.w, childAspectRatio: 0.85, // 调整宽高比 ), itemCount: widget.giftList.length, itemBuilder: (context, index) { return LiveRoomGiftItem( item: widget.giftList[index], active: active ?? 0, index: index, changeActive: widget.changeActive, ); }, ); }, ), ); } Widget _buildBottomBar() { return SafeArea( top: false, child: Container( padding: EdgeInsets.only( left: 10.w, right: 10.w, bottom: MediaQuery.of(context).padding.bottom > 0 ? MediaQuery.of(context).padding.bottom : 10.h, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Image.asset(Assets.imagesRoseGift, width: 21.w, height: 21.w), SizedBox(width: 8.w), Obx(() { final roomController = Get.isRegistered() ? Get.find() : null; final roseCount = roomController?.roseCount.value ?? 0; return Text( roseCount.toString(), style: TextStyle(fontSize: 13.w, color: Colors.white), ); }), SizedBox(width: 12.w), ], ), // 判断是否可以选择赠送(如果showHeader为true,需要选中用户;如果为false,直接使用targetUserId) Builder( builder: (context) { final bool canSend = widget.showHeader ? (_selectedUserId != null && _selectedUserId! > 0) : (widget.targetUserId != null || _selectedUserId != null); return Row( children: [ GestureDetector( onTap: canSend ? () => _handleSendGift(widget.type ?? 0) : null, child: Opacity( opacity: canSend ? 1.0 : 0.5, child: Container( width: 63.w, height: 30.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(30.w)), gradient: canSend ? const LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Color.fromRGBO(61, 138, 224, 1), Color.fromRGBO(131, 89, 255, 1), ], ) : null, color: canSend ? null : Colors.grey.withOpacity(0.5), ), child: Center( child: Text( "赠送", style: TextStyle(fontSize: 13.w, color: Colors.white), ), ), ), ), ), ], ); }, ), ], ), ), ); } }