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
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.

View File

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

View File

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

View File

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

View File

@ -16,6 +16,7 @@
#include <Entry.h>
#include <Notification.h>
#include <Path.h>
#include <StringList.h>
#include <TranslationUtils.h>
#include "Account.h"
@ -154,14 +155,14 @@ Server::ImMessage(BMessage* msg)
if (msg->FindInt32("status", &status) != B_OK)
return B_SKIP_MESSAGE;
Contact* contact = _EnsureContact(msg);
if (!contact)
User* user = _EnsureUser(msg);
if (!user)
break;
contact->SetNotifyStatus((CayaStatus)status);
user->SetNotifyStatus((CayaStatus)status);
BString statusMsg;
if (msg->FindString("message", &statusMsg) == B_OK) {
contact->SetNotifyPersonalStatus(statusMsg);
user->SetNotifyPersonalStatus(statusMsg);
// contact->GetView()->UpdatePersonalMessage();
}
break;
@ -254,6 +255,38 @@ Server::ImMessage(BMessage* msg)
{
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:
{
// Route this message through the appropriate ProtocolLooper
@ -541,11 +574,18 @@ User*
Server::_EnsureUser(BMessage* message)
{
BString id = message->FindString("user_id");
return _EnsureUser(id, _LooperFromMessage(message));
}
User*
Server::_EnsureUser(BString id, ProtocolLooper* protoLooper)
{
User* user = UserById(id);
if (user == NULL && id.IsEmpty() == false) {
user = new User(id, Looper());
user->SetProtocolLooper(_LooperFromMessage(message));
user->SetProtocolLooper(protoLooper);
AddUser(user);
}

View File

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

View File

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

View File

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

View File

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