[Super Group]

This commit is contained in:
hrxiang
2022-07-15 18:19:17 +08:00
parent a9343bf892
commit c76bfeb07a
24 changed files with 376 additions and 81 deletions

View File

@@ -3,9 +3,12 @@ class ConversationType {
/// 单聊
static const single = 1;
/// 群
/// 群
static const group = 2;
/// 大群
static const superGroup = 3;
/// 通知
static const notification = 4;
}

View File

@@ -45,6 +45,9 @@ class MessageType {
/// 自定义表情
static const custom_face = 115;
/// 高级撤回
static const advancedRevoke = 118;
/// 通知类型
static const notificationBegin = 1000;

View File

@@ -6,6 +6,7 @@ class OnAdvancedMsgListener {
Function(List<ReadReceiptInfo> list)? onRecvGroupMessageReadReceipt;
Function(String msgId)? onRecvMessageRevoked;
Function(Message msg)? onRecvNewMessage;
Function(RevokedInfo info)? onRecvMessageRevokedV2;
/// Uniquely identifies
String id;
@@ -13,8 +14,9 @@ class OnAdvancedMsgListener {
OnAdvancedMsgListener({
this.onRecvC2CMessageReadReceipt,
this.onRecvGroupMessageReadReceipt,
this.onRecvMessageRevoked,
@deprecated this.onRecvMessageRevoked,
this.onRecvNewMessage,
this.onRecvMessageRevokedV2,
}) : id = "id_${DateTime.now().microsecondsSinceEpoch}";
/// C2C消息已读回执
@@ -36,4 +38,9 @@ class OnAdvancedMsgListener {
void recvNewMessage(Message msg) {
onRecvNewMessage?.call(msg);
}
/// 消息被撤回
void recvMessageRevokedV2(RevokedInfo info) {
onRecvMessageRevokedV2?.call(info);
}
}

View File

@@ -46,7 +46,7 @@ class ConversationManager {
/// 查询会话,如果会话不存在会自动生成一个
/// [sourceID] 如果是单聊会话传userID如果是群聊会话传GroupID
/// [sessionType] 如果是单聊会话传1如果是群聊会话传2
/// [sessionType] 参考[ConversationType]
Future<ConversationInfo> getOneConversation({
required String sourceID,
required int sessionType,
@@ -149,7 +149,7 @@ class ConversationManager {
/// 查询会话id
/// [sourceID] 如果是单聊值传用户ID如果是群聊值传组ID
/// [sessionType] 如果是单聊值传1如果是群聊值传2
/// [sessionType] 参考[ConversationType]
Future<dynamic> getConversationIDBySessionType({
required String sourceID,
required int sessionType,

View File

@@ -236,16 +236,19 @@ class GroupManager {
(value) => Utils.toList(value, (map) => GroupInfo.fromJson(map)));
/// 申请加入组,需要通过管理员/群组同意。
/// [joinSource] 2通过邀请 3通过搜索 4通过二维码
Future<dynamic> joinGroup({
required String gid,
String? reason,
String? operationID,
int joinSource = 3,
}) =>
_channel.invokeMethod(
'joinGroup',
_buildParam({
'gid': gid,
'reason': reason,
'joinSource': joinSource,
'operationID': Utils.checkOperationID(operationID),
}));
@@ -497,6 +500,54 @@ class GroupManager {
'operationID': Utils.checkOperationID(operationID),
}));
/// 不允许通过群获取成员资料
/// [groupID] 群ID
/// [status] 0关闭1打开
Future<dynamic> setGroupLookMemberInfo({
required String groupID,
required int status,
String? operationID,
}) =>
_channel.invokeMethod(
'setGroupLookMemberInfo',
_buildParam({
'groupID': groupID,
'status': status,
'operationID': Utils.checkOperationID(operationID),
}));
/// 不允许通过群添加好友
/// [groupID] 群ID
/// [status] 0关闭1打开
Future<dynamic> setGroupApplyMemberFriend({
required String groupID,
required int status,
String? operationID,
}) =>
_channel.invokeMethod(
'setGroupApplyMemberFriend',
_buildParam({
'groupID': groupID,
'status': status,
'operationID': Utils.checkOperationID(operationID),
}));
/// 获取群拥有者,管理员
/// [groupId] 群ID
Future<List<GroupMembersInfo>> getGroupOwnerAndAdmin({
required String groupID,
String? operationID,
}) =>
_channel
.invokeMethod(
'getGroupMemberOwnerAndAdmin',
_buildParam({
'groupID': groupID,
'operationID': Utils.checkOperationID(operationID),
}))
.then((value) =>
Utils.toList(value, (map) => GroupMembersInfo.fromJson(map)));
static Map _buildParam(Map param) {
param["ManagerName"] = "groupManager";
return param;

View File

@@ -147,6 +147,11 @@ class IMManager {
Utils.toList(value, (map) => ReadReceiptInfo.fromJson(map));
messageManager.msgListener.recvGroupMessageReadReceipt(list);
break;
case 'onNewRecvMessageRevoked':
var value = call.arguments['data']['revokedMessageV2'];
var info = Utils.toObj(value, (map) => RevokedInfo.fromJson(map));
messageManager.msgListener.recvMessageRevokedV2(info);
break;
}
} else if (call.method == ListenerType.msgSendProgressListener) {
String type = call.arguments['type'];

View File

@@ -77,8 +77,9 @@ class MessageManager {
}))
.then((value) => Utils.toList(value, (map) => Message.fromJson(map)));
/// 撤回消息
/// 撤回消息[revokeMessageV2]
/// [message] 被撤回的消息体
@deprecated
Future revokeMessage({
required Message message,
String? operationID,
@@ -686,6 +687,19 @@ class MessageManager {
}))
.then((value) => Utils.toList(value, (map) => Message.fromJson(map)));
/// 撤回消息
/// [message] 被撤回的消息体
Future revokeMessageV2({
required Message message,
String? operationID,
}) =>
_channel.invokeMethod(
'newRevokeMessage',
_buildParam(message.toJson()
..addAll({
"operationID": Utils.checkOperationID(operationID),
})));
static Map _buildParam(Map param) {
param["ManagerName"] = "messageManager";
return param;

View File

@@ -118,9 +118,16 @@ class ConversationInfo {
return data;
}
/// 是单聊
bool get isSingleChat => conversationType == ConversationType.single;
bool get isGroupChat => conversationType == ConversationType.group;
/// 是群聊
bool get isGroupChat =>
conversationType == ConversationType.group ||
conversationType == ConversationType.superGroup;
/// 是有效的
bool get isValid => isSingleChat || isGroupChat && !isNotInGroup!;
@override
bool operator ==(Object other) =>

View File

@@ -32,7 +32,7 @@ class GroupInfo {
/// 创建者ID
String? creatorUserID;
/// 群类型
/// 群类型[GroupType]
int? groupType;
/// 扩展字段
@@ -41,6 +41,18 @@ class GroupInfo {
/// 进群验证方式[GroupVerification]
int? needVerification;
/// 不允许通过群获取成员资料 0关闭1打开
int? lookMemberInfo;
/// 不允许通过群添加好友 0关闭1打开
int? applyMemberFriend;
/// 通知更新时间
int? notificationUpdateTime;
/// 通知发起人
String? notificationUserID;
GroupInfo({
required this.groupID,
this.groupName,
@@ -55,6 +67,10 @@ class GroupInfo {
this.groupType,
this.ex,
this.needVerification,
this.lookMemberInfo,
this.applyMemberFriend,
this.notificationUpdateTime,
this.notificationUserID,
});
GroupInfo.fromJson(Map<String, dynamic> json) : groupID = json['groupID'] {
@@ -71,6 +87,10 @@ class GroupInfo {
groupType = json['groupType'];
ex = json['ex'];
needVerification = json['needVerification'];
lookMemberInfo = json['lookMemberInfo'];
applyMemberFriend = json['applyMemberFriend'];
notificationUpdateTime = json['notificationUpdateTime'];
notificationUserID = json['notificationUserID'];
}
Map<String, dynamic> toJson() {
@@ -88,8 +108,17 @@ class GroupInfo {
data['groupType'] = this.groupType;
data['ex'] = this.ex;
data['needVerification'] = this.needVerification;
data['lookMemberInfo'] = this.lookMemberInfo;
data['applyMemberFriend'] = this.applyMemberFriend;
data['notificationUpdateTime'] = this.notificationUpdateTime;
data['notificationUserID'] = this.notificationUserID;
return data;
}
/// 群类型对应的会话类型
int get sessionType => groupType == GroupType.general
? ConversationType.group
: ConversationType.superGroup;
}
/// 群成员信息
@@ -112,7 +141,7 @@ class GroupMembersInfo {
/// 加入时间
int? joinTime;
/// 入群方式
/// 入群方式 2邀请加入 3搜索加入 4通过二维码加入
int? joinSource;
/// 操作者id
@@ -123,8 +152,13 @@ class GroupMembersInfo {
/// 禁言时间s
int? muteEndTime;
///
int? appMangerLevel;
/// 邀请人id
String? inviterUserID;
GroupMembersInfo({
this.groupID,
this.userID,
@@ -137,6 +171,7 @@ class GroupMembersInfo {
this.operatorUserID,
this.muteEndTime,
this.appMangerLevel,
this.inviterUserID,
});
GroupMembersInfo.fromJson(Map<String, dynamic> json) {
@@ -151,6 +186,7 @@ class GroupMembersInfo {
operatorUserID = json['operatorUserID'];
muteEndTime = json['muteEndTime'];
appMangerLevel = json['appMangerLevel'];
inviterUserID = json['inviterUserID'];
}
Map<String, dynamic> toJson() {
@@ -166,6 +202,7 @@ class GroupMembersInfo {
data['operatorUserID'] = this.operatorUserID;
data['muteEndTime'] = this.muteEndTime;
data['appMangerLevel'] = this.appMangerLevel;
data['inviterUserID'] = this.inviterUserID;
return data;
}
}

View File

@@ -287,6 +287,14 @@ class Message {
faceElem = message.faceElem;
attachedInfoElem = message.attachedInfoElem;
}
/// 单聊消息
bool get isSingleChat => sessionType == ConversationType.single;
/// 群聊消息
bool get isGroupChat =>
sessionType == ConversationType.group ||
sessionType == ConversationType.superGroup;
}
/// 图片消息内容
@@ -958,3 +966,71 @@ class AtUserInfo {
return data;
}
}
/// 消息撤回具体信息
class RevokedInfo {
/// 撤回者ID
String? revokerID;
/// 撤回者群角色 [GroupRoleLevel]
int? revokerRole;
/// 撤回者昵称
String? revokerNickname;
/// 消息id
String? clientMsgID;
/// 撤回时间
int? revokeTime;
/// 消息发送时间
int? sourceMessageSendTime;
/// 消息发送者
String? sourceMessageSendID;
/// 消息发送者昵称
String? sourceMessageSenderNickname;
/// 会话类型 [ConversationType]
int? sessionType;
RevokedInfo({
this.revokerID,
this.revokerRole,
this.revokerNickname,
this.clientMsgID,
this.revokeTime,
this.sourceMessageSendTime,
this.sourceMessageSendID,
this.sourceMessageSenderNickname,
this.sessionType,
});
RevokedInfo.fromJson(Map<String, dynamic> json) {
revokerID = json['revokerID'];
revokerRole = json['revokerRole'];
revokerNickname = json['revokerNickname'];
clientMsgID = json['clientMsgID'];
revokeTime = json['revokeTime'];
sourceMessageSendTime = json['sourceMessageSendTime'];
sourceMessageSendID = json['sourceMessageSendID'];
sourceMessageSenderNickname = json['sourceMessageSenderNickname'];
sessionType = json['sessionType'];
}
Map<String, dynamic> toJson() {
final data = Map<String, dynamic>();
data['revokerID'] = this.revokerID;
data['revokerRole'] = this.revokerRole;
data['revokerNickname'] = this.revokerNickname;
data['clientMsgID'] = this.clientMsgID;
data['revokeTime'] = this.revokeTime;
data['sourceMessageSendTime'] = this.sourceMessageSendTime;
data['sourceMessageSendID'] = this.sourceMessageSendID;
data['sourceMessageSenderNickname'] = this.sourceMessageSenderNickname;
data['sessionType'] = this.sessionType;
return data;
}
}

View File

@@ -322,6 +322,13 @@ class FriendInfo {
data['ex'] = this.ex;
return data;
}
String getShowName() => _isNull(remark) ?? _isNull(nickname) ?? userID!;
static String? _isNull(String? value) {
if (value == null || value.trim().isEmpty) return null;
return value;
}
}
/// 黑名单信息

View File

@@ -2,7 +2,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
class OpenIM {
static const version = '2.1.0';
static const version = '2.3.0';
static const _channel = const MethodChannel('flutter_openim_sdk');