diff --git a/application/Conversation.cpp b/application/Conversation.cpp index ddc2f1b..407a2c7 100644 --- a/application/Conversation.cpp +++ b/application/Conversation.cpp @@ -222,6 +222,17 @@ Conversation::ImMessage(BMessage* msg) RemoveUser(user); break; } + case IM_ROOM_ROLECHANGED: + { + BString user_id; + Role* role = _GetRole(msg); + if (msg->FindString("user_id", &user_id) != B_OK || role == NULL) + break; + + SetRole(user_id, role); + GetView()->MessageReceived(msg); + break; + } case IM_LOGS_RECEIVED: default: GetView()->MessageReceived(msg); @@ -437,7 +448,6 @@ Conversation::SetRole(BString id, Role* role) fRoles.RemoveItemFor(id); delete oldRole; } - fRoles.AddItem(id, role); } @@ -579,7 +589,7 @@ Conversation::_EnsureUser(BMessage* msg) user = serverUser; GetView()->UpdateUserList(fUsers); - _CloneUserIcon(user); + _AdoptUserIcon(user); } // Not anywhere; create user else if (user == NULL) { @@ -590,7 +600,7 @@ Conversation::_EnsureUser(BMessage* msg) fUsers.AddItem(id, user); GetView()->UpdateUserList(fUsers); - _CloneUserIcon(user); + _AdoptUserIcon(user); } if (name.IsEmpty() == false) { @@ -601,8 +611,26 @@ Conversation::_EnsureUser(BMessage* msg) } +Role* +Conversation::_GetRole(BMessage* msg) +{ + if (!msg) + return NULL; + BString title; + int32 perms; + int32 priority; + + if (msg->FindString("role_title", &title) != B_OK + || msg->FindInt32("role_perms", &perms) != B_OK + || msg->FindInt32("role_priority", &priority) != B_OK) + return NULL; + + return new Role(title, perms, priority); +} + + void -Conversation::_CloneUserIcon(User* user) +Conversation::_AdoptUserIcon(User* user) { // If it's a one-on-one chat without custom icon, steal a user's if ((fUsers.CountItems() <= 2 && user->GetId() != GetOwnContact()->GetId()) diff --git a/application/Conversation.h b/application/Conversation.h index 9979bd9..ed1d05d 100644 --- a/application/Conversation.h +++ b/application/Conversation.h @@ -85,7 +85,9 @@ private: void _EnsureCachePath(); User* _EnsureUser(BMessage* msg); - void _CloneUserIcon(User* user); + Role* _GetRole(BMessage* msg); + + void _AdoptUserIcon(User* user); void _SortConversationList(); diff --git a/application/Server.cpp b/application/Server.cpp index f54e5d2..16526a0 100644 --- a/application/Server.cpp +++ b/application/Server.cpp @@ -388,14 +388,6 @@ Server::ImMessage(BMessage* msg) SendProtocolMessage(msg); break; } - case IM_ROOM_CREATED: - case IM_ROOM_JOINED: - { - Conversation* chat = _EnsureConversation(msg); - if (chat != NULL) - chat->ImMessage(msg); - break; - } case IM_ROOM_PARTICIPANTS: { Conversation* chat = _EnsureConversation(msg); @@ -417,44 +409,28 @@ Server::ImMessage(BMessage* msg) } break; } + case IM_MESSAGE_SENT: + case IM_MESSAGE_RECEIVED: + case IM_ROOM_JOINED: + case IM_ROOM_CREATED: + case IM_ROOM_METADATA: + case IM_ROOM_ROLECHANGED: case IM_ROOM_PARTICIPANT_JOINED: case IM_ROOM_PARTICIPANT_LEFT: case IM_ROOM_PARTICIPANT_BANNED: case IM_ROOM_PARTICIPANT_KICKED: - { - Conversation* chat = _EnsureConversation(msg); - if (chat == NULL) - break; - chat->ImMessage(msg); - break; - } - case IM_ROOM_METADATA: { Conversation* chat = _EnsureConversation(msg); if (chat != NULL) chat->ImMessage(msg); break; } - case IM_ROOM_ROLECHANGED: - { - Conversation* chat = _EnsureConversation(msg); - BString user_id; - Role* role = _GetRole(msg); - - if (chat == NULL || msg->FindString("user_id", &user_id) != B_OK - || role == NULL) - break; - - chat->SetRole(user_id, role); - break; - } case IM_ROOM_NAME_SET: { BString name; Conversation* chat = _EnsureConversation(msg); if (msg->FindString("chat_name", &name) != B_OK || chat == NULL) break; - chat->SetNotifyName(name.String()); break; } @@ -464,7 +440,6 @@ Server::ImMessage(BMessage* msg) Conversation* chat = _EnsureConversation(msg); if (msg->FindString("subject", &subject) != B_OK || chat == NULL) break; - chat->SetNotifySubject(subject.String()); break; } @@ -476,13 +451,6 @@ Server::ImMessage(BMessage* msg) conversation->GetProtocolLooper()->PostMessage(msg); break; } - case IM_MESSAGE_SENT: - case IM_MESSAGE_RECEIVED: - { - Conversation* item = _EnsureConversation(msg); - item->ImMessage(msg); - break; - } case IM_ROOM_INVITE_RECEIVED: { BString chat_id; @@ -987,25 +955,6 @@ Server::_EnsureConversation(BMessage* message) } -Role* -Server::_GetRole(BMessage* msg) -{ - if (!msg) - return NULL; - - BString title; - int32 perms; - int32 priority; - - if (msg->FindString("role_title", &title) != B_OK - || msg->FindInt32("role_perms", &perms) != B_OK - || msg->FindInt32("role_priority", &priority) != B_OK) - return NULL; - - return new Role(title, perms, priority); -} - - void Server::_ProtocolNotification(ProtocolLooper* looper, BString title, BString desc, notification_type type) diff --git a/application/Server.h b/application/Server.h index 6d1c8ac..2ce1be1 100644 --- a/application/Server.h +++ b/application/Server.h @@ -77,8 +77,6 @@ private: Contact* _GetOwnContact(BMessage* message); Conversation* _EnsureConversation(BMessage* message); - Role* _GetRole(BMessage* msg); - void _ProtocolNotification(ProtocolLooper* looper, BString title, BString desc, notification_type type=B_INFORMATION_NOTIFICATION); diff --git a/application/views/ConversationView.cpp b/application/views/ConversationView.cpp index b14dd85..2bfd8a7 100644 --- a/application/views/ConversationView.cpp +++ b/application/views/ConversationView.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "AppMessages.h" #include "AppPreferences.h" @@ -185,6 +186,33 @@ ConversationView::ImMessage(BMessage* msg) msg); break; } + case IM_ROOM_ROLECHANGED: + { + BString user_id = msg->FindString("user_id"); + + if (user_id == fConversation->GetOwnContact()->GetId()) { + Role* role = fConversation->GetRole(user_id); + if (role == NULL) + break; + int32 perms = role->fPerms; + fNameTextView->MakeEditable(perms & PERM_ROOM_NAME); + fSubjectTextView->MakeEditable(perms & PERM_ROOM_SUBJECT); + } + break; + } + case IM_SET_ROOM_NAME: + case IM_SET_ROOM_SUBJECT: + { + if (fConversation == NULL) + return; + fConversation->GetProtocolLooper()->MessageReceived(msg); + + // Reset to current values; if the change went through, it'll + // come back. + fNameTextView->SetText(fConversation->GetName()); + fSubjectTextView->SetText(fConversation->GetSubject()); + break; + } case IM_PROTOCOL_READY: { fReceiveView->SetText(""); @@ -209,8 +237,21 @@ ConversationView::SetConversation(Conversation* chat) if (chat == NULL) return; fConversation = chat; + + BMessage name(IM_MESSAGE); + name.AddInt32("im_what", IM_SET_ROOM_NAME); + name.AddString("chat_id", chat->GetId()); fNameTextView->SetText(chat->GetName()); + fNameTextView->SetMessage(name, "chat_name"); + fNameTextView->SetTarget(this); + + BMessage subject(IM_MESSAGE); + subject.AddInt32("im_what", IM_SET_ROOM_SUBJECT); + subject.AddString("chat_id", chat->GetId()); fSubjectTextView->SetText(chat->GetSubject()); + fSubjectTextView->SetMessage(subject, "subject"); + fSubjectTextView->SetTarget(this); + fProtocolView->SetBitmap(chat->ProtocolBitmap()); } @@ -273,13 +314,13 @@ ConversationView::_InitInterface() fSendView = new SendTextView("sendView", this); - fNameTextView = new BTextView("roomName", be_bold_font, NULL, B_WILL_DRAW); + fNameTextView = new EnterTextView("roomName", be_bold_font, NULL, B_WILL_DRAW); fNameTextView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); fNameTextView->SetStylable(true); fNameTextView->MakeEditable(false); fNameTextView->MakeResizable(true); - fSubjectTextView = new BTextView("roomSubject"); + fSubjectTextView = new EnterTextView("roomSubject"); fSubjectTextView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR); fSubjectTextView->MakeEditable(false); fSubjectTextView->MakeResizable(true); diff --git a/application/views/ConversationView.h b/application/views/ConversationView.h index ba4e74d..6267fbb 100644 --- a/application/views/ConversationView.h +++ b/application/views/ConversationView.h @@ -13,9 +13,9 @@ #include "Observer.h" class BStringView; -class BTextView; class BitmapView; +class EnterTextView; class RenderView; class SendTextView; class User; @@ -61,8 +61,8 @@ private: Conversation* fConversation; BObjectList fMessageQueue; - BTextView* fNameTextView; - BTextView* fSubjectTextView; + EnterTextView* fNameTextView; + EnterTextView* fSubjectTextView; BitmapView* fProtocolView; BitmapView* fIcon; diff --git a/application/views/SendTextView.cpp b/application/views/SendTextView.cpp index 439a4c7..65bc091 100644 --- a/application/views/SendTextView.cpp +++ b/application/views/SendTextView.cpp @@ -13,10 +13,12 @@ SendTextView::SendTextView(const char* name, ConversationView* convView) : - BTextView(name), + EnterTextView(name), fConversationView(convView), fCurrentIndex(0) { + SetMessage(BMessage(APP_CHAT)); + SetTarget(convView); } @@ -35,10 +37,8 @@ SendTextView::KeyDown(const char* bytes, int32 numBytes) if ((bytes[0] == B_ENTER) && (modifiers & B_COMMAND_KEY)) Insert("\n"); - else if (bytes[0] == B_ENTER) - fConversationView->MessageReceived(new BMessage(APP_CHAT)); else - BTextView::KeyDown(bytes, numBytes); + EnterTextView::KeyDown(bytes, numBytes); } diff --git a/application/views/SendTextView.h b/application/views/SendTextView.h index 6e12864..21f12ea 100644 --- a/application/views/SendTextView.h +++ b/application/views/SendTextView.h @@ -5,12 +5,12 @@ #ifndef _SEND_TEXT_VIEW_H #define _SEND_TEXT_VIEW_H -#include +#include #include "ConversationView.h" -class SendTextView : public BTextView { +class SendTextView : public EnterTextView { public: SendTextView(const char* name, ConversationView* convView); @@ -25,5 +25,4 @@ private: BString fCurrentWord; }; - #endif // _SEND_TEXT_VIEW_H diff --git a/libs/libinterface/EnterTextView.cpp b/libs/libinterface/EnterTextView.cpp new file mode 100644 index 0000000..669623c --- /dev/null +++ b/libs/libinterface/EnterTextView.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ + +#include "EnterTextView.h" + +#include + + +EnterTextView::EnterTextView(const char* name) + : + BTextView(name), + fTarget(NULL) +{ +} + + +EnterTextView::EnterTextView(const char* name, const BFont* initialFont, + const rgb_color* initialColor, uint32 flags) + : + BTextView(name, initialFont, initialColor, flags), + fTarget(NULL) +{ +} + + +void +EnterTextView::KeyDown(const char* bytes, int32 numBytes) +{ + int32 modifiers = Window()->CurrentMessage()->GetInt32("modifiers", 0); + + if (fTarget != NULL && (bytes[0] == B_ENTER) && (modifiers == 0)) + { + BMessage* msg = new BMessage(fMessage); + if (fTextSlot.IsEmpty() == false) + msg->AddString(fTextSlot.String(), Text()); + fTarget->MessageReceived(msg); + } + else + BTextView::KeyDown(bytes, numBytes); +} + + +void +EnterTextView::SetMessage(BMessage msg, const char* textSlot) +{ + fMessage = msg; + if (textSlot != NULL) + fTextSlot.SetTo(textSlot); +} diff --git a/libs/libinterface/EnterTextView.h b/libs/libinterface/EnterTextView.h new file mode 100644 index 0000000..4c26966 --- /dev/null +++ b/libs/libinterface/EnterTextView.h @@ -0,0 +1,31 @@ +/* + * Copyright 2021, Jaidyn Levesque + * All rights reserved. Distributed under the terms of the MIT license. + */ +#ifndef _ENTER_TEXT_VIEW_H +#define _ENTER_TEXT_VIEW_H + +#include + + +class EnterTextView : public BTextView { +public: + EnterTextView(const char* name); + EnterTextView(const char* name, const BFont* initialFont, + const rgb_color* initialColor, + uint32 flags = B_WILL_DRAW); + + virtual void KeyDown(const char* bytes, int32 numBytes); + + void SetTarget(BHandler* handler) { fTarget = handler; } + + BMessage Message() { return fMessage; } + void SetMessage(BMessage msg, const char* textSlot = NULL); + +private: + BMessage fMessage; + BHandler* fTarget; + BString fTextSlot; +}; + +#endif // _ENTER_TEXT_VIEW_H diff --git a/libs/libinterface/Makefile b/libs/libinterface/Makefile index 44d4d55..da0cf93 100644 --- a/libs/libinterface/Makefile +++ b/libs/libinterface/Makefile @@ -36,6 +36,7 @@ SRCS = \ libs/libinterface/BitmapUtils.cpp \ libs/libinterface/BitmapView.cpp \ libs/libinterface/Divider.cpp \ + libs/libinterface/EnterTextView.cpp \ libs/libinterface/MenuButton.cpp \ libs/libinterface/NotifyingTextView.cpp \ libs/libinterface/PictureView.cpp