Exemplo n.º 1
0
 public InviteToMenu(IrcProtocolManager protocolManager,
                     ChatViewManager chatViewManager,
                     PersonModel invitee)
     : this(protocolManager,
                     chatViewManager,
                     new [] { invitee })
 {
 }
Exemplo n.º 2
0
 public CtcpMenu(IrcProtocolManager protocolManager,
                 ChatViewManager chatViewManager,
                 PersonModel target)
     : this(protocolManager,
                 chatViewManager,
                 new [] { target })
 {
 }
Exemplo n.º 3
0
        public PersonHookEnvironment(string prefix, PersonModel person)
        {
            if (person == null) {
                throw new ArgumentNullException("person");
            }

            this[prefix + "PERSON_ID"] = person.ID;
            this[prefix + "PERSON_IDENTITY_NAME"] = person.IdentityName;
            this[prefix + "PERSON_NETWORK_ID"] = person.NetworkID;
            this[prefix + "PERSON_NETWORK_PROTOCOL"] = person.NetworkProtocol;
        }
Exemplo n.º 4
0
        public void AddPerson(PersonModel person)
        {
            Trace.Call(person);

            if (_PersonListStore == null) {
                // no liststore, nothing todo
                return;
            }

            _PersonListStore.AppendValues(person);
            Participants.Add(person);
            OnParticipantsChanged(EventArgs.Empty);
        }
Exemplo n.º 5
0
        private void AddPersonToGroup(Room room, string nickname)
        {
            string jid = room.JID.Bare;
            var chat = (XmppGroupChatModel) Session.GetChat(jid, ChatType.Group, this);
            // first notice we're joining a group chat is the participant info:
            if (chat == null) {
                chat = Session.CreateChat<XmppGroupChatModel>(jid, jid, this);
                chat.OwnNickname = room.Nickname;
                Session.AddChat(chat);
            }

            lock (chat) {
                if (chat.UnsafePersons.ContainsKey(nickname)) {
                    return;
                }
                // manual construction is necessary for group chats
                var person = new PersonModel(nickname, nickname, NetworkID, Protocol, this);
                if (chat.IsSynced) {
                    Session.AddPersonToGroupChat(chat, person);
                } else {
                    chat.UnsafePersons.Add(nickname, person);
                }
            }

            // did I join? then the chat roster is fully received
            if (!chat.IsSynced && nickname == room.Nickname) {
                chat.IsSynced = true;
                Session.SyncChat(chat);
            }
        }
Exemplo n.º 6
0
        public override void Sync()
        {
            Trace.Call();

            PersonModel = PersonChatModel.Person;

            base.Sync();
        }
Exemplo n.º 7
0
 public void RemovePerson(PersonModel person)
 {
 }
Exemplo n.º 8
0
        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
        {
            Trace.Call(groupChat, oldPerson, newPerson);

            try {
                var chatView = _ChatViewManager.GetChat(groupChat);
                if (chatView == null) {
            #if LOG4NET
                    _Logger.Fatal(String.Format("UpdatePersonInGroupChat(): _ChatViewManager.GetChat(groupChat) groupChat.Name: {0} returned null!", groupChat.Name));
            #endif
                    return;
                }

                lock (chatView.Participants) {
                    chatView.Participants.Remove(oldPerson);
                    chatView.Participants.Add(newPerson);
                }
            } catch (Exception ex) {
            #if LOG4NET
                _Logger.Fatal(ex);
            #endif
            }
        }
Exemplo n.º 9
0
 public PersonChatModel(PersonModel person, string id, string name, IProtocolManager networkManager) :
     base(id, name, ChatType.Person, networkManager)
 {
     _Person = person;
 }
Exemplo n.º 10
0
        void FormatUpload(MessageBuilder bld, PersonModel person, ChatModel chat, Message message)
        {
            // Figure out what the user uploaded, we need to issue another call for this
            var upload = Client.Get<UploadWrapper>(String.Format("/room/{0}/messages/{1}/upload.json", chat.ID, message.Id)).Upload;

            bld.AppendEventPrefix();
            bld.AppendIdendityName(person).AppendSpace();
            bld.AppendText(_("has uploaded '{0}' ({1} B) {2}"), upload.Name, upload.Byte_Size, upload.Full_Url);
        }
Exemplo n.º 11
0
 private void _AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
 {
     f_TaskQueue.Queue(delegate {
         _UI.AddPersonToGroupChat(groupChat, person);
     });
 }
Exemplo n.º 12
0
 void FormatEvent(MessageBuilder bld, PersonModel person, string action)
 {
     bld.AppendEventPrefix();
     bld.AppendIdendityName(person).AppendSpace();
     bld.AppendText(action);
 }
Exemplo n.º 13
0
 public PersonHookEnvironment(PersonModel person) :
     this(null, person)
 {
 }
Exemplo n.º 14
0
 bool AlreadyPosted(PersonModel person, int messageId)
 {
     return(person == Me && messageId <= LastSentId);
 }
Exemplo n.º 15
0
        public void UpdatePerson(PersonModel oldPerson, PersonModel newPerson)
        {
            Trace.Call(oldPerson, newPerson);

            if (_PersonListStore == null) {
                // no liststore, nothing todo
                return;
            }

            Gtk.TreeIter iter;
            bool res = _PersonListStore.GetIterFirst(out iter);
            if (!res) {
            #if LOG4NET
                _Logger.Error("UpdatePersonModelInChannel(): _PersonsStore.GetIterFirst() returned false, ignoring update...");
            #endif
                return;
            }

            do {
                PersonModel person = (PersonModel) _PersonListStore.GetValue(iter, 0);
                if (person.ID  == oldPerson.ID) {
                     _PersonListStore.SetValue(iter, 0, newPerson);
                    break;
                }
            } while (_PersonListStore.IterNext(ref iter));
            _PersonTreeView.CheckResize();
            //_PersonListStore.Reorder();

            for (int i = 0; i < Participants.Count; ++i) {
                if (Participants[i].ID == oldPerson.ID) {
                    Participants[i] = newPerson;
                    break;
                }
            }
        }
Exemplo n.º 16
0
        private void TextMessageReceived(object sender, TextMessageEventArgs e)
        {
            Trace.Call(sender, e);

            string user = e.Sender.Name;
            string status = e.Sender.Status.ToString();
            string message = e.Message.Text;

            ChatModel chat = Session.GetChat(user, ChatType.Person, this);
            if (chat == null) {
               PersonModel person = new PersonModel(user, user, NetworkID, Protocol, this);
                   Session.AddChat(chat);
            }

            MessageModel msg = new MessageModel();
            TextMessagePartModel msgPart;

            msgPart = new TextMessagePartModel();
            msgPart.Text = String.Format("{0} (Status: {1}) says:\n{2}", user, status, message);
            msg.MessageParts.Add(msgPart);

            Session.AddMessageToChat(chat, msg);
        }
Exemplo n.º 17
0
        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
        {
            if (!IsSynced(groupChat))
            {
                return;
            }

            _UpdatePersonInGroupChat(groupChat, oldPerson, newPerson);
        }
Exemplo n.º 18
0
 public PersonChatModel(PersonModel person, string id, string name, IProtocolManager networkManager)
     : base(id, name, ChatType.Person, networkManager)
 {
     _Person = person;
 }
Exemplo n.º 19
0
 private void _UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
 {
     f_TaskQueue.Queue(delegate {
         _UI.UpdatePersonInGroupChat(groupChat, oldPerson, newPerson);
     });
 }
Exemplo n.º 20
0
        public void AddPersonToGroupChat(GroupChatModel groupChat, PersonModel person)
        {
            Trace.Call(groupChat, person);

            try {
                var chatView = _ChatViewManager.GetChat(groupChat);
                if (chatView == null) {
            #if LOG4NET
                    _Logger.Fatal(String.Format("AddPersonToGroupChat(): _ChatViewManager.GetChat(chat) chat.Name: {0} returned null!", groupChat.Name));
            #endif
                    return;
                }

                lock (chatView.Participants) {
                    chatView.Participants.Add(person);
                }
            } catch (Exception ex) {
            #if LOG4NET
                _Logger.Fatal(ex);
            #endif
            }
        }
Exemplo n.º 21
0
 private void _RemovePersonFromGroupChat(GroupChatModel groupChat, PersonModel person)
 {
     f_TaskQueue.Queue(delegate {
         _UI.RemovePersonFromGroupChat(groupChat, person);
     });
 }
Exemplo n.º 22
0
 public void AddPerson(PersonModel person)
 {
 }
Exemplo n.º 23
0
 public void RemovePersonFromGroupChat(GroupChatModel cpage, PersonModel user)
 {
     Trace.Call(cpage, user);
 }
Exemplo n.º 24
0
 public void UpdatePerson(PersonModel oldPerson, PersonModel newPerson)
 {
 }
Exemplo n.º 25
0
 public void UpdatePersonInGroupChat(GroupChatModel cpage, PersonModel olduser, PersonModel newuser)
 {
     Trace.Call(cpage, olduser, newuser);
 }
Exemplo n.º 26
0
        void OnPresence(object sender, Presence pres)
        {
            JID jid = pres.From;
            var groupChat = (XmppGroupChatModel) Session.GetChat(jid.Bare, ChatType.Group, this);

            MessageBuilder builder = CreateMessageBuilder();
            builder.AppendEventPrefix();
            PersonModel person = null;
            if (groupChat != null) {
                string displayName = jid.Resource ?? jid.Bare;
                person = new PersonModel("", displayName, "", "", this);
            } else {
                person = CreatePerson(jid.Bare);
            }
            builder.AppendIdendityName(person);
            if (jid != person.IdentityName) {
                builder.AppendText(" [{0}]", jid);
            }

            switch (pres.Type) {
                case PresenceType.available:
                    // groupchat is already managed
                    if (groupChat == null) {
                        if (ContactChat != null) {
                            // anyone who is online/away/dnd will be added to the list
                            lock (ContactChat) {
                                PersonModel p = ContactChat.GetPerson(jid.Bare);
                                if (p != null) {
                                    // p already exists, don't add a new person
                                    Session.UpdatePersonInGroupChat(ContactChat, p, person);
                                } else {
                                    Session.AddPersonToGroupChat(ContactChat, person);
                                }
                            }
                        }
                    }
                    if (pres.Show == null) {
                        builder.AppendText(_(" is now available"));
                    } else if (pres.Show == "away") {
                        builder.AppendText(_(" is now away"));
                    } else if (pres.Show == "dnd") {
                        builder.AppendText(_(" wishes not to be disturbed"));
                    } else {
                        builder.AppendText(_(" set status to {0}"), pres.Show);
                    }
                    if (pres.Status == null) break;
                    if (pres.Status.Length == 0) break;
                    builder.AppendText(": {0}", pres.Status);
                    break;
                case PresenceType.unavailable:
                    builder.AppendText(_(" is now offline"));
                    if(groupChat == null) {
                        if (ContactChat != null) {
                            lock (ContactChat) {
                                PersonModel p = ContactChat.GetPerson(jid.Bare);
                                if (p == null) {
                                    // doesn't exist, got an offline message w/o a preceding online message?
                                    return;
                                }
                                Session.RemovePersonFromGroupChat(ContactChat, p);
                            }
                        }
                    }
                    break;
                case PresenceType.subscribe:
                    builder.AppendText(_(" wishes to subscribe to you"));
                    break;
                case PresenceType.subscribed:
                    builder.AppendText(_(" allows you to subscribe"));
                    break;
            }
            if (groupChat != null) {
                Session.AddMessageToChat(groupChat, builder.ToMessage());
            } else if (ContactChat != null) {
                Session.AddMessageToChat(ContactChat, builder.ToMessage());
            }
            var personChat = Session.GetChat(jid.Bare, ChatType.Person, this);
            if (personChat != null) {
                Session.AddMessageToChat(personChat, builder.ToMessage());
            }
        }
Exemplo n.º 27
0
 public void AddPersonToGroupChat(GroupChatModel cpage, PersonModel user)
 {
     Trace.Call(cpage, user);
 }
Exemplo n.º 28
0
        private void OnMessage(object sender, Message msg)
        {
            if (msg.Body == null) {
                return;
            }

            var delay = msg["delay"];
            string stamp = null;
            if (delay != null) {
                stamp = delay.Attributes["stamp"].Value;
            }
            bool display = true;

            ChatModel chat = null;
            PersonModel person = null;
            if (msg.Type != XmppMessageType.groupchat) {
                var sender_jid = msg.From.Bare;
                var personChat = (PersonChatModel) Session.GetChat(
                    sender_jid, ChatType.Person, this
                );
                if (personChat == null) {
                    person = CreatePerson(msg.From);
                    personChat = Session.CreatePersonChat(
                        person, sender_jid, person.IdentityName, this
                    );
                    Session.AddChat(personChat);
                    Session.SyncChat(personChat);
                } else {
                    person = personChat.Person;
                }
                chat = personChat;
            } else {
                string group_jid = msg.From.Bare;
                string group_name = group_jid;
                XmppGroupChatModel groupChat = (XmppGroupChatModel) Session.GetChat(group_jid, ChatType.Group, this);
                if (groupChat == null) {
                    groupChat = Session.CreateChat<XmppGroupChatModel>(
                        group_jid, group_name, this
                    );
                    Session.AddChat(groupChat);
                }
                // resource can be empty for room messages
                var sender_id = msg.From.Resource ?? msg.From.Bare;
                person = groupChat.GetPerson(sender_id);
                if (person == null) {
                    // happens in case of a delayed message if the participant has left meanwhile
                    person = new PersonModel(sender_id,
                                             sender_id,
                                             NetworkID, Protocol, this);
                }

                // XXX maybe only a Google Talk bug requires this:
                if (stamp != null) {
                    // XXX can't use > because of seconds precision :-(
                    if (stamp.CompareTo(groupChat.LatestSeenStamp) >= 0) {
                        groupChat.LatestSeenStamp = stamp;
                    } else {
                        display = false; // already seen newer delayed message
                    }
                    if (groupChat.SeenNewMessages) {
                        display = false; // already seen newer messages
                    }
                } else {
                    groupChat.SeenNewMessages = true;
                }

                chat = groupChat;
            }

            if (display) {
                var builder = CreateMessageBuilder();
                if (msg.Type != XmppMessageType.error) {
                    if (chat is PersonChatModel) {
                        // private message
                        builder.AppendSenderPrefix(person, true);
                        builder.AppendMessage(msg.Body);
                        builder.MarkHighlights();
                    } else if (chat is XmppGroupChatModel) {
                        // public message
                        builder.AppendMessage(person, msg.Body);
                        // mark highlights only for received messages
                        var muc = (XmppGroupChatModel) chat;
                        if (person.ID != muc.OwnNickname) {
                            builder.MarkHighlights();
                        }
                    }
                } else {
                    // TODO: nicer formatting
                    builder.AppendMessage(msg.Error.ToString());
                }
                if (stamp != null) {
                    string format = DateTimeFormatInfo.InvariantInfo.UniversalSortableDateTimePattern.Replace(" ", "T");
                    builder.TimeStamp = DateTime.ParseExact(stamp, format, null);
                }
                Session.AddMessageToChat(chat, builder.ToMessage());
            }
        }
Exemplo n.º 29
0
        public void AddPerson(PersonModel person)
        {
            Trace.Call(person);

            if (_PersonListStore == null) {
                // no liststore, nothing todo
                return;
            }

            _PersonListStore.AppendValues(person);
            UpdatePersonCount();
        }
Exemplo n.º 30
0
        public void RemovePerson(PersonModel person)
        {
            Trace.Call(person);

            if (_PersonListStore == null) {
                // no liststore, nothing todo
                return;
            }

            Gtk.TreeIter iter;
            bool res = _PersonListStore.GetIterFirst(out iter);
            if (!res) {
            #if LOG4NET
                _Logger.Error("RemovePerson(): GetIterFirst() returned false!");
            #endif
                return;
            }

            do {
                PersonModel currentPerson = (PersonModel) _PersonListStore.GetValue(iter, 0);
                if (currentPerson.ID == person.ID) {
                    _PersonListStore.Remove(ref iter);
                    break;
                }
            } while (_PersonListStore.IterNext(ref iter));

            for (int i = 0; i < Participants.Count; ++i) {
                if (Participants[i].ID == person.ID) {
                    Participants.RemoveAt(i);
                    break;
                }
            }

            OnParticipantsChanged(EventArgs.Empty);
        }
Exemplo n.º 31
0
        public void RemovePerson(PersonModel person)
        {
            Trace.Call(person);

            if (_PersonListStore == null) {
                // no liststore, nothing todo
                return;
            }

            Gtk.TreeIter iter;
            bool res = _PersonListStore.GetIterFirst(out iter);
            if (!res) {
            #if LOG4NET
                _Logger.Error("RemovePerson(): GetIterFirst() returned false!");
            #endif
                return;
            }

            do {
                PersonModel currentPerson = (PersonModel) _PersonListStore.GetValue(iter, 0);
                if (currentPerson.ID == person.ID) {
                    _PersonListStore.Remove(ref iter);
                    break;
                }
            } while (_PersonListStore.IterNext(ref iter));
            UpdatePersonCount();
        }
Exemplo n.º 32
0
        //        private void _OnReadText(xobject sender, string text)
        //        {
        //                Session.AddTextToChat(_NetworkChat, "-!- RECV: " + text);
        //        }
        //        private void _OnWriteText(xobject sender, string text)
        //        {
        //                Session.AddTextToChat(_NetworkChat, "-!- SENT: " + text);
        //        }
        private void MsnClient_ConversationCreated(object sender, ConversationCreatedEventArgs e)
        {
            Trace.Call(sender, e);

            // Session.AddTextToChat(_NetworkChat, "Conversation bla");
            //e.Conversation.Switchboard.Co
            //_MsnClient.Nameserver.RequestScreenName();

            // NetworkChatModel nchat = new NetworkChatModel("MSN", "MSN", this);
             //Session.AddChat(nchat);

            e.Conversation.Switchboard.TextMessageReceived +=  delegate(object sender2, TextMessageEventArgs e2) {
                PersonModel person = new PersonModel(e2.Sender.Name,
                                                     e2.Sender.Name,
                                                     NetworkID, Protocol,
                                                     this);
                PersonChatModel personChat = new PersonChatModel(person,
                                                                 e2.Sender.Name,
                                                                 e2.Sender.Name,
                                                                 this);
                Session.AddChat(personChat);
                Session.AddTextToChat(personChat, e2.Message.Text);
             };
        }
Exemplo n.º 33
0
        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
        {
            TraceRemotingCall(groupChat, oldPerson, newPerson);

            MethodBase mb = Trace.GetMethodBase();
            Gtk.Application.Invoke(delegate {
                TraceRemotingCall(mb, groupChat, oldPerson, newPerson);

                try {
                    GroupChatView groupChatView = (GroupChatView) _ChatViewManager.GetChat(groupChat);
                    if (groupChatView == null) {
            #if LOG4NET
                        _Logger.Fatal(
                            String.Format(
                                "UpdatePersonInGroupChat(): " +
                                "_ChatViewManager.GetChat(groupChat) " +
                                "groupChat.Name: {0} returned null!",
                                groupChat.Name
                            )
                        );
            #endif
                        return;
                    }
                    groupChatView.UpdatePerson(oldPerson, newPerson);
                } catch (Exception ex) {
                    Frontend.ShowException(ex);
                }
            });
        }
Exemplo n.º 34
0
 void FormatEvent(MessageBuilder bld, PersonModel person, string action)
 {
     bld.AppendEventPrefix();
     bld.AppendIdendityName(person).AppendSpace();
     bld.AppendText(action);
 }
Exemplo n.º 35
0
        public void RemovePersonFromGroupChat(GroupChatModel groupChat, PersonModel person)
        {
            TraceRemotingCall(groupChat, person);

            MethodBase mb = Trace.GetMethodBase();
            _Dispatcher.Invoke(DispatcherPriority.Normal,new MethodInvoker(delegate {
                TraceRemotingCall(mb, groupChat, person);

                GroupChatView groupChatView = (GroupChatView) _ChatViewManager.GetChat(groupChat);
                groupChatView.RemovePerson(person);
            }));
        }
Exemplo n.º 36
0
        //private void _OnMessageReceived(OscarSession sess, UserInfo userInfo, string message, Encoding encoding, MessageFlags msgFlags)
        private void _OnMessageReceived(object sender, MessageReceivedEventArgs e)
        {
            ChatModel chat = GetChat(e.Message.ScreenName, ChatType.Person);
            if (chat == null) {
                PersonModel person = new PersonModel(e.Message.ScreenName,
                                                     e.Message.ScreenName,
                                                     NetworkID,
                                                     Protocol,
                                                     this);
                chat = new PersonChatModel(person,
                                           e.Message.ScreenName,
                                           e.Message.ScreenName,
                                           this);
                Session.AddChat(chat);
                Session.SyncChat(chat);
            }

            MessageModel msg = new MessageModel();
            TextMessagePartModel textMsg;

            textMsg = new TextMessagePartModel();
            textMsg.Text = String.Format("<{0}> ", e.Message.ScreenName);
            textMsg.IsHighlight = true;
            msg.MessageParts.Add(textMsg);

            textMsg = new TextMessagePartModel();
            textMsg.Text = e.Message.Message;
            msg.MessageParts.Add(textMsg);

            Session.AddMessageToChat(chat, msg);
        }
Exemplo n.º 37
0
        public void UpdatePersonInGroupChat(GroupChatModel groupChat, PersonModel oldPerson, PersonModel newPerson)
        {
            TraceRemotingCall(groupChat, oldPerson, newPerson);

            MethodBase mb = Trace.GetMethodBase();
            _Dispatcher.Invoke(DispatcherPriority.Normal,new MethodInvoker(delegate {
                TraceRemotingCall(mb, groupChat, oldPerson, newPerson);

                GroupChatView groupChatView = (GroupChatView) _ChatViewManager.GetChat(groupChat);
                groupChatView.UpdatePerson(oldPerson, newPerson);
            }));
        }
Exemplo n.º 38
0
 protected override string GenerateIdString(PersonModel contact)
 {
     return "";
 }
Exemplo n.º 39
0
        private void OnMessage(object sender, Message msg)
        {
            if (msg.Body == null)
            {
                return;
            }

            var    delay = msg["delay"];
            string stamp = null;

            if (delay != null)
            {
                stamp = delay.Attributes["stamp"].Value;
            }
            bool display = true;

            ChatModel   chat   = null;
            PersonModel person = null;

            if (msg.Type != XmppMessageType.groupchat)
            {
                string jid      = msg.From.Bare;
                var    contact  = _RosterManager[jid];
                string nickname = null;
                if (contact == null || String.IsNullOrEmpty(contact.Nickname))
                {
                    nickname = jid;
                }
                else
                {
                    nickname = contact.Nickname;
                }
                PersonChatModel personChat = (PersonChatModel)Session.GetChat(jid, ChatType.Person, this);
                if (personChat == null)
                {
                    person = new PersonModel(jid, nickname, NetworkID,
                                             Protocol, this);
                    personChat = Session.CreatePersonChat(
                        person, jid, nickname, this
                        );
                    Session.AddChat(personChat);
                    Session.SyncChat(personChat);
                }
                else
                {
                    person = personChat.Person;
                }
                chat = personChat;
            }
            else
            {
                string             group_jid  = msg.From.Bare;
                string             group_name = group_jid;
                string             sender_jid = msg.From.ToString();
                XmppGroupChatModel groupChat  = (XmppGroupChatModel)Session.GetChat(group_jid, ChatType.Group, this);
                if (groupChat == null)
                {
                    // FIXME shouldn't happen?
                    groupChat = Session.CreateChat <XmppGroupChatModel>(
                        group_jid, group_name, this
                        );
                    Session.AddChat(groupChat);
                    Session.SyncChat(groupChat);
                }
                person = groupChat.GetPerson(msg.From.Resource);
                if (person == null)
                {
                    // happens in case of a delayed message if the participant has left meanwhile
                    person = new PersonModel(msg.From.Resource,
                                             msg.From.Resource,
                                             NetworkID, Protocol, this);
                }

                // XXX maybe only a Google Talk bug requires this:
                if (stamp != null)
                {
                    // XXX can't use > because of seconds precision :-(
                    if (stamp.CompareTo(groupChat.LatestSeenStamp) >= 0)
                    {
                        groupChat.LatestSeenStamp = stamp;
                    }
                    else
                    {
                        display = false; // already seen newer delayed message
                    }
                    if (groupChat.SeenNewMessages)
                    {
                        display = false; // already seen newer messages
                    }
                }
                else
                {
                    groupChat.SeenNewMessages = true;
                }

                chat = groupChat;
            }

            if (display)
            {
                var builder = CreateMessageBuilder();
                if (msg.Type != XmppMessageType.error)
                {
                    builder.AppendMessage(person, msg.Body);
                }
                else
                {
                    // TODO: nicer formatting
                    builder.AppendMessage(msg.Error.ToString());
                }
                if (stamp != null)
                {
                    string format = DateTimeFormatInfo.InvariantInfo.UniversalSortableDateTimePattern.Replace(" ", "T");
                    builder.TimeStamp = DateTime.ParseExact(stamp, format, null);
                }
                Session.AddMessageToChat(chat, builder.ToMessage());
            }
        }