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:flutter_swiper_null_safety/flutter_swiper_null_safety.dart'; import 'package:get/get.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; class LiveGiftPopup extends StatefulWidget { const LiveGiftPopup({ super.key, required this.activeGift, required this.giftNum, required this.giftList, required this.changeActive, }); final ValueNotifier activeGift; final ValueNotifier giftNum; final List giftList; // 支持 List 或 List final void Function(int) changeActive; @override State createState() => _LiveGiftPopupState(); } class _LiveGiftPopupState extends State { // 选中的用户ID(单选) String? _selectedUserId; // 切换用户选中状态(单选模式) void _toggleUserSelection(String userId) { setState(() { if (_selectedUserId == userId) { // 如果点击的是已选中的用户,则取消选中 _selectedUserId = null; } else { // 否则选中该用户(自动取消之前的选中) _selectedUserId = userId; } }); } // 处理赠送礼物 Future _handleSendGift() async { // 检查是否选中了礼物 final activeIndex = widget.activeGift.value; if (activeIndex == null || activeIndex < 0 || activeIndex >= widget.giftList.length) { SmartDialog.showToast('请先选择礼物'); return; } // 检查是否选中了接收用户 if (_selectedUserId == null || _selectedUserId!.isEmpty) { 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); // 关闭弹窗 SmartDialog.dismiss(); SmartDialog.showToast('礼物已送出'); } @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: [ _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: [ _buildTab(), _buildGiftSwiper(), _buildBottomBar(), ], ), ), ), ], ), ), ); } Widget _buildHeader() { return Obx(() { // 获取 RoomController final roomController = Get.isRegistered() ? Get.find() : null; // 获取 rtcChannelDetail 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(); 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.userId; return GestureDetector( onTap: () => _toggleUserSelection(user.userId), 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 _buildTab() { return Container( height: 47.w, padding: EdgeInsets.only(left: 29.w), child: Row( children: [ Text( "互动", style: TextStyle( fontSize: 13.w, color: const Color.fromRGBO(144, 144, 144, 1), ), ), SizedBox(width: 40.w), Text( "礼物", style: TextStyle( fontSize: 13.w, color: Colors.white, fontWeight: FontWeight.w700, ), ), ], ), ); } Widget _buildGiftSwiper() { if (widget.giftList.isEmpty) { return Expanded( child: Center( child: Text( '暂无礼物', style: TextStyle(fontSize: 14.w, color: Colors.white70), ), ), ); } // 计算需要多少页,每页显示8个礼物(2行4列) final itemsPerPage = 8; final totalPages = (widget.giftList.length / itemsPerPage).ceil(); return Expanded( child: ValueListenableBuilder( valueListenable: widget.activeGift, builder: (context, active, _) { return Swiper( autoplay: false, itemCount: totalPages, loop: false, pagination: totalPages > 1 ? const SwiperPagination( alignment: Alignment.bottomCenter, builder: TDSwiperDotsPagination( color: Color.fromRGBO(144, 144, 144, 1), activeColor: Color.fromRGBO(77, 77, 77, 1), ), ) : null, itemBuilder: (context, pageIndex) { final startIndex = pageIndex * itemsPerPage; final endIndex = (startIndex + itemsPerPage).clamp( 0, widget.giftList.length, ); final pageItems = widget.giftList.sublist(startIndex, endIndex); return Align( alignment: Alignment.topCenter, child: Wrap( spacing: 7.w, runSpacing: 7.w, children: [ ...pageItems.asMap().entries.map((entry) { final globalIndex = startIndex + entry.key; return LiveRoomGiftItem( item: entry.value, active: active ?? 0, index: globalIndex, changeActive: widget.changeActive, ); }), ], ), ); }, ); }, ), ); } Widget _buildBottomBar() { return Container( padding: EdgeInsets.symmetric(horizontal: 10.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ Image.asset(Assets.imagesRoseGift, width: 21.w, height: 21.w), SizedBox(width: 8.w), Text( "9", style: TextStyle(fontSize: 13.w, color: Colors.white), ), SizedBox(width: 12.w), Image.asset(Assets.imagesRoseGift, width: 68.w, height: 33.w), ], ), ValueListenableBuilder( valueListenable: widget.giftNum, builder: (context, num, _) { return Row( children: [ GestureDetector( onTap: () => _handleSendGift(), child: Container( width: 63.w, height: 30.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(30.w)), gradient: const LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ Color.fromRGBO(61, 138, 224, 1), Color.fromRGBO(131, 89, 255, 1), ], ), ), child: Center( child: Text( "赠送", style: TextStyle(fontSize: 13.w, color: Colors.white), ), ), ), ), ], ); }, ), ], ), ); } Widget _buildAdjustButton({ required String label, required bool enabled, required VoidCallback onTap, }) { return InkWell( onTap: enabled ? onTap : null, child: Container( width: 14.w, height: 14.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(14.w)), color: enabled ? const Color.fromRGBO(117, 98, 249, 1) : Colors.transparent, border: Border.all( width: 1, color: const Color.fromRGBO(117, 98, 249, 1), ), ), child: Center( child: Text( label, style: TextStyle( fontSize: 13.w, color: enabled ? Colors.white : const Color.fromRGBO(117, 98, 249, 1), height: 1, ), ), ), ), ); } }