Create JoinWindow and protocol messages for joining rooms

Protocol messages was added to the API to allow joining abstract rooms
by their chat_id― IM_JOIN_ROOM and IM_ROOM_JOINED. To make room in
anticipation of future room-related calls, some messages' values have
been shifted.

A JoinWindow was created (found through [Chat→Join Room] or [Alt-J] in
the main window), to allow joining a room with this protocol message.
The user can select which account the room should be joined from through
a drop-down menu in the lower left-hand corner― a design I think could
be replicated in other parts of Caya well.

Path() and SetPath() in CayaProtocol were renamed to AddOnPath() and
SetAddOnPath() respectively. GetName() and SetName() were also added,
where "name" is the account name (aka the leaf of the protocols settings
path).

To Server, a new KeyMap was added for convenience (AccountInstances), to
associate these account names with their instance IDs.
This commit is contained in:
Jaidyn Ann 2021-06-01 21:43:19 -05:00
parent 5c5b180bbe
commit 75de08a18b
11 changed files with 240 additions and 8 deletions

View File

@ -34,6 +34,8 @@ Account::Account(bigtime_t instanceId, CayaProtocol* cayap,
if (path.InitCheck() == B_OK) {
path.Append(name);
fProtocol->SetName(name);
// Load settings file
BFile file(path.Path(), B_READ_ONLY);
if (fSettings->Unflatten(&file) == B_OK)

View File

@ -20,6 +20,9 @@ const uint32 CAYA_CHAT = 'CYch';
//! Create a new chat
const uint32 CAYA_NEW_CHAT = 'CYnc';
//! Join a chat
const uint32 CAYA_JOIN_CHAT = 'CYjc';
//! Invite user to current chat
const uint32 CAYA_SEND_INVITE = 'CYin';

View File

@ -51,8 +51,12 @@ public:
virtual bool SaveLogs() const = 0;
//! Add-on's path
virtual void SetPath(BPath path) = 0;
virtual BPath Path() = 0;
virtual void SetAddOnPath(BPath path) = 0;
virtual BPath AddOnPath() = 0;
//! Name of account file (leaf)
virtual const char* GetName() = 0;
virtual void SetName(const char* name) = 0;
//! Preferred encoding of messages
virtual uint32 GetEncoding() = 0;

View File

@ -52,7 +52,7 @@ CayaProtocol*
CayaProtocolAddOn::ProtocolAt(int32 i) const
{
CayaProtocol* proto = fGetProtocol(i);
proto->SetPath(BPath(fPath.String()));
proto->SetAddOnPath(BPath(fPath.String()));
return proto;
}

View File

@ -40,17 +40,18 @@ enum im_what_code {
//! Contact(s) removed from the server-side list
IM_CONTACT_LIST_REMOVED_CONTACT = 4,
/*
* Messages related to text chat.
*/
//! Send a chat message to a contact
//! Send a chat message
IM_SEND_MESSAGE = 20,
//! Chat message has been sent to contact
//! Chat message has been sent
IM_MESSAGE_SENT = 21,
//! Chat message received from contact
//! Chat message received
IM_MESSAGE_RECEIVED = 22,
//! Contact started typing
@ -71,11 +72,23 @@ enum im_what_code {
//! Logs received
IM_LOGS_RECEIVED = 28,
/*
* Messages related to rooms
*/
//! Create an individual chat
IM_CREATE_CHAT = 29,
IM_CREATE_CHAT = 30,
//! Chat has been created
IM_CHAT_CREATED = 30,
IM_CHAT_CREATED = 31,
//! Join a room
IM_JOIN_ROOM = 32,
//! Confirm the room's been joined
IM_ROOM_JOINED = 33,
/*
* Messages related to contact changes.
@ -87,6 +100,7 @@ enum im_what_code {
//! Contact's status has changed
IM_NICKNAME_SET = 41,
/*
* Messages related to contact's information received from protocols.
*/
@ -109,6 +123,7 @@ enum im_what_code {
//! Received extended contact information
IM_EXTENDED_CONTACT_INFO = 65,
/*
* Messages that involve changing own information.
*/
@ -134,6 +149,7 @@ enum im_what_code {
//! Own avatar icon was changed
IM_OWN_AVATAR_SET = 86,
/*
* Contacts registration.
*/
@ -144,6 +160,7 @@ enum im_what_code {
//! Stop listening to status changes from these contacts
IM_UNREGISTER_CONTACTS = 101,
/*
* Authorization.
*/
@ -163,6 +180,7 @@ enum im_what_code {
//! Contact has been authorized
IM_CONTACT_AUTHORIZED = 124,
/*
* Miscellaneous.
*/

116
application/JoinWindow.cpp Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "JoinWindow.h"
#include <Alert.h>
#include <Button.h>
#include <LayoutBuilder.h>
#include <Messenger.h>
#include <StringView.h>
#include "CayaProtocolMessages.h"
const uint32 kJoinRoom = 'JWjr';
const uint32 kAccSelected = 'JWas';
JoinWindow::JoinWindow(BMessenger* messenger, AccountInstances accounts)
:
BWindow(BRect(0, 0, 300, 100), "Join a room", B_FLOATING_WINDOW, 0),
fTarget(messenger),
fAccounts(accounts),
fSelectedAcc(0)
{
_InitInterface();
CenterOnScreen();
}
void
JoinWindow::MessageReceived(BMessage* msg)
{
switch (msg->what)
{
case kAccSelected:
{
int32 index;
if (msg->FindInt32("index", &index) == B_OK)
fSelectedAcc = index;
break;
}
case kJoinRoom:
{
BString roomId = fTextBox->Text();
BString selected = fMenuField->Menu()->ItemAt(fSelectedAcc)->Label();
int64 instanceId = fAccounts.ValueFor(selected);
if (roomId.IsEmpty() == true) {
BAlert* alert = new BAlert("No room ID", "You can't join a room "
"with no name― you need to specify a room ID.", "OK", "", "",
B_WIDTH_AS_USUAL, B_EVEN_SPACING, B_IDEA_ALERT);
alert->Go();
return;
}
BMessage* joinMsg = new BMessage(IM_MESSAGE);
joinMsg->AddInt32("im_what", IM_JOIN_ROOM);
joinMsg->AddInt64("instance", instanceId);
joinMsg->AddString("chat_id", roomId);
fTarget->SendMessage(joinMsg);
Quit();
break;
}
default:
BWindow::MessageReceived(msg);
}
}
void
JoinWindow::_InitInterface()
{
fMenuField = new BMenuField("accountMenuField", NULL, _CreateAccountMenu());
BButton* join = new BButton("Join", new BMessage(kJoinRoom));
fTextBox = new BTextControl("Room ID:", "", NULL);
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_DEFAULT_SPACING)
.Add(fTextBox)
.AddGroup(B_HORIZONTAL)
.Add(fMenuField)
.AddGlue()
.Add(new BButton("Cancel", new BMessage(B_QUIT_REQUESTED)))
.Add(join)
.End()
.End();
fTextBox->MakeFocus(true);
join->MakeDefault(true);
}
BMenu*
JoinWindow::_CreateAccountMenu()
{
BMenu* menu = new BMenu("accountMenu");
for (int i = 0; i < fAccounts.CountItems(); i++)
menu->AddItem(new BMenuItem(fAccounts.KeyAt(i).String(),
new BMessage(kAccSelected)));
menu->SetRadioMode(true);
menu->SetLabelFromMarked(true);
menu->ItemAt(fSelectedAcc)->SetMarked(true);
return menu;
}

40
application/JoinWindow.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef JOINWINDOW_H
#define JOINWINDOW_H
#include <Window.h>
#include "Server.h"
class BMenu;
class BMenuField;
class BMessenger;
class BTextControl;
/* A window used to specify a room to join. */
class JoinWindow : public BWindow {
public:
JoinWindow(BMessenger* messenger, AccountInstances accounts);
void MessageReceived(BMessage* message);
private:
void _InitInterface();
BMenu* _CreateAccountMenu();
BMessenger* fTarget;
AccountInstances fAccounts;
BMenuField* fMenuField;
BTextControl* fTextBox;
int32 fSelectedAcc;
};
#endif // JOINWINDOW_H

View File

@ -23,6 +23,7 @@
#include "ConversationListView.h"
#include "ConversationView.h"
#include "EditingFilter.h"
#include "JoinWindow.h"
#include "MainWindow.h"
#include "NotifyMessage.h"
#include "PreferencesDialog.h"
@ -111,6 +112,14 @@ MainWindow::MessageReceived(BMessage* message)
break;
}
case CAYA_JOIN_CHAT:
{
JoinWindow* win = new JoinWindow(new BMessenger(this),
fServer->GetAccounts());
win->Show();
break;
}
case CAYA_MOVE_UP:
{
if (fConversation == NULL)
@ -350,9 +359,16 @@ MainWindow::_CreateMenuBar()
BMenuItem* invite = new BMenuItem("Invite user" B_UTF8_ELLIPSIS,
new BMessage(CAYA_SEND_INVITE), 'I', B_COMMAND_KEY);
invite->SetEnabled(false);
BMenuItem* newRoom = new BMenuItem("New room" B_UTF8_ELLIPSIS,
new BMessage(), 'N', B_COMMAND_KEY);
newRoom->SetEnabled(false);
chatMenu->AddItem(new BMenuItem("Join room" B_UTF8_ELLIPSIS,
new BMessage(CAYA_JOIN_CHAT), 'J', B_COMMAND_KEY));
chatMenu->AddSeparatorItem();
chatMenu->AddItem(new BMenuItem("New chat" B_UTF8_ELLIPSIS,
new BMessage(CAYA_NEW_CHAT), 'M', B_COMMAND_KEY));
chatMenu->AddItem(newRoom);
chatMenu->AddSeparatorItem();
chatMenu->AddItem(invite);
chatMenu->SetTargetForItems(this);

View File

@ -41,6 +41,7 @@ SRCS = \
application/Conversation.cpp \
application/EditingFilter.cpp \
application/ImageCache.cpp \
application/JoinWindow.cpp \
application/Main.cpp \
application/MainWindow.cpp \
application/Notifier.cpp \

View File

@ -245,6 +245,15 @@ Server::ImMessage(BMessage* msg)
break;
}
case IM_JOIN_ROOM:
{
SendProtocolMessage(msg);
break;
}
case IM_ROOM_JOINED:
{
break;
}
case IM_SEND_MESSAGE:
{
// Route this message through the appropriate ProtocolLooper
@ -348,6 +357,7 @@ Server::AddProtocolLooper(bigtime_t instanceId, CayaProtocol* cayap)
{
ProtocolLooper* looper = new ProtocolLooper(cayap);
fLoopers.AddItem(instanceId, looper);
fAccounts.AddItem(cayap->GetName(), instanceId);
}
@ -357,6 +367,21 @@ Server::RemoveProtocolLooper(bigtime_t instanceId)
}
ProtocolLooper*
Server::GetProtocolLooper(bigtime_t instanceId)
{
bool found = false;
return fLoopers.ValueFor(instanceId, &found);
}
AccountInstances
Server::GetAccounts()
{
return fAccounts;
}
void
Server::SendProtocolMessage(BMessage* msg)
{

View File

@ -25,6 +25,7 @@ typedef KeyMap<BString, Contact*> RosterMap;
typedef KeyMap<BString, User*> UserMap;
typedef KeyMap<BString, Conversation*> ChatMap;
typedef KeyMap<bigtime_t, ProtocolLooper*> ProtocolLoopers;
typedef KeyMap<BString, bigtime_t> AccountInstances;
class Server: public BMessageFilter {
@ -39,6 +40,10 @@ public:
void AddProtocolLooper(bigtime_t instanceId,
CayaProtocol* cayap);
void RemoveProtocolLooper(bigtime_t instanceId);
ProtocolLooper* GetProtocolLooper(bigtime_t instanceId);
AccountInstances
GetAccounts();
void SendProtocolMessage(BMessage* msg);
void SendAllProtocolMessage(BMessage* msg);
@ -71,6 +76,8 @@ private:
UserMap fUserMap;
ChatMap fChatMap;
ProtocolLoopers fLoopers;
AccountInstances
fAccounts;
BString fMySelf;
};