Example #1
0
        public async Task GetLastValidChatMessage()
        {
            var chat            = fillTestDbHelper.Chats.FirstOrDefault();
            var expectedMessage = fillTestDbHelper.Messages
                                  .OrderByDescending(opt => opt.SendingTime)
                                  .FirstOrDefault(opt => !opt.Deleted && opt.ChatId == chat.Id);
            var actualMessage = await loadMessagesService.GetLastValidChatMessageAsync(chat.Id);

            Assert.Equal(expectedMessage.GlobalId, actualMessage.GlobalId);
        }
        private async Task <List <MessageDto> > DeleteChatMessagesInfoAsync(long chatId, IEnumerable <Guid> messagesIds, long userId)
        {
            try
            {
                using (MessengerDbContext context = contextFactory.Create())
                {
                    var messagesCondition = PredicateBuilder.New <Message>();
                    messagesCondition = messagesIds.Aggregate(messagesCondition,
                                                              (current, value) => current.Or(opt => opt.GlobalId == value && opt.ChatId == chatId && opt.Deleted == false));
                    var query = from conversation in context.Chats
                                join chatUser in context.ChatUsers on conversation.Id equals chatUser.ChatId
                                where chatUser.Banned == false &&
                                chatUser.Deleted == false &&
                                conversation.Deleted == false &&
                                chatUser.UserId == userId &&
                                conversation.Id == chatId
                                select new
                    {
                        Chat = conversation,
                        User = chatUser
                    };
                    var result = await query.FirstOrDefaultAsync().ConfigureAwait(false);

                    if (result == null || result.User == null)
                    {
                        return(new List <MessageDto>());
                    }

                    List <Message> messages = await context.Messages
                                              .Include(opt => opt.Attachments)
                                              .Where(messagesCondition)
                                              .ToListAsync()
                                              .ConfigureAwait(false);

                    if (!messages.Any())
                    {
                        return(new List <MessageDto>());
                    }
                    var deletedMessagesIds = messages.Select(message => message.GlobalId).ToList();
                    var usersCondition     = PredicateBuilder.New <ChatUser>();
                    usersCondition = deletedMessagesIds.Aggregate(usersCondition,
                                                                  (current, value) => current.Or(opt => opt.LastReadedGlobalMessageId == value).Expand());
                    var chatUsers = await context.ChatUsers.Where(usersCondition).ToListAsync().ConfigureAwait(false);

                    var groupedChatUsers = chatUsers.GroupBy(opt => opt.LastReadedGlobalMessageId);
                    foreach (var group in groupedChatUsers)
                    {
                        var message = await context.Messages
                                      .OrderByDescending(opt => opt.SendingTime)
                                      .ThenBy(opt => opt.GlobalId)
                                      .Where(opt => !deletedMessagesIds.Contains(opt.GlobalId) && opt.ChatId == chatId && !opt.Deleted)
                                      .FirstOrDefaultAsync()
                                      .ConfigureAwait(false);

                        foreach (var chatUser in group)
                        {
                            chatUser.LastReadedGlobalMessageId = message?.GlobalId;
                        }
                        context.ChatUsers.UpdateRange(group);
                    }
                    List <MessageDto> deletedMessages = MessageConverter.GetMessagesDto(messages);
                    foreach (var message in messages)
                    {
                        if (message.SenderId != result.User.UserId && result.User.UserRole == UserRole.User)
                        {
                            continue;
                        }

                        message.Deleted   = true;
                        message.UpdatedAt = DateTime.UtcNow.ToUnixTime();
                        if (NodeSettings.Configs.Node.PermanentlyDeleting)
                        {
                            message.Attachments = null;
                            message.Replyto     = null;
                            message.SendingTime = 0;
                            message.Text        = null;
                            message.SenderId    = null;
                        }
                    }
                    context.UpdateRange(messages);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    Message lastMessage = await _loadMessagesService.GetLastValidChatMessageAsync(chatId).ConfigureAwait(false);

                    result.Chat.LastMessageId       = lastMessage?.Id ?? null;
                    result.Chat.LastMessageGlobalId = lastMessage?.GlobalId;
                    context.Update(result.Chat);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(deletedMessages);
                }
            }
            catch (Exception ex)
            {
                throw new DeleteMessagesException("An error occurred while deleting messages.", ex);
            }
        }