Example #1
0
        /// <summary>
        /// Primary method for loading more messages when user scrolls to the top of a chat box, aka infinite scrolling.
        /// </summary>
        /// <returns>
        /// A paged list of messages. Client-side will append this new set of messages to the existing set it already has.
        /// </returns>
        public async Task GetMoreMessages(MemberChatParams memberChatParams)
        {
            var username = Context.User.GetUsername();
            var sender   = await _unitOfWork.UserRepository.GetUserByUsernameAsync(username);

            var recipient = await _unitOfWork.UserRepository.GetUserByUsernameAsync(memberChatParams.RecipientUsername);

            if (recipient == null)
            {
                throw new HubException("Not found user");
            }

            var messages = await _unitOfWork.MessageRepository
                           .GetScrolledMessageThread(Context.User.GetUsername(), memberChatParams.RecipientUsername, memberChatParams);

            await Clients.Caller.SendAsync("ReceivedMessageThread", messages);
        }
Example #2
0
        /// <summary>
        /// Performs various critical functionality for sending and receiving messages via Signal R.
        /// Creates a groupname based on the sender and recipient. Combo of usernames, in alphabetical order.
        /// Asynchronously send data to front end that are called in client-side methods
        /// The name of the client-side method must match the string passed through in the "SendAsync()"
        /// </summary>
        public override async Task OnConnectedAsync()
        {
            var httpContext = Context.GetHttpContext();

            // pass in the other user name (via a query string) with the key of user to get it into this variable.
            var otherUser = httpContext.Request.Query["user"].ToString();

            // initialize the memberChatParams that are needed to get messages from the repo for scrolled pagination.
            var memberChatParams = new MemberChatParams {
                PageNumber        = 1,
                PageSize          = 10, // SCROLLED PAGE SIZE
                RecipientUsername = otherUser
            };

            // TODO: Consider adding a check here to see if they exist first.
            // the group that a pair of users belong to.
            var groupName = GetGroupName(Context.User.GetUsername(), otherUser);
            await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

            var group = await AddToGroup(groupName);

            await Clients.Group(groupName).SendAsync("UpdatedGroup", group);

            // get messages using GetMessageThread method from repo. (original method, consider removing)
            // TODO: Revisit whether this method is necessary anymore. Functionality has been moved to GetScrolledMessageThread()
            var messages = await _unitOfWork.MessageRepository
                           .GetMessageThread(Context.User.GetUsername(), otherUser);

            // get messages using GetScrolledMessageThread method from repo (for scrolled pagination)
            var messages2 = await _unitOfWork.MessageRepository
                            .GetScrolledMessageThread(Context.User.GetUsername(), otherUser, memberChatParams);

            // check to see if changes in this step. If there are, then save them to the DB here, not within the message repo itself.
            if (_unitOfWork.HasChanges())
            {
                await _unitOfWork.Complete();
            }

            // send the response back to the caller
            await Clients.Caller.SendAsync("ReceiveMessageThread", messages2);
        }
Example #3
0
        /// <summary>
        /// Primary method to load a set of messages for a message thread. Used withi infinte scrolling
        /// </summary>
        /// <param name="currentUsername">The current user's username</param>
        /// <param name="recipientUsername">The other user's username</param>
        /// <param name="memberChatParams">Params with data for the PagedList settings</param>
        /// <returns>
        ///  A PagedList of messages (used for scrolled apges)
        /// </returns>
        public async Task <IEnumerable <MessageDto> > GetScrolledMessageThread(string currentUsername, string recipientUsername, MemberChatParams memberChatParams)
        {
            // store the query. Filter messagse for these users. Include photos. Order descending by MessageSent date
            var query = _context.Messages
                        .Include(u => u.Sender).ThenInclude(p => p.Photos)
                        .Include(u => u.Recipient).ThenInclude(p => p.Photos)
                        .Where(m => m.Recipient.UserName == currentUsername && m.RecipientDeleted == false &&
                               m.Sender.UserName == recipientUsername ||
                               m.Recipient.UserName == recipientUsername &&
                               m.Sender.UserName == currentUsername && m.SenderDeleted == false
                               )
                        .OrderByDescending(m => m.MessageSent)
                        .AsQueryable();


            // from the list of messages, determine if the current user has unread messages.
            var unreadMessages = query.Where(m => m.DateRead == null && m.Recipient.UserName == currentUsername).ToList();

            // then mark those unread messages as read
            if (unreadMessages.Any())
            {
                foreach (var message in unreadMessages)
                {
                    message.DateRead = DateTime.UtcNow;
                }
                // save to DB (slight deviation from Unit of Work framework. But need for now if we still want to return a list of MessageDtos)
                // alternative is to have this method return a list of type Message, instead of the  MessageDto.
                await _context.SaveChangesAsync();
            }

            return(await PagedList <MessageDto> .CreateScrolledAsync(query.ProjectTo <MessageDto>(_mapper.ConfigurationProvider).AsNoTracking(),
                                                                     memberChatParams.PageNumber, memberChatParams.PageSize));
        }