예제 #1
0
        public async Task <List <MessageDto> > SearchMessagesAsync(
            string query,
            ConversationType?conversationType,
            long?conversationId,
            ConversationType?navConversationType,
            long?navConversationId,
            Guid?navMessageId,
            long?userId,
            int limit = 30)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var messagesCondition = PredicateBuilder.New <Message>();
                var messagesQuery     = context.Messages.AsNoTracking();
                ExpressionsHelper expressionsHelper = new ExpressionsHelper();
                var messageExpression = expressionsHelper.GetMessageExpression(query);
                if (conversationType != null && conversationId != null)
                {
                    if (userId != null && !await conversationsService.IsUserInConversationAsync(conversationType.Value, conversationId.Value, userId.Value).ConfigureAwait(false))
                    {
                        return(new List <MessageDto>());
                    }

                    switch (conversationType.Value)
                    {
                    case ConversationType.Dialog:
                        messagesQuery = messagesQuery.Where(message => message.DialogId == conversationId);
                        break;

                    case ConversationType.Chat:
                        messagesQuery = messagesQuery.Where(message => message.ChatId == conversationId);
                        break;

                    case ConversationType.Channel:
                        messagesQuery = messagesQuery.Where(message => message.ChannelId == conversationId);
                        break;
                    }
                }
                else
                {
                    if (userId != null)
                    {
                        var dialogsIds = await loadDialogsService.GetUserDialogsIdAsync(userId.Value).ConfigureAwait(false);

                        var chatsIds = await loadChatsService.GetUserChatsIdAsync(userId.Value).ConfigureAwait(false);

                        var channelsIds = await loadChannelsService.GetUserChannelsIdAsync(userId.Value).ConfigureAwait(false);

                        messagesCondition = dialogsIds.Aggregate(messagesCondition,
                                                                 (current, value) => current.Or(option => option.DialogId == value).Expand());
                        messagesCondition = chatsIds.Aggregate(messagesCondition,
                                                               (current, value) => current.Or(option => option.ChatId == value).Expand());
                        messagesCondition = channelsIds.Aggregate(messagesCondition,
                                                                  (current, value) => current.Or(option => option.ChannelId == value).Expand());
                        messagesQuery = messagesQuery.Where(messagesCondition);
                    }
                }
                if (navConversationId != null && navConversationType != null && navMessageId != null)
                {
                    var navMessage = (await GetMessagesByIdAsync(
                                          new List <Guid> {
                        navMessageId.Value
                    },
                                          navConversationType.Value,
                                          navConversationId.Value,
                                          userId).ConfigureAwait(false)).FirstOrDefault();
                    if (navMessage != null)
                    {
                        messagesQuery = messagesQuery
                                        .Where(message => message.SendingTime <= navMessage.SendingTime && message.GlobalId != navMessage.GlobalId);
                    }
                }
                var messages = await messagesQuery
                               .Where(messageExpression)
                               .Where(message => !message.Deleted && (message.ExpiredAt == null || message.ExpiredAt > DateTime.UtcNow.ToUnixTime()))
                               .OrderByDescending(message => message.SendingTime)
                               .Take(limit)
                               .Include(message => message.Attachments)
                               .ToListAsync()
                               .ConfigureAwait(false);

                return(MessageConverter.GetMessagesDto(messages));
            }
        }