public virtual void UpdateTypings() { Peer peer = Peer; if (peer.Constructor == Constructor.peerUser) { if (userTyping != null && DateTime.Now - userTyping.lastUpdate > TimeSpan.FromSeconds(5)) { userTyping = null; OnPropertyChanged("PreviewOrAction"); OnPropertyChanged("StatusOrAction"); } } else if (peer.Constructor == Constructor.peerChat) { var toRemove = (from typing in chatTyping where DateTime.Now - typing.Value.lastUpdate > TimeSpan.FromSeconds(5) select typing.Key).ToList(); if (toRemove.Count != 0) { foreach (var i in toRemove) { chatTyping.Remove(i); } OnPropertyChanged("PreviewOrAction"); OnPropertyChanged("StatusOrAction"); } } }
/// <summary> /// If a user unexpectedly disconnects whilst sending a message, clients will be unaware and continue seeing the user as /// typing a message. /// This procedure will go through conversations a client is in and forcefully tell other clients that the user has stopped /// typing. /// </summary> /// <remarks> /// This could have be done in the Client when a client senses that a user's <see cref="ConnectionStatus" /> has been /// modified. /// But I'd rather have it as a rule here where a client can use their same /// <see cref="EntityNotification{UserNotification}" /> logic. /// </remarks> /// <param name="userId">The user that disconnected.</param> /// <param name="clientManager">Holds the connected clients.</param> /// <param name="repositoryManager">Holds the repositories in the system.</param> private static void SendUserTypingNotification(int userId, IClientManager clientManager, RepositoryManager repositoryManager) { var participationRepository = (ParticipationRepository)repositoryManager.GetRepository <Participation>(); var userRepository = (UserRepository)repositoryManager.GetRepository <User>(); IEnumerable <int> conversationIdsUserIsIn = participationRepository.GetAllConversationIdsByUserId(userId); foreach (int conversationId in conversationIdsUserIsIn) { Participation participation = participationRepository.GetParticipationByUserIdandConversationId(userId, conversationId); var userTyping = new UserTyping(false, participation.Id); var userTypingNotification = new EntityNotification <UserTyping>(userTyping, NotificationType.Create); List <Participation> participationsForConversation = participationRepository.GetParticipationsByConversationId(conversationId); List <int> userIdsInConversation = participationsForConversation.Select(x => x.UserId).ToList(); foreach (int userIdInConversation in userIdsInConversation) { User user = userRepository.FindEntityById(userIdInConversation); if (user.ConnectionStatus.UserConnectionStatus != ConnectionStatus.Status.Disconnected) { clientManager.SendMessageToClient(userTypingNotification, userIdInConversation); } } } }
private void Socket_DataReceived(object sender, dynamic data) { var type = data.Value <string>("type"); switch (type)//todo more from https://api.slack.com/rtm { case "message": case "message.channels": case "message.groups": case "message.im": case "message.mpim": MessageReceived?.Invoke(this, new MessageReceivedEventArgs(MakeMessageFromData(data))); break; case "reaction_added": ReactionAdded?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "reaction_removed": ReactionRemoved?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "star_added": StarAdded?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "star_removed": StarRemoved?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "pin_added": PinAdded?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "pin_removed": PinRemoved?.Invoke(this, GetReactionAddedEventArgs(data)); break; case "team_join": UserJoined?.Invoke(this, new UserDataReceivedEventArgs(Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")), null, Team)); break; case "user_typing": UserTyping?.Invoke(this, new UserDataReceivedEventArgs(Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")), Team.Channels.FirstOrDefault(x => x.Id == data.Value <string>("channel")), Team)); break; case "presence_change": UserPresenceChanged?.Invoke(this, new UserPresenceChangeEventArgs(data.Value <string>("presence"), Team.Users.FirstOrDefault(x => x.Id == data.Value <string>("user")))); break; } }
private void RecipientUser_IsTyping() { Invoke(new MethodInvoker(() => { bool typing = RecipientUser.UserTyping; if (typing) { if (!UserTyping.Visible) { UserTyping.Show(); } UserTyping.Text = RecipientUser.UserName + " is typing..."; UserTyping.BringToFront(); UserTyping.Location = new Point(ChatContainer.Width / 2 - (UserTyping.Width / 2), UserTyping.Location.Y); } else { UserTyping.Hide(); } })); }
public void SetTyping() { logger.debug("user typing in dialog model"); Peer peer = Peer; if (peer.Constructor == Constructor.peerChat) { logger.warning("invalid user typing event for chat dialog"); return; } if (userTyping == null) { userTyping = new UserTyping(DateTime.Now); OnPropertyChanged("PreviewOrAction"); OnPropertyChanged("StatusOrAction"); } else { userTyping.lastUpdate = DateTime.Now; } }
public void ProcessNewMessage(MessageModel messageModel) { logger.info("processing message and adding to observable collection"); if (messageModel is MessageModelDelivered) { MessageModelDelivered newMessage = (MessageModelDelivered)messageModel; var selectedMessages = from message in messages where message is MessageModelDelivered && ((MessageModelDelivered)message).Id == messageModel.Id select message; if (selectedMessages.Any()) { logger.info("message with this ID already in list"); return; } } messages.Add(messageModel); Peer peer = Peer; if (peer.Constructor == Constructor.peerUser) { if (userTyping != null) { userTyping = null; } } else if (peer.Constructor == Constructor.peerChat) { if (chatTyping.Count != 0) { chatTyping.Clear(); } } OnPropertyChanged("PreviewOrAction"); OnPropertyChanged("StatusOrAction"); OnPropertyChanged("MessageDeliveryStateProperty"); }
public UserTypingRequest(UserTyping userTyping) { UserTyping = userTyping; }
public void RaiseUserTyping(UserTypingEventArgs e) { UserTyping.SafeInvoke(this, e); }
void OnUserTyping(object sender, UserTypingEventArgs e) { GetParticipant(e.User).IsTyping = e.Starting; UserTyping.SafeInvoke(this, e); }
public void ProcessNewMessage(MessageModel messageModel) { logger.info("processing message and adding to observable collection"); if (messageModel is MessageModelDelivered) { MessageModelDelivered newMessage = (MessageModelDelivered) messageModel; var selectedMessages = from message in messages where message is MessageModelDelivered && ((MessageModelDelivered) message).Id == messageModel.Id select message; if (selectedMessages.Any()) { logger.info("message with this ID already in list"); return; } } messages.Add(messageModel); Peer peer = Peer; if (peer.Constructor == Constructor.peerUser) { if (userTyping != null) { userTyping = null; } } else if (peer.Constructor == Constructor.peerChat) { if (chatTyping.Count != 0) { chatTyping.Clear(); } } OnPropertyChanged("PreviewOrAction"); OnPropertyChanged("StatusOrAction"); OnPropertyChanged("MessageDeliveryStateProperty"); }
public void RaiseUserTyping(string userUuid) { UserTyping?.Invoke(this, new UserTypingEventArg(userUuid)); }