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.
This commit is contained in:
Jaidyn Ann 2021-06-07 00:03:15 -05:00
parent fde681bbf4
commit 77d914312c
7 changed files with 185 additions and 55 deletions

View File

@ -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,
/*

View File

@ -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;

View File

@ -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:

View File

@ -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);
}

View File

@ -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<BMessage> fMessageQueue;

View File

@ -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());
}

View File

@ -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,
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);