Use a single ChatWindow for all conversations

All chats now stay in a single window, which removes and switches its
current ConversationView with the appropriate one using
Conversation::GetView().

This is a stepping-stone to merging the ChatWindow into the MainWindow.
This commit is contained in:
Jaidyn Ann 2021-05-28 22:26:32 -05:00
parent 3ace145248
commit b9d120a8f6
10 changed files with 157 additions and 159 deletions

View File

@ -40,15 +40,14 @@
#include "CayaRenderView.h"
#include "NotifyMessage.h"
ChatWindow::ChatWindow(Conversation* cl)
ChatWindow::ChatWindow()
:
BWindow(BRect(200, 200, 500, 500), "Chat", B_TITLED_WINDOW, 0)
{
fChatView = new ConversationView(cl);
fChatView = new ConversationView();
fSendView = new BTextView("fReceiveView");
BScrollView* scrollViewSend = new BScrollView("scrollviewS", fSendView,
fSendView = new BTextView("fSendView");
fSendScroll = new BScrollView("fSendScroll", fSendView,
B_WILL_DRAW, false, true);
fSendView->SetWordWrap(true);
@ -57,11 +56,34 @@ ChatWindow::ChatWindow(Conversation* cl)
BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(fChatView)
.Add(scrollViewSend)
.Add(fSendScroll)
.End();
}
ChatWindow::ChatWindow(Conversation* cl)
:
ChatWindow()
{
fChatView = new ConversationView(cl);
SetConversation(cl);
}
void
ChatWindow::SetConversation(Conversation* chat)
{
BView* current = FindView("chatView");
RemoveChild(FindView("chatView"));
RemoveChild(FindView("fSendScroll"));
fChatView = chat->GetView();
AddChild(fChatView);
AddChild(fSendScroll);
}
void
ChatWindow::ShowWindow()
{

View File

@ -5,15 +5,16 @@
#ifndef _CHAT_WINDOW_H
#define _CHAT_WINDOW_H
#include <Window.h>
#include <TextView.h>
#include <StringView.h>
#include <Notification.h>
#include "Observer.h"
#include <StringView.h>
#include <TextView.h>
#include <Window.h>
#include "CayaConstants.h"
#include "Observer.h"
class BitmapView;
class BScrollVie;
class Conversation;
class ConversationView;
class CayaRenderView;
@ -22,7 +23,9 @@ class Contact;
class ChatWindow : public BWindow, public Observer {
public:
ChatWindow();
ChatWindow(Conversation* cl);
void SetConversation(Conversation* chat);
virtual void ShowWindow();
@ -37,6 +40,7 @@ public:
void AvoidFocus(bool avoid);
private:
BScrollView* fSendScroll;
BTextView* fSendView;
ConversationView* fChatView;
};

View File

@ -11,9 +11,11 @@
#include "CayaPreferences.h"
#include "CayaProtocolMessages.h"
#include "CayaRenderView.h"
#include "CayaUtils.h"
#include "ChatWindow.h"
#include "ConversationItem.h"
#include "ConversationView.h"
#include "MainWindow.h"
#include "ProtocolLooper.h"
#include "ProtocolManager.h"
@ -27,8 +29,7 @@ Conversation::Conversation(BString id, BMessenger msgn)
fID(id),
fName(id),
fMessenger(msgn),
fChatWindow(NULL),
fNewWindow(true),
fChatView(NULL),
fLooper(NULL),
fDateFormatter()
{
@ -53,11 +54,8 @@ Conversation::ImMessage(BMessage* msg)
case IM_MESSAGE_RECEIVED:
{
_EnsureUser(msg);
_LogChatMessage(msg);
ChatWindow* win = GetChatWindow();
ShowWindow();
win->PostMessage(msg);
GetView()->MessageReceived(msg);
break;
}
case IM_SEND_MESSAGE:
@ -67,7 +65,7 @@ Conversation::ImMessage(BMessage* msg)
break;
}
default:
GetChatWindow()->PostMessage(msg);
GetView()->MessageReceived(msg);
}
}
@ -75,83 +73,32 @@ Conversation::ImMessage(BMessage* msg)
void
Conversation::ObserveString(int32 what, BString str)
{
if (fChatWindow != NULL)
fChatWindow->ObserveString(what, str);
if (fChatView != NULL)
fChatView->ObserveString(what, str);
}
void
Conversation::ObservePointer(int32 what, void* ptr)
{
if (fChatWindow != NULL)
fChatWindow->ObservePointer(what, ptr);
if (fChatView != NULL)
fChatView->ObservePointer(what, ptr);
}
void
Conversation::ObserveInteger(int32 what, int32 val)
{
if (fChatWindow != NULL)
fChatWindow->ObserveInteger(what, val);
}
ChatWindow*
Conversation::GetChatWindow()
{
if (fChatWindow == NULL)
_CreateChatWindow();
return fChatWindow;
if (fChatView != NULL)
fChatView->ObserveInteger(what, val);
}
void
Conversation::DeleteWindow()
Conversation::ShowView(bool typing, bool userAction)
{
if (fChatWindow != NULL) {
if (fChatWindow->Lock()) {
fChatWindow->Quit();
fChatWindow = NULL;
fNewWindow = true;
}
}
}
void
Conversation::ShowWindow(bool typing, bool userAction)
{
if (fChatWindow == NULL)
_CreateChatWindow();
fChatWindow->AvoidFocus(true);
if (CayaPreferences::Item()->MoveToCurrentWorkspace)
fChatWindow->SetWorkspaces(B_CURRENT_WORKSPACE);
if (fNewWindow || userAction) {
fChatWindow->AvoidFocus(false);
fChatWindow->ShowWindow();
fNewWindow = false;
} else {
if (typing) {
if (CayaPreferences::Item()->RaiseUserIsTyping)
fChatWindow->ShowWindow();
} else {
if (CayaPreferences::Item()->RaiseOnMessageReceived
|| fChatWindow->IsHidden())
fChatWindow->ShowWindow();
}
}
fChatWindow->AvoidFocus(false);
}
void
Conversation::HideWindow()
{
if ((fChatWindow != NULL) && !fChatWindow->IsHidden())
fChatWindow->Hide();
((TheApp*)be_app)->GetMainWindow()->GetChatWindow()->SetConversation(this);
((TheApp*)be_app)->GetMainWindow()->GetChatWindow()->ShowWindow();
}
@ -221,20 +168,12 @@ Conversation::AddUser(User* user)
}
void
Conversation::_CreateChatWindow()
ConversationView*
Conversation::GetView()
{
fChatWindow = new ChatWindow(this);
WindowsManager::Get()->RelocateWindow(fChatWindow);
if (fLooper->Protocol()->SaveLogs() == false)
return;
BStringList logs = _GetChatLogs();
BMessage logMsg(IM_MESSAGE);
logMsg.AddInt32("im_what", IM_LOGS_RECEIVED);
logMsg.AddStrings("log", logs);
fChatWindow->ImMessage(&logMsg);
if (fChatView == NULL)
fChatView = new ConversationView(this);
return fChatView;
}

View File

@ -17,6 +17,7 @@
class ChatWindow;
class Contact;
class ConversationItem;
class ConversationView;
class ProtocolLooper;
class Server;
@ -38,11 +39,9 @@ public:
void ObserveInteger(int32 what, int32 value);
void ObservePointer(int32 what, void* ptr);
ChatWindow* GetChatWindow();
void DeleteWindow();
ConversationView* GetView();
void ShowWindow(bool typing = false, bool userAction = false);
void HideWindow();
void ShowView(bool typing, bool userAction);
BMessenger Messenger() const;
void SetMessenger(BMessenger messenger);
@ -63,14 +62,12 @@ private:
BStringList _GetChatLogs();
void _EnsureLogPath();
void _CreateChatWindow();
Contact* _EnsureUser(BMessage* msg);
Server* _GetServer();
BMessenger fMessenger;
ProtocolLooper* fLooper;
ChatWindow* fChatWindow;
bool fNewWindow;
ConversationView* fChatView;
ConversationItem* fConversationItem;
BString fID;

View File

@ -26,8 +26,10 @@
#include "CayaMessages.h"
#include "CayaProtocolMessages.h"
#include "CayaPreferences.h"
#include "ChatWindow.h"
#include "ConversationItem.h"
#include "ConversationListView.h"
#include "ConversationView.h"
#include "NotifyMessage.h"
#include "MainWindow.h"
#include "PreferencesDialog.h"
@ -47,6 +49,9 @@ MainWindow::MainWindow()
{
fStatusView = new StatusView("statusView");
fChatWindow = new ChatWindow();
fChatWindow->Show();
// Menubar
BMenuBar* menuBar = new BMenuBar("MenuBar");
@ -225,6 +230,11 @@ MainWindow::ImMessage(BMessage* msg)
break;
}
case IM_MESSAGE_RECEIVED:
{
_EnsureConversationItem(msg);
// fChatWindow->PostMessage(msg);
break;
}
case IM_MESSAGE_SENT:
case IM_CHAT_CREATED:
{

View File

@ -15,6 +15,8 @@ class BTextControl;
class ConversationItem;
class ConversationListView;
class ConversationView;
class ChatWindow;
class Server;
class StatusView;
class RosterItem;
@ -36,6 +38,7 @@ public:
void ObserveInteger(int32 what, int32 val);
ChatWindow* GetChatWindow() { return fChatWindow; }
Server* GetServer() const { return fServer; }
void UpdateListItem(ConversationItem* item);
@ -46,6 +49,7 @@ public:
private:
ConversationItem* _EnsureConversationItem(BMessage* msg);
ChatWindow* fChatWindow;
ConversationListView* fListView;
StatusView* fStatusView;
Server* fServer;

View File

@ -51,8 +51,8 @@ Server::Quit()
}
while (conversation = fChatMap.ValueAt(0)) {
conversation->DeleteWindow();
fChatMap.RemoveItemAt(0);
delete conversation;
}
}
@ -132,9 +132,6 @@ Server::Filter(BMessage* message, BHandler **target)
if (id.Length() > 0) {
bool found = false;
Conversation* item = fChatMap.ValueFor(id, &found);
if (found)
item->HideWindow();
}
result = B_SKIP_MESSAGE;
break;
@ -268,7 +265,7 @@ Server::ImMessage(BMessage* msg)
BString statusMsg;
if (msg->FindString("message", &statusMsg) == B_OK) {
contact->SetNotifyPersonalStatus(statusMsg);
// contact->GetChatWindow()->UpdatePersonalMessage();
// contact->GetView()->UpdatePersonalMessage();
}
break;
}
@ -338,7 +335,7 @@ Server::ImMessage(BMessage* msg)
if (chat != NULL && user != NULL) {
chat->AddUser(user);
chat->ShowWindow(false, true);
chat->ShowView(false, true);
}
break;

View File

@ -34,7 +34,7 @@ ConversationListView::MessageReceived(BMessage* msg)
int32 selIndex = CurrentSelection();
if ((item = (ConversationItem*)ItemAt(selIndex)) != NULL)
item->GetConversation()->ShowWindow(false, true);
item->GetConversation()->ShowView(false, true);
break;
}

View File

@ -8,43 +8,26 @@
#include "ConversationView.h"
#include <Alert.h>
#include <Application.h>
#include <Box.h>
#include <Button.h>
#include <CheckBox.h>
#include <GridLayout.h>
#include <GridLayoutBuilder.h>
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <Layout.h>
#include <LayoutBuilder.h>
#include <ListView.h>
#include <Message.h>
#include <SpaceLayoutItem.h>
#include <ScrollView.h>
#include <String.h>
#include <StringList.h>
#include <Notification.h>
#include <ScrollView.h>
#include <StringList.h>
#include <libinterface/BitmapView.h>
#include "CayaConstants.h"
#include "CayaMessages.h"
#include "CayaPreferences.h"
#include "CayaProtocolMessages.h"
#include "CayaRenderView.h"
#include "Contact.h"
#include "Conversation.h"
#include "EditingFilter.h"
#include "NotifyMessage.h"
ConversationView::ConversationView(Conversation* chat)
ConversationView::ConversationView()
:
BGroupView("chatView", B_VERTICAL, B_USE_DEFAULT_SPACING),
fConversation(chat),
fContact(chat->Users().ValueAt(0))
fMessageQueue()
{
fMessageCount = 0;
@ -85,6 +68,13 @@ ConversationView::ConversationView(Conversation* chat)
}
ConversationView::ConversationView(Conversation* chat)
: ConversationView()
{
SetConversation(chat);
}
bool
ConversationView::QuitRequested()
{
@ -102,6 +92,15 @@ ConversationView::GetConversation()
}
void
ConversationView::SetConversation(Conversation* chat)
{
fConversation = chat;
fContact = chat->Users().ValueAt(0);
fPersonalMessage->SetText(chat->GetName());
}
void
ConversationView::UpdateAvatar()
{
@ -148,6 +147,16 @@ ConversationView::MessageReceived(BMessage* message)
}
void
ConversationView::AttachedToWindow()
{
while (fMessageQueue.IsEmpty() == false) {
BMessage* msg = fMessageQueue.RemoveItemAt(0);
ImMessage(msg);
}
}
void
ConversationView::ImMessage(BMessage* msg)
{
@ -161,35 +170,48 @@ ConversationView::ImMessage(BMessage* msg)
User* sender = fConversation->UserById(id);
BString uname = sender->GetName();
// Send a notification, if it's appropriate
if ((Window() == NULL || Window()->IsActive() == false)
&& (!CayaPreferences::Item()->NotifyNewMessage))
{
fMessageCount++;
BString notify_message;
notify_message << "You've got ";
notify_message << fMessageCount;
if (fMessageCount==1)
notify_message << " new message from ";
else
notify_message << " new messages from ";
notify_message << uname;
BNotification notification(B_INFORMATION_NOTIFICATION);
notification.SetGroup(BString("Caya"));
notification.SetTitle(BString("New message"));
notification.SetIcon(sender->AvatarBitmap());
notification.SetContent(notify_message);
notification.SetMessageID(uname);
notification.Send();
// Check if the user want the notification
if (!CayaPreferences::Item()->NotifyNewMessage)
break;
}
// If not attached to the chat window, then re-handle this message
// later [AttachedToWindow()], since that's required to append to
// fReceiveview.
if (Window() == NULL) {
fMessageQueue.AddItem(new BMessage(*msg));
return;
}
// Now we're free to append!
Window()->LockLooper();
fReceiveView->AppendOtherMessage(uname.String(), message.String());
Window()->UnlockLooper();
// Message received, clear status anyway
fStatus->SetText("");
fMessageCount++;
// Check if the user want the notification
if (!CayaPreferences::Item()->NotifyNewMessage)
break;
BString notify_message;
notify_message << "You've got ";
notify_message << fMessageCount;
if (fMessageCount==1) {
notify_message << " new message from ";
} else {
notify_message << " new messages from ";
};
notify_message << uname;
BNotification notification(B_INFORMATION_NOTIFICATION);
notification.SetGroup(BString("Caya"));
notification.SetTitle(BString("New message"));
notification.SetIcon(sender->AvatarBitmap());
notification.SetContent(notify_message);
notification.SetMessageID(uname);
notification.Send();
break;
}
case IM_LOGS_RECEIVED:

View File

@ -5,32 +5,33 @@
#ifndef _CHAT_VIEW_H
#define _CHAT_VIEW_H
#include <Window.h>
#include <TextView.h>
#include <StringView.h>
#include <GroupView.h>
#include <Notification.h>
#include "Observer.h"
#include <ObjectList.h>
#include <StringView.h>
#include <TextView.h>
#include "CayaConstants.h"
class BMessageQueue;
class BitmapView;
class Conversation;
class CayaRenderView;
class Contact;
class Conversation;
class ConversationView : public BGroupView {
public:
ConversationView();
ConversationView(Conversation* chat);
// virtual void ShowWindow();
virtual void MessageReceived(BMessage* message);
// void WindowActivated(bool active);
virtual bool QuitRequested();
Conversation* GetConversation();
void SetConversation(Conversation* chat);
void AttachedToWindow();
void UpdateAvatar();
void UpdatePersonalMessage();
@ -39,9 +40,11 @@ public:
void ObserveString(int32 what, BString str);
void ObservePointer(int32 what, void* ptr);
void ObserveInteger(int32 what, int32 val);
void AppendStatus(CayaStatus status);
void AvoidFocus(bool avoid);
private:
Conversation* fConversation;
Contact* fContact;
@ -51,7 +54,7 @@ private:
BitmapView* fProtocolView;
BitmapView* fAvatar;
int32 fMessageCount;
BObjectList<BMessage> fMessageQueue;
};