From b5659bf9ade976353d771d9fcd1a3f1f3c3fb663 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 24 Nov 2018 19:17:47 +0100 Subject: Add change user nickname/avatar menu --- depends/dchat_core | 2 +- include/ChatWindow.hpp | 5 +- include/UserSettingsWindow.hpp | 33 +++++++++++ src/ChatMessage.cpp | 1 - src/ChatWindow.cpp | 52 +++++++++++++++- src/RoomSettingsWindow.cpp | 4 +- src/UserSettingsWindow.cpp | 131 +++++++++++++++++++++++++++++++++++++++++ src/Window.cpp | 4 ++ 8 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 include/UserSettingsWindow.hpp create mode 100644 src/UserSettingsWindow.cpp diff --git a/depends/dchat_core b/depends/dchat_core index 2c28fbc..982ead1 160000 --- a/depends/dchat_core +++ b/depends/dchat_core @@ -1 +1 @@ -Subproject commit 2c28fbc12f487a93ff3341eba42fe47368416fd3 +Subproject commit 982ead1c2ea75670efecd4318ead25dc27b7c78b diff --git a/include/ChatWindow.hpp b/include/ChatWindow.hpp index b0f4001..764ca32 100644 --- a/include/ChatWindow.hpp +++ b/include/ChatWindow.hpp @@ -3,6 +3,7 @@ #include "ImageButton.hpp" #include "RoomSettingsWindow.hpp" #include "RoomNotificationsWindow.hpp" +#include "UserSettingsWindow.hpp" #include #include #include @@ -30,6 +31,7 @@ namespace dchat void addMessage(const RoomAddMessageRequest &request); void addUser(const RoomAddUserRequest &request); void setUserNickname(const UserChangeNicknameRequest &request); + void setUserAvatar(const UserChangeAvatarRequest &request); void changeRoomName(const RoomChangeNameRequest &request); void addInviteRequest(const InviteUserRequest &request); void scrollToBottom(); @@ -39,7 +41,9 @@ namespace dchat Gtk::Grid chatPage; RoomSettingsWindow roomSettingsWindow; RoomNotificationsWindow roomNotificationsWindow; + UserSettingsWindow userSettingsWindow; Window *window; + std::shared_ptr currentRoom; private: void setupTopbar(); void setupLeftPanel(Gtk::ResponsivePaned *sidePanels); @@ -69,7 +73,6 @@ namespace dchat int chatPrevNumLines; int roomCount; RoomData *currentRoomData; - std::shared_ptr currentRoom; bool chatInputShowPlaceholder; bool chatInputChangeByPlaceholder; }; diff --git a/include/UserSettingsWindow.hpp b/include/UserSettingsWindow.hpp new file mode 100644 index 0000000..e7062e1 --- /dev/null +++ b/include/UserSettingsWindow.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include +#include + +namespace Gtk +{ + class Paned; +} + +namespace dchat +{ + class ChatWindow; + + class UserSettingsWindow : public Gtk::Grid + { + public: + UserSettingsWindow(ChatWindow *chatWindow); + void setAvatarUrl(const std::string &url); + void setNickname(const std::string &nickname); + + void setupLeftPanel(Gtk::Paned *sidePanels); + void setupRightPanel(Gtk::Paned *sidePanels); + private: + ChatWindow *chatWindow; + Gtk::Entry nicknameEntry; + Gtk::Entry avatarUrlEntry; + Glib::ustring prevNickname; + Glib::ustring prevAvatarUrl; + }; +} \ No newline at end of file diff --git a/src/ChatMessage.cpp b/src/ChatMessage.cpp index 59eb059..e1fe927 100644 --- a/src/ChatMessage.cpp +++ b/src/ChatMessage.cpp @@ -10,7 +10,6 @@ namespace dchat avatar.set_halign(Gtk::ALIGN_START); avatar.set_valign(Gtk::ALIGN_START); avatar.set_size_request(35, 35); - avatar.url = "https://discordemoji.com/assets/emoji/PeepoHide.png"; username.set_selectable(true); username.set_alignment(Gtk::ALIGN_START, Gtk::ALIGN_START); diff --git a/src/ChatWindow.cpp b/src/ChatWindow.cpp index 529b857..9cc4ff1 100644 --- a/src/ChatWindow.cpp +++ b/src/ChatWindow.cpp @@ -18,6 +18,7 @@ namespace dchat ChatWindow::ChatWindow(Window *_window) : roomSettingsWindow(this), roomNotificationsWindow(this), + userSettingsWindow(this), createRoomButton("images/add_button_small.png", " Create room"), joinRoomButton("images/add_button_small.png", " Join room"), userSettingsButton("images/settings-icon.png", " User settings"), @@ -37,8 +38,9 @@ namespace dchat attach(stack, 0, 1, 2, 2); stack.add(chatPage, "chat"); - stack.add(roomSettingsWindow, "settings"); + stack.add(roomSettingsWindow, "room-settings"); stack.add(roomNotificationsWindow, "notifications"); + stack.add(userSettingsWindow, "user-settings"); Gtk::ResponsivePaned *sidePanels = Gtk::manage(new Gtk::ResponsivePaned(Gtk::ORIENTATION_HORIZONTAL)); sidePanels->get_style_context()->add_class("side-panels"); @@ -95,7 +97,7 @@ namespace dchat roomSettingsWindow.show_all(); roomSettingsWindow.selectRoom(currentRoom); - stack.set_visible_child("settings"); + stack.set_visible_child("room-settings"); }); topbar->roomNotificationsButton.signal_clicked().connect([this] @@ -219,7 +221,20 @@ namespace dchat leftPanelLayout->attach_next_to(userSettingsButton, joinRoomButton, Gtk::POS_BOTTOM, 1, 1); userSettingsButton.signal_clicked().connect([this]() { - printf("user settings!\n"); + if(!currentRoom) + { + window->windowNotification->show("You need to be inside a room to go to user settings"); + return; + } + + if(!currentRoom->localUser) + { + window->windowNotification->show("You need to be a member of the room to go to user settings"); + return; + } + + userSettingsWindow.show_all(); + stack.set_visible_child("user-settings"); }); } @@ -394,7 +409,20 @@ namespace dchat currentRoom = room; currentRoomData = roomDataById[*room->id]; if(room->localUser) + { chatInput.set_editable(true); + + std::string nickname = "Anonymous"; + if(!room->localUser->nickname.empty()) + nickname = room->localUser->nickname; + + std::string avatarUrl = "https://discordemoji.com/assets/emoji/PeepoHide.png"; + if(!room->localUser->avatarUrl.empty()) + avatarUrl = room->localUser->avatarUrl; + + userSettingsWindow.setNickname(nickname); + userSettingsWindow.setAvatarUrl(avatarUrl); + } else chatInput.set_editable(false); @@ -432,6 +460,10 @@ namespace dchat if(userNickname.empty()) userNickname = "Anonymous"; ChatMessage *message = Gtk::manage(new ChatMessage(userNickname, request.message.text, request.message.timestampSeconds)); + if(request.message.creator->avatarUrl.empty()) + message->avatar.url = "https://discordemoji.com/assets/emoji/PeepoHide.png"; + else + message->avatar.url = request.message.creator->avatarUrl; message->set_valign(Gtk::Align::ALIGN_START); message->set_hexpand(true); message->show_all(); @@ -461,7 +493,11 @@ namespace dchat if(roomData == currentRoomData) { if(request.room->localUser) + { chatInput.set_editable(true); + userSettingsWindow.setNickname("Anonymous"); + userSettingsWindow.setAvatarUrl("https://discordemoji.com/assets/emoji/PeepoHide.png"); + } else chatInput.set_editable(false); } @@ -478,9 +514,19 @@ namespace dchat { Gtk::Label *userNicknameLabel = (Gtk::Label*)request.user->userdata; userNicknameLabel->set_text(request.newNickname); + if(request.user == request.room->localUser) + userSettingsWindow.setNickname(request.newNickname); fprintf(stderr, "Set nickname for user %s to %s\n", request.user->publicKey.toString().c_str(), request.newNickname.c_str()); } + void ChatWindow::setUserAvatar(const UserChangeAvatarRequest &request) + { + request.user->avatarUrl = request.url; + if(request.user == request.room->localUser) + userSettingsWindow.setAvatarUrl(request.url); + fprintf(stderr, "Set avatar for user %s to %s\n", request.user->publicKey.toString().c_str(), request.url.c_str()); + } + void ChatWindow::changeRoomName(const RoomChangeNameRequest &request) { Gtk::RadioButton *button = roomDataById[*request.room->id]->button; diff --git a/src/RoomSettingsWindow.cpp b/src/RoomSettingsWindow.cpp index 3591962..f9b4998 100644 --- a/src/RoomSettingsWindow.cpp +++ b/src/RoomSettingsWindow.cpp @@ -49,12 +49,12 @@ namespace dchat leftPanel->attach_next_to(*generalButton, *settingsLabel, Gtk::POS_BOTTOM, 1, 1); Gtk::ToggleButton *returnToChatButton = Gtk::manage(new Gtk::ToggleButton("Return to chat")); + leftPanel->attach_next_to(*returnToChatButton, *generalButton, Gtk::POS_BOTTOM, 1, 1); returnToChatButton->signal_clicked().connect([this] { chatWindow->chatPage.show_all(); chatWindow->stack.set_visible_child("chat"); }); - leftPanel->attach_next_to(*returnToChatButton, *generalButton, Gtk::POS_BOTTOM, 1, 1); } void RoomSettingsWindow::setupRightPanel(Gtk::Paned *sidePanels) @@ -82,10 +82,10 @@ namespace dchat rightPanel->attach_next_to(inviteKey, *inviteKeyLabel, Gtk::POS_BOTTOM, 1, 1); Gtk::Button *copyInviteKeyButton = Gtk::manage(new Gtk::Button("_Copy", true)); + rightPanel->attach_next_to(*copyInviteKeyButton, inviteKey, Gtk::POS_RIGHT, 1, 1); copyInviteKeyButton->signal_clicked().connect([this] { Gtk::Clipboard::get()->set_text(inviteKey.get_text()); }); - rightPanel->attach_next_to(*copyInviteKeyButton, inviteKey, Gtk::POS_RIGHT, 1, 1); } } \ No newline at end of file diff --git a/src/UserSettingsWindow.cpp b/src/UserSettingsWindow.cpp new file mode 100644 index 0000000..6eda049 --- /dev/null +++ b/src/UserSettingsWindow.cpp @@ -0,0 +1,131 @@ +#include "../include/UserSettingsWindow.hpp" +#include "../include/ChatWindow.hpp" +#include "../include/Window.hpp" +#include +#include +#include +#include +#include + +namespace dchat +{ + UserSettingsWindow::UserSettingsWindow(ChatWindow *_chatWindow) : + chatWindow(_chatWindow) + { + assert(chatWindow); + Gtk::Paned *sidePanels = Gtk::manage(new Gtk::Paned(Gtk::ORIENTATION_HORIZONTAL)); + sidePanels->get_style_context()->add_class("side-panels"); + sidePanels->set_vexpand(true); + sidePanels->set_hexpand(true); + sidePanels->set_wide_handle(true); + attach(*sidePanels, 0, 0, 1, 1); + + setupLeftPanel(sidePanels); + setupRightPanel(sidePanels); + + set_vexpand(true); + set_hexpand(true); + } + + void UserSettingsWindow::setAvatarUrl(const std::string &url) + { + avatarUrlEntry.set_text(url); + prevAvatarUrl = url; + } + + void UserSettingsWindow::setNickname(const std::string &nickname) + { + nicknameEntry.set_text(nickname); + prevNickname = nickname; + } + + void UserSettingsWindow::setupLeftPanel(Gtk::Paned *sidePanels) + { + Gtk::Grid *leftPanel = Gtk::manage(new Gtk::Grid()); + leftPanel->set_vexpand(true); + leftPanel->set_size_request(200); + leftPanel->get_style_context()->add_class("left-panel"); + sidePanels->add1(*leftPanel); + + Gtk::Label *settingsLabel = Gtk::manage(new Gtk::Label("Settings")); + leftPanel->attach(*settingsLabel, 0, 0, 1, 1); + + Gtk::ToggleButton *generalButton = Gtk::manage(new Gtk::ToggleButton("General")); + leftPanel->attach_next_to(*generalButton, *settingsLabel, Gtk::POS_BOTTOM, 1, 1); + + Gtk::ToggleButton *returnToChatButton = Gtk::manage(new Gtk::ToggleButton("Return to chat")); + leftPanel->attach_next_to(*returnToChatButton, *generalButton, Gtk::POS_BOTTOM, 1, 1); + returnToChatButton->signal_clicked().connect([this] + { + chatWindow->chatPage.show_all(); + chatWindow->stack.set_visible_child("chat"); + }); + } + + void UserSettingsWindow::setupRightPanel(Gtk::Paned *sidePanels) + { + Gtk::Grid *rightPanel = Gtk::manage(new Gtk::Grid()); + rightPanel->set_margin_top(10); + rightPanel->set_margin_left(10); + rightPanel->set_vexpand(true); + rightPanel->set_valign(Gtk::ALIGN_START); + rightPanel->set_halign(Gtk::ALIGN_START); + sidePanels->add2(*rightPanel); + + Gtk::Label *nicknameLabel = Gtk::manage(new Gtk::Label("Nickname")); + rightPanel->attach(*nicknameLabel, 0, 0, 2, 1); + rightPanel->attach_next_to(nicknameEntry, *nicknameLabel, Gtk::POS_BOTTOM, 2, 1); + + Gtk::Label *avatarUrlLabel = Gtk::manage(new Gtk::Label("Avatar url")); + rightPanel->attach_next_to(*avatarUrlLabel, nicknameEntry, Gtk::POS_BOTTOM, 2, 1); + rightPanel->attach_next_to(avatarUrlEntry, *avatarUrlLabel, Gtk::POS_BOTTOM, 2, 1); + + Gtk::Button *resetButton = Gtk::manage(new Gtk::Button("Rest")); + resetButton->set_halign(Gtk::ALIGN_END); + rightPanel->attach_next_to(*resetButton, avatarUrlEntry, Gtk::POS_BOTTOM, 1, 1); + resetButton->signal_clicked().connect([this] + { + avatarUrlEntry.set_text(prevAvatarUrl); + nicknameEntry.set_text(prevNickname); + }); + + Gtk::Button *saveButton = Gtk::manage(new Gtk::Button("Save")); + saveButton->get_style_context()->add_class("confirm-button"); + rightPanel->attach_next_to(*saveButton, *resetButton, Gtk::POS_RIGHT, 1, 1); + saveButton->signal_clicked().connect([this] + { + Glib::ustring avatarUrl = avatarUrlEntry.get_text(); + Glib::ustring nickname = nicknameEntry.get_text(); + if(avatarUrl.size() < 5) + { + chatWindow->window->windowNotification->show("Invalid avatar url!"); + return; + } + if(nickname.empty()) + { + chatWindow->window->windowNotification->show("Invalid nickname!"); + return; + } + + bool changed = false; + if(avatarUrl != prevAvatarUrl) + { + prevAvatarUrl = avatarUrl; + chatWindow->currentRoom->setAvatarUrl(avatarUrl); + changed = true; + } + + if(nickname != prevNickname) + { + prevNickname = nickname; + chatWindow->currentRoom->setNickname(nickname); + changed = true; + } + + if(changed) + { + chatWindow->window->windowNotification->show("Saved changes!"); + } + }); + } +} \ No newline at end of file diff --git a/src/Window.cpp b/src/Window.cpp index b3c8dcc..6aa50ee 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -125,6 +125,10 @@ namespace dchat { chatWindow.setUserNickname(request); }; + roomCallbackFuncs.userChangeAvatarCallbackFunc = [this](const UserChangeAvatarRequest &request) + { + chatWindow.setUserAvatar(request); + }; roomCallbackFuncs.changeRoomNameCallbackFunc = [this](const RoomChangeNameRequest &request) { chatWindow.changeRoomName(request); -- cgit v1.2.3