void OnGroupChatPresence(XmppGroupChatModel chat, Presence pres)
{
Jid jid = pres.From;
var person = new PersonModel(jid, pres.From.Resource ?? pres.From, NetworkID, Protocol, this);
PrintGroupChatPresence(chat, person, pres);
switch (pres.Type) {
case PresenceType.available:
// don't do anything if the contact already exists
if (chat.UnsafePersons.ContainsKey(person.ID)) {
return;
}
// is the chat synced? add the new contact the regular way
if (chat.IsSynced) {
Session.AddPersonToGroupChat(chat, person);
return;
}
chat.UnsafePersons.Add(person.ID, person);
// did I join? then the chat roster is fully received
if (pres.From.Resource == chat.OwnNickname ||
pres.MucUser.StatusCodes.Exists(x => x.Code == StatusCode.SelfPresence)) {
if (pres.MucUser.StatusCodes.Exists(x => x.Code == StatusCode.ModifiedNick)) {
// as per XEP-0045 7.2.3 Example 24 the server is
// allowed to give us a different nick than we requested
chat.OwnNickname = pres.From.Resource;
}
chat.IsJoining = false;
// HACK: lower probability of sync race condition swallowing messages
ThreadPool.QueueUserWorkItem(delegate {
Thread.Sleep(1000);
lock (this) {
if (IsDisposed) {
return;
}
chat.IsSynced = true;
Session.SyncChat(chat);
Session.EnableChat(chat);
}
});
}
break;
case PresenceType.unavailable:
Session.RemovePersonFromGroupChat(chat, person);
// did I leave? then I "probably" left the room
if (pres.From.Resource == chat.OwnNickname) {
Session.RemoveChat(chat);
}
break;
case PresenceType.error:
OnGroupChatPresenceError(chat, pres);
break;
}
}