using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Linq; using System.Collections.ObjectModel; using LeanCloud.Storage; namespace LeanCloud.Realtime { /// /// 普通对话 /// public class LCIMConversation { /// /// 对话 Id /// public string Id { get; internal set; } /// /// 是否唯一 /// public bool Unique { get; internal set; } /// /// 唯一 Id /// public string UniqueId { get; internal set; } /// /// 对话名称 /// public string Name { get { return this["name"] as string; } internal set { this["name"] = value; } } /// /// 创建者 Id /// public string CreatorId { get; set; } /// /// 成员 Id /// public ReadOnlyCollection MemberIds { get { return new ReadOnlyCollection(ids.ToList()); } } /// /// 静音成员 Id /// public ReadOnlyCollection MutedMemberIds { get { return new ReadOnlyCollection(mutedIds.ToList()); } } /// /// 未读消息数量 /// public int Unread { get; internal set; } /// /// 最新的一条消息 /// public LCIMMessage LastMessage { get; internal set; } /// /// 创建时间 /// public DateTime CreatedAt { get; internal set; } /// /// 更新时间 /// public DateTime UpdatedAt { get; internal set; } /// /// 最新送达消息时间戳 /// public long LastDeliveredTimestamp { get; internal set; } /// /// 最新送达消息时间 /// public DateTime LastDeliveredAt { get { DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(LastDeliveredTimestamp); return dateTimeOffset.DateTime; } } /// /// 最新已读消息时间戳 /// public long LastReadTimestamp { get; internal set; } /// /// 最新已读消息时间 /// public DateTime LastReadAt { get { DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeMilliseconds(LastReadTimestamp); return dateTimeOffset.DateTime; } } /// /// 设置/获取对话属性 /// /// /// public object this[string key] { get { return customProperties[key]; } set { customProperties[key] = value; } } /// /// 是否已静音 /// public bool IsMute { get; private set; } protected LCIMClient Client { get; private set; } private readonly Dictionary customProperties; internal HashSet ids; internal HashSet mutedIds; internal LCIMConversation(LCIMClient client) { Client = client; customProperties = new Dictionary(); ids = new HashSet(); mutedIds = new HashSet(); customProperties = new Dictionary(); } /// /// 获取对话人数,或暂态对话的在线人数 /// /// public async Task GetMembersCount() { return await Client.ConversationController.GetMembersCount(Id); } /// /// 将该会话标记为已读 /// /// /// public async Task Read() { if (LastMessage == null) { return; } await Client.MessageController.Read(Id, LastMessage); Unread = 0; } /// /// 修改对话属性 /// /// /// public async Task UpdateInfo(Dictionary attributes) { if (attributes == null || attributes.Count == 0) { throw new ArgumentNullException(nameof(attributes)); } Dictionary updatedAttr = await Client.ConversationController.UpdateInfo(Id, attributes); if (updatedAttr != null) { MergeInfo(updatedAttr); } } /// /// 添加用户到对话 /// /// 用户 Id /// public virtual async Task AddMembers(IEnumerable clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } LCIMPartiallySuccessResult result = await Client.ConversationController.AddMembers(Id, clientIds); ids.UnionWith(result.SuccessfulClientIdList); return result; } /// /// 删除用户 /// /// 用户 Id /// public async Task RemoveMembers(IEnumerable removeIds) { if (removeIds == null || removeIds.Count() == 0) { throw new ArgumentNullException(nameof(removeIds)); } LCIMPartiallySuccessResult result = await Client.ConversationController.RemoveMembers(Id, removeIds); ids.RemoveWhere(id => result.SuccessfulClientIdList.Contains(id)); return result; } /// /// 加入对话 /// /// public async Task Join() { LCIMPartiallySuccessResult result = await Client.ConversationController.AddMembers(Id, new string[] { Client.Id }); if (result.IsSuccess) { ids.UnionWith(result.SuccessfulClientIdList); } else { LCIMOperationFailure error = result.FailureList[0]; throw new LCException(error.Code, error.Reason); } } /// /// 离开对话 /// /// public async Task Quit() { LCIMPartiallySuccessResult result = await RemoveMembers(new string[] { Client.Id }); if (!result.IsSuccess) { LCIMOperationFailure error = result.FailureList[0]; throw new LCException(error.Code, error.Reason); } } /// /// 发送消息 /// /// /// public async Task Send(LCIMMessage message, LCIMMessageSendOptions options = null) { if (message == null) { throw new ArgumentNullException(nameof(message)); } if (options == null) { options = LCIMMessageSendOptions.Default; } await Client.MessageController.Send(Id, message, options); LastMessage = message; return message; } /// /// 静音 /// /// public async Task Mute() { await Client.ConversationController.Mute(Id); IsMute = true; } /// /// 取消静音 /// /// public async Task Unmute() { await Client.ConversationController.Unmute(Id); IsMute = false; } /// /// 禁言 /// /// /// public async Task MuteMembers(IEnumerable clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } LCIMPartiallySuccessResult result = await Client.ConversationController.MuteMembers(Id, clientIds); if (result.SuccessfulClientIdList != null) { mutedIds.UnionWith(result.SuccessfulClientIdList); } return result; } /// /// 取消禁言 /// /// /// public async Task UnmuteMembers(IEnumerable clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } LCIMPartiallySuccessResult result = await Client.ConversationController.UnmuteMembers(Id, clientIds); if (result.SuccessfulClientIdList != null) { mutedIds.RemoveWhere(id => result.SuccessfulClientIdList.Contains(id)); } return result; } /// /// 将用户加入黑名单 /// /// /// public async Task BlockMembers(IEnumerable clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } return await Client.ConversationController.BlockMembers(Id, clientIds); } /// /// 将用户移除黑名单 /// /// /// public async Task UnblockMembers(IEnumerable clientIds) { if (clientIds == null || clientIds.Count() == 0) { throw new ArgumentNullException(nameof(clientIds)); } return await Client.ConversationController.UnblockMembers(Id, clientIds); } /// /// 撤回消息 /// /// /// public async Task RecallMessage(LCIMMessage message) { if (message == null) { throw new ArgumentNullException(nameof(message)); } await Client.MessageController.RecallMessage(Id, message); } /// /// 修改消息 /// /// /// /// public async Task UpdateMessage(LCIMMessage oldMessage, LCIMMessage newMessage) { if (oldMessage == null) { throw new ArgumentNullException(nameof(oldMessage)); } if (newMessage == null) { throw new ArgumentNullException(nameof(newMessage)); } await Client.MessageController.UpdateMessage(Id, oldMessage, newMessage); } /// /// 更新对话中成员的角色 /// /// /// /// public async Task UpdateMemberRole(string memberId, string role) { if (string.IsNullOrEmpty(memberId)) { throw new ArgumentNullException(nameof(memberId)); } if (role != LCIMConversationMemberInfo.Manager && role != LCIMConversationMemberInfo.Member) { throw new ArgumentException("role MUST be Manager Or Memebr"); } await Client.ConversationController.UpdateMemberRole(Id, memberId, role); } /// /// 获取对话中成员的角色(只返回管理员) /// /// public async Task> GetAllMemberInfo() { return await Client.ConversationController.GetAllMemberInfo(Id); } /// /// 获取对话中指定成员的角色 /// /// /// public async Task GetMemberInfo(string memberId) { if (string.IsNullOrEmpty(memberId)) { throw new ArgumentNullException(nameof(memberId)); } ReadOnlyCollection members = await GetAllMemberInfo(); foreach (LCIMConversationMemberInfo member in members) { if (member.MemberId == memberId) { return member; } } return null; } /// /// 查询禁言用户 /// /// /// /// public async Task QueryMutedMembers(int limit = 10, string next = null) { return await Client.ConversationController.QueryMutedMembers(Id, limit, next); } /// /// 查询黑名单用户 /// /// 限制 /// 其实用户 Id /// public async Task QueryBlockedMembers(int limit = 10, string next = null) { return await Client.ConversationController.QueryBlockedMembers(Id, limit, next); } /// /// 查询聊天记录 /// /// 起点 /// 终点 /// 查找方向 /// 限制 /// 消息类型 /// public async Task> QueryMessages(LCIMMessageQueryEndpoint start = null, LCIMMessageQueryEndpoint end = null, LCIMMessageQueryDirection direction = LCIMMessageQueryDirection.NewToOld, int limit = 20, int messageType = 0) { return await Client.MessageController.QueryMessages(Id, start, end, direction, limit, messageType); } /// /// 获取会话已收/已读时间戳 /// /// public async Task FetchReciptTimestamps() { await Client.ConversationController.FetchReciptTimestamp(Id); } internal static bool IsTemporayConversation(string convId) { return convId.StartsWith("_tmp:"); } internal void MergeFrom(Dictionary conv) { if (conv.TryGetValue("objectId", out object idObj)) { Id = idObj as string; } if (conv.TryGetValue("unique", out object uniqueObj)) { Unique = (bool)uniqueObj; } if (conv.TryGetValue("uniqueId", out object uniqueIdObj)) { UniqueId = uniqueIdObj as string; } if (conv.TryGetValue("createdAt", out object createdAtObj)) { CreatedAt = DateTime.Parse(createdAtObj.ToString()); } if (conv.TryGetValue("updatedAt", out object updatedAtObj)) { UpdatedAt = DateTime.Parse(updatedAtObj.ToString()); } if (conv.TryGetValue("c", out object co)) { CreatorId = co as string; } if (conv.TryGetValue("m", out object mo)) { IEnumerable ids = (mo as IList).Cast(); this.ids = new HashSet(ids); } if (conv.TryGetValue("mu", out object muo)) { IEnumerable ids = (muo as IList).Cast(); mutedIds = new HashSet(ids); } //if (conv.TryGetValue("lm", out object lmo)) { // LastMessageAt = (DateTime)LCDecoder.Decode(lmo); //} } internal void MergeInfo(Dictionary attr) { if (attr == null || attr.Count == 0) { return; } foreach (KeyValuePair kv in attr) { customProperties[kv.Key] = kv.Value; } } } }