Browse Source

feat(im): 添加自定义消息发送功能并完善直播互动逻辑

- 在 IMManager 中新增 sendCustomMessage 方法用于发送自定义消息
- 实现直播间嘉宾邀请功能,通过自定义消息传递房间信息
- 完善礼物赠送后的公屏消息展示逻辑
- 优化直播间关闭后 overlay controller 的显示时机
- 增强消息处理逻辑以兼容不同的数据类型和异常情况
ios
Jolie 4 months ago
parent
commit
0ca289ee22
4 changed files with 163 additions and 9 deletions
  1. 89
      lib/controller/discover/room_controller.dart
  2. 13
      lib/im/im_manager.dart
  3. 4
      lib/pages/discover/live_room_page.dart
  4. 66
      lib/widget/live/live_room_guest_list_dialog.dart

89
lib/controller/discover/room_controller.dart

@ -429,6 +429,43 @@ class RoomController extends GetxController with WidgetsBindingObserver {
message: json.encode(messageData),
);
print('✅ 礼物消息已发送: ${gift.productTitle}');
//
final senderNickName = GlobalData().userData?.nickName ?? '用户';
String targetNickName = '用户';
final targetUserIdStr = targetUserId.toString();
//
final channelDetail = rtcChannelDetail.value;
if (channelDetail != null) {
//
if (channelDetail.anchorInfo?.userId == targetUserIdStr ||
channelDetail.anchorInfo?.miId == targetUserIdStr) {
targetNickName = channelDetail.anchorInfo?.nickName ?? '用户';
}
//
else if (channelDetail.maleInfo?.userId == targetUserIdStr ||
channelDetail.maleInfo?.miId == targetUserIdStr) {
targetNickName = channelDetail.maleInfo?.nickName ?? '用户';
}
//
else if (channelDetail.femaleInfo?.userId == targetUserIdStr ||
channelDetail.femaleInfo?.miId == targetUserIdStr) {
targetNickName = channelDetail.femaleInfo?.nickName ?? '用户';
}
}
//
final giftMessage = LiveChatMessage(
userId: GlobalData().userId ?? GlobalData().userData?.id ?? '',
userName: senderNickName,
avatar: GlobalData().userData?.profilePhoto,
content: '$targetNickName赠送了${gift.productTitle}',
timestamp: DateTime.now().millisecondsSinceEpoch,
);
//
_addMessage(giftMessage);
} catch (e) {
print('❌ 发送礼物失败: $e');
SmartDialog.showToast('发送礼物失败');
@ -442,9 +479,51 @@ class RoomController extends GetxController with WidgetsBindingObserver {
try {
final svgaFile = message['svgaFile']?.toString() ?? '';
final giftProductId = message['giftProductId']?.toString();
final targetUserId = message['targetUserId']?.toInt() ?? 0;
final senderUserId = message['senderUserId']?.toInt() ?? 0;
final senderNickName = message['senderNickName']?.toString() ?? '';
final targetUserId = message['targetUserId'];
final senderUserId = message['senderUserId'];
final senderNickName = message['senderNickName']?.toString() ?? '用户';
//
String giftTitle = '礼物';
if (giftProductId != null && giftProductId.isNotEmpty) {
try {
final gift = giftProducts.firstWhere(
(g) => g.productId == giftProductId,
);
giftTitle = gift.productTitle;
} catch (e) {
// 使
print('⚠️ 未找到礼物ID: $giftProductId');
}
}
//
String targetNickName = '用户';
final channelDetail = rtcChannelDetail.value;
if (channelDetail != null) {
//
if (channelDetail.anchorInfo?.uid == targetUserId) {
targetNickName = channelDetail.anchorInfo?.nickName ?? '用户';
}
//
else if (channelDetail.maleInfo?.userId == targetUserId) {
targetNickName = channelDetail.maleInfo?.nickName ?? '用户';
}
//
else if (channelDetail.femaleInfo?.userId == targetUserId) {
targetNickName = channelDetail.femaleInfo?.nickName ?? '用户';
}
}
//
final giftMessage = LiveChatMessage(
userId: senderUserId?.toString() ?? '',
userName: senderNickName,
avatar: null, //
content: '$targetNickName赠送了$giftTitle',
timestamp: DateTime.now().millisecondsSinceEpoch,
);
_addMessage(giftMessage);
if (svgaFile.isNotEmpty) {
//
@ -453,7 +532,9 @@ class RoomController extends GetxController with WidgetsBindingObserver {
SvgaAnimationItem(
svgaFile: svgaFile,
targetUserId: targetUserId,
senderUserId: senderUserId,
senderUserId: senderUserId is int
? senderUserId
: (int.tryParse(senderUserId?.toString() ?? '') ?? 0),
giftProductId: giftProductId,
),
);

13
lib/im/im_manager.dart

@ -429,6 +429,19 @@ class IMManager {
}
}
///
Future<EMMessage?> sendCustomMessage(String targetId, String event, Map<String, String>? data,) async {
final customMsg = EMMessage.createCustomSendMessage(
targetId: targetId,
// `event`
event: event,
// `params` `Map<String, String>`
params: data,
);
return await EMClient.getInstance.chatManager.sendMessage(customMsg);
}
///
Future<List<EMConversation>> getConversations() async {
return EMClient.getInstance.chatManager.loadAllConversations();

4
lib/pages/discover/live_room_page.dart

@ -181,8 +181,10 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
popularityText: popularityText,
avatarAsset: avatarAsset,
onCloseTap: () {
_overlayController.toggle();
Get.back();
Future.delayed(Duration(seconds: 1), (){
_overlayController.show();
});
},
);
}),

66
lib/widget/live/live_room_guest_list_dialog.dart

@ -1,11 +1,14 @@
import 'dart:convert';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/im/im_manager.dart';
import 'package:dating_touchme_app/network/network_service.dart';
import 'package:dating_touchme_app/rtc/rtc_manager.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 LiveRoomGuestListDialog extends StatefulWidget {
@ -311,13 +314,13 @@ class _LiveRoomGuestListDialogState extends State<LiveRoomGuestListDialog> {
),
),
//
_buildActionButton(hasGuest),
_buildActionButton(hasGuest, guest),
],
),
);
}
Widget _buildActionButton(bool hasGuest) {
Widget _buildActionButton(bool hasGuest, Map<String, dynamic> guest) {
if (hasGuest) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.w),
@ -333,8 +336,7 @@ class _LiveRoomGuestListDialogState extends State<LiveRoomGuestListDialog> {
} else {
return GestureDetector(
onTap: () {
// TODO:
SmartDialog.showToast('邀请${_selectedTab == 0 ? "" : ""}嘉宾');
_inviteGuest(guest);
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.w),
@ -377,4 +379,60 @@ class _LiveRoomGuestListDialogState extends State<LiveRoomGuestListDialog> {
}
return parts.isEmpty ? '' : parts.join('·');
}
///
Future<void> _inviteGuest(Map<String, dynamic> guest) async {
try {
final targetUserId = guest['userId'] as String?;
if (targetUserId == null || targetUserId.isEmpty) {
SmartDialog.showToast('用户ID不存在');
return;
}
//
final roomController = Get.isRegistered<RoomController>()
? Get.find<RoomController>()
: null;
if (roomController == null) {
SmartDialog.showToast('房间控制器未初始化');
return;
}
final channelId = RTCManager.instance.currentChannelId;
if (channelId == null || channelId.isEmpty) {
SmartDialog.showToast('频道ID不存在');
return;
}
//
final channelDetail = roomController.rtcChannelDetail.value;
final anchorName = channelDetail?.anchorInfo?.nickName ?? '主持人';
//
final messageData = <String, String>{
'type': 'live_room_invite',
'channelId': channelId,
'anchorAvatar': channelDetail?.anchorInfo?.profilePhoto ?? '',
'anchorName': anchorName,
};
//
final result = await IMManager.instance.sendCustomMessage(
targetUserId,
'live_room_invite',
messageData,
);
if (result != null) {
SmartDialog.showToast('邀请已发送');
SmartDialog.dismiss();
} else {
SmartDialog.showToast('邀请发送失败');
}
} catch (e) {
print('❌ 邀请嘉宾失败: $e');
SmartDialog.showToast('邀请发送失败');
}
}
}
Loading…
Cancel
Save