Allow leaving/getting booted from rooms

Now the user can leave or be forced to leave a chat.
For this, two protocol API messages were added: IM_LEAVE_ROOM, and IM_ROOM_LEFT.

Aside from that, IM_ROOM_BAN_PARTICIPANT and IM_ROOM_KICK_PARTICIPANT
were added, though they aren't used yet.
This commit is contained in:
Jaidyn Ann 2021-06-04 16:32:18 -05:00
parent 89905fe23c
commit effd010b46
7 changed files with 86 additions and 5 deletions

View File

@ -191,14 +191,20 @@ enum im_what_code {
//! Confirm the room's been joined
IM_ROOM_JOINED = 153,
//! User left the room
IM_LEAVE_ROOM = 154,
//! User left the room
IM_ROOM_LEFT = 155,
//! Quietly add a user(s) to the chat
IM_ROOM_PARTICIPANTS = 154,
IM_ROOM_PARTICIPANTS = 156,
//! User has newly and explicitly joined
IM_ROOM_PARTICIPANT_JOINED = 155,
IM_ROOM_PARTICIPANT_JOINED = 157,
//! A user left the room
IM_ROOM_PARTICIPANT_LEFT = 156,
IM_ROOM_PARTICIPANT_LEFT = 158,
/*
@ -212,6 +218,17 @@ enum im_what_code {
IM_ROOM_SUBJECT = 161,
/*
* Room moderation
*/
//! Ban user
IM_ROOM_BAN_PARTICIPANT = 170,
//! Kick user
IM_ROOM_KICK_PARTICIPANT = 171,
/*
* Special messages
*/

View File

@ -176,7 +176,6 @@ MainWindow::MessageReceived(BMessage* message)
message->AddString("body", fSendView->Text());
fChatView->MessageReceived(message);
fSendView->SetText("");
break;
}
@ -214,6 +213,7 @@ MainWindow::ImMessage(BMessage* msg)
}
break;
}
case IM_ROOM_JOINED:
case IM_ROOM_PARTICIPANTS:
case IM_MESSAGE_RECEIVED:
case IM_MESSAGE_SENT:
@ -222,6 +222,16 @@ MainWindow::ImMessage(BMessage* msg)
_EnsureConversationItem(msg);
break;
}
case IM_ROOM_LEFT:
{
ConversationItem* item = _EnsureConversationItem(msg);
if (item == NULL)
break;
_RemoveListItem(item);
item->GetConversation()->GetView()->MessageReceived(msg);
break;
}
case IM_AVATAR_SET:
case IM_CONTACT_INFO:
case IM_EXTENDED_CONTACT_INFO:
@ -422,3 +432,22 @@ MainWindow::_UpdateListItem(ConversationItem* item)
}
void
MainWindow::_RemoveListItem(ConversationItem* item)
{
int32 index = fListView->IndexOf(item);
if (index > 0)
index--;
fListView->RemoveItem(item);
fServer->RemoveConversation(item->GetConversation());
if (fListView->CountItems() == 0) {
fChatView = new ConversationView();
SetConversation(NULL);
}
else
fListView->Select(index);
}

View File

@ -48,8 +48,11 @@ private:
void _InitInterface();
BMenuBar* _CreateMenuBar();
ConversationItem* _EnsureConversationItem(BMessage* msg);
ConversationItem*
_EnsureConversationItem(BMessage* msg);
void _UpdateListItem(ConversationItem* item);
void _RemoveListItem(ConversationItem* item);
Server* fServer;
RosterWindow* fRosterWindow;

View File

@ -251,6 +251,7 @@ Server::ImMessage(BMessage* msg)
}
case IM_ROOM_JOINED:
{
_EnsureConversation(msg);
break;
}
case IM_ROOM_PARTICIPANTS:
@ -535,6 +536,13 @@ Server::AddConversation(Conversation* chat)
}
void
Server::RemoveConversation(Conversation* chat)
{
fChatMap.RemoveItemFor(chat->GetId());
}
BString
Server::GetOwnContact()
{

View File

@ -59,6 +59,7 @@ public:
ChatMap Conversations() const;
Conversation* ConversationById(BString id);
void AddConversation(Conversation* chat);
void RemoveConversation(Conversation* chat);
// TODO: there should be a contact for each account.
BString GetOwnContact();

View File

@ -10,8 +10,10 @@
#include <Window.h>
#include "CayaMessages.h"
#include "CayaProtocolMessages.h"
#include "Conversation.h"
#include "ConversationItem.h"
#include "ProtocolLooper.h"
const uint32 kOpenSelectedChat = 'CVos';
@ -38,6 +40,21 @@ ConversationListView::MessageReceived(BMessage* msg)
break;
}
case kLeaveSelectedChat:
{
ConversationItem* item;
int32 selIndex = CurrentSelection();
if ((item = (ConversationItem*)ItemAt(selIndex)) == NULL)
break;
BMessage leave(IM_MESSAGE);
leave.AddInt32("im_what", IM_LEAVE_ROOM);
leave.AddString("chat_id", item->GetConversation()->GetId());
item->GetConversation()->GetProtocolLooper()->MessageReceived(&leave);
break;
}
default:
BListView::MessageReceived(msg);
}

View File

@ -100,6 +100,12 @@ ConversationView::ImMessage(BMessage* msg)
int32 im_what = msg->FindInt32("im_what");
switch (im_what) {
case IM_ROOM_LEFT:
{
delete fConversation;
delete this;
break;
}
case IM_MESSAGE_RECEIVED:
{
BString message = msg->FindString("body");