Show/receive room subjects, show protocol icon in conversation view

The conversation view now displays the protocol icon and room subject.
Messages for receiving room names (IM_ROOM_NAME) and subjects
(IM_ROOM_SUBJECT) were added, and support for the latter was given to
the XMPP add-on.

New message APIs were added, and several (room-related) im_what values were
moved into the 150s/160s.

UserItem::_TintColor() was moved to CayaUtils, because it can be used in
several different contexts.
This commit is contained in:
Jaidyn Ann 2021-06-04 13:57:04 -05:00
parent e00164c1aa
commit 89905fe23c
12 changed files with 186 additions and 135 deletions

View File

@ -73,29 +73,6 @@ enum im_what_code {
IM_LOGS_RECEIVED = 28, IM_LOGS_RECEIVED = 28,
/*
* Messages related to rooms
*/
//! Create an individual chat
IM_CREATE_CHAT = 30,
//! Chat has been created
IM_CHAT_CREATED = 31,
//! Join a room
IM_JOIN_ROOM = 32,
//! 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. * Messages related to contact changes.
*/ */
@ -197,6 +174,44 @@ enum im_what_code {
//! Notifications //! Notifications
IM_NOTIFICATION = 141, IM_NOTIFICATION = 141,
/*
* Room membership
*/
//! Create an individual chat
IM_CREATE_CHAT = 150,
//! Chat has been created
IM_CHAT_CREATED = 151,
//! Join a room
IM_JOIN_ROOM = 152,
//! Confirm the room's been joined
IM_ROOM_JOINED = 153,
//! Quietly add a user(s) to the chat
IM_ROOM_PARTICIPANTS = 154,
//! User has newly and explicitly joined
IM_ROOM_PARTICIPANT_JOINED = 155,
//! A user left the room
IM_ROOM_PARTICIPANT_LEFT = 156,
/*
* Room metadata
*/
//! Room name
IM_ROOM_NAME = 160,
//! Room subject
IM_ROOM_SUBJECT = 161,
/* /*
* Special messages * Special messages
*/ */

View File

@ -9,6 +9,7 @@
#include <memory.h> #include <memory.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <InterfaceDefs.h>
#include <Directory.h> #include <Directory.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <IconUtils.h> #include <IconUtils.h>
@ -145,6 +146,35 @@ CayaLogPath(const char* signature, const char* subsignature)
} }
rgb_color
CayaTintColor(rgb_color color, int severity)
{
bool dark = false;
if (color.Brightness() < 127)
dark = true;
switch (severity)
{
case 1:
if (dark == true)
return tint_color(color, B_LIGHTEN_1_TINT + 0.2f);
else
return tint_color(color, B_DARKEN_1_TINT);
case 2:
if (dark == true)
return tint_color(color, B_LIGHTEN_1_TINT);
else
return tint_color(color, B_DARKEN_2_TINT);
case 3:
if (dark == true)
return tint_color(color, B_LIGHTEN_2_TINT + 0.1f);
else
return tint_color(color, B_DARKEN_3_TINT);
}
return color;
}
extern "C" { extern "C" {
status_t status_t

View File

@ -7,6 +7,7 @@
#include <image.h> #include <image.h>
#include <GraphicsDefs.h>
#include <Mime.h> #include <Mime.h>
#include <Resources.h> #include <Resources.h>
@ -23,6 +24,11 @@ const char* CayaAccountPath(const char* signature, const char* subsignature);
const char* CayaCachePath(); const char* CayaCachePath();
const char* CayaLogPath(const char* signature, const char* subsignature); const char* CayaLogPath(const char* signature, const char* subsignature);
// Will return a tinted color― light or dark― based on brightness.
rgb_color CayaTintColor(rgb_color color, int severity);
extern "C" status_t our_image(image_info& image); extern "C" status_t our_image(image_info& image);
#endif // _CAYA_UTILS_H #endif // _CAYA_UTILS_H

View File

@ -16,6 +16,7 @@
#include "ConversationItem.h" #include "ConversationItem.h"
#include "ConversationView.h" #include "ConversationView.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "NotifyMessage.h"
#include "ProtocolLooper.h" #include "ProtocolLooper.h"
#include "ProtocolManager.h" #include "ProtocolManager.h"
#include "Server.h" #include "Server.h"
@ -29,6 +30,7 @@ Conversation::Conversation(BString id, BMessenger msgn)
fMessenger(msgn), fMessenger(msgn),
fChatView(NULL), fChatView(NULL),
fLooper(NULL), fLooper(NULL),
fIcon(NULL),
fDateFormatter() fDateFormatter()
{ {
fConversationItem = new ConversationItem(fName.String(), this); fConversationItem = new ConversationItem(fName.String(), this);
@ -96,6 +98,16 @@ Conversation::ObservePointer(int32 what, void* ptr)
} }
void
Conversation::SetNotifySubject(const char* subject)
{
if (BString(subject) == fSubject)
return;
fSubject = subject;
NotifyString(STR_ROOM_SUBJECT, fSubject.String());
}
BMessenger BMessenger
Conversation::Messenger() const Conversation::Messenger() const
@ -125,6 +137,24 @@ Conversation::SetProtocolLooper(ProtocolLooper* looper)
} }
BBitmap*
Conversation::ProtocolBitmap() const
{
CayaProtocol* protocol = fLooper->Protocol();
CayaProtocolAddOn* addOn
= ProtocolManager::Get()->ProtocolAddOn(protocol->Signature());
return addOn->ProtoIcon();
}
BBitmap*
Conversation::IconBitmap() const
{
return fIcon;
}
BString BString
Conversation::GetName() const Conversation::GetName() const
{ {

View File

@ -15,6 +15,7 @@
#include "Server.h" #include "Server.h"
#include "User.h" #include "User.h"
class BBitmap;
class ConversationItem; class ConversationItem;
class ConversationView; class ConversationView;
class ProtocolLooper; class ProtocolLooper;
@ -37,12 +38,17 @@ public:
void ObserveInteger(int32 what, int32 value); void ObserveInteger(int32 what, int32 value);
void ObservePointer(int32 what, void* ptr); void ObservePointer(int32 what, void* ptr);
void SetNotifySubject(const char* subject);
BMessenger Messenger() const; BMessenger Messenger() const;
void SetMessenger(BMessenger messenger); void SetMessenger(BMessenger messenger);
ProtocolLooper* GetProtocolLooper() const; ProtocolLooper* GetProtocolLooper() const;
void SetProtocolLooper(ProtocolLooper* looper); void SetProtocolLooper(ProtocolLooper* looper);
BBitmap* ProtocolBitmap() const;
BBitmap* IconBitmap() const;
void ShowView(bool typing, bool userAction); void ShowView(bool typing, bool userAction);
ConversationView* GetView(); ConversationView* GetView();
@ -71,6 +77,9 @@ private:
BString fID; BString fID;
BString fName; BString fName;
BString fSubject;
BBitmap* fIcon;
BPath fLogPath; BPath fLogPath;
BDateTimeFormat fDateFormatter; BDateTimeFormat fDateFormatter;

View File

@ -8,6 +8,7 @@
enum { enum {
STR_CONTACT_NAME, STR_CONTACT_NAME,
STR_PERSONAL_STATUS, STR_PERSONAL_STATUS,
STR_ROOM_SUBJECT,
PTR_AVATAR_BITMAP, PTR_AVATAR_BITMAP,

View File

@ -285,6 +285,16 @@ Server::ImMessage(BMessage* msg)
chat->RemoveUser(user); chat->RemoveUser(user);
break; break;
} }
case IM_ROOM_SUBJECT:
{
BString subject;
Conversation* chat = _EnsureConversation(msg);
if (msg->FindString("subject", &subject) != B_OK || chat == NULL)
break;
chat->SetNotifySubject(subject.String());
break;
}
case IM_SEND_MESSAGE: case IM_SEND_MESSAGE:
{ {
// Route this message through the appropriate ProtocolLooper // Route this message through the appropriate ProtocolLooper

View File

@ -21,6 +21,7 @@
#include "CayaPreferences.h" #include "CayaPreferences.h"
#include "CayaProtocolMessages.h" #include "CayaProtocolMessages.h"
#include "CayaRenderView.h" #include "CayaRenderView.h"
#include "CayaUtils.h"
#include "Conversation.h" #include "Conversation.h"
#include "NotifyMessage.h" #include "NotifyMessage.h"
#include "User.h" #include "User.h"
@ -133,10 +134,6 @@ ConversationView::ImMessage(BMessage* msg)
} }
_AppendOrEnqueueMessage(msg); _AppendOrEnqueueMessage(msg);
// Message received, clear status anyway
// fStatus->SetText("");
break; break;
} }
case IM_MESSAGE_SENT: case IM_MESSAGE_SENT:
@ -145,17 +142,6 @@ ConversationView::ImMessage(BMessage* msg)
_AppendOrEnqueueMessage(msg); _AppendOrEnqueueMessage(msg);
break; break;
} }
case IM_CONTACT_STARTED_TYPING:
fStatus->SetText("Contact is typing...");
break;
case IM_CONTACT_STOPPED_TYPING:
fStatus->SetText("");
break;
case IM_CONTACT_GONE:
fStatus->SetText("Contact closed the chat window!");
snooze(10000);
fStatus->SetText("");
break;
default: default:
break; break;
} }
@ -173,24 +159,16 @@ void
ConversationView::SetConversation(Conversation* chat) ConversationView::SetConversation(Conversation* chat)
{ {
fConversation = chat; fConversation = chat;
fContact = chat->Users().ValueAt(0); fNameTextView->SetText(chat->GetName());
fPersonalMessage->SetText(chat->GetName()); fProtocolView->SetBitmap(chat->ProtocolBitmap());
} }
void void
ConversationView::UpdateAvatar() ConversationView::UpdateIcon()
{ {
if (fContact->AvatarBitmap() != NULL) if (fConversation->IconBitmap() != NULL)
fAvatar->SetBitmap(fContact->AvatarBitmap()); fIcon->SetBitmap(fConversation->IconBitmap());
}
void
ConversationView::UpdatePersonalMessage()
{
if (fContact->GetNotifyPersonalStatus() != NULL)
fPersonalMessage->SetText(fContact->GetNotifyPersonalStatus());
} }
@ -217,18 +195,14 @@ ConversationView::InvalidateUserList()
void void
ConversationView::ObserveString(int32 what, BString str) ConversationView::ObserveString(int32 what, BString str)
{ {
} switch (what)
void
ConversationView::ObservePointer(int32 what, void* ptr)
{ {
} case STR_ROOM_SUBJECT:
void
ConversationView::ObserveInteger(int32 what, int32 val)
{ {
fSubjectTextView->SetText(str);
break;
}
}
} }
@ -239,20 +213,18 @@ ConversationView::_InitInterface()
BScrollView* scrollViewReceive = new BScrollView("receiveScrollView", BScrollView* scrollViewReceive = new BScrollView("receiveScrollView",
fReceiveView, B_WILL_DRAW, false, true); fReceiveView, B_WILL_DRAW, false, true);
fPersonalMessage = new BTextView("personalMessage", B_WILL_DRAW); fNameTextView = new BTextView("roomName", B_WILL_DRAW);
fPersonalMessage->SetExplicitAlignment( fNameTextView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
BAlignment(B_ALIGN_LEFT, B_ALIGN_MIDDLE)); fNameTextView->MakeEditable(false);
fPersonalMessage->SetText(""); fSubjectTextView = new BTextView("roomSubject", B_WILL_DRAW);
fPersonalMessage->MakeEditable(false); fSubjectTextView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
fPersonalMessage->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); fSubjectTextView->MakeEditable(false);
fStatus = new BStringView("status", ""); fIcon = new BitmapView("ContactIcon");
fIcon->SetExplicitMinSize(BSize(50, 50));
fAvatar = new BitmapView("ContactIcon"); fIcon->SetExplicitPreferredSize(BSize(50, 50));
fAvatar->SetExplicitMinSize(BSize(50, 50)); fIcon->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE));
fAvatar->SetExplicitPreferredSize(BSize(50, 50));
fAvatar->SetExplicitAlignment(BAlignment(B_ALIGN_RIGHT, B_ALIGN_MIDDLE));
fProtocolView = new BitmapView("protocolView"); fProtocolView = new BitmapView("protocolView");
@ -262,15 +234,17 @@ ConversationView::_InitInterface()
BLayoutBuilder::Group<>(this, B_VERTICAL) BLayoutBuilder::Group<>(this, B_VERTICAL)
.AddGroup(B_HORIZONTAL) .AddGroup(B_HORIZONTAL)
.Add(fIcon)
.AddGroup(B_VERTICAL)
.Add(fNameTextView)
.Add(fSubjectTextView)
.End()
.Add(fProtocolView) .Add(fProtocolView)
.Add(fPersonalMessage)
.Add(fAvatar)
.End() .End()
.AddSplit(B_HORIZONTAL, 0) .AddSplit(B_HORIZONTAL, 0)
.Add(scrollViewReceive, 5) .Add(scrollViewReceive, 5)
.Add(scrollViewUsers, 1) .Add(scrollViewUsers, 1)
.End(); .End();
// .Add(fStatus, 4)
} }

View File

@ -35,15 +35,12 @@ public:
Conversation* GetConversation(); Conversation* GetConversation();
void SetConversation(Conversation* chat); void SetConversation(Conversation* chat);
void UpdateAvatar(); void UpdateIcon();
void UpdatePersonalMessage();
void UpdateUserList(UserMap users); void UpdateUserList(UserMap users);
void InvalidateUserList(); void InvalidateUserList();
void ObserveString(int32 what, BString str); void ObserveString(int32 what, BString str);
void ObservePointer(int32 what, void* ptr);
void ObserveInteger(int32 what, int32 val);
void AvoidFocus(bool avoid); void AvoidFocus(bool avoid);
@ -54,15 +51,15 @@ private:
void _AppendMessage(BMessage* msg); void _AppendMessage(BMessage* msg);
Conversation* fConversation; Conversation* fConversation;
User* fContact;
int32 fMessageCount; int32 fMessageCount;
BObjectList<BMessage> fMessageQueue; BObjectList<BMessage> fMessageQueue;
CayaRenderView* fReceiveView; BTextView* fNameTextView;
BStringView* fStatus; BTextView* fSubjectTextView;
BTextView* fPersonalMessage;
BitmapView* fProtocolView; BitmapView* fProtocolView;
BitmapView* fAvatar; BitmapView* fIcon;
CayaRenderView* fReceiveView;
UserListView* fUserList; UserListView* fUserList;
}; };

View File

@ -9,6 +9,7 @@
#include <View.h> #include <View.h>
#include "CayaConstants.h" #include "CayaConstants.h"
#include "CayaUtils.h"
#include "NotifyMessage.h" #include "NotifyMessage.h"
#include "User.h" #include "User.h"
@ -17,9 +18,8 @@ UserItem::UserItem(const char* name, User* user, int32 status)
: :
BStringItem(name), BStringItem(name),
fUser(user), fUser(user),
fTextColor(ui_color(B_LIST_ITEM_TEXT_COLOR)) fStatus(status)
{ {
_UpdateColor(status);
} }
@ -27,7 +27,7 @@ void
UserItem::DrawItem(BView* owner, BRect frame, bool complete) UserItem::DrawItem(BView* owner, BRect frame, bool complete)
{ {
rgb_color highColor = owner->HighColor(); rgb_color highColor = owner->HighColor();
owner->SetHighColor(fTextColor); owner->SetHighColor(_GetTextColor(highColor));
BStringItem::DrawItem(owner, frame, complete); BStringItem::DrawItem(owner, frame, complete);
@ -52,7 +52,7 @@ UserItem::ObserveInteger(int32 what, int32 value)
switch (what) { switch (what) {
case INT_CONTACT_STATUS: case INT_CONTACT_STATUS:
{ {
_UpdateColor(value); fStatus = value;
break; break;
} }
} }
@ -66,54 +66,20 @@ UserItem::GetUser()
} }
void rgb_color
UserItem::_UpdateColor(int32 status) UserItem::_GetTextColor(rgb_color highColor)
{ {
switch (status) switch (fStatus)
{ {
case CAYA_AWAY: case CAYA_AWAY:
fTextColor = _TintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 1); return CayaTintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 1);
break;
case CAYA_INVISIBLE: case CAYA_INVISIBLE:
case CAYA_DO_NOT_DISTURB: case CAYA_DO_NOT_DISTURB:
fTextColor = _TintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 2); return CayaTintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 2);
break;
case CAYA_OFFLINE: case CAYA_OFFLINE:
fTextColor = _TintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 3); return CayaTintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 3);
break;
default:
fTextColor = ui_color(B_LIST_ITEM_TEXT_COLOR);
}
}
rgb_color
UserItem::_TintColor(rgb_color color, int severity)
{
bool dark = false;
if (color.Brightness() < 127)
dark = true;
switch (severity)
{
case 0:
return color;
case 1:
if (dark == true)
return tint_color(color, B_LIGHTEN_1_TINT + 0.2f);
else
return tint_color(color, B_DARKEN_1_TINT);
case 2:
if (dark == true)
return tint_color(color, B_LIGHTEN_1_TINT);
else
return tint_color(color, B_DARKEN_2_TINT);
case 3:
if (dark == true)
return tint_color(color, B_LIGHTEN_2_TINT + 0.1f);
else
return tint_color(color, B_DARKEN_3_TINT);
} }
return highColor;
} }

View File

@ -25,12 +25,11 @@ public:
User* GetUser(); User* GetUser();
protected: protected:
void _UpdateColor(int32 status); rgb_color _GetTextColor(rgb_color highColor);
rgb_color _TintColor(rgb_color color, int severity);
private: private:
rgb_color fTextColor;
User* fUser; User* fUser;
int fStatus;
}; };

View File

@ -1207,6 +1207,20 @@ void
JabberHandler::handleMUCSubject(gloox::MUCRoom *room, const std::string &nick, JabberHandler::handleMUCSubject(gloox::MUCRoom *room, const std::string &nick,
const std::string &subject) const std::string &subject)
{ {
BString user_id;
BString chat_id = _MUCChatId(room);
bool isSelf = _MUCUserId(chat_id, nick.c_str(), &user_id);
if (chat_id.IsEmpty() == true)
return;
BMessage msg(IM_MESSAGE);
msg.AddInt32("im_what", IM_ROOM_SUBJECT);
msg.AddString("subject", subject.c_str());
msg.AddString("chat_id", chat_id);
if (user_id.IsEmpty() == false)
msg.AddString("user_id", user_id);
_SendMessage(&msg);
} }