Highlight room list-items, auto-scroll in chat

When a new message is posted (or the user is messaged), the room's item
in the roomlist is now highlighted, like Vision.

Chat also auto-scrolls when new messages are posted.
This commit is contained in:
Jaidyn Ann 2021-07-17 00:23:56 -05:00
parent fe4d0661a7
commit 6f73db12b7
7 changed files with 92 additions and 22 deletions

View File

@ -39,7 +39,8 @@ Conversation::Conversation(BString id, BMessenger msgn)
fDateFormatter(),
fRoomFlags(0),
fDisallowedFlags(0),
fNotifyCount(0)
fNotifyMessageCount(0),
fNotifyMentionCount(0)
{
fConversationItem = new ConversationItem(fName.String(), this);
RegisterObserver(fConversationItem);
@ -81,29 +82,34 @@ Conversation::ImMessage(BMessage* msg)
BString text = msg->FindString("body");
Contact* contact = GetOwnContact();
BWindow* win = fChatView->Window();
bool winFocused = (win != NULL &&
(win->IsFront() && !(win->IsMinimized())));
bool mentioned = ((text.IFindFirst(contact->GetName()) != B_ERROR)
|| (text.IFindFirst(contact->GetName()) != B_ERROR));
// Send a notification, if it's appropriate
BWindow* win = fChatView->Window();
if ((win == NULL || !win->IsFront() || win->IsMinimized())
&& AppPreferences::Item()->NotifyNewMessage
&& (fUsers.CountItems() <= 2 || mentioned))
// Send a notification, if appropriate
if (winFocused == false && AppPreferences::Item()->NotifyNewMessage
&& (fUsers.CountItems() <= 2 || mentioned == true))
{
fNotifyCount++;
BString notifyTitle = "New mention";
BString notifyText = "You've been summoned from %source%.";
if (mentioned == false) {
fNotifyMessageCount++;
notifyTitle.SetTo("New message");
notifyText.SetTo("");
BStringFormat pmFormat("{0, plural,"
"=1{You've got a new message from %source%.}"
"other{You've got # new messages from %source%.}}");
pmFormat.Format(notifyText, fNotifyCount);
pmFormat.Format(notifyText, fNotifyMessageCount);
}
else
fNotifyMentionCount++;
notifyText.ReplaceAll("%source%", GetName());
BBitmap* icon = IconBitmap();
@ -119,6 +125,13 @@ Conversation::ImMessage(BMessage* msg)
notification.SetMessageID(fID);
notification.Send();
}
// If unattached, highlight the ConversationItem
if (win == NULL && mentioned == true)
NotifyInteger(INT_NEW_MENTION, fNotifyMentionCount);
else if (win == NULL)
NotifyInteger(INT_NEW_MESSAGE, fNotifyMessageCount);
break;
}
case IM_MESSAGE_SENT:
@ -215,6 +228,11 @@ Conversation::ObserveString(int32 what, BString str)
void
Conversation::ObserveInteger(int32 what, int32 value)
{
if (what == INT_WINDOW_FOCUSED) {
fNotifyMessageCount = 0;
fNotifyMentionCount = 0;
}
else
GetView()->InvalidateUserList();
}
@ -316,6 +334,9 @@ Conversation::GetView()
return fChatView;
fChatView = new ConversationView(this);
fChatView->RegisterObserver(fConversationItem);
fChatView->RegisterObserver(this);
RegisterObserver(fChatView);
if (!(fRoomFlags & ROOM_POPULATE_LOGS))
return fChatView;
@ -324,7 +345,6 @@ Conversation::GetView()
if (_GetChatLogs(&logMsg) == B_OK)
fChatView->MessageReceived(&logMsg);
RegisterObserver(fChatView);
return fChatView;
}

View File

@ -90,7 +90,8 @@ private:
ProtocolLooper* fLooper;
ConversationView* fChatView;
ConversationItem* fConversationItem;
int32 fNotifyCount;
int32 fNotifyMessageCount;
int32 fNotifyMentionCount;
BString fID;
BString fName;

View File

@ -15,7 +15,10 @@ enum {
INT_ACCOUNT_STATUS,
INT_CONTACT_STATUS,
INT_USER_PERMS
INT_USER_PERMS,
INT_NEW_MESSAGE,
INT_NEW_MENTION,
INT_WINDOW_FOCUSED
};
#endif // _NOTIFY_MESSAGE_H

View File

@ -5,18 +5,42 @@
#include "ConversationItem.h"
#include <InterfaceDefs.h>
#include <View.h>
#include "Conversation.h"
#include "NotifyMessage.h"
#include "Utils.h"
const int8 kMentioned = 1;
const int8 kMessage = 2;
ConversationItem::ConversationItem(const char* name, Conversation* chat)
:
BStringItem(name),
fChat(chat)
fChat(chat),
fStatus(0)
{
}
void
ConversationItem::DrawItem(BView* owner, BRect frame, bool complete)
{
rgb_color old = owner->HighColor();
if (fStatus & kMentioned)
owner->SetHighUIColor(B_SUCCESS_COLOR);
else if (fStatus & kMessage)
owner->SetHighColor(TintColor(ui_color(B_LIST_ITEM_TEXT_COLOR), 2));
BStringItem::DrawItem(owner, frame, complete);
owner->SetHighColor(old);
}
Conversation*
ConversationItem::GetConversation()
{
@ -36,3 +60,19 @@ ConversationItem::ObserveString(int32 what, BString str)
}
void
ConversationItem::ObserveInteger(int32 what, int32 num)
{
switch (what)
{
case INT_NEW_MESSAGE:
fStatus |= kMessage;
break;
case INT_NEW_MENTION:
fStatus |= kMentioned;
break;
case INT_WINDOW_FOCUSED:
fStatus = 0;
break;
}
}

View File

@ -2,8 +2,8 @@
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef CONVERSATIONITEM_H
#define CONVERSATIONITEM_H
#ifndef _CONVERSATION_ITEM_H
#define _CONVERSATION_ITEM_H
#include <StringItem.h>
@ -16,14 +16,16 @@ class ConversationItem : public BStringItem, public Observer {
public:
ConversationItem(const char* name, Conversation* chat);
virtual void DrawItem(BView* owner, BRect frame, bool complete=false);
Conversation* GetConversation();
protected:
void ObserveString(int32 what, BString str);
void ObserveInteger(int32 what, int32 num);
private:
Conversation* fChat;
int8 fStatus;
};
#endif // CONVERSATIONITEM_H
#endif // _CONVERSATION_ITEM_H

View File

@ -79,6 +79,7 @@ ConversationView::AttachedToWindow()
if (fSubjectTextView->Text() != fConversation->GetSubject())
fSubjectTextView->SetText(fConversation->GetSubject());
}
NotifyInteger(INT_WINDOW_FOCUSED, 0);
}
@ -129,11 +130,14 @@ ConversationView::ImMessage(BMessage* msg)
case IM_MESSAGE_RECEIVED:
{
_AppendOrEnqueueMessage(msg);
fReceiveView->ScrollToBottom();
break;
}
case IM_MESSAGE_SENT:
case IM_LOGS_RECEIVED:
{
if (im_what == IM_MESSAGE_SENT)
fReceiveView->ScrollToBottom();
_AppendOrEnqueueMessage(msg);
break;
}

View File

@ -22,7 +22,7 @@ class User;
class UserListView;
class ConversationView : public BGroupView, public Observer {
class ConversationView : public BGroupView, public Observer, public Notifier {
public:
ConversationView();
ConversationView(Conversation* chat);