From 89ff195c8dbe321d468f4a4ce92ddb1c5a17ac53 Mon Sep 17 00:00:00 2001 From: Jaidyn Ann Date: Thu, 29 Jul 2021 22:00:01 -0500 Subject: [PATCH] Set room topic/name through conversation view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user has permission to change a room's subject or name, they can now edit the text views displaying them (toward the top of the window). When enter is pressed, the changes will be sent to the protocol. To do this, a BTextView subclass was added to libinterface (splitting somewhat from SendTextView)― EnterTextView sends a message containing the text to the given target when the user hits enter sans modifiers. --- application/Conversation.cpp | 36 +++++++++++++-- application/Conversation.h | 4 +- application/Server.cpp | 63 +++----------------------- application/Server.h | 2 - application/views/ConversationView.cpp | 45 +++++++++++++++++- application/views/ConversationView.h | 6 +-- application/views/SendTextView.cpp | 8 ++-- application/views/SendTextView.h | 5 +- libs/libinterface/EnterTextView.cpp | 51 +++++++++++++++++++++ libs/libinterface/EnterTextView.h | 31 +++++++++++++ libs/libinterface/Makefile | 1 + 11 files changed, 176 insertions(+), 76 deletions(-) create mode 100644 libs/libinterface/EnterTextView.cpp create mode 100644 libs/libinterface/EnterTextView.h 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