Browse Source
feat(rtc): 添加踢出RTC频道用户功能
feat(rtc): 添加踢出RTC频道用户功能
- 新增API接口用于踢出RTC频道中的指定用户 - 在RoomController中实现踢出用户的业务逻辑 - 更新RTC API定义及自动生成的代码 - 添加解除连麦对话框组件DisconnectMicDialog - 实现嘉宾连麦状态管理和UI展示逻辑ios
5 changed files with 272 additions and 0 deletions
Unified View
Diff Options
-
34lib/controller/discover/room_controller.dart
-
2lib/network/api_urls.dart
-
6lib/network/rtc_api.dart
-
34lib/network/rtc_api.g.dart
-
196lib/widget/live/disconnect_mic_dialog.dart
@ -0,0 +1,196 @@ |
|||||
|
import 'package:dating_touchme_app/controller/discover/room_controller.dart'; |
||||
|
import 'package:dating_touchme_app/generated/assets.dart'; |
||||
|
import 'package:dating_touchme_app/model/rtc/rtc_channel_detail.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 DisconnectMicDialog extends StatelessWidget { |
||||
|
const DisconnectMicDialog({super.key}); |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
final roomController = Get.find<RoomController>(); |
||||
|
|
||||
|
return Dialog( |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(12.w), |
||||
|
), |
||||
|
child: Container( |
||||
|
padding: EdgeInsets.all(20.w), |
||||
|
child: Column( |
||||
|
mainAxisSize: MainAxisSize.min, |
||||
|
children: [ |
||||
|
// 标题栏 |
||||
|
Row( |
||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||
|
children: [ |
||||
|
Text( |
||||
|
'解除连麦', |
||||
|
style: TextStyle( |
||||
|
fontSize: 18.sp, |
||||
|
fontWeight: FontWeight.bold, |
||||
|
color: Colors.black87, |
||||
|
), |
||||
|
), |
||||
|
GestureDetector( |
||||
|
onTap: () => SmartDialog.dismiss(), |
||||
|
child: Icon( |
||||
|
Icons.close, |
||||
|
size: 24.w, |
||||
|
color: Colors.grey, |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
SizedBox(height: 20.w), |
||||
|
// 嘉宾列表 |
||||
|
Obx(() { |
||||
|
final maleInfo = roomController.rtcChannelDetail.value?.maleInfo; |
||||
|
final femaleInfo = roomController.rtcChannelDetail.value?.femaleInfo; |
||||
|
|
||||
|
// 如果没有嘉宾在连麦 |
||||
|
if (maleInfo == null && femaleInfo == null) { |
||||
|
return Padding( |
||||
|
padding: EdgeInsets.symmetric(vertical: 20.w), |
||||
|
child: Text( |
||||
|
'暂无嘉宾连麦', |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: Colors.grey, |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
return Row( |
||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||
|
children: [ |
||||
|
// 男嘉宾 |
||||
|
if (maleInfo != null) |
||||
|
Expanded( |
||||
|
child: _buildGuestItem( |
||||
|
context: context, |
||||
|
userInfo: maleInfo, |
||||
|
roomController: roomController, |
||||
|
isMale: true, |
||||
|
), |
||||
|
), |
||||
|
if (maleInfo != null && femaleInfo != null) |
||||
|
SizedBox(width: 20.w), |
||||
|
// 女嘉宾 |
||||
|
if (femaleInfo != null) |
||||
|
Expanded( |
||||
|
child: _buildGuestItem( |
||||
|
context: context, |
||||
|
userInfo: femaleInfo, |
||||
|
roomController: roomController, |
||||
|
isMale: false, |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
); |
||||
|
}), |
||||
|
SizedBox(height: 10.w), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 构建嘉宾项 |
||||
|
Widget _buildGuestItem({ |
||||
|
required BuildContext context, |
||||
|
required RtcSeatUserInfo userInfo, |
||||
|
required RoomController roomController, |
||||
|
required bool isMale, |
||||
|
}) { |
||||
|
// 判断当前嘉宾是否还在连麦 |
||||
|
final isConnected = userInfo.isMicrophoneOn; |
||||
|
|
||||
|
return Column( |
||||
|
children: [ |
||||
|
// 头像 |
||||
|
ClipOval( |
||||
|
child: Image.network( |
||||
|
userInfo.profilePhoto, |
||||
|
width: 60.w, |
||||
|
height: 60.w, |
||||
|
fit: BoxFit.cover, |
||||
|
errorBuilder: (context, error, stackTrace) { |
||||
|
return Image.asset( |
||||
|
Assets.imagesUserAvatar, |
||||
|
width: 60.w, |
||||
|
height: 60.w, |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
), |
||||
|
SizedBox(height: 10.w), |
||||
|
// 昵称 |
||||
|
Text( |
||||
|
userInfo.nickName, |
||||
|
style: TextStyle( |
||||
|
fontSize: 14.sp, |
||||
|
color: Colors.black87, |
||||
|
), |
||||
|
maxLines: 1, |
||||
|
overflow: TextOverflow.ellipsis, |
||||
|
), |
||||
|
SizedBox(height: 10.w), |
||||
|
// 解除连麦按钮 |
||||
|
GestureDetector( |
||||
|
onTap: isConnected |
||||
|
? () async { |
||||
|
// 解除连麦 |
||||
|
await _disconnectMic(roomController, isMale); |
||||
|
} |
||||
|
: null, |
||||
|
child: Container( |
||||
|
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w), |
||||
|
decoration: BoxDecoration( |
||||
|
color: isConnected ? const Color(0xFF8B5CF6) : Colors.grey[300], |
||||
|
borderRadius: BorderRadius.circular(20.w), |
||||
|
), |
||||
|
child: Row( |
||||
|
mainAxisSize: MainAxisSize.min, |
||||
|
children: [ |
||||
|
Image.asset( |
||||
|
Assets.imagesMicOff, |
||||
|
width: 14.w, |
||||
|
color: isConnected ? Colors.white : Colors.grey[600], |
||||
|
), |
||||
|
SizedBox(width: 4.w), |
||||
|
Text( |
||||
|
isConnected ? '解除连麦' : '已解除连麦', |
||||
|
style: TextStyle( |
||||
|
fontSize: 12.sp, |
||||
|
color: isConnected ? Colors.white : Colors.grey[600], |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
/// 解除连麦 |
||||
|
Future<void> _disconnectMic(RoomController roomController, bool isMale) async { |
||||
|
// 更新本地状态 - 移除对应嘉宾的信息 |
||||
|
final currentDetail = roomController.rtcChannelDetail.value; |
||||
|
if (currentDetail != null) { |
||||
|
final newDetail = RtcChannelDetail( |
||||
|
channelId: currentDetail.channelId, |
||||
|
anchorInfo: currentDetail.anchorInfo, |
||||
|
maleInfo: isMale ? null : currentDetail.maleInfo, |
||||
|
femaleInfo: !isMale ? null : currentDetail.femaleInfo, |
||||
|
); |
||||
|
roomController.rtcChannelDetail.value = newDetail; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save