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 "CayaRenderView.h"
#include "NotifyMessage.h" #include "NotifyMessage.h"
ChatWindow::ChatWindow()
ChatWindow::ChatWindow(Conversation* cl)
: :
BWindow(BRect(200, 200, 500, 500), "Chat", B_TITLED_WINDOW, 0) BWindow(BRect(200, 200, 500, 500), "Chat", B_TITLED_WINDOW, 0)
{ {
fChatView = new ConversationView(cl); fChatView = new ConversationView();
fSendView = new BTextView("fReceiveView"); fSendView = new BTextView("fSendView");
BScrollView* scrollViewSend = new BScrollView("scrollviewS", fSendView, fSendScroll = new BScrollView("fSendScroll", fSendView,
B_WILL_DRAW, false, true); B_WILL_DRAW, false, true);
fSendView->SetWordWrap(true); fSendView->SetWordWrap(true);
@ -57,11 +56,34 @@ ChatWindow::ChatWindow(Conversation* cl)
BLayoutBuilder::Group<>(this, B_VERTICAL) BLayoutBuilder::Group<>(this, B_VERTICAL)
.Add(fChatView) .Add(fChatView)
.Add(scrollViewSend) .Add(fSendScroll)
.End(); .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 void
ChatWindow::ShowWindow() ChatWindow::ShowWindow()
{ {

View File

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

View File

@ -11,9 +11,11 @@
#include "CayaPreferences.h" #include "CayaPreferences.h"
#include "CayaProtocolMessages.h" #include "CayaProtocolMessages.h"
#include "CayaRenderView.h"
#include "CayaUtils.h" #include "CayaUtils.h"
#include "ChatWindow.h" #include "ChatWindow.h"
#include "ConversationItem.h" #include "ConversationItem.h"
#include "ConversationView.h"
#include "MainWindow.h" #include "MainWindow.h"
#include "ProtocolLooper.h" #include "ProtocolLooper.h"
#include "ProtocolManager.h" #include "ProtocolManager.h"
@ -27,8 +29,7 @@ Conversation::Conversation(BString id, BMessenger msgn)
fID(id), fID(id),
fName(id), fName(id),
fMessenger(msgn), fMessenger(msgn),
fChatWindow(NULL), fChatView(NULL),
fNewWindow(true),
fLooper(NULL), fLooper(NULL),
fDateFormatter() fDateFormatter()
{ {
@ -53,11 +54,8 @@ Conversation::ImMessage(BMessage* msg)
case IM_MESSAGE_RECEIVED: case IM_MESSAGE_RECEIVED:
{ {
_EnsureUser(msg); _EnsureUser(msg);
_LogChatMessage(msg); _LogChatMessage(msg);
ChatWindow* win = GetChatWindow(); GetView()->MessageReceived(msg);
ShowWindow();
win->PostMessage(msg);
break; break;
} }
case IM_SEND_MESSAGE: case IM_SEND_MESSAGE:
@ -67,7 +65,7 @@ Conversation::ImMessage(BMessage* msg)
break; break;
} }
default: default:
GetChatWindow()->PostMessage(msg); GetView()->MessageReceived(msg);
} }
} }
@ -75,83 +73,32 @@ Conversation::ImMessage(BMessage* msg)
void void
Conversation::ObserveString(int32 what, BString str) Conversation::ObserveString(int32 what, BString str)
{ {
if (fChatWindow != NULL) if (fChatView != NULL)
fChatWindow->ObserveString(what, str); fChatView->ObserveString(what, str);
} }
void void
Conversation::ObservePointer(int32 what, void* ptr) Conversation::ObservePointer(int32 what, void* ptr)
{ {
if (fChatWindow != NULL) if (fChatView != NULL)
fChatWindow->ObservePointer(what, ptr); fChatView->ObservePointer(what, ptr);
} }
void void
Conversation::ObserveInteger(int32 what, int32 val) Conversation::ObserveInteger(int32 what, int32 val)
{ {
if (fChatWindow != NULL) if (fChatView != NULL)
fChatWindow->ObserveInteger(what, val); fChatView->ObserveInteger(what, val);
}
ChatWindow*
Conversation::GetChatWindow()
{
if (fChatWindow == NULL)
_CreateChatWindow();
return fChatWindow;
} }
void void
Conversation::DeleteWindow() Conversation::ShowView(bool typing, bool userAction)
{ {
if (fChatWindow != NULL) { ((TheApp*)be_app)->GetMainWindow()->GetChatWindow()->SetConversation(this);
if (fChatWindow->Lock()) { ((TheApp*)be_app)->GetMainWindow()->GetChatWindow()->ShowWindow();
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();
} }
@ -221,20 +168,12 @@ Conversation::AddUser(User* user)
} }
void ConversationView*
Conversation::_CreateChatWindow() Conversation::GetView()
{ {
fChatWindow = new ChatWindow(this); if (fChatView == NULL)
WindowsManager::Get()->RelocateWindow(fChatWindow); fChatView = new ConversationView(this);
return fChatView;
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);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,43 +8,26 @@
#include "ConversationView.h" #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 <LayoutBuilder.h>
#include <ListView.h>
#include <Message.h>
#include <SpaceLayoutItem.h>
#include <ScrollView.h>
#include <String.h>
#include <StringList.h>
#include <Notification.h> #include <Notification.h>
#include <ScrollView.h>
#include <StringList.h>
#include <libinterface/BitmapView.h> #include <libinterface/BitmapView.h>
#include "CayaConstants.h"
#include "CayaMessages.h" #include "CayaMessages.h"
#include "CayaPreferences.h" #include "CayaPreferences.h"
#include "CayaProtocolMessages.h" #include "CayaProtocolMessages.h"
#include "CayaRenderView.h" #include "CayaRenderView.h"
#include "Contact.h" #include "Contact.h"
#include "Conversation.h" #include "Conversation.h"
#include "EditingFilter.h"
#include "NotifyMessage.h" #include "NotifyMessage.h"
ConversationView::ConversationView(Conversation* chat) ConversationView::ConversationView()
: :
BGroupView("chatView", B_VERTICAL, B_USE_DEFAULT_SPACING), BGroupView("chatView", B_VERTICAL, B_USE_DEFAULT_SPACING),
fConversation(chat), fMessageQueue()
fContact(chat->Users().ValueAt(0))
{ {
fMessageCount = 0; fMessageCount = 0;
@ -85,6 +68,13 @@ ConversationView::ConversationView(Conversation* chat)
} }
ConversationView::ConversationView(Conversation* chat)
: ConversationView()
{
SetConversation(chat);
}
bool bool
ConversationView::QuitRequested() 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 void
ConversationView::UpdateAvatar() 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 void
ConversationView::ImMessage(BMessage* msg) ConversationView::ImMessage(BMessage* msg)
{ {
@ -161,25 +170,18 @@ ConversationView::ImMessage(BMessage* msg)
User* sender = fConversation->UserById(id); User* sender = fConversation->UserById(id);
BString uname = sender->GetName(); BString uname = sender->GetName();
fReceiveView->AppendOtherMessage(uname.String(), message.String()); // Send a notification, if it's appropriate
if ((Window() == NULL || Window()->IsActive() == false)
// Message received, clear status anyway && (!CayaPreferences::Item()->NotifyNewMessage))
fStatus->SetText(""); {
fMessageCount++; fMessageCount++;
// Check if the user want the notification
if (!CayaPreferences::Item()->NotifyNewMessage)
break;
BString notify_message; BString notify_message;
notify_message << "You've got "; notify_message << "You've got ";
notify_message << fMessageCount; notify_message << fMessageCount;
if (fMessageCount==1) { if (fMessageCount==1)
notify_message << " new message from "; notify_message << " new message from ";
} else { else
notify_message << " new messages from "; notify_message << " new messages from ";
};
notify_message << uname; notify_message << uname;
BNotification notification(B_INFORMATION_NOTIFICATION); BNotification notification(B_INFORMATION_NOTIFICATION);
@ -189,6 +191,26 @@ ConversationView::ImMessage(BMessage* msg)
notification.SetContent(notify_message); notification.SetContent(notify_message);
notification.SetMessageID(uname); notification.SetMessageID(uname);
notification.Send(); 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("");
break; break;
} }

View File

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