From 77d914312cca6392386d5477925c0edc5e698b77 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Mon, 7 Jun 2021 00:03:15 -0500 Subject: [PATCH] Show users' joins/parts in chat view New API messages were added to distinguish between a user leaving of their own volition and being kicked/banned. Messages are now shown in the chat view when a user leaves or or kicked/banned, etc. --- application/CayaProtocolMessages.h | 18 ++-- application/Conversation.cpp | 31 +++++++ application/Server.cpp | 13 ++- application/views/ConversationView.cpp | 56 ++++++++++++- application/views/ConversationView.h | 3 + protocols/xmpp/JabberHandler.cpp | 110 ++++++++++++++++--------- protocols/xmpp/JabberHandler.h | 9 +- 7 files changed, 185 insertions(+), 55 deletions(-) diff --git a/application/CayaProtocolMessages.h b/application/CayaProtocolMessages.h index 9cfd0b7..0c01887 100644 --- a/application/CayaProtocolMessages.h +++ b/application/CayaProtocolMessages.h @@ -228,23 +228,29 @@ enum im_what_code { //! Kick user IM_ROOM_KICK_PARTICIPANT = 171, + //! A user was kicked + IM_ROOM_PARTICIPANT_KICKED = 172, + //! Ban user - IM_ROOM_BAN_PARTICIPANT = 172, + IM_ROOM_BAN_PARTICIPANT = 173, + + //! A user was banned + IM_ROOM_PARTICIPANT_BANNED = 174, //! Unban user - IM_ROOM_UNBAN_PARTICIPANT = 173, + IM_ROOM_UNBAN_PARTICIPANT = 175, //! Mute user - IM_ROOM_MUTE_PARTICIPANT = 174, + IM_ROOM_MUTE_PARTICIPANT = 176, //! Unmute user - IM_ROOM_UNMUTE_PARTICIPANT = 175, + IM_ROOM_UNMUTE_PARTICIPANT = 177, //! Deafen - IM_ROOM_DEAFEN_PARTICIPANT = 176, + IM_ROOM_DEAFEN_PARTICIPANT = 178, //! Allow to read messages - IM_ROOM_UNDEAFEN_PARTICIPANT = 177, + IM_ROOM_UNDEAFEN_PARTICIPANT = 179, /* diff --git a/application/Conversation.cpp b/application/Conversation.cpp index 3be62a4..2853245 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -70,6 +70,31 @@ Conversation::ImMessage(BMessage* msg) fMessenger.SendMessage(msg); break; } + case IM_ROOM_PARTICIPANT_JOINED: + { + BString user_id; + if (msg->FindString("user_id", &user_id) != B_OK) + break; + + if (UserById(user_id) == NULL) { + _EnsureUser(msg); + GetView()->MessageReceived(msg); + } + break; + } + case IM_ROOM_PARTICIPANT_LEFT: + case IM_ROOM_PARTICIPANT_KICKED: + case IM_ROOM_PARTICIPANT_BANNED: + { + BString user_id = msg->FindString("user_id"); + User* user; + if (user_id.IsEmpty() == true || (user = UserById(user_id)) == NULL) + break; + + GetView()->MessageReceived(msg); + RemoveUser(user); + break; + } case IM_LOGS_RECEIVED: default: GetView()->MessageReceived(msg); @@ -347,16 +372,19 @@ User* Conversation::_EnsureUser(BMessage* msg) { BString id = msg->FindString("user_id"); + BString name = msg->FindString("user_name"); if (id.IsEmpty() == true) return NULL; User* user = UserById(id); User* serverUser = _GetServer()->UserById(id); + // Not here, but found in server if (user == NULL && serverUser != NULL) { fUsers.AddItem(id, serverUser); user = serverUser; GetView()->UpdateUserList(fUsers); } + // Not anywhere; create user else if (user == NULL) { user = new User(id, _GetServer()->Looper()); user->SetProtocolLooper(fLooper); @@ -364,6 +392,9 @@ Conversation::_EnsureUser(BMessage* msg) _GetServer()->AddUser(user); fUsers.AddItem(id, user); GetView()->UpdateUserList(fUsers); + + if (name.IsEmpty() == false) + user->SetNotifyName(name); } user->RegisterObserver(this); return user; diff --git a/application/Server.cpp b/application/Server.cpp index fc2a7fb..9d034b0 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -186,10 +186,8 @@ Server::ImMessage(BMessage* msg) contact->SetNotifyName(name); BString status; - if (msg->FindString("message", &status) == B_OK) { + if (msg->FindString("message", &status) == B_OK) contact->SetNotifyPersonalStatus(status); -// contact->GetChatWindow()->UpdatePersonalMessage(); - } break; } case IM_EXTENDED_CONTACT_INFO: @@ -276,14 +274,15 @@ Server::ImMessage(BMessage* msg) } break; } + case IM_ROOM_PARTICIPANT_JOINED: case IM_ROOM_PARTICIPANT_LEFT: + case IM_ROOM_PARTICIPANT_BANNED: + case IM_ROOM_PARTICIPANT_KICKED: { Conversation* chat = _EnsureConversation(msg); - User* user = _EnsureUser(msg); - - if (user == NULL || chat == NULL) + if (chat == NULL) break; - chat->RemoveUser(user); + chat->ImMessage(msg); break; } case IM_ROOM_ROLECHANGE: diff --git a/application/views/ConversationView.cpp b/application/views/ConversationView.cpp index eb9ef8a..d3e48ea 100644 --- a/application/views/ConversationView.cpp +++ b/application/views/ConversationView.cpp @@ -149,6 +149,30 @@ ConversationView::ImMessage(BMessage* msg) _AppendOrEnqueueMessage(msg); break; } + case IM_ROOM_PARTICIPANT_JOINED: + { + _UserMessage("%user% has joined the room.\n", + "%user% has joined the room (%body%).\n", msg); + break; + } + case IM_ROOM_PARTICIPANT_LEFT: + { + _UserMessage("%user% has left the room.\n", + "%user% has left the room (%body%).\n", msg); + break; + } + case IM_ROOM_PARTICIPANT_KICKED: + { + _UserMessage("%user% was kicked.\n", + "%user% was kicked (%body%).\n", msg); + break; + } + case IM_ROOM_PARTICIPANT_BANNED: + { + _UserMessage("%user% has been banned.\n", + "%user% has been banned (%body%).\n", msg); + break; + } default: break; } @@ -276,9 +300,9 @@ void ConversationView::_AppendMessage(BMessage* msg) { BStringList users, bodies; - if (msg->FindStrings("body", &bodies) != B_OK - || msg->FindStrings("user_id", &users) != B_OK) + if (msg->FindStrings("body", &bodies) != B_OK) return; + msg->FindStrings("user_id", &users); for (int i = bodies.CountStrings(); i >= 0; i--) { User* sender = fConversation->UserById(users.StringAt(i)); @@ -298,3 +322,31 @@ ConversationView::_AppendMessage(BMessage* msg) } +void +ConversationView::_UserMessage(const char* format, const char* bodyFormat, + BMessage* msg) +{ + BString user_id; + BString user_name = msg->FindString("user_name"); + BString body = msg->FindString("body"); + + if (msg->FindString("user_id", &user_id) != B_OK) + return; + if (user_name.IsEmpty() == true) + user_name = user_id; + + BString newBody("** "); + if (body.IsEmpty() == true) + newBody << format; + else { + newBody << bodyFormat; + newBody.ReplaceAll("%body%", body.String()); + } + newBody.ReplaceAll("%user%", user_name.String()); + + BMessage newMsg; + newMsg.AddString("body", newBody); + _AppendOrEnqueueMessage(&newMsg); +} + + diff --git a/application/views/ConversationView.h b/application/views/ConversationView.h index 307430d..a07b978 100644 --- a/application/views/ConversationView.h +++ b/application/views/ConversationView.h @@ -50,6 +50,9 @@ private: bool _AppendOrEnqueueMessage(BMessage* msg); void _AppendMessage(BMessage* msg); + void _UserMessage(const char* format, const char* bodyFormat, + BMessage* msg); + Conversation* fConversation; int32 fMessageCount; BObjectList fMessageQueue; diff --git a/protocols/xmpp/JabberHandler.cpp b/protocols/xmpp/JabberHandler.cpp index 7dfd221..ccf1679 100644 --- a/protocols/xmpp/JabberHandler.cpp +++ b/protocols/xmpp/JabberHandler.cpp @@ -140,7 +140,7 @@ JabberHandler::Process(BMessage* msg) if (!invite_id) return B_ERROR; - _ChatCreated(invite_id); + _ChatCreatedMsg(invite_id); break; } @@ -705,7 +705,7 @@ JabberHandler::_MessageSent(const char* id, const char* subject, void -JabberHandler::_ChatCreated(const char* id) +JabberHandler::_ChatCreatedMsg(const char* id) { BMessage msg(IM_MESSAGE); msg.AddInt32("im_what", IM_CHAT_CREATED); @@ -715,6 +715,70 @@ JabberHandler::_ChatCreated(const char* id) } +void +JabberHandler::_RoleChangedMsg(BString chat_id, BString user_id, + gloox::MUCRoomRole role, gloox::MUCRoomAffiliation aff) +{ + BMessage roleMsg(IM_MESSAGE); + roleMsg.AddInt32("im_what", IM_ROOM_ROLECHANGE); + roleMsg.AddString("user_id", user_id); + roleMsg.AddString("chat_id", chat_id); + roleMsg.AddString("role_title", _RoleTitle(role, aff)); + roleMsg.AddInt32("role_perms", _RolePerms(role, aff)); + roleMsg.AddInt32("role_priority", _RolePriority(role, aff)); + _SendMessage(&roleMsg); +} + + +void +JabberHandler::_UserLeftMsg(BString chat_id, gloox::MUCRoomParticipant participant) +{ + BString user_id; + const char* nick = participant.nick->resource().c_str(); + bool isSelf = _MUCUserId(chat_id, nick, &user_id); + + if (user_id.IsEmpty() == true) + return; + + int32 im_what = IM_ROOM_PARTICIPANT_LEFT; + int flags = participant.flags; + + if (flags & gloox::UserBanned) + im_what = IM_ROOM_PARTICIPANT_BANNED; + else if (flags & gloox::UserKicked) + im_what = IM_ROOM_PARTICIPANT_KICKED; + + BMessage leftMsg(IM_MESSAGE); + leftMsg.AddInt32("im_what", im_what); + leftMsg.AddString("chat_id", chat_id); + leftMsg.AddString("user_id", user_id); + leftMsg.AddString("user_name", nick); + if (participant.reason.empty() == false) + leftMsg.AddString("body", participant.reason.c_str()); + _SendMessage(&leftMsg); +} + + +void +JabberHandler::_StatusSetMsg(const char* user_id, gloox::Presence::PresenceType type, + const char* message, const char* resource) +{ + BMessage msg(IM_MESSAGE); + msg.AddInt32("im_what", IM_STATUS_SET); + msg.AddString("user_id", user_id); + msg.AddInt32("status", _GlooxStatusToCaya(type)); + + if (BString(resource).IsEmpty() == false) + msg.AddString("resource", resource); + if (BString(message).IsEmpty() == false) + msg.AddString("message", message); + + msg.PrintToStream(); + + _SendMessage(&msg); +} + + status_t JabberHandler::_SetupAvatarCache() { @@ -1251,49 +1315,26 @@ JabberHandler::handleMUCParticipantPresence(gloox::MUCRoom *room, joinedMsg.AddInt32("im_what", im_what); joinedMsg.AddString("chat_id", chat_id); _SendMessage(&joinedMsg); - _RoleChanged(chat_id, user_id, role, aff); + _RoleChangedMsg(chat_id, user_id, role, aff); return; } - BMessage statusMsg(IM_MESSAGE); - statusMsg.AddInt32("im_what", IM_STATUS_SET); - statusMsg.AddString("user_id", user_id); - statusMsg.AddInt32("status", _GlooxStatusToCaya(presence.presence())); - _SendMessage(&statusMsg); + _StatusSetMsg(user_id.String(), presence.presence(), presence.status().c_str(), ""); // If unavailable (disconnected/left chat) if (presence.presence() == 5) { - BMessage leftMsg(IM_MESSAGE); - leftMsg.AddInt32("im_what", IM_ROOM_PARTICIPANT_LEFT); - leftMsg.AddString("user_id", user_id); - leftMsg.AddString("chat_id", chat_id); - _SendMessage(&leftMsg); + _UserLeftMsg(chat_id, participant); return; } BMessage joinMsg(IM_MESSAGE); - joinMsg.AddInt32("im_what", IM_ROOM_PARTICIPANTS); + joinMsg.AddInt32("im_what", IM_ROOM_PARTICIPANT_JOINED); joinMsg.AddString("user_id", user_id); joinMsg.AddString("user_name", nick); joinMsg.AddString("chat_id", chat_id); _SendMessage(&joinMsg); - _RoleChanged(chat_id, user_id, role, aff); -} - - -void -JabberHandler::_RoleChanged(BString chat_id, BString user_id, - gloox::MUCRoomRole role, gloox::MUCRoomAffiliation aff) -{ - BMessage roleMsg(IM_MESSAGE); - roleMsg.AddInt32("im_what", IM_ROOM_ROLECHANGE); - roleMsg.AddString("user_id", user_id); - roleMsg.AddString("chat_id", chat_id); - roleMsg.AddString("role_title", _RoleTitle(role, aff)); - roleMsg.AddInt32("role_perms", _RolePerms(role, aff)); - roleMsg.AddInt32("role_priority", _RolePriority(role, aff)); - _SendMessage(&roleMsg); + _RoleChangedMsg(chat_id, user_id, role, aff); } @@ -1482,13 +1523,8 @@ JabberHandler::handleRosterPresence(const gloox::RosterItem& item, gloox::Presence::PresenceType type, const std::string& presenceMsg) { - BMessage msg(IM_MESSAGE); - msg.AddInt32("im_what", IM_STATUS_SET); - msg.AddString("user_id", item.jidJID().full().c_str()); - msg.AddInt32("status", _GlooxStatusToCaya(type)); - msg.AddString("resource", resource.c_str()); - msg.AddString("message", presenceMsg.c_str()); - _SendMessage(&msg); + _StatusSetMsg(item.jidJID().full().c_str(), type, presenceMsg.c_str(), + resource.c_str()); } diff --git a/protocols/xmpp/JabberHandler.h b/protocols/xmpp/JabberHandler.h index bb9b89c..3365f0e 100644 --- a/protocols/xmpp/JabberHandler.h +++ b/protocols/xmpp/JabberHandler.h @@ -117,9 +117,12 @@ private: void _MessageSent(const char* id, const char* subject, const char* body); - void _ChatCreated(const char* id); - void _RoleChanged(BString chat_id, BString user_id, - gloox::MUCRoomRole role, gloox::MUCRoomAffiliation aff); + void _ChatCreatedMsg(const char* id); + void _RoleChangedMsg(BString chat_id, BString user_id, + gloox::MUCRoomRole role, gloox::MUCRoomAffiliation aff); + void _UserLeftMsg(BString chat_id, gloox::MUCRoomParticipant participant); + void _StatusSetMsg(const char* user_id, gloox::Presence::PresenceType type, + const char* message, const char* resource); void _Notify(notification_type type, const char* title, const char* message); void _NotifyProgress(const char* title, const char* message, float progress);