Receive lists and changes in room participants from protocols

Two new messages were added to the protocol API to do this:
M_ROOM_PARTICIPANTS, which can be used when someone joins a room, or
on joining a room to send a full list of users, and IM_ROOM_PARTICIPANT_LEFT,
for when a user has left the room/disconnected.

IM_SET_STATUS no longer assumes received data comes from contacts, but
any general user.

UserItem was made to reflect changes in the User's name.

Chat messages can now be reliably received in a given room. :)
This commit is contained in:
Jaidyn Ann 2021-06-02 16:53:03 -05:00
parent 061489ba2e
commit ad1c7b5782
9 changed files with 76 additions and 26 deletions

View File

@ -89,6 +89,12 @@ enum im_what_code {
//! Confirm the room's been joined //! Confirm the room's been joined
IM_ROOM_JOINED = 33, IM_ROOM_JOINED = 33,
//! Returning a (not necessarily complete) list of room users
IM_ROOM_PARTICIPANTS = 34,
//! A user left the room
IM_ROOM_PARTICIPANT_LEFT = 35,
/* /*
* Messages related to contact changes. * Messages related to contact changes.

View File

@ -153,10 +153,19 @@ Conversation::AddUser(User* user)
{ {
BMessage msg; BMessage msg;
msg.AddString("user_id", user->GetId()); msg.AddString("user_id", user->GetId());
msg.AddString("user_name", user->GetName());
_EnsureUser(&msg); _EnsureUser(&msg);
} }
void
Conversation::RemoveUser(User* user)
{
fUsers.RemoveItemFor(user->GetId());
GetView()->UpdateUserList(fUsers);
}
void void
Conversation::ShowView(bool typing, bool userAction) Conversation::ShowView(bool typing, bool userAction)
{ {

View File

@ -53,7 +53,9 @@ public:
UserMap Users(); UserMap Users();
User* UserById(BString id); User* UserById(BString id);
void AddUser(User* user); void AddUser(User* user);
void RemoveUser(User* user);
private: private:
void _LogChatMessage(BMessage* msg); void _LogChatMessage(BMessage* msg);

View File

@ -214,11 +214,8 @@ MainWindow::ImMessage(BMessage* msg)
} }
break; break;
} }
case IM_ROOM_PARTICIPANTS:
case IM_MESSAGE_RECEIVED: case IM_MESSAGE_RECEIVED:
{
_EnsureConversationItem(msg);
break;
}
case IM_MESSAGE_SENT: case IM_MESSAGE_SENT:
case IM_CHAT_CREATED: case IM_CHAT_CREATED:
{ {
@ -230,8 +227,9 @@ MainWindow::ImMessage(BMessage* msg)
case IM_EXTENDED_CONTACT_INFO: case IM_EXTENDED_CONTACT_INFO:
case IM_STATUS_SET: case IM_STATUS_SET:
{ {
if (fRosterWindow != NULL) if (fServer->ContactById(msg->FindString("user_id")) != NULL)
fRosterWindow->PostMessage(msg); if (fRosterWindow != NULL)
fRosterWindow->PostMessage(msg);
break; break;
} }
} }

View File

@ -16,6 +16,7 @@
#include <Entry.h> #include <Entry.h>
#include <Notification.h> #include <Notification.h>
#include <Path.h> #include <Path.h>
#include <StringList.h>
#include <TranslationUtils.h> #include <TranslationUtils.h>
#include "Account.h" #include "Account.h"
@ -154,14 +155,14 @@ Server::ImMessage(BMessage* msg)
if (msg->FindInt32("status", &status) != B_OK) if (msg->FindInt32("status", &status) != B_OK)
return B_SKIP_MESSAGE; return B_SKIP_MESSAGE;
Contact* contact = _EnsureContact(msg); User* user = _EnsureUser(msg);
if (!contact) if (!user)
break; break;
contact->SetNotifyStatus((CayaStatus)status); user->SetNotifyStatus((CayaStatus)status);
BString statusMsg; BString statusMsg;
if (msg->FindString("message", &statusMsg) == B_OK) { if (msg->FindString("message", &statusMsg) == B_OK) {
contact->SetNotifyPersonalStatus(statusMsg); user->SetNotifyPersonalStatus(statusMsg);
// contact->GetView()->UpdatePersonalMessage(); // contact->GetView()->UpdatePersonalMessage();
} }
break; break;
@ -254,6 +255,38 @@ Server::ImMessage(BMessage* msg)
{ {
break; break;
} }
case IM_ROOM_PARTICIPANTS:
{
Conversation* chat = _EnsureConversation(msg);
BStringList ids;
BStringList name;
msg->FindStrings("user_name", &name);
if (msg->FindStrings("user_id", &ids) != B_OK)
break;
ProtocolLooper* protoLooper = _LooperFromMessage(msg);
for (int i = 0; i < ids.CountStrings(); i++) {
User* user = _EnsureUser(ids.StringAt(i), protoLooper);
if (name.CountStrings() >= i) {
user->SetNotifyName(name.StringAt(i));
}
chat->AddUser(user);
}
break;
}
case IM_ROOM_PARTICIPANT_LEFT:
{
Conversation* chat = _EnsureConversation(msg);
User* user = _EnsureUser(msg);
if (user == NULL || chat == NULL)
break;
chat->RemoveUser(user);
break;
}
case IM_SEND_MESSAGE: case IM_SEND_MESSAGE:
{ {
// Route this message through the appropriate ProtocolLooper // Route this message through the appropriate ProtocolLooper
@ -541,11 +574,18 @@ User*
Server::_EnsureUser(BMessage* message) Server::_EnsureUser(BMessage* message)
{ {
BString id = message->FindString("user_id"); BString id = message->FindString("user_id");
return _EnsureUser(id, _LooperFromMessage(message));
}
User*
Server::_EnsureUser(BString id, ProtocolLooper* protoLooper)
{
User* user = UserById(id); User* user = UserById(id);
if (user == NULL && id.IsEmpty() == false) { if (user == NULL && id.IsEmpty() == false) {
user = new User(id, Looper()); user = new User(id, Looper());
user->SetProtocolLooper(_LooperFromMessage(message)); user->SetProtocolLooper(protoLooper);
AddUser(user); AddUser(user);
} }

View File

@ -68,6 +68,7 @@ private:
Contact* _EnsureContact(BMessage* message); Contact* _EnsureContact(BMessage* message);
User* _EnsureUser(BMessage* message); User* _EnsureUser(BMessage* message);
User* _EnsureUser(BString id, ProtocolLooper* protoLooper);
Conversation* _EnsureConversation(BMessage* message); Conversation* _EnsureConversation(BMessage* message);
void _ReplicantStatusNotify(CayaStatus status); void _ReplicantStatusNotify(CayaStatus status);

View File

@ -142,8 +142,10 @@ User::ProtocolBitmap() const
UserItem* UserItem*
User::GetListItem() User::GetListItem()
{ {
if (fListItem == NULL) if (fListItem == NULL) {
fListItem = new UserItem(fName, this); fListItem = new UserItem(fName, this);
RegisterObserver(fListItem);
}
return fListItem; return fListItem;
} }

View File

@ -5,6 +5,7 @@
#include "UserItem.h" #include "UserItem.h"
#include "NotifyMessage.h"
#include "User.h" #include "User.h"
@ -26,18 +27,11 @@ UserItem::GetUser()
void void
UserItem::ObserveString(int32 what, BString str) UserItem::ObserveString(int32 what, BString str)
{ {
} switch (what) {
case STR_CONTACT_NAME:
SetText(str);
void break;
UserItem::ObservePointer(int32 what, void* ptr) }
{
}
void
UserItem::ObserveInteger(int32 what, int32 val)
{
} }

View File

@ -20,8 +20,6 @@ public:
protected: protected:
void ObserveString(int32 what, BString str); void ObserveString(int32 what, BString str);
void ObservePointer(int32 what, void* ptr);
void ObserveInteger(int32 what, int32 val);
private: private:
User* fUser; User* fUser;