跳到主要内容

群组信息

要在Flutter IMKit的UI界面上展示群组的头像、群名称等信息,需要应用层(App)主动向IMKit SDK提供群组信息

在Flutter IMKit中,同样使用CustomInfoProvider函数类型来提供群组信息。本文将介绍如何为IMKit提供群组信息,以便在UI界面上展示。

群组信息数据结构

在Flutter IMKit中,群组信息与用户信息使用同一个数据结构RCKChatProfileInfo,通过isGroup字段区分:

Dart
class RCKChatProfileInfo {
final String id; // 群组ID
final String name; // 群组名称
final String avatar; // 群组头像URL
final bool isGroup; // 设置为true表示这是群组信息
final String extraInfo; // 额外信息,如群公告等

// 构造函数
RCKChatProfileInfo({
required this.id,
required this.name,
required this.avatar,
this.isGroup = true, // 群组信息设置为true
this.extraInfo = '',
});
}

提供群组信息

在应用中,您需要在CustomInfoProvider函数中同时处理用户信息和群组信息的请求:

Dart
Future<RCKChatProfileInfo> customInfoProvider(
{RCIMIWMessage? message, RCIMIWConversation? conversation}) async {
String targetId = '';
bool isGroup = false;

// 确定目标ID和类型
if (message != null) {
// 消息场景下,通常是获取发送者信息
targetId = message.senderUserId ?? '';
// 对于群聊消息,可能需要特别判断
// isGroup = message.conversationType == RCIMIWConversationType.group;
} else if (conversation != null) {
// 会话场景下,获取会话目标信息
targetId = conversation.targetId ?? '';
isGroup = conversation.conversationType == RCIMIWConversationType.group;
}

// 如果是群组信息请求
if (isGroup) {
// 从您的群组信息提供者获取信息
final groupInfo = await yourGroupInfoProvider.getGroupInfo(targetId);

return RCKChatProfileInfo(
id: targetId,
name: groupInfo?.groupName ?? '未知群组',
avatar: groupInfo?.groupAvatar ?? '',
isGroup: true,
extraInfo: groupInfo?.announcement ?? '',
);
} else {
// 处理用户信息请求...
// ...
}
}

群组信息缓存

与用户信息类似,群组信息也建议实现缓存机制以提高性能:

Dart
class GroupInfoCache {
// 群组信息缓存
final Map<String, GroupInfo> _groupCache = {};
// 正在获取的群组ID集合
final Set<String> _fetchingGroupIds = {};

// 获取群组信息
Future<GroupInfo?> getGroupInfo(String groupId) async {
// 如果缓存中已有数据,直接返回
if (_groupCache.containsKey(groupId)) {
return _groupCache[groupId];
}

// 避免重复请求
if (_fetchingGroupIds.contains(groupId)) {
// 等待直到获取完成
while (_fetchingGroupIds.contains(groupId)) {
await Future.delayed(const Duration(milliseconds: 100));
}
if (_groupCache.containsKey(groupId)) {
return _groupCache[groupId];
}
}

// 标记为正在获取
_fetchingGroupIds.add(groupId);

try {
// 从服务器获取群组信息
final groupInfo = await _fetchGroupInfoFromServer(groupId);

if (groupInfo != null) {
// 添加到缓存
_groupCache[groupId] = groupInfo;
}

return groupInfo;
} finally {
// 清除标记
_fetchingGroupIds.remove(groupId);
}
}

// 从服务器获取群组信息
Future<GroupInfo?> _fetchGroupInfoFromServer(String groupId) async {
// 实现从服务器获取群组信息的逻辑
// ...
}
}

群组成员信息

在群聊场景中,有时需要获取群成员的信息。您可以扩展现有的信息提供机制来支持这一功能:

Dart
class GroupMemberProvider {
// 群成员缓存,按群组ID分类
final Map<String, Map<String, GroupMemberInfo>> _groupMemberCache = {};

// 获取群成员信息
Future<GroupMemberInfo?> getGroupMemberInfo(String groupId, String userId) async {
// 检查缓存
if (_groupMemberCache.containsKey(groupId) &&
_groupMemberCache[groupId]!.containsKey(userId)) {
return _groupMemberCache[groupId]![userId];
}

// 获取群成员信息
final memberInfo = await _fetchGroupMemberInfoFromServer(groupId, userId);

if (memberInfo != null) {
// 确保群组缓存存在
_groupMemberCache[groupId] ??= {};
// 添加到缓存
_groupMemberCache[groupId]![userId] = memberInfo;
}

return memberInfo;
}

// 批量获取群成员信息
Future<List<GroupMemberInfo>> getGroupMembers(String groupId) async {
// 从服务器获取群成员列表
final memberList = await _fetchGroupMembersFromServer(groupId);

if (memberList.isNotEmpty) {
// 更新缓存
_groupMemberCache[groupId] ??= {};
for (var member in memberList) {
_groupMemberCache[groupId]![member.userId] = member;
}
}

return memberList;
}

// 从服务器获取群成员信息
Future<GroupMemberInfo?> _fetchGroupMemberInfoFromServer(String groupId, String userId) async {
// 实现逻辑...
}

// 从服务器获取群成员列表
Future<List<GroupMemberInfo>> _fetchGroupMembersFromServer(String groupId) async {
// 实现逻辑...
}
}

群组信息更新

当群组信息发生变化时(如群名称、头像变更),需要更新缓存并通知UI刷新:

Dart
class GroupInfoProvider with ChangeNotifier {
// ... 其他代码

// 更新群组信息
Future<void> updateGroupInfo(GroupInfo newGroupInfo) async {
// 更新缓存
_groupCache[newGroupInfo.groupId] = newGroupInfo;

// 通知UI更新
notifyListeners();
}

// 更新群成员信息
Future<void> updateGroupMemberInfo(GroupMemberInfo memberInfo) async {
// 确保群组缓存存在
_groupMemberCache[memberInfo.groupId] ??= {};
// 更新成员信息
_groupMemberCache[memberInfo.groupId]![memberInfo.userId] = memberInfo;

// 通知UI更新
notifyListeners();
}
}

监听群组信息变化

在实际应用中,群组信息可能会频繁变化。您可以监听服务端的通知或者定期轮询,以保持群组信息的最新状态:

Dart
class GroupInfoProvider with ChangeNotifier {
// ... 其他代码

// 监听群组信息变化
void listenToGroupInfoChanges() {
// 示例:通过消息服务监听群组信息变化
messageService.onReceiveMessage = (message) {
if (message.objectName == 'RC:InfoNtf') {
// 解析消息内容
final content = message.content as InfoNotificationMessage;
if (content.messageType == 'GROUP_INFO_CHANGED') {
// 刷新群组信息
refreshGroupInfo(message.targetId);
}
}
};
}

// 刷新群组信息
Future<void> refreshGroupInfo(String groupId) async {
// 清除缓存中的旧数据
_groupCache.remove(groupId);

// 重新获取最新数据
await getGroupInfo(groupId);
}
}

完整示例:群组信息提供者

以下是一个完整的群组信息提供者示例,结合了上述功能:

Dart
class GroupInfoProvider with ChangeNotifier {
final Map<String, GroupInfo> _groupCache = {};
final Map<String, Map<String, GroupMemberInfo>> _groupMemberCache = {};
final ApiService _apiService;

GroupInfoProvider(this._apiService) {
// 初始化时开始监听群组信息变化
listenToGroupInfoChanges();
}

// 获取群组信息
Future<GroupInfo?> getGroupInfo(String groupId) async {
if (_groupCache.containsKey(groupId)) {
return _groupCache[groupId];
}

// 从服务器获取
final groupInfo = await _apiService.getGroupInfo(groupId);
if (groupInfo != null) {
_groupCache[groupId] = groupInfo;
notifyListeners();
}

return groupInfo;
}

// 获取群成员信息
Future<GroupMemberInfo?> getGroupMemberInfo(String groupId, String userId) async {
if (_groupMemberCache.containsKey(groupId) &&
_groupMemberCache[groupId]!.containsKey(userId)) {
return _groupMemberCache[groupId]![userId];
}

// 获取群成员信息
final memberInfo = await _apiService.getGroupMemberInfo(groupId, userId);

if (memberInfo != null) {
_groupMemberCache[groupId] ??= {};
_groupMemberCache[groupId]![userId] = memberInfo;
notifyListeners();
}

return memberInfo;
}

// 批量获取群成员
Future<List<GroupMemberInfo>> getGroupMembers(String groupId) async {
// 从服务器获取群成员列表
final memberList = await _apiService.getGroupMembers(groupId);

if (memberList.isNotEmpty) {
_groupMemberCache[groupId] ??= {};
for (var member in memberList) {
_groupMemberCache[groupId]![member.userId] = member;
}
notifyListeners();
}

return memberList;
}

// 更新群组信息
Future<void> updateGroupInfo(GroupInfo newGroupInfo) async {
_groupCache[newGroupInfo.groupId] = newGroupInfo;
notifyListeners();
}

// 监听群组信息变化
void listenToGroupInfoChanges() {
// 实现监听逻辑...
}

// 供CustomInfoProvider使用的方法
Future<RCKChatProfileInfo> provideGroupInfo(String groupId) async {
final groupInfo = await getGroupInfo(groupId);

return RCKChatProfileInfo(
id: groupId,
name: groupInfo?.name ?? groupId,
avatar: groupInfo?.portraitUri ?? '',
isGroup: true,
extraInfo: groupInfo?.extra ?? '',
);
}
}

综合实现:用户和群组信息提供者

最后,将用户信息和群组信息提供者结合,实现完整的信息提供机制:

Dart
// 应用初始化时:
void initializeProviders(BuildContext context) {
// 获取提供者实例
final userInfoProvider = Provider.of<UserInfoProvider>(context, listen: false);
final groupInfoProvider = Provider.of<GroupInfoProvider>(context, listen: false);

// 设置自定义信息提供者
Provider.of<RCKEngineProvider>(context, listen: false).customInfoProvider =
({RCIMIWMessage? message, RCIMIWConversation? conversation}) async {
String targetId = '';
bool isGroup = false;

if (message != null) {
targetId = message.senderUserId ?? '';
} else if (conversation != null) {
targetId = conversation.targetId ?? '';
isGroup = conversation.conversationType == RCIMIWConversationType.group;
}

if (isGroup) {
return await groupInfoProvider.provideGroupInfo(targetId);
} else {
return await userInfoProvider.provideUserInfo(targetId);
}
};
}

通过以上设置,Flutter IMKit将能够获取并显示正确的群组信息,为用户提供完整的群聊体验。