From 616fb291ee1f62202affbec3a043f741c2c2469c Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 25 Oct 2018 17:51:19 +0200 Subject: Login works and showing messages, nothing else --- css/style.css | 4 +++ include/Cache.hpp | 16 ++++++++++++ include/ChannelDataType.hpp | 16 ++++++++++++ include/ChatWindow.hpp | 15 +++++++++++ include/LoginWindow.hpp | 6 ++++- include/Window.hpp | 24 ++++++++++------- include/env.hpp | 59 ++++++++++++++++++++++++++++++++++++++++++ include/types.hpp | 22 ++++++++++++++++ src/Cache.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++++ src/ChatWindow.cpp | 52 +++++++++++++++++++++++++------------ src/LoginWindow.cpp | 16 ++++++++---- src/Window.cpp | 63 +++++++++++++++++++++++++++++++++++++++++++-- src/main.cpp | 33 +++++------------------- 13 files changed, 329 insertions(+), 60 deletions(-) create mode 100644 include/Cache.hpp create mode 100644 include/ChannelDataType.hpp create mode 100644 include/env.hpp create mode 100644 include/types.hpp create mode 100644 src/Cache.cpp diff --git a/css/style.css b/css/style.css index d07b4c4..bcafa69 100644 --- a/css/style.css +++ b/css/style.css @@ -54,6 +54,10 @@ button { font-size: 16px; } +.channel-button { + background-color: transparent; +} + #users-title { color: #f7f7f7; font-weight: bold; diff --git a/include/Cache.hpp b/include/Cache.hpp new file mode 100644 index 0000000..97ef495 --- /dev/null +++ b/include/Cache.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace dchat +{ + class Cache + { + public: + Cache(); + ~Cache(); + + // Creates directory if it doesn't exist (recursively). Throws boost exception on failure + static boost::filesystem::path getDchatDir(); + }; +} diff --git a/include/ChannelDataType.hpp b/include/ChannelDataType.hpp new file mode 100644 index 0000000..398e716 --- /dev/null +++ b/include/ChannelDataType.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "types.hpp" + +namespace dchat +{ + enum class ChannelDataType : u8 + { + ADD_MESSAGE, + EDIT_MESSAGE, + DELETE_MESSAGE, + NICKNAME_CHANGE, + CHANGE_AVATAR, + CHANGE_CHANNEL_NAME, + }; +} \ No newline at end of file diff --git a/include/ChatWindow.hpp b/include/ChatWindow.hpp index 2d45b76..b13046e 100644 --- a/include/ChatWindow.hpp +++ b/include/ChatWindow.hpp @@ -1,12 +1,14 @@ #pragma once #include +#include #include #include #include #include #include #include +#include namespace dchat { @@ -14,6 +16,8 @@ namespace dchat { public: ChatWindow(); + void addChannel(const odhtdb::Hash &nodeHash); + void addLocalMessage(const odhtdb::Hash &channelId, Glib::ustring msg); private: void setupTopBar(); void setupLeftPanel(Gtk::Paned *sidePanels); @@ -22,8 +26,19 @@ namespace dchat private: Gtk::Grid topbar; Gtk::Entry topbarSearchBar; + Gtk::Grid leftPanelChannels; Gtk::Label currentChannelTitle; Gtk::ScrolledWindow chatArea; + Gtk::Grid chatAreaLayout; Gtk::TextView chatInput; + + struct ChannelData + { + Gtk::Button *button; + int messageCount; + }; + + odhtdb::MapHash channelDataById; + int channelCount; }; } \ No newline at end of file diff --git a/include/LoginWindow.hpp b/include/LoginWindow.hpp index b60dddb..b842eb5 100644 --- a/include/LoginWindow.hpp +++ b/include/LoginWindow.hpp @@ -7,15 +7,19 @@ namespace dchat { + using LoginHandler = std::function; + class LoginWindow : public Gtk::Grid { public: LoginWindow(); - void setLoginHandler(std::function loginHandler); + void setLoginHandler(LoginHandler loginHandler); private: Gtk::Entry usernameInput; Gtk::Entry passwordInput; Gtk::Button loginButton; + std::function loginHandler; + LoginHandler loginHandlerUser; }; } \ No newline at end of file diff --git a/include/Window.hpp b/include/Window.hpp index 2810bbd..96197c6 100644 --- a/include/Window.hpp +++ b/include/Window.hpp @@ -4,17 +4,21 @@ #include "LoginWindow.hpp" #include #include +#include +#include namespace dchat { - class Window : public Gtk::Window - { - public: - Window(); - virtual ~Window(); - protected: - Gtk::Stack stack; - LoginWindow loginWindow; - ChatWindow chatWindow; - }; + class Window : public Gtk::Window + { + public: + Window(); + virtual ~Window(); + protected: + std::unique_ptr database; + std::mutex databaseCallbackMutex; + Gtk::Stack stack; + LoginWindow loginWindow; + ChatWindow chatWindow; + }; } \ No newline at end of file diff --git a/include/env.hpp b/include/env.hpp new file mode 100644 index 0000000..abaedd8 --- /dev/null +++ b/include/env.hpp @@ -0,0 +1,59 @@ +#pragma once + +#define OS_FAMILY_WINDOWS 0 +#define OS_FAMILY_POSIX 1 + +#define OS_TYPE_WINDOWS 0 +#define OS_TYPE_LINUX 1 + +#if defined(_WIN32) || defined(_WIN64) + #if defined(_WIN64) + #define SYS_ENV_64BIT + #else + #define SYS_ENV_32BIT + #endif + #define OS_FAMILY OS_FAMILY_WINDOWS + #define OS_TYPE OS_TYPE_WINDOWS + + #ifndef UNICODE + #define UNICODE + #endif + + #ifndef _UNICODE + #define _UNICODE + #endif + + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + + #include +#endif + +#if defined(__linux__) || defined(__unix__) || defined(__APPLE__) || defined(_POSIX_VERSION) + #define OS_FAMILY OS_FAMILY_POSIX +#endif + +#ifdef __linux__ + #define OS_TYPE OS_TYPE_LINUX +#endif + +#if defined(__GNUC__) + #if defined(__x86_64__) || defined(__pc64__) + #define SYS_ENV_64BIT + #else + #define SYS_ENV_32BIT + #endif +#endif + +#if !defined(SYS_ENV_32BIT) && !defined(SYS_ENV_64BIT) + #error "System is not detected as either 32-bit or 64-bit" +#endif + +#if !defined(OS_FAMILY) + #error "System not supported. Only Windows and Posix systems supported right now" +#endif + +#if !defined(OS_TYPE) + #error "System not supported. Only Windows and linux systems supported right now" +#endif diff --git a/include/types.hpp b/include/types.hpp new file mode 100644 index 0000000..762dab1 --- /dev/null +++ b/include/types.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +namespace dchat +{ + typedef int8_t i8; + typedef int16_t i16; + typedef int32_t i32; + typedef int64_t i64; + + typedef uint8_t u8; + typedef uint16_t u16; + typedef uint32_t u32; + typedef uint64_t u64; + + typedef float f32; + typedef double f64; + + typedef intptr_t ssize; + typedef uintptr_t usize; +} diff --git a/src/Cache.cpp b/src/Cache.cpp new file mode 100644 index 0000000..d4c19fb --- /dev/null +++ b/src/Cache.cpp @@ -0,0 +1,63 @@ +#include "../include/Cache.hpp" +#include "../include/env.hpp" +#include + +#if OS_FAMILY == OS_FAMILY_POSIX +#include +#else +#include +#endif + +using namespace std; + +namespace dchat +{ + static boost::filesystem::path getHomeDir() + { + #if OS_FAMILY == OS_FAMILY_POSIX + const char *homeDir = getenv("HOME"); + if(!homeDir) + { + passwd *pw = getpwuid(getuid()); + homeDir = pw->pw_dir; + } + return boost::filesystem::path(homeDir); + #elif OS_FAMILY == OS_FAMILY_WINDOWS + BOOL ret; + HANDLE hToken; + std::wstring homeDir; + DWORD homeDirLen = MAX_PATH; + homeDir.resize(homeDirLen); + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) + return Result::Err("Failed to open process token"); + + if (!GetUserProfileDirectory(hToken, &homeDir[0], &homeDirLen)) + { + CloseHandle(hToken); + return Result::Err("Failed to get home directory"); + } + + CloseHandle(hToken); + homeDir.resize(wcslen(homeDir.c_str())); + return boost::filesystem::path(homeDir); + #endif + } + + Cache::Cache() + { + + } + + Cache::~Cache() + { + + } + + boost::filesystem::path Cache::getDchatDir() + { + boost::filesystem::path dchatHomeDir = getHomeDir() / ".local" / "share" / "dchat"; + boost::filesystem::create_directories(dchatHomeDir); + return dchatHomeDir; + } +} diff --git a/src/ChatWindow.cpp b/src/ChatWindow.cpp index a428d0b..70dd734 100644 --- a/src/ChatWindow.cpp +++ b/src/ChatWindow.cpp @@ -1,10 +1,12 @@ #include "../include/ChatWindow.hpp" #include "../include/ChatMessage.hpp" #include +#include namespace dchat { - ChatWindow::ChatWindow() + ChatWindow::ChatWindow() : + channelCount(0) { setupTopBar(); @@ -54,14 +56,14 @@ namespace dchat leftPanel->set_vexpand(true); sidePanels->add1(*leftPanel); - Gtk::Grid *leftPanelChannels = Gtk::manage(new Gtk::Grid()); - leftPanelChannels->set_vexpand(true); - leftPanel->add1(*leftPanelChannels); + leftPanelChannels.set_vexpand(true); + leftPanel->add1(leftPanelChannels); Gtk::Label *channelsTitle = Gtk::manage(new Gtk::Label()); channelsTitle->set_name("channels-title"); channelsTitle->set_text("Channels"); - leftPanelChannels->attach(*channelsTitle, 0, 0, 1, 1); + channelsTitle->set_halign(Gtk::ALIGN_START); + leftPanelChannels.attach(*channelsTitle, 0, 0, 1, 1); //// Gtk::Grid *leftPanelUsers = Gtk::manage(new Gtk::Grid()); @@ -71,6 +73,7 @@ namespace dchat Gtk::Label *usersTitle = Gtk::manage(new Gtk::Label()); usersTitle->set_name("users-title"); usersTitle->set_text("Users"); + usersTitle->set_halign(Gtk::ALIGN_START); leftPanelUsers->attach(*usersTitle, 0, 0, 1, 1); } @@ -79,17 +82,8 @@ namespace dchat chatArea.set_vexpand(true); rightPanel->attach(chatArea, 0, 0, 1, 2); - Gtk::Grid *chatAreaLayout = Gtk::manage(new Gtk::Grid()); - chatAreaLayout->set_name("chat-area-layout"); - chatArea.add(*chatAreaLayout); - - for(int i = 0; i < 100; ++i) - { - ChatMessage *message = Gtk::manage(new ChatMessage("Arezu", "hellooooo" + std::to_string(i))); - message->set_valign(Gtk::Align::ALIGN_START); - message->set_hexpand(true); - chatAreaLayout->attach(*message, 0, i, 1, 1); - } + chatAreaLayout.set_name("chat-area-layout"); + chatArea.add(chatAreaLayout); } void ChatWindow::setupChatInput(Gtk::Grid *rightPanel) @@ -103,4 +97,30 @@ namespace dchat chatInput.set_wrap_mode(Gtk::WrapMode::WRAP_WORD_CHAR); chatScrollWindow->add(chatInput); } + + void ChatWindow::addChannel(const odhtdb::Hash &nodeHash) + { + assert(channelDataById.find(nodeHash) == channelDataById.end()); + printf("Added channel\n"); + Gtk::Button *channelButton = Gtk::manage(new Gtk::Button("Channel name")); + 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 }; + } + + void ChatWindow::addLocalMessage(const odhtdb::Hash &channelId, Glib::ustring msg) + { + auto it = channelDataById.find(channelId); + assert(it != channelDataById.end()); + ChatMessage *message = Gtk::manage(new ChatMessage("Arezu", msg)); + message->set_valign(Gtk::Align::ALIGN_START); + message->set_hexpand(true); + message->show_all(); + chatAreaLayout.attach(*message, 0, it->second.messageCount, 1, 1); + ++it->second.messageCount; + } } \ No newline at end of file diff --git a/src/LoginWindow.cpp b/src/LoginWindow.cpp index 4232982..5dfbed6 100644 --- a/src/LoginWindow.cpp +++ b/src/LoginWindow.cpp @@ -10,12 +10,19 @@ namespace dchat LoginWindow::LoginWindow() : loginButton("Login") { + loginHandler = [this] + { + if(loginHandlerUser) + loginHandlerUser(usernameInput.get_text(), passwordInput.get_text()); + }; + Gtk::Label *username = Gtk::manage(new Gtk::Label()); username->set_text("Username"); username->set_halign(Gtk::ALIGN_START); 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); Gtk::Alignment *usernamePasswordSpacer = Gtk::manage(new Gtk::Alignment()); @@ -29,6 +36,7 @@ namespace dchat passwordInput.set_visibility(false); passwordInput.set_size_request(200); + passwordInput.signal_activate().connect(loginHandler); attach_next_to(passwordInput, *password, Gtk::POS_BOTTOM, 3, 1); Gtk::Alignment *loginButtonSpacerTop = Gtk::manage(new Gtk::Alignment()); @@ -39,6 +47,7 @@ namespace dchat 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); set_halign(Gtk::ALIGN_CENTER); @@ -46,11 +55,8 @@ namespace dchat get_style_context()->add_class("login-window"); } - void LoginWindow::setLoginHandler(std::function loginHandler) + void LoginWindow::setLoginHandler(LoginHandler loginHandler) { - assert(loginHandler); - usernameInput.signal_activate().connect(loginHandler); - passwordInput.signal_activate().connect(loginHandler); - loginButton.signal_clicked().connect(loginHandler); + loginHandlerUser = loginHandler; } } \ No newline at end of file diff --git a/src/Window.cpp b/src/Window.cpp index c912130..5f27000 100644 --- a/src/Window.cpp +++ b/src/Window.cpp @@ -1,4 +1,6 @@ #include "../include/Window.hpp" +#include "../include/Cache.hpp" +#include "../include/ChannelDataType.hpp" namespace dchat { @@ -12,10 +14,67 @@ namespace dchat show_all_children(); - loginWindow.setLoginHandler([] + loginWindow.setLoginHandler([this](const Glib::ustring &username, const Glib::ustring &password) { - printf("login!\n"); + if(!database) + { + fprintf(stderr, "You are not connected to the bootstrap node yet! please wait...\n"); + return; + } + + try + { + printf("Trying to login with username %s\n", username.raw().c_str()); + auto storedNodes = database->getStoredNodeUserInfoDecrypted(username.raw(), password.raw()); + printf("Successfully logged in as %s\n", username.raw().c_str()); + stack.set_visible_child(chatWindow); + + for(auto &nodeInfo : storedNodes) + { + database->loadNode(nodeInfo.first); + } + } + catch(std::exception &e) + { + fprintf(stderr, "Failed to login, reason: %s\n", e.what()); + } }); + + odhtdb::DatabaseCallbackFuncs callbackFuncs; + callbackFuncs.createNodeCallbackFunc = [this](const odhtdb::DatabaseCreateNodeRequest &request) + { + std::lock_guard lock(databaseCallbackMutex); + chatWindow.addChannel(*request.nodeHash); + }; + + callbackFuncs.addNodeCallbackFunc = [this](const odhtdb::DatabaseAddNodeRequest &request) + { + std::lock_guard lock(databaseCallbackMutex); + if(request.decryptedData.size == 0) + return; + + ChannelDataType channelDataType = (ChannelDataType)static_cast(request.decryptedData.data)[0]; + switch(channelDataType) + { + case ChannelDataType::ADD_MESSAGE: + { + Glib::ustring msg((const char*)request.decryptedData.data + 1, request.decryptedData.size - 1); + chatWindow.addLocalMessage(*request.nodeHash, std::move(msg)); + break; + } + default: + break; + } + }; + + callbackFuncs.addUserCallbackFunc = [this](const odhtdb::DatabaseAddUserRequest &request) + { + std::lock_guard lock(databaseCallbackMutex); + }; + + printf("Connecting...\n"); + database = odhtdb::Database::connect("83.252.53.188", 27130, Cache::getDchatDir(), callbackFuncs).get(); + stack.set_visible_child(loginWindow); } Window::~Window() diff --git a/src/main.cpp b/src/main.cpp index d83fd27..6c7dec6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,6 @@ #include "../include/Window.hpp" #include #include -#include int main (int argc, char *argv[]) { @@ -10,16 +9,16 @@ int main (int argc, char *argv[]) auto css = Gtk::CssProvider::create(); try { - if(!css->load_from_path("css/style.css")) - { - fprintf(stderr, "Failed to load css/style.css"); - return 1; - } + if(!css->load_from_path("css/style.css")) + { + fprintf(stderr, "Failed to load css/style.css"); + return 1; + } } catch(Gtk::CssProviderError &e) { - fprintf(stderr, "Failed to load css/style.css, error: %s\n", e.what().c_str()); - return 1; + fprintf(stderr, "Failed to load css/style.css, error: %s\n", e.what().c_str()); + return 1; } dchat::Window window; @@ -27,23 +26,5 @@ int main (int argc, char *argv[]) auto screen = Gdk::Screen::get_default(); ctx->add_provider_for_screen(screen, css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - odhtdb::DatabaseCallbackFuncs callbackFuncs; - callbackFuncs.createNodeCallbackFunc = [](const odhtdb::DatabaseCreateNodeRequest &request) - { - - }; - - callbackFuncs.addNodeCallbackFunc = [](const odhtdb::DatabaseAddNodeRequest &request) - { - - }; - - callbackFuncs.addUserCallbackFunc = [](const odhtdb::DatabaseAddUserRequest &request) - { - - }; - - //odhtdb::Database database("206.189.13.66", 27130, "/tmp/dchat_gtk", callbackFuncs); - return app->run(window); } -- cgit v1.2.3