diff options
Diffstat (limited to 'src/ChatWindow.cpp')
-rw-r--r-- | src/ChatWindow.cpp | 121 |
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 |