Exemplo n.º 1
0
        public virtual Tuple <List <UserId>, List <ITextChatMessage> > JoinRoom(UserId userId, RoomId roomId)
        {
            var user = ChatModel.GetUser(userId);

            // If the room is private and the user has nothing to do here, EXPLODE!
            if (roomId.IsPrivate() && !UserIdsInPrivateRoom(roomId).Contains(userId))
            {
                throw new LogReadyException(LogTag.PrivateRoomIntrusionAttempt, new { userId, roomId });
            }

            if (!ChatModel.IsInRoom(roomId, user.Id))
            {
                ChatModel.AddUserToRoom(userId, roomId);
                OnUserJoinedRoom?.Invoke(roomId, user.Id);
                if (roomId.IsPublic())
                {
                    OnCountOfUsersUpdated?.Invoke(roomId, ChatModel.UsersCountOf(roomId));
                }
            }

            var withVisibilities = new List <MessageVisibility> {
                MessageVisibility.Everyone, MessageVisibility.Sender, MessageVisibility.Ephemeral, MessageVisibility.News
            };

            var customMessageHistory = ChatModel.LatestMessagesIn(roomId, HistoryLength * 2, withVisibilities)
                                       .Where(a => (a.Visibility != MessageVisibility.Sender && a.Visibility != MessageVisibility.Ephemeral) || a.UserId == userId)
                                       .Reverse().Take(HistoryLength).Reverse()
                                       .ToList();

            // If in a private room and the partner doesn't want private chat, Signal it with a service message
            if (roomId.IsGroup())
            {
                goto Skip;
            }
            var partnerId = PartnerInPrivateRoom(roomId, userId);

            if (!ChatModel.IsInChat(partnerId))
            {
                goto Skip;
            }
            var partner = ChatModel.GetUser(partnerId);

            if (partner.IsNoPrivateChat)
            {
                customMessageHistory.Add(new TextChatMessage {
                    RoomId = roomId,
                    Text   = JsonConvert.SerializeObject(new { noPrivateChat = ChatModel.GetPublicRoomsFor(partner.Id) }, Formatting.None, new JsonSerializerSettings {
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    }),
                    Visibility = MessageVisibility.System
                });
            }
Skip:

            return(new Tuple <List <UserId>, List <ITextChatMessage> >(
                       ChatModel.UsersInRoom(roomId, user.Id),
                       customMessageHistory
                       ));
        }
        public static async Task <Result <bool> > JoinRoom(User user, RoomId roomId)
        {
            var result = Result <bool> .True;

            if (!roomId.IsPrivate())
            {
                return(result);
            }

            int userIdEf = user.Id; string roomIdEf = roomId;             // Casting named types into their base type because EF doesn't get it otherwise.
            int partnerId = ChatModel.PartnerIdFrom(roomId, user.Id);

            using (var db = new HellolingoEntities()) {
                var userTracker    = db.TextChatTrackers.Find(userIdEf, roomIdEf);
                var partnerTracker = db.TextChatTrackers.Find(partnerId, roomIdEf);

                // Handle people directly joining by the url from outside the chat
                if (userTracker == null || partnerTracker == null)
                {
                    await RequestPrivateChat(user, roomId, partnerId);

                    result.Reports.AddReport(LogTag.ChatRequestAddedFromJoinRoom, new { userId = user.Id, roomId });
                    return(result);
                }

                // Set new statuses according to current status
                if ((userTracker.Status == TrackerStatus.Invited || userTracker.Status == TrackerStatus.IgnoredInvite) && partnerTracker.Status == TrackerStatus.Inviting)
                {
                    userTracker.Status    = TrackerStatus.AcceptedInvite;
                    partnerTracker.Status = TrackerStatus.InviteAccepted;
                    userTracker.StatusAt  = partnerTracker.StatusAt = DateTime.Now;
                    result.Reports        = new LogReports(LogTag.ChatRequestAccepted);
                }
                else if (userTracker.Status == TrackerStatus.InviteAccepted)
                {
                    userTracker.Status   = TrackerStatus.SeenInviteResponse;
                    userTracker.StatusAt = DateTime.Now;
                }

                await db.SaveChangesAsync();
            }

            return(result);
        }