summary refs log tree commit diff
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-12-11 23:00:37 +0200
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-12-11 23:00:37 +0200
commit544b62351212188449851b7092cf229091c6f612 (patch)
treeb4201211717b25fc90819a1291e8a16373bd7aea
parentAdd system theme colors for FloatingButton (#112) (diff)
downloadnheko-544b62351212188449851b7092cf229091c6f612.tar.xz
Add dialog to create rooms
fixes #25
-rw-r--r--CMakeLists.txt2
-rw-r--r--include/MatrixClient.h3
-rw-r--r--include/SideBarActions.h5
-rw-r--r--include/dialogs/CreateRoom.h44
m---------libs/matrix-structs0
-rw-r--r--resources/styles/nheko-dark.qss1
-rw-r--r--resources/styles/nheko.qss1
-rw-r--r--src/ChatPage.cc7
-rw-r--r--src/MatrixClient.cc43
-rw-r--r--src/SideBarActions.cc27
-rw-r--r--src/dialogs/CreateRoom.cc152
11 files changed, 285 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b6affe75..4e71b5f0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -141,6 +141,7 @@ endif()
 #
 set(SRC_FILES
     # Dialogs
+    src/dialogs/CreateRoom.cc
     src/dialogs/ImageOverlay.cc
     src/dialogs/InviteUsers.cc
     src/dialogs/JoinRoom.cc
@@ -219,6 +220,7 @@ include_directories(${LMDB_INCLUDE_DIR})
 
 qt5_wrap_cpp(MOC_HEADERS
     # Dialogs
+    include/dialogs/CreateRoom.h
     include/dialogs/ImageOverlay.h
     include/dialogs/InviteUsers.h
     include/dialogs/JoinRoom.h
diff --git a/include/MatrixClient.h b/include/MatrixClient.h
index ee493da6..2e76061f 100644
--- a/include/MatrixClient.h
+++ b/include/MatrixClient.h
@@ -61,6 +61,7 @@ public:
         void removeTypingNotification(const QString &roomid);
         void readEvent(const QString &room_id, const QString &event_id);
         void inviteUser(const QString &room_id, const QString &user);
+        void createRoom(const mtx::requests::CreateRoom &request);
 
         QUrl getHomeServer() { return server_; };
         int transactionId() { return txn_id_; };
@@ -86,6 +87,7 @@ signals:
 
         void loggedOut();
         void invitedUser(const QString &room_id, const QString &user);
+        void roomCreated(const QString &room_id);
 
         void loginSuccess(const QString &userid, const QString &homeserver, const QString &token);
         void registerSuccess(const QString &userid,
@@ -115,6 +117,7 @@ signals:
         void messagesRetrieved(const QString &room_id, const mtx::responses::Messages &msgs);
         void joinedRoom(const QString &room_id);
         void leftRoom(const QString &room_id);
+        void roomCreationFailed(const QString &msg);
 
 private:
         QNetworkReply *makeUploadRequest(const QString &filename);
diff --git a/include/SideBarActions.h b/include/SideBarActions.h
index 7fbb7e67..f9b9bb1c 100644
--- a/include/SideBarActions.h
+++ b/include/SideBarActions.h
@@ -8,6 +8,7 @@
 #include "FlatButton.h"
 #include "Menu.h"
 
+#include "dialogs/CreateRoom.h"
 #include "dialogs/JoinRoom.h"
 
 class OverlayModal;
@@ -23,6 +24,7 @@ public:
 signals:
         void showSettings();
         void joinRoom(const QString &room);
+        void createRoom(const mtx::requests::CreateRoom &request);
 
 protected:
         void resizeEvent(QResizeEvent *event) override;
@@ -37,6 +39,9 @@ private:
         QSharedPointer<OverlayModal> joinRoomModal_;
         QSharedPointer<dialogs::JoinRoom> joinRoomDialog_;
 
+        QSharedPointer<OverlayModal> createRoomModal_;
+        QSharedPointer<dialogs::CreateRoom> createRoomDialog_;
+
         FlatButton *settingsBtn_;
         FlatButton *createRoomBtn_;
         FlatButton *joinRoomBtn_;
diff --git a/include/dialogs/CreateRoom.h b/include/dialogs/CreateRoom.h
new file mode 100644
index 00000000..96095187
--- /dev/null
+++ b/include/dialogs/CreateRoom.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <QFrame>
+
+#include <mtx.hpp>
+
+class FlatButton;
+class TextField;
+class QComboBox;
+class Toggle;
+
+namespace dialogs {
+
+class CreateRoom : public QFrame
+{
+        Q_OBJECT
+public:
+        CreateRoom(QWidget *parent = nullptr);
+
+signals:
+        void closing(bool isCreating, const mtx::requests::CreateRoom &request);
+
+protected:
+        void paintEvent(QPaintEvent *event) override;
+
+private:
+        void clearFields();
+
+        QComboBox *visibilityCombo_;
+        QComboBox *presetCombo_;
+
+        Toggle *directToggle_;
+
+        FlatButton *confirmBtn_;
+        FlatButton *cancelBtn_;
+
+        TextField *nameInput_;
+        TextField *topicInput_;
+        TextField *aliasInput_;
+
+        mtx::requests::CreateRoom request_;
+};
+
+} // dialogs
diff --git a/libs/matrix-structs b/libs/matrix-structs
-Subproject 9946ed125e5cc3b2fb425648679ada615c862be
+Subproject d03a370ffd1bbdd5623afbe9817d1b929bc76cd
diff --git a/resources/styles/nheko-dark.qss b/resources/styles/nheko-dark.qss
index 42ee6740..0fd519ea 100644
--- a/resources/styles/nheko-dark.qss
+++ b/resources/styles/nheko-dark.qss
@@ -79,6 +79,7 @@ Avatar {
 
 dialogs--Logout,
 dialogs--LeaveRoom,
+dialogs--CreateRoom,
 dialogs--InviteUsers,
 dialogs--JoinRoom {
     background-color: #383c4a;
diff --git a/resources/styles/nheko.qss b/resources/styles/nheko.qss
index 6c592ac8..c55b64fb 100644
--- a/resources/styles/nheko.qss
+++ b/resources/styles/nheko.qss
@@ -81,6 +81,7 @@ Avatar {
 
 dialogs--Logout,
 dialogs--LeaveRoom,
+dialogs--CreateRoom,
 dialogs--InviteUsers,
 dialogs--JoinRoom {
     background-color: white;
diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index dfae487d..4f03026d 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -70,6 +70,8 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
           sidebarActions_, &SideBarActions::showSettings, this, &ChatPage::showUserSettingsPage);
         connect(
           sidebarActions_, &SideBarActions::joinRoom, client_.data(), &MatrixClient::joinRoom);
+        connect(
+          sidebarActions_, &SideBarActions::createRoom, client_.data(), &MatrixClient::createRoom);
 
         user_info_widget_ = new UserInfoWidget(sideBar_);
         room_list_        = new RoomList(client, sideBar_);
@@ -202,6 +204,8 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
                 client_->uploadAudio(current_room_, filename);
         });
 
+        connect(
+          client_.data(), &MatrixClient::roomCreationFailed, this, &ChatPage::showNotification);
         connect(client_.data(), &MatrixClient::joinFailed, this, &ChatPage::showNotification);
         connect(client_.data(),
                 &MatrixClient::imageUploaded,
@@ -268,6 +272,9 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
         connect(client_.data(), &MatrixClient::invitedUser, this, [=](QString, QString user) {
                 emit showNotification(QString("Invited user %1").arg(user));
         });
+        connect(client_.data(), &MatrixClient::roomCreated, this, [=](QString room_id) {
+                emit showNotification(QString("Room %1 created").arg(room_id));
+        });
         connect(client_.data(), &MatrixClient::leftRoom, this, &ChatPage::removeRoom);
 
         showContentTimer_ = new QTimer(this);
diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc
index b18b6e4a..4634345b 100644
--- a/src/MatrixClient.cc
+++ b/src/MatrixClient.cc
@@ -890,6 +890,49 @@ MatrixClient::inviteUser(const QString &roomId, const QString &user)
                 emit invitedUser(roomId, user);
         });
 }
+
+void
+MatrixClient::createRoom(const mtx::requests::CreateRoom &create_room_request)
+{
+        QUrlQuery query;
+        query.addQueryItem("access_token", token_);
+
+        QUrl endpoint(server_);
+        endpoint.setPath(clientApiUrl_ + QString("/createRoom"));
+        endpoint.setQuery(query);
+
+        QNetworkRequest request(endpoint);
+        request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json");
+
+        nlohmann::json body = create_room_request;
+        auto reply          = post(request, QString::fromStdString(body.dump()).toUtf8());
+
+        connect(reply, &QNetworkReply::finished, this, [this, reply]() {
+                reply->deleteLater();
+
+                int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+                if (status == 0 || status >= 400) {
+                        auto data     = reply->readAll();
+                        auto response = QJsonDocument::fromJson(data);
+                        auto json     = response.object();
+
+                        if (json.contains("error"))
+                                emit roomCreationFailed(json["error"].toString());
+                        else
+                                qDebug() << reply->errorString();
+
+                        return;
+                }
+
+                auto data     = reply->readAll();
+                auto response = QJsonDocument::fromJson(data);
+                auto room_id  = response.object()["room_id"].toString();
+
+                emit roomCreated(room_id);
+        });
+}
+
 void
 MatrixClient::sendTypingNotification(const QString &roomid, int timeoutInMillis)
 {
diff --git a/src/SideBarActions.cc b/src/SideBarActions.cc
index f6e99270..c09821ff 100644
--- a/src/SideBarActions.cc
+++ b/src/SideBarActions.cc
@@ -1,3 +1,4 @@
+#include <QDebug>
 #include <QIcon>
 
 #include "Config.h"
@@ -59,6 +60,32 @@ SideBarActions::SideBarActions(QWidget *parent)
                 joinRoomModal_->fadeIn();
         });
 
+        connect(createRoomAction_, &QAction::triggered, this, [=]() {
+                if (createRoomDialog_.isNull()) {
+                        createRoomDialog_ =
+                          QSharedPointer<dialogs::CreateRoom>(new dialogs::CreateRoom(this));
+
+                        connect(createRoomDialog_.data(),
+                                &dialogs::CreateRoom::closing,
+                                this,
+                                [=](bool isCreating, const mtx::requests::CreateRoom &request) {
+                                        createRoomModal_->fadeOut();
+
+                                        if (isCreating)
+                                                emit createRoom(request);
+                                });
+                }
+
+                if (createRoomModal_.isNull()) {
+                        createRoomModal_ = QSharedPointer<OverlayModal>(
+                          new OverlayModal(MainWindow::instance(), createRoomDialog_.data()));
+                        createRoomModal_->setDuration(0);
+                        createRoomModal_->setColor(QColor(30, 30, 30, 170));
+                }
+
+                createRoomModal_->fadeIn();
+        });
+
         addMenu_->addAction(createRoomAction_);
         addMenu_->addAction(joinRoomAction_);
 
diff --git a/src/dialogs/CreateRoom.cc b/src/dialogs/CreateRoom.cc
new file mode 100644
index 00000000..c46636ab
--- /dev/null
+++ b/src/dialogs/CreateRoom.cc
@@ -0,0 +1,152 @@
+#include <QComboBox>
+#include <QLabel>
+#include <QStyleOption>
+#include <QVBoxLayout>
+
+#include "Config.h"
+#include "FlatButton.h"
+#include "TextField.h"
+#include "Theme.h"
+#include "ToggleButton.h"
+
+#include "dialogs/CreateRoom.h"
+
+using namespace dialogs;
+
+CreateRoom::CreateRoom(QWidget *parent)
+  : QFrame(parent)
+{
+        setMaximumSize(520, 600);
+
+        auto layout = new QVBoxLayout(this);
+        layout->setSpacing(30);
+        layout->setMargin(20);
+
+        auto buttonLayout = new QHBoxLayout();
+        buttonLayout->setSpacing(0);
+        buttonLayout->setMargin(0);
+
+        confirmBtn_ = new FlatButton("CREATE", this);
+        confirmBtn_->setFontSize(conf::btn::fontSize);
+
+        cancelBtn_ = new FlatButton(tr("CANCEL"), this);
+        cancelBtn_->setFontSize(conf::btn::fontSize);
+
+        buttonLayout->addStretch(1);
+        buttonLayout->addWidget(confirmBtn_);
+        buttonLayout->addWidget(cancelBtn_);
+
+        QFont font;
+        font.setPixelSize(conf::headerFontSize);
+
+        nameInput_ = new TextField(this);
+        nameInput_->setLabel(tr("Name"));
+
+        topicInput_ = new TextField(this);
+        topicInput_->setLabel(tr("Topic"));
+
+        aliasInput_ = new TextField(this);
+        aliasInput_->setLabel(tr("Alias"));
+
+        auto visibilityLayout = new QHBoxLayout;
+        visibilityLayout->setContentsMargins(0, 10, 0, 10);
+
+        auto presetLayout = new QHBoxLayout;
+        presetLayout->setContentsMargins(0, 10, 0, 10);
+
+        auto visibilityLabel = new QLabel(tr("Room visibility"), this);
+        visibilityCombo_     = new QComboBox(this);
+        visibilityCombo_->addItem("Private");
+        visibilityCombo_->addItem("Public");
+
+        visibilityLayout->addWidget(visibilityLabel);
+        visibilityLayout->addWidget(visibilityCombo_, 0, Qt::AlignBottom | Qt::AlignRight);
+
+        auto presetLabel = new QLabel(tr("Room preset"), this);
+        presetCombo_     = new QComboBox(this);
+        presetCombo_->addItem("Private Chat");
+        presetCombo_->addItem("Public Chat");
+        presetCombo_->addItem("Trusted Private Chat");
+
+        presetLayout->addWidget(presetLabel);
+        presetLayout->addWidget(presetCombo_, 0, Qt::AlignBottom | Qt::AlignRight);
+
+        auto directLabel_ = new QLabel(tr("Direct Chat"), this);
+        directToggle_     = new Toggle(this);
+        directToggle_->setActiveColor(QColor("#38A3D8"));
+        directToggle_->setInactiveColor(QColor("gray"));
+        directToggle_->setState(true);
+        directLabel_->setStyleSheet("font-size: 15px;");
+
+        auto directLayout = new QHBoxLayout;
+        directLayout->setContentsMargins(0, 10, 0, 10);
+        directLayout->addWidget(directLabel_);
+        directLayout->addWidget(directToggle_, 0, Qt::AlignBottom | Qt::AlignRight);
+
+        layout->addWidget(nameInput_);
+        layout->addWidget(topicInput_);
+        layout->addWidget(aliasInput_);
+        layout->addLayout(visibilityLayout);
+        layout->addLayout(presetLayout);
+        layout->addLayout(directLayout);
+        layout->addLayout(buttonLayout);
+
+        connect(confirmBtn_, &QPushButton::clicked, this, [=]() {
+                request_.name            = nameInput_->text().toStdString();
+                request_.topic           = topicInput_->text().toStdString();
+                request_.room_alias_name = aliasInput_->text().toStdString();
+
+                emit closing(true, request_);
+
+                clearFields();
+        });
+
+        connect(cancelBtn_, &QPushButton::clicked, this, [=]() {
+                emit closing(false, request_);
+
+                clearFields();
+        });
+
+        connect(visibilityCombo_,
+                static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
+                [=](const QString &text) {
+                        if (text == "Private") {
+                                request_.visibility = mtx::requests::Visibility::Private;
+                        } else {
+                                request_.visibility = mtx::requests::Visibility::Public;
+                        }
+                });
+
+        connect(presetCombo_,
+                static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),
+                [=](const QString &text) {
+                        if (text == "Private Chat") {
+                                request_.preset = mtx::requests::Preset::PrivateChat;
+                        } else if (text == "Public Chat") {
+                                request_.preset = mtx::requests::Preset::PublicChat;
+                        } else {
+                                request_.preset = mtx::requests::Preset::TrustedPrivateChat;
+                        }
+                });
+
+        connect(directToggle_, &Toggle::toggled, this, [=](bool isDisabled) {
+                request_.is_direct = !isDisabled;
+        });
+}
+
+void
+CreateRoom::clearFields()
+{
+        nameInput_->clear();
+        topicInput_->clear();
+        aliasInput_->clear();
+}
+
+void
+CreateRoom::paintEvent(QPaintEvent *)
+{
+        QStyleOption opt;
+        opt.init(this);
+        QPainter p(this);
+        style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
+}