예제 #1
0
        public override void Process(CmdTrigger <RealmServerCmdArgs> trigger)
        {
            var ticket = trigger.Args.TicketHandler.HandlingTicket;

            if (ticket != null)
            {
                Character user = ticket.Owner;

                if (ticket.Owner == null)
                {
                    trigger.Reply("The owner of this Ticket is offline.");
                }
                else
                {
                    var me         = new ChannelMember(trigger.Args.User);
                    var ircChannel = new ChatChannelGroup(FactionGroup.Invalid);
                    var chan       = new ChatChannel(ircChannel);

                    chan.Invite(me, user);
                    //user.SendMessage(trigger.Args.User,
                    //                 "A staff member wants to chat with you about your ticket. Please do not leave the channel.");
                }
            }
            else
            {
                trigger.Reply("You must have a ticket selected.");
            }
        }
예제 #2
0
        public override IEnumerable <object> Run()
        {
            if (base.Connection.RemoteCategory != "FrontendServiceCore.FrontendService")
            {
                base.Finished = true;
                yield return(new FailMessage("[LeaveChannelProcessor] Connection.RemoteCategory")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else
            {
                ChannelMember member = base.Connection.Tag as ChannelMember;
                if (member == null)
                {
                    base.Finished = true;
                    yield return(new FailMessage("[LeaveChannelProcessor] member")
                    {
                        Reason = FailMessage.ReasonCode.LogicalFail
                    });
                }
                else
                {
                    base.Finished = true;
                    yield return(new OkMessage());

                    member.Close();
                }
            }
            yield break;
        }
예제 #3
0
        public ChannelSummaryResponse MapToChannelSummaryResponse(Channel channel, ChannelMember channelMember, Message lastReadMessage = null)
        {
            var response = new ChannelSummaryResponse();

            if (channelMember != null)
            {
                response = _mapper.Map(channelMember, response);
            }

            if (channel != null)
            {
                response = _mapper.Map(channel, response);

                if (channel.Messages == null)
                {
                    response.UnreadMessagesCount = 0;
                    return(response);
                }

                var lastMessage = channel.Messages.OrderBy(o => o.Created).LastOrDefault();
                if (lastMessage != null)
                {
                    response.LastMessage = MapToMessageResponse(lastMessage, lastReadMessage?.Created);
                }
                response.UnreadMessagesCount = lastReadMessage != null?
                                               channel.Messages.Count(x => x.Created > lastReadMessage.Created) :
                                                   channel.Messages.Count;
            }

            return(response);
        }
예제 #4
0
        public override IEnumerable <object> Run()
        {
            ChannelMember member = base.Entity.FindMember(base.Operation.CID);

            if (member == null || member.SharingInfo == null)
            {
                base.Finished = true;
                yield return(new FailMessage("[SharingResponseProcessor] member.SharingInfo")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else if (!base.Operation.Accept)
            {
                member.SharingInfo = null;
            }
            else
            {
                AddStatusEffect op = new AddStatusEffect
                {
                    Type       = member.SharingInfo.StatusEffect,
                    Level      = member.SharingInfo.EffectLevel,
                    RemainTime = member.SharingInfo.DurationSec
                };
                member.CharacterConn.RequestOperation(op);
            }
            yield break;
        }
예제 #5
0
        public override IEnumerable <object> Run()
        {
            if (base.Connection.RemoteCategory != "FrontendServiceCore.FrontendService")
            {
                base.Finished = true;
                yield return(JoinChannel.FailReasonEnum.NotFrontEnd);
            }
            else if (base.Entity.Count >= this.service.Capacity || this.service.CurrentLoad > (long)LoadManager.MaxLoad)
            {
                base.Finished = true;
                Log <JoinChannelProcessor> .Logger.WarnFormat("load or capacity exceed : {0}, {1}", base.Entity.Count, this.service.CurrentLoad);

                base.Finished = true;
                yield return(JoinChannel.FailReasonEnum.MaxCapacityOver);
            }
            else
            {
                Log <JoinChannelProcessor> .Logger.InfoFormat("load or capacity not exceed : {0}, {1}", base.Entity.Count, this.service.CurrentLoad);

                ChannelMember member = new ChannelMember(base.Operation.CID, base.Connection, base.Operation.PartitionID, base.Operation.Action)
                {
                    ChannelJoined = base.Entity
                };
                if (!this.service.AddWaitingMember(base.Operation.CID, member))
                {
                    Log <JoinChannelProcessor> .Logger.WarnFormat("duplicate join channel waiting members : [{0} -> {1}]", base.Operation.CID, base.Entity.Entity.ID);

                    base.Finished = true;
                    yield return(JoinChannel.FailReasonEnum.HasWaitingMemeber);
                }
                else
                {
                    int key = this.service.Server.KeyGen(base.Operation.CID);
                    Scheduler.Schedule(this.service.Thread, Job.Create(delegate
                    {
                        IEntity entity = member.ChannelJoined.Entity;
                        if (this.service.RemoveWaitingMember(member.CID, member))
                        {
                            Log <JoinChannelProcessor> .Logger.ErrorFormat("Cannot Connect to client(peer) : [{0} -> {1}]", member.CID, this.Entity.Entity.ID);
                            this.service.Server.RemoveKey(member.CID);
                            member.Close();
                            this.service.RequestOperation(entity, new Location(member.FID, "FrontendServiceCore.FrontendService"), new NotifyEnterChannelResult
                            {
                                ResultEnum = EnterChannelResult.Timeout
                            });
                        }
                    }), 60000);
                    base.Finished = true;
                    yield return(this.service.Server.Address);

                    yield return(this.service.Server.Port);

                    yield return(base.Entity.Entity.ID);

                    yield return(key);
                }
            }
            yield break;
        }
예제 #6
0
        public async Task GetPotentialChannelMembersAsync_ShouldReturnMembersByPages()
        {
            var secondChannel = new Channel
            {
                Id           = Guid.NewGuid(),
                IsClosed     = true,
                CreatorId    = _memberId,
                Created      = DateTimeOffset.UtcNow,
                Type         = ChannelType.Public,
                MembersCount = 1
            };
            await UnitOfWork.ChannelRepository.AddChannelAsync(secondChannel);


            const int membersCount = 22;

            for (var i = 0; i < membersCount; i++)
            {
                var isEvenCounter = i % 2 == 0;

                var member = new Member
                {
                    Id           = Guid.NewGuid(),
                    Role         = UserRole.User,
                    IsBanned     = true,
                    LastActivity = DateTimeOffset.UtcNow,
                    Status       = UserStatus.Online,
                    Name         = isEvenCounter ? $"{i}EVEN{i}" : $"{i}ODD{i}"
                };
                await UnitOfWork.MemberRepository.AddMemberAsync(member);

                var channelMember = new ChannelMember
                {
                    MemberId = member.Id,
                    // Odd members will be potential members for the channel '_channelId'
                    // Even members will be potential members for the second channel
                    ChannelId = isEvenCounter ? _channelId : secondChannel.Id
                };
                await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);
            }

            const int pageSize = 10;

            var potentialEvenMembersForFirstChannel = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(_channelId, 1, pageSize, "even");

            var potentialOddMembersForFirstChannelFirstPage = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(_channelId, 1, pageSize, "odd");

            var potentialOddMembersForFirstChannelSecondPage = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(_channelId, 2, pageSize, "odd");

            var allPotentialMembersForFirstChannel = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(_channelId, 1, 100, null);

            var allPotentialMembersForSecondChannel = await UnitOfWork.MemberRepository.GetPotentialChannelMembersAsync(secondChannel.Id, 1, 100, null);

            potentialEvenMembersForFirstChannel.Results.Count().Should().Be(0);
            potentialOddMembersForFirstChannelFirstPage.Results.Count().Should().Be(pageSize);
            potentialOddMembersForFirstChannelSecondPage.Results.Count().Should().Be(1);
            allPotentialMembersForFirstChannel.Results.Count().Should().Be(membersCount / 2 + _initialTestMembersCount);
            allPotentialMembersForSecondChannel.Results.Count().Should().Be(membersCount / 2 + _initialTestMembersCount);
        }
예제 #7
0
        public async Task GetLastReadMessageAsyncTest_ShouldReturnLastReadMessageIfExists()
        {
            var firstMessage = new Message
            {
                Id                  = Guid.NewGuid(),
                Body                = "Body",
                Created             = DateTimeOffset.UtcNow,
                ImageUrl            = "test",
                Type                = 0,
                ChannelId           = _channelId,
                Owner               = _member,
                OwnerId             = _member.Id,
                AccessibilityStatus = AccessibilityStatus.Present
            };
            await UnitOfWork.MessageRepository.AddMessageAsync(firstMessage);

            var channelMember = new ChannelMember
            {
                ChannelId         = _channelId,
                MemberId          = _member.Id,
                LastReadMessageId = null
            };
            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            // Have no read messages
            var readMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(_member.Id, _channelId);

            readMessage.Should().BeNull();

            // Mark as read
            await UnitOfWork.ChannelMemberRepository.SetLastReadMessageAsync(_member.Id, _channelId, firstMessage.Id);

            readMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(_member.Id, _channelId);

            readMessage.Should().BeEquivalentTo(firstMessage);

            // Add second message
            var secondMessage = new Message
            {
                Id                  = Guid.NewGuid(),
                Body                = "Body",
                Created             = DateTimeOffset.UtcNow,
                ImageUrl            = "test",
                Type                = 0,
                ChannelId           = _channelId,
                Owner               = _member,
                OwnerId             = _member.Id,
                AccessibilityStatus = AccessibilityStatus.Present
            };
            await UnitOfWork.MessageRepository.AddMessageAsync(secondMessage);

            // Mark as read
            await UnitOfWork.ChannelMemberRepository.SetLastReadMessageAsync(_member.Id, _channelId, secondMessage.Id);

            readMessage = await UnitOfWork.MessageRepository.GetLastReadMessageAsync(_member.Id, _channelId);

            readMessage.Should().BeEquivalentTo(secondMessage);
        }
        public async Task ShouldReturnChannelSummaryResponse()
        {
            // Arrange
            var allowedChannel = new Channel {
                Id = new Guid("4C13BEC1-2979-4822-9AAC-520B474214FD")
            };
            var saasUserId = "2A70F115-9F55-4024-829B-6521FE18680C";

            _channelRepositoryMock.Setup(x => x.GetChannelWithCreatorAsync(It.Is <Guid>(channel => channel.Equals(allowedChannel.Id))))
            .ReturnsAsync(allowedChannel)
            .Verifiable();

            var member = new MemberSummaryResponse();

            _memberServiceMock.Setup(x => x.GetMemberBySaasUserIdAsync(It.IsAny <string>()))
            .ReturnsAsync(member)
            .Verifiable();

            var allowedChannelMember = new ChannelMember();

            _channelMemberRepositoryMock.Setup(x => x.GetChannelMemberAsync(
                                                   It.Is <Guid>(memberId => memberId.Equals(member.Id)),
                                                   It.Is <Guid>(channelId => channelId.Equals(allowedChannel.Id))))
            .ReturnsAsync(allowedChannelMember)
            .Verifiable();

            var lastReadMessage = new Message();

            _messageRepositoryMock.Setup(x => x.GetLastReadMessageAsync(
                                             It.Is <Guid>(memberId => memberId.Equals(member.Id)),
                                             It.Is <Guid>(channelId => channelId.Equals(allowedChannel.Id))))
            .ReturnsAsync(lastReadMessage)
            .Verifiable();

            var channelSummaryResponse = new ChannelSummaryResponse();

            _domainModelsMapperMock.Setup(x => x.MapToChannelSummaryResponse(
                                              It.Is <Channel>(channel => channel.Equals(allowedChannel)),
                                              It.Is <ChannelMember>(channelMember => channelMember.Equals(allowedChannelMember)),
                                              It.Is <Message>(message => message.Equals(lastReadMessage))))
            .Returns(channelSummaryResponse)
            .Verifiable();

            var messages = new List <Message>();

            _messageRepositoryMock.Setup(x => x.GetAllChannelMessagesWithOwnersAsync(It.IsAny <Guid>()))
            .ReturnsAsync(messages)
            .Verifiable();

            // Act
            var result = await _channelService.GetChannelSummaryAsync(saasUserId, allowedChannel.Id);

            // Assert
            VerifyMocks();
            result.Should().BeEquivalentTo(channelSummaryResponse);
        }
예제 #9
0
        public void AddMember(Channel channel, LoginUser user)
        {
            var channelMember = new ChannelMember
            {
                Channel = channel,
                UserId  = user.Id
            };

            _context.Add(channelMember);
            _context.SaveChanges();
        }
예제 #10
0
        public override void Process(CmdTrigger <RealmServerCmdArgs> trigger)
        {
            var wcellUser = trigger.Args.User as WCellUser;
            var chanName  = trigger.Text.NextWord();
            var targetUsr = trigger.Args.GetCharArgumentOrTarget(trigger, trigger.Text.NextWord());

            ChannelMember    me = new ChannelMember(wcellUser);
            ChatChannelGroup ircChannelGroup = new ChatChannelGroup(FactionGroup.Invalid);
            var chatChan = new ChatChannel(ircChannelGroup, chanName);

            chatChan.Invite(me, targetUsr);
            //ChatMgr.OnChat += new ChatNotifyDelegate(ChatMgr_OnChat);
        }
예제 #11
0
 public MemberCard(
     ChannelMember member,
     GestureTapCallback onTap    = null,
     UserType userType           = UserType.unFollow,
     GestureTapCallback onFollow = null,
     Key key = null
     ) : base(key: key)
 {
     this.member   = member;
     this.onTap    = onTap;
     this.userType = userType;
     this.onFollow = onFollow;
 }
예제 #12
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));
        }
        public async Task SetLastReadMessageAsync_ShouldSetLastReadMessage()
        {
            var channelMember = new ChannelMember
            {
                MemberId          = _memberId,
                ChannelId         = _channelId,
                LastReadMessageId = null
            };
            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            await UnitOfWork.ChannelMemberRepository.SetLastReadMessageAsync(channelMember.MemberId, channelMember.ChannelId, _lastReadMessageId);

            var newChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            newChannelMember.LastReadMessageId.Should().Be(_lastReadMessageId);
        }
        public async Task DeleteChannelMemberAsync_ShouldDeleteChannelMember()
        {
            var channelMember = new ChannelMember
            {
                MemberId  = _memberId,
                ChannelId = _channelId
            };

            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            await UnitOfWork.ChannelMemberRepository.DeleteChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            var newChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            newChannelMember.Should().BeNull();
        }
        Widget _buildMemberItem(BuildContext context, int index)
        {
            ChannelMember member = this.widget.viewModel.members[index : index];

            var userDict = this.widget.viewModel.userDict;

            if (!userDict.ContainsKey(key: member.user.id))
            {
                return(new Container());
            }

            var      user = userDict[key : member.user.id];
            UserType userType;

            if (!this.widget.viewModel.isLoggedIn)
            {
                userType = UserType.unFollow;
            }
            else
            {
                if (this.widget.viewModel.currentUserId == user.id)
                {
                    userType = UserType.me;
                }
                else if (user.followUserLoading ?? false)
                {
                    userType = UserType.loading;
                }
                else if (this.widget.viewModel.followed != null &&
                         this.widget.viewModel.followed.ContainsKey(key: user.id))
                {
                    userType = UserType.follow;
                }
                else
                {
                    userType = UserType.unFollow;
                }
            }

            return(new MemberCard(
                       member: member,
                       () => this.widget.actionModel.pushToUserDetail(obj: user.id),
                       userType: userType,
                       () => this._onFollow(userType: userType, userId: user.id)
                       ));
        }
예제 #16
0
        public async Task JoinToChannelAsync(string saasUserId, Guid channelId)
        {
            var channel = await UnitOfWork.ChannelRepository.GetChannelAsync(channelId);

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

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

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

            if (channel.Type == ChannelType.Private && channel.CreatorId != member.Id)
            {
                throw new NetKitChatAccessForbiddenException("Unable to join private channel.");
            }

            if (channel.Type == ChannelType.Direct)
            {
                throw new NetKitChatInvalidOperationException($"Unable to join direct channel.");
            }

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

            if (isMemberExistsInChannel)
            {
                throw new NetKitChatInvalidOperationException($"Unable to join channel. Member {nameof(member.Id)}:{member.Id} 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);
            });
        }
        public async Task GetChannelMemberAsync_ShouldReturnChannelMember()
        {
            var channelMember = new ChannelMember
            {
                MemberId          = _memberId,
                ChannelId         = _channelId,
                LastReadMessageId = _lastReadMessageId,
                IsMuted           = true,
                IsPinned          = true
            };

            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            var newChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            newChannelMember.Should().BeEquivalentTo(channelMember);
        }
예제 #18
0
        /// <summary>
        /// Send the "name has joined channel" reply to everyone
        /// </summary>
        /// <param name="chan">name of channel</param>
        /// <param name="sender">sender (to check the ignore list)</param>
        public static void SendJoinedReplyToEveryone(ChatChannel chan, ChannelMember sender)
        {
            // the packet has the same size no matter the opcode, so it's really
            // a retarded way of doing it... but blame blizz.
            var opcode = chan.IsConstant ? RealmServerOpCode.SMSG_USERLIST_ADD
                : RealmServerOpCode.SMSG_USERLIST_UPDATE;

            using (RealmPacketOut packet = new RealmPacketOut(opcode))
            {
                //packet.WriteByte((byte)ChannelNotification.PlayerJoined);
                packet.Write(sender.User.EntityId);
                packet.Write((byte)sender.Flags);
                packet.Write((byte)chan.ClientFlags);
                packet.WriteUInt(chan.MemberCount);
                packet.WriteCString(chan.Name);

                SendPacketToChannel(chan, packet, sender.User.EntityId);
            }
        }
예제 #19
0
        public void MapToChannelSummaryResponse_ShouldSetLastMessageNULL_WithoutMessages()
        {
            // Arrange
            var channel = new Channel
            {
                Messages = new List <Message>()
            };

            var channelMember = new ChannelMember();

            var lastReadMessage = new Message {
                Created = DateTimeOffset.UtcNow
            };

            // Act
            var response = _domainModelsMapper.MapToChannelSummaryResponse(channel, channelMember, lastReadMessage);

            // Assert
            response.UnreadMessagesCount.Should().Be(0);
            response.LastMessage.Should().Be(null);
        }
        public async Task MuteChannelAsync_ShouldSetMuteField()
        {
            var channelMember = new ChannelMember
            {
                MemberId  = _memberId,
                ChannelId = _channelId,
                IsMuted   = false
            };
            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            await UnitOfWork.ChannelMemberRepository.MuteChannelAsync(channelMember.MemberId, channelMember.ChannelId, true);

            var mutedMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            mutedMember.IsMuted.Should().BeTrue();

            await UnitOfWork.ChannelMemberRepository.MuteChannelAsync(channelMember.MemberId, channelMember.ChannelId, false);

            var unmutedMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(channelMember.MemberId, channelMember.ChannelId);

            unmutedMember.IsMuted.Should().BeFalse();
        }
예제 #21
0
        public override IEnumerable <object> Run()
        {
            ChannelMember member = base.Entity.FindMember(base.Operation.CID);

            if (member == null)
            {
                base.Finished = true;
                Log <ChannelChatProcessor> .Logger.ErrorFormat("character {0} is not in channel {1}", base.Operation.CID, base.Entity.Entity.ID);

                yield return(new FailMessage("[ChannelChatProcessor] member")
                {
                    Reason = FailMessage.ReasonCode.LogicalFail
                });
            }
            else
            {
                member.Client.Player.BroadCastChat(base.Operation.Message);
                base.Finished = true;
                yield return(new OkMessage());
            }
            yield break;
        }
        public async Task PinChannelAsync_ShouldChangeIsPinnedStatus()
        {
            var channelMember = new ChannelMember
            {
                MemberId          = _memberId,
                ChannelId         = _channelId,
                LastReadMessageId = null,
                IsPinned          = false
            };
            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);

            await UnitOfWork.ChannelMemberRepository.PinChannelAsync(_memberId, _channelId, true);

            var pinnedChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(_memberId, _channelId);

            pinnedChannelMember.IsPinned.Should().BeTrue();

            await UnitOfWork.ChannelMemberRepository.PinChannelAsync(_memberId, _channelId, false);

            var unPinnedChannelMember = await UnitOfWork.ChannelMemberRepository.GetChannelMemberAsync(_memberId, _channelId);

            unPinnedChannelMember.IsPinned.Should().BeFalse();
        }
예제 #23
0
        public async Task AddChannelMemberAsync(ChannelMember channelMember)
        {
            using (var connection = _sqlConnectionFactory.CreateConnection())
            {
                var sqlQuery = $@"
                    INSERT INTO ChannelMembers
                    (
                        {nameof(ChannelMember.ChannelId)}, 
                        {nameof(ChannelMember.MemberId)}, 
                        {nameof(ChannelMember.LastReadMessageId)}, 
                        {nameof(ChannelMember.IsMuted)}, 
                        {nameof(ChannelMember.IsPinned)}
                    ) VALUES 
                    (
                        @{nameof(ChannelMember.ChannelId)}, 
                        @{nameof(ChannelMember.MemberId)}, 
                        @{nameof(ChannelMember.LastReadMessageId)}, 
                        @{nameof(ChannelMember.IsMuted)}, 
                        @{nameof(ChannelMember.IsPinned)}
                    )";

                await connection.ExecuteScalarAsync(sqlQuery, channelMember);
            }
        }
예제 #24
0
        public void MapToChannelSummaryResponse_ShouldMapChannelAndChannelMember_WithMessages_ToChannelSummaryResponse()
        {
            // Arrange
            var lastReadMessage = new Message
            {
                Body    = "last read message",
                Created = DateTimeOffset.UtcNow
            };
            var oldMessage = new Message
            {
                Body    = "old message",
                Created = lastReadMessage.Created.AddMinutes(-1)
            };
            var lastChannelMessage = new Message
            {
                Body    = "last channel message",
                Created = lastReadMessage.Created.AddMinutes(1)
            };

            var channel = new Channel
            {
                Id       = Guid.NewGuid(),
                Created  = DateTimeOffset.UtcNow.AddMinutes(-10),
                Updated  = DateTimeOffset.UtcNow.AddMinutes(-5),
                Messages = new List <Message>
                {
                    oldMessage,
                    lastReadMessage,
                    lastChannelMessage
                },
                Name      = "channel name",
                IsClosed  = true,
                CreatorId = Guid.NewGuid(),
                Creator   = new Member
                {
                    Id         = Guid.NewGuid(),
                    SaasUserId = "63975AE7-A5B2-477A-9163-72191B7793A4"
                },
                Description    = "Description",
                WelcomeMessage = "WelcomeMessage",
                Type           = ChannelType.Private,
                PhotoUrl       = "PhotoUrl"
            };

            var channelMember = new ChannelMember
            {
                IsMuted  = true,
                IsPinned = true
            };

            // Act
            var response = _domainModelsMapper.MapToChannelSummaryResponse(channel, channelMember, lastReadMessage);

            // Assert
            response.IsMuted.Should().Be(channelMember.IsMuted);
            response.IsPinned.Should().Be(channelMember.IsPinned);

            response.Id.Should().Be(channel.Id);
            response.Created.Should().Be(channel.Created);
            response.Updated.Should().Be(channel.Updated);
            response.Name.Should().Be(channel.Name);
            response.IsClosed.Should().Be(channel.IsClosed);
            response.CreatorId.Should().Be(channel.CreatorId);
            response.CreatorSaasUserId.Should().Be(channel.Creator.SaasUserId);
            response.Description.Should().Be(channel.Description);
            response.WelcomeMessage.Should().Be(channel.WelcomeMessage);
            response.Type.Should().Be(channel.Type);
            response.PhotoUrl.Should().Be(channel.PhotoUrl);

            response.UnreadMessagesCount.Should().Be(1);
            response.LastMessage.Body.Should().Be(lastChannelMessage.Body);
            response.LastMessage.IsRead.Should().Be(false);
            response.Creator.Id.Should().Be(channel.Creator.Id);
        }
예제 #25
0
        public async Task GetAllMembersByChannelIdAsync_ShouldReturnAllMembersInChannel()
        {
            // Arrange

            // Add list of members to expected channel
            var expectedMembers = new List <Member>();

            for (var i = 0; i < 5; i++)
            {
                var member = new Member
                {
                    Id           = Guid.NewGuid(),
                    Role         = UserRole.User,
                    IsBanned     = true,
                    LastActivity = DateTimeOffset.UtcNow,
                    Status       = UserStatus.Online,
                    Email        = $"Email{i}",
                    LastNudged   = DateTimeOffset.UtcNow,
                    Name         = $"Name{i}",
                    PhotoName    = $"PhotoName{i}",
                    SaasUserId   = $"SaasUserId{i}"
                };
                await UnitOfWork.MemberRepository.AddMemberAsync(member);

                expectedMembers.Add(member);

                var channelMember = new ChannelMember
                {
                    MemberId  = member.Id,
                    ChannelId = _channelId
                };
                await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(channelMember);
            }

            // Add second channel and member for this channel
            var secondChannel = new Channel
            {
                Id           = Guid.NewGuid(),
                IsClosed     = true,
                CreatorId    = _memberId,
                Created      = DateTimeOffset.UtcNow,
                Type         = ChannelType.Public,
                MembersCount = 1
            };
            await UnitOfWork.ChannelRepository.AddChannelAsync(secondChannel);

            var memberInAnotherChannel = new Member
            {
                Id           = Guid.NewGuid(),
                Role         = UserRole.User,
                IsBanned     = true,
                LastActivity = DateTimeOffset.UtcNow,
                Status       = UserStatus.Online,
                Email        = "Email",
                LastNudged   = DateTimeOffset.UtcNow,
                Name         = "Name",
                PhotoName    = "PhotoName",
                SaasUserId   = "SaasUserId"
            };
            await UnitOfWork.MemberRepository.AddMemberAsync(memberInAnotherChannel);

            var anotherChannelMember = new ChannelMember
            {
                MemberId  = memberInAnotherChannel.Id,
                ChannelId = secondChannel.Id
            };
            await UnitOfWork.ChannelMemberRepository.AddChannelMemberAsync(anotherChannelMember);

            // Add member without channel
            var memberWithoutChannel = new Member
            {
                Id           = Guid.NewGuid(),
                Role         = UserRole.User,
                IsBanned     = true,
                LastActivity = DateTimeOffset.UtcNow,
                Status       = UserStatus.Online,
                Email        = "Email",
                LastNudged   = DateTimeOffset.UtcNow,
                Name         = "Name",
                PhotoName    = "PhotoName",
                SaasUserId   = "SaasUserId"
            };
            await UnitOfWork.MemberRepository.AddMemberAsync(memberWithoutChannel);


            // Act
            var membersFromChannel = await UnitOfWork.MemberRepository.GetAllMembersByChannelIdAsync(_channelId);

            // Assert
            membersFromChannel.Should().BeEquivalentTo(expectedMembers);
        }
예제 #26
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));
        }
예제 #27
0
 public void RemoveMember(ChannelMember channelMember)
 {
     _context.ChannelMember.Remove(channelMember);
     _context.SaveChanges();
 }
예제 #28
0
        Widget _buildMentionTile(BuildContext context, int index)
        {
            var mentionObj = this.mentionList[index : index];

            if (mentionObj is ChannelMember)
            {
                ChannelMember member = (ChannelMember)this.mentionList[index : index];
                var           user   = member.user;
                return(new GestureDetector(
                           onTap: () => this.widget.actionModel.chooseMentionConfirm(member.user.id, member.user.fullName),
                           child: new Container(
                               color: CColors.White,
                               height: 60,
                               child: new Row(
                                   children: new List <Widget> {
                    new SizedBox(width: 16),
                    Avatar.User(user: user, 32),
                    new Expanded(
                        child: new Container(
                            padding: EdgeInsets.symmetric(0, 16),
                            child: new Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: new List <Widget> {
                        new Flexible(child: new Text(
                                         data: user.fullName,
                                         style: CTextStyle.PLargeBody,
                                         maxLines: 1,
                                         overflow: TextOverflow.ellipsis
                                         ))
                    }
                                )
                            )
                        )
                }
                                   )
                               )
                           ));
            }

            if (mentionObj is AtAllMention)
            {
                return(new GestureDetector(
                           onTap: () => this.widget.actionModel.chooseMentionConfirm("everyone", "所有人"),
                           child: new Container(
                               color: CColors.White,
                               height: 60,
                               child: new Row(
                                   children: new List <Widget> {
                    new Expanded(
                        child: new Container(
                            padding: EdgeInsets.symmetric(0, 16),
                            child: new Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: new List <Widget> {
                        new Flexible(child: new Text(
                                         data: "@所有人",
                                         style: CTextStyle.PLargeBody,
                                         maxLines: 1,
                                         overflow: TextOverflow.ellipsis
                                         ))
                    }
                                )
                            )
                        )
                }
                                   )
                               )
                           ));
            }

            return(new Container());
        }
예제 #29
0
        public override IEnumerable <object> Run()
        {
            ChannelMember channelMember = base.Entity.FindMember(base.Operation.CID);

            if (channelMember == null)
            {
                Log <StartSharingProcessor> .Logger.Error("member is null");
            }
            else if (base.Operation.TargetsCID == null)
            {
                Log <StartSharingProcessor> .Logger.Error("TargetsCID is null");
            }
            else if (base.Operation.SharingInfo == null)
            {
                Log <StartSharingProcessor> .Logger.Error("SharingInfo is null");
            }
            else
            {
                if (base.Operation.SharingInfo.ItemClassName.Equals("dancing_pipe"))
                {
                    channelMember.SharingInfo = base.Operation.SharingInfo;
                    ServiceCore.CharacterServiceOperations.AddStatusEffect op = new ServiceCore.CharacterServiceOperations.AddStatusEffect
                    {
                        Type       = channelMember.SharingInfo.StatusEffect,
                        Level      = channelMember.SharingInfo.EffectLevel,
                        RemainTime = channelMember.SharingInfo.DurationSec
                    };
                    channelMember.CharacterConn.RequestOperation(op);
                }
                using (List <long> .Enumerator enumerator = base.Operation.TargetsCID.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        long          cid            = enumerator.Current;
                        ChannelMember channelMember2 = base.Entity.FindMember(cid);
                        if (channelMember2 != null)
                        {
                            channelMember2.SharingInfo = base.Operation.SharingInfo;
                            if (base.Operation.SharingInfo.ItemClassName.Equals("dancing_pipe"))
                            {
                                ServiceCore.CharacterServiceOperations.AddStatusEffect op2 = new ServiceCore.CharacterServiceOperations.AddStatusEffect
                                {
                                    Type       = channelMember2.SharingInfo.StatusEffect,
                                    Level      = channelMember2.SharingInfo.EffectLevel,
                                    RemainTime = channelMember2.SharingInfo.DurationSec
                                };
                                channelMember2.CharacterConn.RequestOperation(op2);
                            }
                            else
                            {
                                channelMember2.FrontendConn.RequestOperation(SendPacket.Create <SharingCheckMessage>(new SharingCheckMessage
                                {
                                    SharingCharacterName = channelMember.Look.CharacterID,
                                    ItemClassName        = base.Operation.SharingInfo.ItemClassName,
                                    StatusEffect         = base.Operation.SharingInfo.StatusEffect,
                                    EffectLevel          = base.Operation.SharingInfo.EffectLevel,
                                    DurationSec          = base.Operation.SharingInfo.DurationSec
                                }));
                            }
                        }
                    }
                    yield break;
                }
            }
            yield break;
        }
예제 #30
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));
        }
예제 #31
0
 private void AddChannelMemberToStruct(ChannelMember cmtemp)
 {
     ChannelMember[] temp = new ChannelMember[_channelMember.Length + 1];
     Array.Copy(_channelMember, temp, Math.Min(_channelMember.Length, temp.Length));
     temp[_channelMember.Length] = cmtemp;
     _channelMember = temp;
 }