You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

244 lines
8.2 KiB

import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
import 'package:dating_touchme_app/widget/live/live_room_user_header.dart';
import 'package:dating_touchme_app/widget/live/live_room_anchor_showcase.dart';
import 'package:dating_touchme_app/widget/live/live_room_active_speaker.dart';
import 'package:dating_touchme_app/widget/live/live_room_notice_chat_panel.dart';
import 'package:dating_touchme_app/widget/live/live_room_action_bar.dart';
import 'package:dating_touchme_app/widget/live/live_gift_popup.dart';
import 'package:dating_touchme_app/widget/live/live_recharge_popup.dart';
import 'package:dating_touchme_app/widget/live/svga_player_widget.dart';
class LiveRoomPage extends StatefulWidget {
final int id;
const LiveRoomPage({super.key, required this.id});
@override
State<LiveRoomPage> createState() => _LiveRoomPageState();
}
class _LiveRoomPageState extends State<LiveRoomPage> {
late final RoomController _roomController;
late final OverlayController _overlayController;
String message = '';
final TextEditingController _messageController = TextEditingController();
final activeGift = ValueNotifier<int?>(null);
final giftNum = ValueNotifier<int>(1);
changeActive(int index) {
activeGift.value = index;
setState(() {});
}
@override
void initState() {
super.initState();
_roomController = Get.isRegistered<RoomController>()
? Get.find<RoomController>()
: Get.put(RoomController());
_overlayController = Get.find<OverlayController>();
// 进入直播间时,确保隐藏小窗口(延迟到 build 完成后执行,避免在 build 过程中触发 setState)
WidgetsBinding.instance.addPostFrameCallback((_) {
_overlayController.hide();
});
// 启用屏幕常亮
WakelockPlus.enable();
// 如果当前用户是男性,请求连麦卡片信息
_loadLinkMicCard();
// 请求玫瑰数量
_loadRoseCount();
}
/// 加载连麦卡片信息(仅男性用户)
Future<void> _loadLinkMicCard() async {
final userData = GlobalData().userData;
if (userData?.genderCode == 0) {
// 男性用户才请求
await _roomController.getUserPropLinkMicCard();
}
}
/// 加载玫瑰数量
Future<void> _loadRoseCount() async {
await _roomController.getVirtualAccount();
}
@override
void dispose() {
// 禁用屏幕常亮
WakelockPlus.disable();
_messageController.dispose();
// 退出房间时清空RTM消息
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
roomController.chatMessages.clear();
}
super.dispose();
}
/// 发送消息
Future<void> _sendMessage() async {
final content = _messageController.text.trim();
if (content.isEmpty) {
return;
}
// 发送消息
await _roomController.sendChatMessage(content);
// 清空输入框
_messageController.clear();
message = '';
}
void _showGiftPopup() {
// 隐藏键盘
FocusScope.of(context).unfocus();
SmartDialog.show(
alignment: Alignment.bottomCenter,
maskColor: TDTheme.of(context).fontGyColor2,
builder: (_) => Obx(() {
// 优先使用 API 返回的 giftProducts,如果为空则使用后备列表
final giftProducts = _roomController.giftProducts;
final giftList = giftProducts.toList();
return LiveGiftPopup(
activeGift: activeGift,
giftNum: giftNum,
giftList: giftList,
changeActive: changeActive,
);
}),
);
}
void _showRechargePopup() {
// 隐藏键盘
FocusScope.of(context).unfocus();
SmartDialog.show(
alignment: Alignment.bottomCenter,
maskColor: TDTheme.of(context).fontGyColor2,
builder: (_) => const LiveRechargePopup(),
);
}
@override
Widget build(BuildContext context) {
return PopScope(
onPopInvokedWithResult: (bool didPop, Object? result) async {
SmartDialog.dismiss();
// 退出房间时清空RTM消息
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
roomController.chatMessages.clear();
}
_overlayController.show();
Get.back();
},
child: Scaffold(
body: Stack(
children: [
Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(248, 242, 255, 1),
Color.fromRGBO(247, 247, 247, 1),
],
),
),
),
Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: [
Color.fromRGBO(19, 16, 47, 1),
Color.fromRGBO(19, 16, 47, 1),
],
),
),
),
Container(
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 10.w),
Obx(() {
final detail =
_roomController.rtcChannelDetail.value;
final anchorInfo = detail?.anchorInfo;
final userName = anchorInfo!.nickName;
final avatarAsset = anchorInfo.profilePhoto;
const popularityText = '0'; // TODO: 使用真实数据
return LiveRoomUserHeader(
userName: userName,
popularityText: popularityText,
avatarAsset: avatarAsset,
onCloseTap: () {
Get.back();
Future.delayed(Duration(seconds: 1), (){
_overlayController.show();
});
},
);
}),
SizedBox(height: 7.w),
LiveRoomAnchorShowcase(),
SizedBox(height: 5.w),
const LiveRoomActiveSpeaker(),
SizedBox(height: 9.w),
const LiveRoomNoticeChatPanel(),
SizedBox(height: 10.w),
],
),
),
),
SafeArea(
top: false,
child: Padding(
padding: EdgeInsets.only(
bottom: 10.w,
left: 0,
right: 0,
),
child: LiveRoomActionBar(
messageController: _messageController,
onMessageChanged: (value) {
message = value;
},
onSendTap: _sendMessage,
onGiftTap: _showGiftPopup,
onChargeTap: _showRechargePopup,
),
),
),
],
),
),
// SVGA 动画播放组件
const SvgaPlayerWidget(),
],
),
),
);
}
}