aboutsummaryrefslogtreecommitdiff
path: root/src/Window.cpp
blob: 970242dab93b603729a0997bf7c13b6dae30850f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "../include/Window.hpp"
#include "../include/Cache.hpp"
#include "../include/ChannelDataType.hpp"
#include "../include/WindowNotification.hpp"
#include <sibs/SafeDeserializer.hpp>

namespace dchat
{
    Window::Window()
    {
        set_border_width(0);
        Gtk::Overlay *overlay = Gtk::manage(new Gtk::Overlay());
        WindowNotification *windowNotification = Gtk::manage(new WindowNotification());
        overlay->add_overlay(*windowNotification);
        overlay->set_overlay_pass_through(*windowNotification);
        overlay->add(stack);
        add(*overlay);

        stack.set_transition_type(Gtk::StackTransitionType::STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT);
        stack.set_transition_duration(250);
        stack.add(loginWindow, "login");
        stack.add(chatWindow, "chat");

        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...");
                return;
            }

            try
            {
                fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str());
                auto storedNodes = database->getStoredNodeUserInfoDecrypted(username.raw(), password.raw());
                windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
                stack.set_visible_child(chatWindow);

                for(auto &nodeInfo : storedNodes)
                {
                    database->loadNode(nodeInfo.first);
                }
            }
            catch(std::exception &e)
            {
                Glib::ustring errMsg = "Failed to login, reason: ";
                errMsg += e.what();
                windowNotification->show(errMsg);
            }
        });

        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)
        {
            std::lock_guard<std::mutex> lock(databaseCallbackMutex);
            chatWindow.addChannel(*request.nodeHash);
            chatWindow.addUser(*request.creatorPublicKey);
        };

        callbackFuncs.addNodeCallbackFunc = [this](const odhtdb::DatabaseAddNodeRequest &request)
        {
            std::lock_guard<std::mutex> lock(databaseCallbackMutex);
            if(request.decryptedData.size == 0)
                return;

            ChannelDataType channelDataType = (ChannelDataType)static_cast<const char*>(request.decryptedData.data)[0];
            try
            {
                switch(channelDataType)
                {
                    case ChannelDataType::ADD_MESSAGE:
                    {
                        Glib::ustring msg((const char*)request.decryptedData.data + 1, request.decryptedData.size - 1);
                        uint32_t timestampSeconds = ntp::NtpTimestamp::fromCombined(request.timestamp).seconds;
                        chatWindow.addLocalMessage(*request.nodeHash, *request.creatorPublicKey, timestampSeconds, std::move(msg));
                        break;
                    }
                    case ChannelDataType::NICKNAME_CHANGE:
                    {
                        sibs::SafeDeserializer deserializer((const u8*)request.decryptedData.data + 1, request.decryptedData.size - 1);
                        u8 nameLength = deserializer.extract<u8>();
                        if(nameLength > 0)
                        {
                            std::string nickname;
                            nickname.resize(nameLength);
                            deserializer.extract((u8*)&nickname[0], nameLength);
                            chatWindow.setUserNickname(*request.creatorPublicKey, nickname);
                        }
                        break;
                    }
                    default:
                        break;
                }
            }
            catch(std::exception &e)
            {
                fprintf(stderr, "Failed to process add node request, reason: %s\n", e.what());
            }
        };

        callbackFuncs.addUserCallbackFunc = [this](const odhtdb::DatabaseAddUserRequest &request)
        {
            std::lock_guard<std::mutex> lock(databaseCallbackMutex);
            chatWindow.addUser(*request.userToAddPublicKey);
        };

        fprintf(stderr, "Connecting...\n");
        database = odhtdb::Database::connect("83.252.53.188", 27130, Cache::getDchatDir(), callbackFuncs).get();
        stack.set_visible_child(loginWindow);
        windowNotification->show("Connected to 83.252.53.188:27130");
    }

    Window::~Window()
    {

    }
}