public async Task <ActionResult <ThreadWithContactsResponseModel> > GetAllThreadsByUserIdAsync([FromRoute] int userId, [FromQuery(Name = "limit")] int limit = -1, [FromQuery(Name = "type")] FetchThreadType fetchType = FetchThreadType.All)
 {
     return(Ok(await _threadManager.GetThreadsByUserId(userId, limit, fetchType)));
 }
Beispiel #2
0
        public async Task <IEnumerable <ThreadWithContactsResponseModel> > GetThreadsByUserId(int userId, int limit, FetchThreadType fetchType)
        {
            IList <ThreadEntity> threads;

            switch (fetchType)
            {
            case FetchThreadType.All:
                threads = (await _threadRepository.SearchByParticipantIdAsync(userId))?.ToList();
                break;

            case FetchThreadType.Archived:
                threads = (await _threadRepository.SearchByParticipantIdAsync(userId))?.Where(x => x.ArchivedBy?.Contains(userId) == true)?.ToList();
                break;

            case FetchThreadType.UnArchived:
                threads = (await _threadRepository.SearchByParticipantIdAsync(userId))?.Where(x => x.ArchivedBy == null || x.ArchivedBy?.Contains(userId) == false)?.ToList();
                break;

            default:
                throw new InvalidRequestException();
            }

            if (threads == null)
            {
                return(_mapper.Map <IEnumerable <ThreadEntity>, IEnumerable <ThreadWithContactsResponseModel> >(null));
            }

            var participants = (await Task.WhenAll(threads.Select(x => _contactRepository.GetChatUserDetailsAsync(x.Participants))))
                               .Where(x => x != null)
                               .ToList();
            var messages = (await Task.WhenAll(threads.Select(x => _messageRepository.GetByThreadIdAsync(x.Id))))
                           .SelectMany(x => x)
                           .Where(x => x != null).OrderBy(x => x.CreatedAt);

            var participantDetails = _mapper.Map <IEnumerable <IEnumerable <ChatUser> >, IEnumerable <IEnumerable <UserContactResponseModel> > >(participants);

            var threadWithContactsResponseModels = limit > 0
                ? _mapper.Map <IEnumerable <ThreadEntity>, IEnumerable <ThreadWithContactsResponseModel> >(threads.Take(limit), options => options.Items[MappingConstants.ThreadRequestUserId] = userId).Zip(participantDetails.Take(limit), ZipContactsWithThread)
                : _mapper.Map <IEnumerable <ThreadEntity>, IEnumerable <ThreadWithContactsResponseModel> >(threads, options => options.Items[MappingConstants.ThreadRequestUserId]             = userId).Zip(participantDetails, ZipContactsWithThread);


            if (fetchType == FetchThreadType.Archived)
            {
                return(threadWithContactsResponseModels.Select(threadResponse =>
                {
                    threadResponse.UnreadMessageCount = threadResponse.Participants.Select(p => new UnreadMessageResponseModel
                    {
                        ChatUserId = p.ChatUserId,
                        UnreadMessagesCount = messages.Where(m => m.ThreadId == threadResponse.Id).Count(m => m.ReadBy?.Contains(p.ChatUserId) != true)
                    });
                    return threadResponse;
                }).OrderByDescending(x => x.ModifiedAt));
            }
            return(threadWithContactsResponseModels.Select(threadResponse =>
            {
                threadResponse.UnreadMessageCount = threadResponse.Participants.Select(p => new UnreadMessageResponseModel
                {
                    ChatUserId = p.ChatUserId,
                    UnreadMessagesCount = messages.Where(m => m.ThreadId == threadResponse.Id).Count(m => m.ReadBy?.Contains(p.ChatUserId) != true)
                });
                return threadResponse;
            }).OrderBy(x => x.ModifiedAt));
        }