aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--css/style.css13
-rw-r--r--include/LoginWindow.hpp21
-rw-r--r--src/LoginWindow.cpp176
-rw-r--r--src/Window.cpp40
4 files changed, 222 insertions, 28 deletions
diff --git a/css/style.css b/css/style.css
index bb40474..5ea60be 100644
--- a/css/style.css
+++ b/css/style.css
@@ -25,12 +25,25 @@ button {
text-shadow: 0px 0px 0px transparent;
}
+.confirm-button {
+ background-color: #3060d8;
+}
+
menu {
background-color: #36393e;
color: #f7f7f7;
border: 1px solid black;
}
+separator {
+ background-color: #444444;
+}
+
+.separator-horizontal-margin {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
.emoji {
background-color: #36393e;
color: #f7f7f7;
diff --git a/include/LoginWindow.hpp b/include/LoginWindow.hpp
index b842eb5..ea9b905 100644
--- a/include/LoginWindow.hpp
+++ b/include/LoginWindow.hpp
@@ -8,6 +8,8 @@
namespace dchat
{
using LoginHandler = std::function<void(const Glib::ustring &username, const Glib::ustring &password)>;
+ using RegisterHandler = std::function<void(const Glib::ustring &username, const Glib::ustring &password)>;
+ using RegisterPasswordMismatchHandler = std::function<void()>;
class LoginWindow : public Gtk::Grid
{
@@ -15,11 +17,26 @@ namespace dchat
LoginWindow();
void setLoginHandler(LoginHandler loginHandler);
+ void setRegisterHandler(RegisterHandler registerHandler);
+ void setRegisterPasswordMismatch(RegisterPasswordMismatchHandler passwordMismatchHandler);
private:
- Gtk::Entry usernameInput;
- Gtk::Entry passwordInput;
+ void setupLogin();
+ void setupRegister();
+ private:
+ Gtk::Grid loginLayout;
+ Gtk::Entry loginUsernameInput;
+ Gtk::Entry loginPasswordInput;
Gtk::Button loginButton;
std::function<void()> loginHandler;
LoginHandler loginHandlerUser;
+
+ Gtk::Grid registerLayout;
+ Gtk::Entry registerUsernameInput;
+ Gtk::Entry registerPasswordInput;
+ Gtk::Entry registerPasswordRepeatInput;
+ Gtk::Button registerButton;
+ std::function<void()> registerHandler;
+ RegisterHandler registerHandlerUser;
+ RegisterPasswordMismatchHandler passwordMismatchHandler;
};
} \ No newline at end of file
diff --git a/src/LoginWindow.cpp b/src/LoginWindow.cpp
index 5dfbed6..33802f1 100644
--- a/src/LoginWindow.cpp
+++ b/src/LoginWindow.cpp
@@ -3,60 +3,188 @@
#include <gtkmm/entry.h>
#include <gtkmm/alignment.h>
#include <gtkmm/button.h>
+#include <gtkmm/separator.h>
+#include <gtkmm/eventbox.h>
+#include <gdkmm/cursor.h>
#include <cassert>
namespace dchat
{
LoginWindow::LoginWindow() :
- loginButton("Login")
+ loginButton("Login"),
+ loginHandlerUser(nullptr),
+
+ registerButton("Register"),
+ registerHandlerUser(nullptr),
+ passwordMismatchHandler(nullptr)
+ {
+ setupLogin();
+ setupRegister();
+
+ set_halign(Gtk::ALIGN_CENTER);
+ set_valign(Gtk::ALIGN_CENTER);
+ set_border_width(0);
+ attach(loginLayout, 0, 0, 1, 1);
+ attach(registerLayout, 0, 0, 1, 1);
+ loginLayout.show_all();
+ }
+
+ void LoginWindow::setLoginHandler(LoginHandler loginHandler)
+ {
+ loginHandlerUser = loginHandler;
+ }
+
+ void LoginWindow::setRegisterHandler(RegisterHandler registerHandler)
+ {
+ registerHandlerUser = registerHandler;
+ }
+
+ void LoginWindow::setRegisterPasswordMismatch(RegisterPasswordMismatchHandler passwordMismatchHandler)
+ {
+ this->passwordMismatchHandler = passwordMismatchHandler;
+ }
+
+ void LoginWindow::setupLogin()
{
loginHandler = [this]
{
if(loginHandlerUser)
- loginHandlerUser(usernameInput.get_text(), passwordInput.get_text());
+ loginHandlerUser(loginUsernameInput.get_text(), loginPasswordInput.get_text());
};
- Gtk::Label *username = Gtk::manage(new Gtk::Label());
- username->set_text("Username");
+ Gtk::Label *username = Gtk::manage(new Gtk::Label("Username"));
username->set_halign(Gtk::ALIGN_START);
- attach(*username, 0, 0, 1, 1);
+ loginLayout.attach(*username, 0, 0, 1, 1);
- usernameInput.set_size_request(200);
- usernameInput.signal_activate().connect(loginHandler);
- attach_next_to(usernameInput, *username, Gtk::POS_BOTTOM, 3, 1);
+ loginUsernameInput.set_size_request(200);
+ loginUsernameInput.signal_activate().connect(loginHandler);
+ loginLayout.attach_next_to(loginUsernameInput, *username, Gtk::POS_BOTTOM, 3, 1);
Gtk::Alignment *usernamePasswordSpacer = Gtk::manage(new Gtk::Alignment());
usernamePasswordSpacer->set_size_request(-1, 35);
- attach_next_to(*usernamePasswordSpacer, usernameInput, Gtk::POS_BOTTOM, 1, 1);
+ loginLayout.attach_next_to(*usernamePasswordSpacer, loginUsernameInput, Gtk::POS_BOTTOM, 1, 1);
- Gtk::Label *password = Gtk::manage(new Gtk::Label());
- password->set_text("Password");
+ Gtk::Label *password = Gtk::manage(new Gtk::Label("Password"));
password->set_halign(Gtk::ALIGN_START);
- attach_next_to(*password, *usernamePasswordSpacer, Gtk::POS_BOTTOM, 1, 1);
+ loginLayout.attach_next_to(*password, *usernamePasswordSpacer, Gtk::POS_BOTTOM, 1, 1);
- passwordInput.set_visibility(false);
- passwordInput.set_size_request(200);
- passwordInput.signal_activate().connect(loginHandler);
- attach_next_to(passwordInput, *password, Gtk::POS_BOTTOM, 3, 1);
+ loginPasswordInput.set_visibility(false);
+ loginPasswordInput.set_size_request(200);
+ loginPasswordInput.signal_activate().connect(loginHandler);
+ loginLayout.attach_next_to(loginPasswordInput, *password, Gtk::POS_BOTTOM, 3, 1);
Gtk::Alignment *loginButtonSpacerTop = Gtk::manage(new Gtk::Alignment());
loginButtonSpacerTop->set_size_request(-1, 20);
- attach_next_to(*loginButtonSpacerTop, passwordInput, Gtk::POS_BOTTOM, 1, 1);
+ loginLayout.attach_next_to(*loginButtonSpacerTop, loginPasswordInput, Gtk::POS_BOTTOM, 1, 1);
Gtk::Alignment *loginButtonSpacer = Gtk::manage(new Gtk::Alignment());
- attach_next_to(*loginButtonSpacer, *loginButtonSpacerTop, Gtk::POS_BOTTOM, 2, 1);
+ loginLayout.attach_next_to(*loginButtonSpacer, *loginButtonSpacerTop, Gtk::POS_BOTTOM, 2, 1);
loginButton.set_halign(Gtk::ALIGN_END);
loginButton.signal_clicked().connect(loginHandler);
- attach_next_to(loginButton, *loginButtonSpacer, Gtk::POS_RIGHT, 1, 1);
+ loginButton.get_style_context()->add_class("confirm-button");
+ loginLayout.attach_next_to(loginButton, *loginButtonSpacer, Gtk::POS_RIGHT, 1, 1);
- set_halign(Gtk::ALIGN_CENTER);
- set_valign(Gtk::ALIGN_CENTER);
- get_style_context()->add_class("login-window");
+ Gtk::Separator *separator = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
+ separator->get_style_context()->add_class("separator-horizontal-margin");
+ loginLayout.attach_next_to(*separator, *loginButtonSpacer, Gtk::POS_BOTTOM, 3, 1);
+
+ Gtk::Label *registerText = Gtk::manage(new Gtk::Label("Don't have an account? "));
+ loginLayout.attach_next_to(*registerText, *separator, Gtk::POS_BOTTOM, 1, 1);
+ Gtk::Label *registerTextClickable = Gtk::manage(new Gtk::Label());
+ registerTextClickable->set_markup("<span color='#3060d8'>Register a new one</span>");
+ Gtk::EventBox *eventBox = Gtk::manage(new Gtk::EventBox());
+ eventBox->add(*registerTextClickable);
+ auto pointerCursor = Gdk::Cursor::create(Gdk::Display::get_default(), "pointer");
+ //eventBox->get_window()->set_cursor(pointerCursor);
+ eventBox->signal_button_release_event().connect([this](GdkEventButton *event)
+ {
+ loginLayout.hide();
+ registerLayout.show_all();
+ return true;
+ });
+ loginLayout.attach_next_to(*eventBox, *registerText, Gtk::POS_RIGHT, 1, 1);
+
+ loginLayout.get_style_context()->add_class("login-window");
}
- void LoginWindow::setLoginHandler(LoginHandler loginHandler)
+ void LoginWindow::setupRegister()
{
- loginHandlerUser = loginHandler;
+ registerHandler = [this]
+ {
+ if(registerPasswordInput.get_text() != registerPasswordRepeatInput.get_text())
+ {
+ if(passwordMismatchHandler)
+ passwordMismatchHandler();
+ return;
+ }
+
+ if(registerHandlerUser)
+ registerHandlerUser(registerUsernameInput.get_text(), registerPasswordInput.get_text());
+ };
+
+ Gtk::Label *username = Gtk::manage(new Gtk::Label("Username"));
+ username->set_halign(Gtk::ALIGN_START);
+ registerLayout.attach(*username, 0, 0, 1, 1);
+
+ registerUsernameInput.set_size_request(200);
+ registerUsernameInput.signal_activate().connect(registerHandler);
+ registerLayout.attach_next_to(registerUsernameInput, *username, Gtk::POS_BOTTOM, 3, 1);
+
+ Gtk::Alignment *usernamePasswordSpacer = Gtk::manage(new Gtk::Alignment());
+ usernamePasswordSpacer->set_size_request(-1, 35);
+ registerLayout.attach_next_to(*usernamePasswordSpacer, registerUsernameInput, Gtk::POS_BOTTOM, 1, 1);
+
+ Gtk::Label *password = Gtk::manage(new Gtk::Label("Password"));
+ password->set_halign(Gtk::ALIGN_START);
+ registerLayout.attach_next_to(*password, *usernamePasswordSpacer, Gtk::POS_BOTTOM, 1, 1);
+
+ registerPasswordInput.set_visibility(false);
+ registerPasswordInput.set_size_request(200);
+ registerPasswordInput.signal_activate().connect(registerHandler);
+ registerLayout.attach_next_to(registerPasswordInput, *password, Gtk::POS_BOTTOM, 3, 1);
+
+ Gtk::Label *repeatPassword = Gtk::manage(new Gtk::Label("Repeat password"));
+ repeatPassword->set_halign(Gtk::ALIGN_START);
+ registerLayout.attach_next_to(*repeatPassword, registerPasswordInput, Gtk::POS_BOTTOM, 1, 1);
+
+ registerPasswordRepeatInput.set_visibility(false);
+ registerPasswordRepeatInput.set_size_request(200);
+ registerPasswordRepeatInput.signal_activate().connect(registerHandler);
+ registerLayout.attach_next_to(registerPasswordRepeatInput, *repeatPassword, Gtk::POS_BOTTOM, 3, 1);
+
+ Gtk::Alignment *registerButtonSpacerTop = Gtk::manage(new Gtk::Alignment());
+ registerButtonSpacerTop->set_size_request(-1, 20);
+ registerLayout.attach_next_to(*registerButtonSpacerTop, registerPasswordRepeatInput, Gtk::POS_BOTTOM, 1, 1);
+
+ Gtk::Alignment *registerButtonSpacer = Gtk::manage(new Gtk::Alignment());
+ registerLayout.attach_next_to(*registerButtonSpacer, *registerButtonSpacerTop, Gtk::POS_BOTTOM, 2, 1);
+
+ registerButton.set_halign(Gtk::ALIGN_END);
+ registerButton.signal_clicked().connect(registerHandler);
+ registerButton.get_style_context()->add_class("confirm-button");
+ registerLayout.attach_next_to(registerButton, *registerButtonSpacer, Gtk::POS_RIGHT, 1, 1);
+
+ Gtk::Separator *separator = Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_HORIZONTAL));
+ separator->get_style_context()->add_class("separator-horizontal-margin");
+ registerLayout.attach_next_to(*separator, *registerButtonSpacer, Gtk::POS_BOTTOM, 3, 1);
+
+ Gtk::Label *loginText = Gtk::manage(new Gtk::Label("Already have an account? "));
+ registerLayout.attach_next_to(*loginText, *separator, Gtk::POS_BOTTOM, 1, 1);
+ Gtk::Label *loginTextClickable = Gtk::manage(new Gtk::Label());
+ loginTextClickable->set_markup("<span color='#3060d8'>Login to an existing account</span>");
+ Gtk::EventBox *eventBox = Gtk::manage(new Gtk::EventBox());
+ eventBox->add(*loginTextClickable);
+ auto pointerCursor = Gdk::Cursor::create(Gdk::Display::get_default(), "pointer");
+ //eventBox->get_window()->set_cursor(pointerCursor);
+ eventBox->signal_button_release_event().connect([this](GdkEventButton *event)
+ {
+ registerLayout.hide();
+ loginLayout.show_all();
+ return true;
+ });
+ registerLayout.attach_next_to(*eventBox, *loginText, Gtk::POS_RIGHT, 1, 1);
+
+ registerLayout.get_style_context()->add_class("login-window");
}
} \ No newline at end of file
diff --git a/src/Window.cpp b/src/Window.cpp
index 72a3d9d..970242d 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -21,10 +21,15 @@ namespace dchat
stack.add(loginWindow, "login");
stack.add(chatWindow, "chat");
- show_all();
+ overlay->show();
+ windowNotification->show_all();
+ stack.show();
+ chatWindow.show_all();
+ loginWindow.show();
loginWindow.setLoginHandler([this, windowNotification](const Glib::ustring &username, const Glib::ustring &password)
{
+ std::lock_guard<std::mutex> lock(databaseCallbackMutex);
if(!database)
{
windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
@@ -35,7 +40,7 @@ namespace dchat
{
fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str());
auto storedNodes = database->getStoredNodeUserInfoDecrypted(username.raw(), password.raw());
- fprintf(stderr, "Successfully logged in as %s\n", username.raw().c_str());
+ windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
stack.set_visible_child(chatWindow);
for(auto &nodeInfo : storedNodes)
@@ -51,6 +56,37 @@ namespace dchat
}
});
+ loginWindow.setRegisterHandler([this, windowNotification](const Glib::ustring &username, const Glib::ustring &password)
+ {
+ std::lock_guard<std::mutex> lock(databaseCallbackMutex);
+ if(!database)
+ {
+ windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
+ return;
+ }
+
+ try
+ {
+ fprintf(stderr, "Trying to register username %s\n", username.raw().c_str());
+ database->storeUserWithoutNodes(username.raw(), password.raw());
+ windowNotification->show(Glib::ustring("Successfully registered user ") + username);
+ stack.set_visible_child(chatWindow);
+ }
+ catch(std::exception &e)
+ {
+ Glib::ustring errMsg = "Failed to register username ";
+ errMsg += username.raw();
+ errMsg += ", reason: ";
+ errMsg += e.what();
+ windowNotification->show(errMsg);
+ }
+ });
+
+ loginWindow.setRegisterPasswordMismatch([windowNotification]
+ {
+ windowNotification->show("Passwords do not match");
+ });
+
odhtdb::DatabaseCallbackFuncs callbackFuncs;
callbackFuncs.createNodeCallbackFunc = [this](const odhtdb::DatabaseCreateNodeRequest &request)
{