Esempio n. 1
0
        public async Task <MessagesResult> GetLastMessagesAsync(GetLastMessagesRequest request)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get last messages. Member {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            IReadOnlyCollection <Message> messages;

            var lastReadMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(member.Id, request.ChannelId);

            if (lastReadMessage != null)
            {
                messages = await UnitOfWork.MessageRepository.GetLastMessagesWithOwnersAsync(request.ChannelId, lastReadMessage.Created, _messagesConfiguration.LastMessageReadCount);
            }
            else
            {
                messages = await UnitOfWork.MessageRepository.GetAllChannelMessagesWithOwnersAsync(request.ChannelId);
            }

            var results = messages.Select(message => DomainModelsMapper.MapToMessageResponse(message, lastReadMessage?.Created)).ToList();

            return(new MessagesResult
            {
                Results = results
            });
        }
Esempio n. 2
0
        public async Task <MessageResponse> UpdateMessageAsync(UpdateMessageRequest request)
        {
            var message = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(request.MessageId);

            if (message == null)
            {
                throw new NetKitChatNotFoundException($"Unable to update message. Message {nameof(request.MessageId)}:{request.MessageId} is not found.");
            }

            if (message.Type == MessageType.System)
            {
                throw new NetKitChatInvalidOperationException($"Unable to update message. Message {nameof(request.MessageId)}:{request.MessageId} update is forbidden.");
            }

            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to update message. Member {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            if (member.Id != message.OwnerId)
            {
                throw new NetKitChatAccessForbiddenException($"Unable to update message. Message {nameof(request.MessageId)}:{request.MessageId} owner required.");
            }

            message.Body    = request.Body;
            message.Updated = _dateTimeProvider.GetUtcNow();

            await UnitOfWork.MessageRepository.UpdateMessageBodyAsync(message.Id, message.Body, message.Updated.Value);

            return(DomainModelsMapper.MapToMessageResponse(message));
        }
Esempio n. 3
0
        public async Task <ChannelResponse> UpdateChannelAsync(UpdateChannelRequest request)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelAsync(request.ChannelId);

            if (channel == null)
            {
                throw new NetKitChatNotFoundException($"Unable to update channel. Channel {nameof(request.ChannelId)}:{request.ChannelId} is not found.");
            }

            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member.Id != channel.CreatorId)
            {
                throw new NetKitChatAccessForbiddenException($"Unable to update channel {nameof(request.ChannelId)}:{request.ChannelId}. Channel owner required.");
            }
            if (channel.Type == ChannelType.Direct)
            {
                throw new NetKitChatInvalidOperationException($"Unable to update direct channel {nameof(request.ChannelId)}:{request.ChannelId}.");
            }

            var permanentChannelImageUrl = await _cloudImageProvider.CopyImageToDestinationContainerAsync(request.PhotoUrl);

            channel.Description    = request.Description;
            channel.WelcomeMessage = request.WelcomeMessage;
            channel.Name           = request.Name;
            channel.PhotoUrl       = permanentChannelImageUrl;
            channel.Updated        = _dateTimeProvider.GetUtcNow();

            await UnitOfWork.ChannelRepository.UpdateChannelAsync(channel);

            return(DomainModelsMapper.MapToChannelResponse(channel));
        }
Esempio n. 4
0
        public async Task <ChannelSummaryResponse> GetChannelSummaryAsync(string saasUserId, Guid channelId)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelWithCreatorAsync(channelId);

            if (channel == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get channel summary. Channel {nameof(channelId)}:{channelId} is not found.");
            }

            var messages = await UnitOfWork.MessageRepository.GetAllChannelMessagesWithOwnersAsync(channel.Id);

            channel.Messages = messages.ToList();

            var member = await _memberService.GetMemberBySaasUserIdAsync(saasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get channel summary. Member {nameof(saasUserId)}:{saasUserId} is not found.");
            }

            var channelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(member.Id, channelId);

            var lastReadMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(member.Id, channelId);

            return(DomainModelsMapper.MapToChannelSummaryResponse(channel, channelMember, lastReadMessage));
        }
Esempio n. 5
0
        public async Task <ChannelResponse> CloseChannelAsync(string saasUserId, Guid channelId)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelAsync(channelId);

            if (channel == null)
            {
                throw new NetKitChatNotFoundException($"Unable to close channel. Channel {nameof(channelId)}:{channelId} is not found.");
            }

            if (channel.IsClosed)
            {
                throw new NetKitChatInvalidOperationException($"Unable to close channel. Channel {nameof(channelId)}:{channelId} already closed.");
            }

            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(saasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to close channel. Member {nameof(saasUserId)}:{saasUserId} is not found.");
            }

            if (member.Id != channel.CreatorId && channel.Type != ChannelType.Direct)
            {
                throw new NetKitChatAccessForbiddenException($"Unable to close channel {nameof(channelId)}:{channelId}. Channel owner required.");
            }

            channel.IsClosed = true;
            await UnitOfWork.ChannelRepository.UpdateChannelAsync(channel);

            return(DomainModelsMapper.MapToChannelResponse(channel));
        }
        public async Task <NotificationSettingResponse> UpdateUserNotificationSettingsAsync(NotificationSettingRequest notificationSettingRequest)
        {
            Ensure.That(notificationSettingRequest).IsNotNull();

            var member = await _memberService.GetMemberBySaasUserIdAsync(notificationSettingRequest.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException("Requested member does not exist.");
            }

            var existingNotificationSettings = await UnitOfWork.NotificationSettingRepository.GetSettingsByMemberIdAsync(member.Id);

            if (existingNotificationSettings != null)
            {
                existingNotificationSettings = FillNotificationSettings(notificationSettingRequest.Key, notificationSettingRequest.Value, existingNotificationSettings);
                await UnitOfWork.NotificationSettingRepository.UpdateSettingsAsync(existingNotificationSettings);
            }
            else
            {
                var notificationSettings = new NotificationSettings
                {
                    Id       = Guid.NewGuid(),
                    MemberId = member.Id
                };

                notificationSettings = FillNotificationSettings(notificationSettingRequest.Key, notificationSettingRequest.Value, notificationSettings);
                await UnitOfWork.NotificationSettingRepository.AddSettingsAsync(notificationSettings);
            }

            var userNotificationSettings = await UnitOfWork.NotificationSettingRepository.GetSettingsByMemberIdAsync(member.Id);

            return(DomainModelsMapper.MapToNotificationSettingsResponse(userNotificationSettings));
        }
Esempio n. 7
0
        public async Task <MessagesResult> GetMessagesAsync(GetMessagesRequest request)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get messages. Member {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            var lastMessage = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(request.MessageId);

            var lastMessageCreatedDate = lastMessage?.Created ?? request.MessageCreatedDate;

            var lastReadMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(member.Id, request.ChannelId);

            var messages = await UnitOfWork.MessageRepository.GetMessagesWithOwnersAsync(request.ChannelId, lastMessageCreatedDate, request.PageSize);

            var results = messages.Select(message => DomainModelsMapper.MapToMessageResponse(message, lastReadMessage?.Created)).ToList();

            return(new MessagesResult
            {
                PageSize = request.PageSize,
                Results = results
            });
        }
Esempio n. 8
0
        public async Task <MessageResponse> CreateMessageAsync(CreateMessageRequest request)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to create message. Member {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            var isChannelOpen = await UnitOfWork.ChannelRepository.IsChannelExistsAndOpenAsync(request.ChannelId);

            if (!isChannelOpen)
            {
                throw new NetKitChatNotFoundException($"Unable to create message. Channel {nameof(request.ChannelId)}:{request.ChannelId} is not found.");
            }

            // move image to persistent container
            if (!string.IsNullOrWhiteSpace(request.ImageUrl))
            {
                request.ImageUrl = await _cloudImageProvider.CopyImageToDestinationContainerAsync(request.ImageUrl);
            }

            var message = new Message
            {
                Id                  = Guid.NewGuid(),
                ChannelId           = request.ChannelId,
                OwnerId             = member.Id,
                Body                = request.Body,
                Created             = _dateTimeProvider.GetUtcNow(),
                Type                = request.Type,
                ImageUrl            = request.ImageUrl,
                AccessibilityStatus = AccessibilityStatus.Present
            };

            await UnitOfWork.ExecuteTransactionAsync(async() =>
            {
                if (request.Type == MessageType.Forward)
                {
                    var forwardedMessage = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(request.ForwardedMessageId);
                    if (forwardedMessage == null)
                    {
                        throw new NetKitChatNotFoundException($"Unable to create message. Forward message {nameof(request.ForwardedMessageId)}:{request.ForwardedMessageId} is not found.");
                    }

                    var forwardMessage = DomainModelsMapper.MapToForwardMessage(forwardedMessage);
                    forwardMessage.Id  = Guid.NewGuid();
                    await UnitOfWork.ForwardMessageRepository.AddForwardMessageAsync(forwardMessage);
                    message.ForwardMessageId = forwardMessage.Id;
                }

                await UnitOfWork.MessageRepository.AddMessageAsync(message);
                await UnitOfWork.ChannelMemberRepository.SetLastReadMessageAsync(member.Id, request.ChannelId, message.Id);
            });

            message = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(message.Id);

            return(DomainModelsMapper.MapToMessageResponse(message));
        }
Esempio n. 9
0
        public async Task <MessageResponse> GetMessageByIdAsync(Guid messageId)
        {
            var message = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(messageId);

            if (message == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get message by {nameof(messageId)}. Message {nameof(messageId)}:{messageId} is not found.");
            }

            return(DomainModelsMapper.MapToMessageResponse(message));
        }
Esempio n. 10
0
        public async Task <MemberSummaryResponse> GetMemberByIdAsync(Guid memberId)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberByIdAsync(memberId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get member by {nameof(memberId)}. Member {nameof(memberId)}:{memberId} is not found.");
            }

            return(DomainModelsMapper.MapToMemberSummaryResponse(member));
        }
Esempio n. 11
0
        public async Task <ClientResponse> GetClientAsync(GetClientRequest request)
        {
            var client = await UnitOfWork.ClientRepository.GetClientWithMemberAsync(request.ClientConnectionId);

            if (client == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get client. Client {nameof(request.ClientConnectionId)}:{request.ClientConnectionId} is not found.");
            }

            return(DomainModelsMapper.MapToClientResponse(client));
        }
Esempio n. 12
0
        public async Task <ChannelResponse> GetChannelByIdAsync(Guid channelId)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelAsync(channelId);

            if (channel == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get channel by {nameof(channelId)}. Channel {nameof(channelId)}:{channelId} is not found.");
            }

            return(DomainModelsMapper.MapToChannelResponse(channel));
        }
Esempio n. 13
0
        public async Task <SettingsResponse> GetChannelSettingsAsync(Guid channelId)
        {
            var settings = await UnitOfWork.SettingRepository.GetSettingsByChannelIdAsync(channelId);

            if (settings == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get channel settings. Settings with {nameof(channelId)}:{channelId} is not found.");
            }

            return(DomainModelsMapper.MapToSettingsResponse(settings));
        }
Esempio n. 14
0
        public async Task <IReadOnlyCollection <ChannelResponse> > GetMemberChannelsAsync(string saasUserId)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(saasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get member channels. Member {nameof(saasUserId)}:{saasUserId} is not found.");
            }

            var channels = await UnitOfWork.ChannelRepository.GetAllowedChannelsAsync(member.Id);

            return(channels.Select(channel => DomainModelsMapper.MapToChannelResponse(channel)).ToList().AsReadOnly());
        }
Esempio n. 15
0
        public async Task <IReadOnlyCollection <ChannelMemberResponse> > GetChannelMembersAsync(Guid channelId)
        {
            var isChannelExists = await UnitOfWork.ChannelRepository.IsChannelExistsAsync(channelId);

            if (!isChannelExists)
            {
                throw new NetKitChatNotFoundException($"Unable to get channel members. Channel {nameof(channelId)}:{channelId} is not found.");
            }

            var channelMembers = await UnitOfWork.ChannelMemberRepository.GetChannelMembersAsync(channelId);

            return(channelMembers.Select(channelMember => DomainModelsMapper.MapToChannelMemberResponse(channelMember)).ToList().AsReadOnly());
        }
Esempio n. 16
0
        public async Task <AttachmentResponse> AddMessageAttachmentAsync(AddMessageAttachmentRequest request)
        {
            var message = await UnitOfWork.MessageRepository.GetMessageWithOwnerAndForwardMessageAsync(request.MessageId);

            if (message == null)
            {
                throw new NetKitChatNotFoundException($"Unable to add message attachment. Message {nameof(request.MessageId)}:{request.MessageId} is not found.");
            }

            if (message.Type == MessageType.System)
            {
                throw new NetKitChatInvalidOperationException($"Unable to add attachment to system message. Message {nameof(request.MessageId)}:{request.MessageId}.");
            }

            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to add message attachment. Member {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            if (member.Id != message.OwnerId)
            {
                throw new NetKitChatAccessForbiddenException($"Unable to add message attachment. Message {nameof(request.MessageId)}:{request.MessageId} owner required.");
            }

            var isAttachmentLimitExceeded = await IsAttachmentLimitExceededAsync(message.Id);

            if (isAttachmentLimitExceeded)
            {
                throw new NetKitChatInvalidOperationException($"Unable to add message attachment. Attachment limit {_messagesConfiguration.MessageAttachmentsLimit} exceeded.");
            }

            var attachment = new Attachment
            {
                Id          = Guid.NewGuid(),
                ContentType = request.ContentType,
                Created     = _dateTimeProvider.GetUtcNow(),
                FileName    = $"{Guid.NewGuid()}.{request.Extension}",
                MessageId   = request.MessageId,
                Size        = request.Size
            };

            // Save attachment in database
            await UnitOfWork.AttachmentRepository.AddAttachmentAsync(attachment);

            // Save attachment in cloud
            await _cloudAttachmentProvider.SaveAttachmentAsync(attachment.FileName, request.Content);

            return(DomainModelsMapper.MapToAttachmentResponse(attachment));
        }
Esempio n. 17
0
        public async Task <ChannelResponse> InviteMemberAsync(Guid memberId, Guid channelId)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelAsync(channelId);

            if (channel == null)
            {
                throw new NetKitChatNotFoundException($"Unable to invite member. Channel {nameof(channelId)}:{channelId} is not found.");
            }

            if (channel.Type == ChannelType.Direct)
            {
                throw new NetKitChatInvalidOperationException($"Unable to invite member to Direct Channel {nameof(channelId)}:{channelId}.");
            }

            if (channel.IsClosed)
            {
                throw new NetKitChatInvalidOperationException($"Unable to invite member. Channel {nameof(channelId)}:{channelId} is closed.");
            }

            var member = await UnitOfWork.MemberRepository.GetMemberByIdAsync(memberId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to invite member. Member {nameof(memberId)}:{memberId} is not found.");
            }

            var isMemberExistsInChannel = await UnitOfWork.ChannelRepository.IsMemberExistsInChannelAsync(member.Id, channel.Id);

            if (isMemberExistsInChannel)
            {
                throw new NetKitChatInvalidOperationException($"Unable to invite member. Member {nameof(memberId)}:{memberId} already joined channel {nameof(channelId)}:{channelId}.");
            }

            var channelMember = new ChannelMember
            {
                ChannelId         = channel.Id,
                MemberId          = member.Id,
                LastReadMessageId = null
            };

            await UnitOfWork.ExecuteTransactionAsync(async() =>
            {
                await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);
                await UnitOfWork.ChannelRepository.IncrementChannelMembersCountAsync(channel.Id);
            });

            channel = await UnitOfWork.ChannelRepository.GetChannelAsync(channel.Id);

            return(DomainModelsMapper.MapToChannelResponse(channel));
        }
Esempio n. 18
0
        public async Task <PagedMembersResponse> GetPotentialChannelMembersAsync(Guid channelId, GetPotentialChannelMembersRequest request)
        {
            var members = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(channelId, request.PageNumber, request.PageSize, request.NameFilter);

            var response = new PagedMembersResponse
            {
                Results            = members.Results.Select(member => DomainModelsMapper.MapToMemberSummaryResponse(member)),
                TotalNumberOfItems = members.TotalNumberOfItems,
                TotalNumberOfPages = members.TotalNumberOfPages,
                PageNumber         = members.PageNumber,
                PageSize           = members.PageSize
            };

            return(response);
        }
Esempio n. 19
0
        public async Task <PagedMembersResponse> GetPagedMembersAsync(int pageNumber, int pageSize, string nameFilter, string currentUserSaasId)
        {
            var members = await UnitOfWork.MemberRepository.GetPagedMembersExceptCurrentAsync(pageNumber, pageSize, nameFilter, currentUserSaasId);

            var response = new PagedMembersResponse
            {
                Results            = members.Results.Select(member => DomainModelsMapper.MapToMemberSummaryResponse(member)),
                TotalNumberOfItems = members.TotalNumberOfItems,
                TotalNumberOfPages = members.TotalNumberOfPages,
                PageNumber         = members.PageNumber,
                PageSize           = members.PageSize
            };

            return(response);
        }
        public async Task <NotificationSettingResponse> GetUserNotificationSettingsAsync(UserRequest userRequest)
        {
            var member = await _memberService.GetMemberBySaasUserIdAsync(userRequest.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException("Requested member does not exist.");
            }

            var userNotificationSettings = await UnitOfWork.NotificationSettingRepository.GetSettingsByMemberIdAsync(member.Id);

            if (userNotificationSettings == null)
            {
                return(new NotificationSettingResponse
                {
                    MemberId = member.Id
                });
            }

            return(DomainModelsMapper.MapToNotificationSettingsResponse(userNotificationSettings));
        }
Esempio n. 21
0
        public async Task <MemberSummaryResponse> AddMemberAsync(string saasUserId, string email)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(saasUserId);

            if (member != null)
            {
                throw new NetKitChatInvalidOperationException($"Unable to add member. Member {nameof(saasUserId)}:{saasUserId} already exists.");
            }

            var newMember = new DomainModels.Member
            {
                Id           = Guid.NewGuid(),
                Role         = UserRole.User,
                IsBanned     = false,
                Status       = UserStatus.Online,
                SaasUserId   = saasUserId,
                Email        = email,
                LastActivity = _dateTimeProvider.GetUtcNow(),
                Name         = email
            };
            await UnitOfWork.MemberRepository.AddMemberAsync(newMember);

            return(DomainModelsMapper.MapToMemberSummaryResponse(newMember));
        }
Esempio n. 22
0
        public async Task <MessageResponse> CreateSystemMessageAsync(CreateMessageRequest request)
        {
            var isChannelExists = await UnitOfWork.ChannelRepository.IsChannelExistsAsync(request.ChannelId);

            if (!isChannelExists)
            {
                throw new NetKitChatNotFoundException($"Unable to create message. Channel {nameof(request.ChannelId)}:{request.ChannelId} is not found.");
            }

            var message = new Message
            {
                Id        = Guid.NewGuid(),
                ChannelId = request.ChannelId,
                Body      = request.Body,
                Created   = _dateTimeProvider.GetUtcNow(),
                Type      = request.Type
            };

            await UnitOfWork.MessageRepository.AddMessageAsync(message);

            message = await UnitOfWork.MessageRepository.GetAsync(message.Id);

            return(DomainModelsMapper.MapToMessageResponse(message));
        }
Esempio n. 23
0
        public async Task <ClientResponse> AddClientAsync(AddClientRequest request)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                await _memberService.AddMemberAsync(request.SaasUserId, request.Email);

                member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);
            }

            await _memberService.UpdateMemberStatusAsync(member.SaasUserId, UserStatus.Online);

            var isClientExists = await UnitOfWork.ClientRepository.IsClientExistsAsync(request.ConnectionId);

            if (isClientExists)
            {
                throw new NetKitChatInvalidOperationException($"Unable to add client. Client {nameof(request.ConnectionId)}:{request.ConnectionId} already exists.");
            }

            var client = new Client
            {
                Id                 = Guid.NewGuid(),
                MemberId           = member.Id,
                Member             = member,
                ClientConnectionId = request.ConnectionId,
                LastActivity       = member.LastActivity,
                LastClientActivity = _dateTimeProvider.GetUtcNow(),
                Name               = request.UserName,
                UserAgent          = request.UserAgent
            };

            await UnitOfWork.ClientRepository.AddClientAsync(client);

            return(DomainModelsMapper.MapToClientResponse(client));
        }
Esempio n. 24
0
        public async Task <ChannelSummaryResponse> CreateChannelAsync(CreateChannelRequest request)
        {
            var member = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to create channel. Member with {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }

            var permanentChannelImageUrl = await _cloudImageProvider.CopyImageToDestinationContainerAsync(request.PhotoUrl);

            var newChannel = new Channel
            {
                Id             = Guid.NewGuid(),
                Created        = _dateTimeProvider.GetUtcNow(),
                Name           = request.Name,
                Description    = request.Description,
                WelcomeMessage = request.WelcomeMessage,
                Type           = request.Type,
                Members        = new List <ChannelMember>(),
                CreatorId      = member.Id,
                Creator        = member,
                MembersCount   = 0,
                PhotoUrl       = permanentChannelImageUrl
            };
            //TODO: [ek] Make creator as nullable. Do not set creator for direct chat. Disable close functionality
            var creator = new ChannelMember
            {
                ChannelId         = newChannel.Id,
                MemberId          = member.Id,
                LastReadMessageId = null,
                IsMuted           = false
            };

            newChannel.Members.Add(creator);

            if ((request.Type == ChannelType.Private || request.Type == ChannelType.Direct) && request.AllowedMembers != null && request.AllowedMembers.Any())
            {
                foreach (var memberId in request.AllowedMembers)
                {
                    var allowedMember = await UnitOfWork.MemberRepository.GetMemberByIdAsync(Guid.Parse(memberId));

                    if (allowedMember == null)
                    {
                        throw new NetKitChatNotFoundException($"Unable to add member to channel. Member {nameof(memberId)}:{memberId} not found.");
                    }

                    var model = new ChannelMember
                    {
                        ChannelId         = newChannel.Id,
                        MemberId          = allowedMember.Id,
                        LastReadMessageId = null
                    };

                    newChannel.Members.Add(model);
                }
            }

            var channelMembers = newChannel.Members.DistinctBy(x => x.MemberId);

            await UnitOfWork.ExecuteTransactionAsync(async() =>
            {
                await UnitOfWork.ChannelRepository.AddChannelAsync(newChannel);

                foreach (var channelMember in channelMembers)
                {
                    await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);
                    await UnitOfWork.ChannelRepository.IncrementChannelMembersCountAsync(newChannel.Id);
                }
            });

            var channel = await UnitOfWork.ChannelRepository.GetChannelWithCreatorAsync(newChannel.Id);

            return(DomainModelsMapper.MapToChannelSummaryResponse(channel, creator));
        }
Esempio n. 25
0
        public async Task <IReadOnlyCollection <ChannelResponse> > GetAllChannelsAsync()
        {
            var channels = await UnitOfWork.ChannelRepository.GetAllChannelsAsync();

            return(channels.Select(channel => DomainModelsMapper.MapToChannelResponse(channel)).ToList().AsReadOnly());
        }
Esempio n. 26
0
        public async Task <IReadOnlyCollection <ChannelSummaryResponse> > GetAllowedChannelsAsync(string saasUserId)
        {
            var currentUser = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(saasUserId);

            if (currentUser == null)
            {
                throw new NetKitChatNotFoundException($"Unable to get allowed channels. Member {nameof(saasUserId)}:{saasUserId} is not found.");
            }

            var channelsResponse = new List <ChannelSummaryResponse>();

            var channels = await UnitOfWork.ChannelRepository.GetAllowedChannelsWithMessagesAndCreatorAsync(currentUser.Id);

            foreach (var channel in channels)
            {
                channel.Messages = channel.Messages?.Where(x => x.AccessibilityStatus == AccessibilityStatus.Present).ToList();
                if (channel.Type == ChannelType.Direct)
                {
                    var members = await UnitOfWork.ChannelMemberRepository.GetChannelMembersWithMemberDetailsAsync(channel.Id);

                    var existingUserChannelMember = members.First(x => x.MemberId == currentUser.Id);

                    //TODO: Extend existing query to make one single request to get all data for both direct and group channel
                    var directChannelMember = members.First(x => x.MemberId != currentUser.Id);
                    var member = directChannelMember.Member;
                    ChannelSummaryResponse channelSummaryResponse;
                    if (existingUserChannelMember.LastReadMessageId.HasValue)
                    {
                        var lastReadMessage = await UnitOfWork.MessageRepository.GetAsync(existingUserChannelMember.LastReadMessageId.Value);

                        //only present message may be last
                        lastReadMessage = lastReadMessage?.AccessibilityStatus == AccessibilityStatus.Present ? lastReadMessage : null;

                        channelSummaryResponse = DomainModelsMapper.MapToDirectChannelSummaryResponse(channel, currentUser, member, lastReadMessage);
                    }
                    else
                    {
                        channelSummaryResponse = DomainModelsMapper.MapToDirectChannelSummaryResponse(channel, currentUser, member);
                    }
                    channelsResponse.Add(channelSummaryResponse);
                }
                else
                {
                    var existingUserChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberWithMemberDetailsAsync(currentUser.Id, channel.Id);

                    if (existingUserChannelMember.LastReadMessageId.HasValue)
                    {
                        var lastReadMessage = await UnitOfWork.MessageRepository.GetAsync(existingUserChannelMember.LastReadMessageId.Value);

                        //only present message may be last
                        lastReadMessage = lastReadMessage?.AccessibilityStatus == AccessibilityStatus.Present ? lastReadMessage : null;
                        channelsResponse.Add(DomainModelsMapper.MapToChannelSummaryResponse(channel, existingUserChannelMember, lastReadMessage));
                    }
                    else
                    {
                        channelsResponse.Add(DomainModelsMapper.MapToChannelSummaryResponse(channel, existingUserChannelMember));
                    }
                }
            }

            // TODO: Improve performance
            var sortedChannels = channelsResponse.Select(channel => new
            {
                Channel    = channel,
                SortedDate = channel.LastMessage?.Created ?? channel.Created
            })
                                 .OrderByDescending(x => x.Channel.IsPinned)
                                 .ThenByDescending(x => x.SortedDate)
                                 .Select(x => x.Channel)
                                 .ToList()
                                 .AsReadOnly();

            return(sortedChannels);
        }
Esempio n. 27
0
        public async Task <IReadOnlyCollection <ClientResponse> > GetClientsByMemberIds(List <Guid> memberIds)
        {
            var clients = await UnitOfWork.ClientRepository.GetClientsWithMembersAsync(memberIds);

            return(clients.Select(client => DomainModelsMapper.MapToClientResponse(client)).ToList().AsReadOnly());
        }
Esempio n. 28
0
        public async Task <ChannelSummaryResponse> CreateDirectChannelAsync(CreateDirectChannelRequest request)
        {
            var creator = await UnitOfWork.MemberRepository.GetMemberBySaasUserIdAsync(request.SaasUserId);

            if (creator == null)
            {
                throw new NetKitChatNotFoundException($"Unable to create channel. Member with {nameof(request.SaasUserId)}:{request.SaasUserId} is not found.");
            }
            var member = await UnitOfWork.MemberRepository.GetMemberByIdAsync(request.MemberId);

            if (member == null)
            {
                throw new NetKitChatNotFoundException($"Unable to create channel. Member with {nameof(request.MemberId)}:{request.MemberId} is not found.");
            }

            var exitingChannelId = await UnitOfWork.ChannelRepository.GetDirectChannelForMembersAsync(creator.Id, member.Id);

            if (exitingChannelId != default(Guid))
            {
                // open existing direct channel
                var existingDirectChannel = await UnitOfWork.ChannelRepository.GetChannelAsync(exitingChannelId);

                existingDirectChannel.Messages = (await UnitOfWork.MessageRepository.GetAllChannelMessagesWithOwnersAsync(exitingChannelId)).ToList();

                existingDirectChannel.IsClosed = false;
                await UnitOfWork.ChannelRepository.UpdateChannelAsync(existingDirectChannel);

                var channelSummary = DomainModelsMapper.MapToDirectChannelSummaryResponse(existingDirectChannel, creator, member);

                //TODO need to send channel summary specific for every user
                channelSummary.LastMessage = null;
                return(channelSummary);
            }

            var newChannel = new Channel
            {
                Id      = Guid.NewGuid(),
                Created = _dateTimeProvider.GetUtcNow(),
                Type    = ChannelType.Direct,
                //TODO: [ek] do not use creator for direct channels
                CreatorId    = creator.Id,
                Creator      = creator,
                Members      = new List <ChannelMember>(),
                MembersCount = 2,
            };
            //TODO: [ek] Make creator as nullable. Do not set creator for direct chat. Disable close functionality
            var creatorChannelMember = new ChannelMember
            {
                ChannelId         = newChannel.Id,
                MemberId          = creator.Id,
                LastReadMessageId = null,
                IsMuted           = false
            };

            newChannel.Members.Add(creatorChannelMember);
            newChannel.Members.Add(new ChannelMember
            {
                ChannelId         = newChannel.Id,
                MemberId          = member.Id,
                LastReadMessageId = null,
                IsMuted           = false
            });

            await UnitOfWork.ExecuteTransactionAsync(async() =>
            {
                await UnitOfWork.ChannelRepository.AddChannelAsync(newChannel);

                foreach (var channelMember in newChannel.Members)
                {
                    await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);
                }
            });

            var channel = await UnitOfWork.ChannelRepository.GetChannelWithCreatorAsync(newChannel.Id);

            return(DomainModelsMapper.MapToDirectChannelSummaryResponse(channel, creator, member));
        }