aboutsummaryrefslogtreecommitdiff
path: root/src/ChatWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ChatWindow.cpp')
-rw-r--r--src/ChatWindow.cpp121
1 files changed, 61 insertions, 60 deletions
diff --git a/src/ChatWindow.cpp b/src/ChatWindow.cpp
index 041d2c3..98c4269 100644
--- a/src/ChatWindow.cpp
+++ b/src/ChatWindow.cpp
@@ -3,6 +3,7 @@
#include <gtkmm/alignment.h>
#include <gtkmm/viewport.h>
#include <gtkmm/scrollbar.h>
+#include <gtkmm/eventbox.h>
#include <cassert>
namespace dchat
@@ -11,8 +12,7 @@ namespace dchat
const int MERGE_MESSAGE_TIMESTAMP_DIFF_SEC = 60;
ChatWindow::ChatWindow() :
- channelCount(0),
- lastMessage(nullptr)
+ roomCount(0)
{
setupTopBar();
@@ -107,9 +107,20 @@ namespace dchat
chatInput.set_hexpand(true);
chatInput.set_name("chat-input");
chatInput.set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR);
+ chatScrollWindow->add(chatInput);
double fontSize = 18.5;//PANGO_PIXELS(chatInput.get_style_context()->get_font().get_size());
chatPrevNumLines = 1;
+ chatInput.signal_key_press_event().connect([this](GdkEventKey *event)
+ {
+ if((event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) && !(event->state & Gdk::SHIFT_MASK))
+ {
+ currentRoom->publishMessage(chatInput.get_buffer()->get_text());
+ chatInput.get_buffer()->set_text("");
+ return true;
+ }
+ return false;
+ }, false);
chatInput.get_buffer()->signal_changed().connect([this, chatScrollWindow, fontSize]
{
int numLines = chatInput.get_buffer()->get_line_count();
@@ -144,100 +155,90 @@ namespace dchat
chatScrollWindow->set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_ALWAYS);
}
});
- chatScrollWindow->add(chatInput);
}
- void ChatWindow::addChannel(const odhtdb::Hash &nodeHash)
+ void ChatWindow::addRoom(std::shared_ptr<Room> room)
{
- assert(channelDataById.find(nodeHash) == channelDataById.end());
- fprintf(stderr, "Added channel %s\n", nodeHash.toString().c_str());
+ fprintf(stderr, "Added channel %s\n", room->id->toString().c_str());
Gtk::ToggleButton *channelButton = Gtk::manage(new Gtk::ToggleButton("Channel name"));
channelButton->set_active(true);
channelButton->get_style_context()->add_class("channel-button");
channelButton->set_hexpand(true);
channelButton->get_child()->set_halign(Gtk::ALIGN_START);
channelButton->show();
- leftPanelChannels.attach(*channelButton, 0, 1 + channelCount, 1, 1);
- ++channelCount;
- channelDataById[nodeHash] = { channelButton, 0 };
+ leftPanelChannels.attach(*channelButton, 0, 1 + roomCount, 1, 1);
+ ++roomCount;
+ roomDataById[*room->id] = { channelButton };
+ currentRoom = room;
}
- void ChatWindow::addLocalMessage(const odhtdb::Hash &channelId, const odhtdb::Signature::PublicKey &userPublicKey, uint32_t timestampSeconds, Glib::ustring msg)
+ void ChatWindow::addMessage(const RoomAddMessageRequest &request)
{
- auto it = channelDataById.find(channelId);
- assert(it != channelDataById.end());
- User *user = getUserByPublicKey(userPublicKey);
- if(!user)
- {
- fprintf(stderr, "Unable to add message to channel because the user %s doesn't exist in it\n", userPublicKey.toString().c_str());
- return;
- }
+ auto roomMessages = request.room->messages;
+ RoomMessage *lastMessage = nullptr;
+ if(!roomMessages.empty())
+ lastMessage = &roomMessages.back();
- if(lastMessage && lastMessage->user->publicKey == userPublicKey)
+ if(lastMessage && lastMessage->creator->publicKey == request.message.creator->publicKey)
{
- int64_t msgTimeDiff = (int64_t)timestampSeconds - (int64_t)lastMessage->timestampSeconds;
+ int64_t msgTimeDiff = (int64_t)request.message.timestampSeconds - (int64_t)lastMessage->timestampSeconds;
if(msgTimeDiff <= MERGE_MESSAGE_TIMESTAMP_DIFF_SEC)
{
- lastMessage->text.set_text(lastMessage->text.get_text() + "\n" + msg);
+ auto message = messageById[lastMessage->id];
+ message->text.set_text(message->text.get_text() + "\n" + request.message.text);
+ // Since messages that are sent withing a timeframe are combined, several message ids can refer to the same message
+ messageById[request.message.id] = message;
+ if(*request.room->id == *currentRoom->id)
+ {
+ auto adj = messageArea.get_vadjustment();
+ adj->set_value(adj->get_upper());
+ messageAreaLayout.queue_draw();
+ while(gtk_events_pending())
+ gtk_main_iteration_do(FALSE);
+ }
return;
}
}
- ChatMessage *message = Gtk::manage(new ChatMessage(user->name, msg, timestampSeconds, user));
- lastMessage = message;
+ ChatMessage *message = Gtk::manage(new ChatMessage(request.message.creator->nickname, request.message.text, request.message.timestampSeconds));
message->set_valign(Gtk::Align::ALIGN_START);
message->set_hexpand(true);
message->show_all();
- messageAreaLayout.attach(*message, 0, it->second.messageCount, 1, 1);
- ++it->second.messageCount;
- }
+ messageById[request.message.id] = message;
+ messageAreaLayout.attach(*message, 0, roomMessages.size(), 1, 1);
- void ChatWindow::addUser(const odhtdb::Signature::PublicKey &userPublicKey)
- {
- User *existingUser = getUserByPublicKey(userPublicKey);
- if(existingUser)
+ // TODO: When we get a message in the current room we scroll to the bottom, but this should only be done if we are not manually scrolling to view old messages
+ if(*request.room->id == *currentRoom->id)
{
- fprintf(stderr, "ChatWindow::addUser: user %s was not added because the user has already been added\n", userPublicKey.toString().c_str());
- return;
+ auto adj = messageArea.get_vadjustment();
+ adj->set_value(adj->get_upper());
+ messageAreaLayout.queue_draw();
+ while(gtk_events_pending())
+ gtk_main_iteration_do(FALSE);
}
+ }
+ void ChatWindow::addUser(std::shared_ptr<Room> room, std::shared_ptr<User> user)
+ {
Gtk::Label *username = Gtk::manage(new Gtk::Label("NoName"));
username->set_halign(Gtk::ALIGN_START);
username->show();
username->get_style_context()->add_class("username-list-username");
- leftPanelUsers.attach(*username, 0, 1 + users.size(), 1, 1);
- users.push_back(new User { userPublicKey, "NoName" });
- fprintf(stderr, "Added user %s\n", userPublicKey.toString().c_str());
+ user->userdata = username;
+ leftPanelUsers.attach(*username, 0, room->userByPublicKey.size(), 1, 1);
+ fprintf(stderr, "Added user %s\n", user->publicKey.toString().c_str());
}
- void ChatWindow::setUserNickname(const odhtdb::Signature::PublicKey &userPublicKey, const Glib::ustring &name)
+ void ChatWindow::setUserNickname(const UserChangeNicknameRequest &request)
{
- for(size_t i = 0; i < users.size(); ++i)
- {
- User *user = users[i];
- if(user->publicKey == userPublicKey)
- {
- user->name = name;
- Gtk::Widget *usernameLabel = leftPanelUsers.get_child_at(0, 1 + i);
- assert(usernameLabel);
- //assert(usernameLabel->get_type() == Gtk::Label::get_type());
- static_cast<Gtk::Label*>(usernameLabel)->set_text(name);
- fprintf(stderr, "Set nickname for user %s to %s\n", userPublicKey.toString().c_str(), name.c_str());
- return;
- }
- }
- fprintf(stderr, "ChatWindow::setUserNickname: user %s doesn't exist\n", userPublicKey.toString().c_str());
+ Gtk::Label *userNicknameLabel = (Gtk::Label*)request.user->userdata;
+ userNicknameLabel->set_text(request.newNickname);
+ fprintf(stderr, "Set nickname for user %s to %s\n", request.user->publicKey.toString().c_str(), request.newNickname.c_str());
}
- User* ChatWindow::getUserByPublicKey(const odhtdb::Signature::PublicKey &publicKey) const
+ void ChatWindow::scrollToBottom()
{
- for(User *user : users)
- {
- if(user->publicKey == publicKey)
- {
- return user;
- }
- }
- return nullptr;
+ auto adj = messageArea.get_vadjustment();
+ adj->set_value(adj->get_upper());
}
} \ No newline at end of file