diff --git a/CMakeLists.txt b/CMakeLists.txt index 699623bd..628a5db2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,6 +123,7 @@ set(SRC_FILES src/TimelineView.cc src/TimelineViewManager.cc src/InputValidator.cc + src/JoinRoomDialog.cc src/Login.cc src/LoginPage.cc src/LogoutDialog.cc @@ -203,6 +204,7 @@ qt5_wrap_cpp(MOC_HEADERS include/EmojiPickButton.h include/ImageItem.h include/ImageOverlayDialog.h + include/JoinRoomDialog.h include/TimelineItem.h include/TimelineView.h include/TimelineViewManager.h diff --git a/include/JoinRoomDialog.h b/include/JoinRoomDialog.h new file mode 100644 index 00000000..6c3fbdcf --- /dev/null +++ b/include/JoinRoomDialog.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include "FlatButton.h" + +class JoinRoomDialog : public QFrame +{ + Q_OBJECT +public: + JoinRoomDialog(QWidget *parent = nullptr); + +signals: + void closing(bool isJoining, QString roomAlias); + +private: + FlatButton *confirmBtn_; + FlatButton *cancelBtn_; + + QLineEdit *roomAliasEdit_; +}; diff --git a/include/MatrixClient.h b/include/MatrixClient.h index 8d6c60a7..f3f818b5 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -52,6 +52,7 @@ public: void downloadImage(const QString &event_id, const QUrl &url); void messages(const QString &room_id, const QString &from_token, int limit = 20) noexcept; void uploadImage(const QString &roomid, const QString &filename); + void joinRoom(const QString &roomIdOrAlias); inline QUrl getHomeServer(); inline int transactionId(); @@ -94,6 +95,7 @@ signals: void messageSent(const QString &event_id, const QString &roomid, const int txn_id); void emoteSent(const QString &event_id, const QString &roomid, const int txn_id); void messagesRetrieved(const QString &room_id, const RoomMessages &msgs); + void joinedRoom(const QString &room_id); private slots: void onResponse(QNetworkReply *reply); @@ -115,6 +117,7 @@ private: Sync, UserAvatar, Versions, + JoinRoom, }; // Response handlers. @@ -132,6 +135,7 @@ private: void onSyncResponse(QNetworkReply *reply); void onUserAvatarResponse(QNetworkReply *reply); void onVersionsResponse(QNetworkReply *reply); + void onJoinRoomResponse(QNetworkReply *reply); // Client API prefix. QString clientApiUrl_; diff --git a/include/RoomList.h b/include/RoomList.h index 573f43a8..6a74da4c 100644 --- a/include/RoomList.h +++ b/include/RoomList.h @@ -21,11 +21,14 @@ #include #include #include +#include #include "MatrixClient.h" #include "RoomInfoListItem.h" #include "RoomState.h" #include "Sync.h" +#include "OverlayModal.h" +#include "JoinRoomDialog.h" class RoomList : public QWidget { @@ -51,6 +54,9 @@ public slots: void updateUnreadMessageCount(const QString &roomid, int count); void updateRoomDescription(const QString &roomid, const DescInfo &info); +private slots: + void closeJoinRoomDialog(bool isJoining, QString roomAlias); + private: void calculateUnreadMessageCount(); @@ -59,6 +65,11 @@ private: QScrollArea *scrollArea_; QWidget *scrollAreaContents_; + QPushButton *joinRoomButton_; + + OverlayModal *joinRoomModal_; + JoinRoomDialog *joinRoomDialog_; + QMap> rooms_; QSharedPointer client_; diff --git a/src/JoinRoomDialog.cc b/src/JoinRoomDialog.cc new file mode 100644 index 00000000..485d97ec --- /dev/null +++ b/src/JoinRoomDialog.cc @@ -0,0 +1,47 @@ +#include +#include + +#include "Config.h" +#include "JoinRoomDialog.h" +#include "Theme.h" + +JoinRoomDialog::JoinRoomDialog(QWidget *parent) + : QFrame(parent) +{ + setMaximumSize(400, 400); + setStyleSheet("background-color: #fff"); + + auto layout = new QVBoxLayout(this); + layout->setSpacing(30); + layout->setMargin(20); + + auto buttonLayout = new QHBoxLayout(); + buttonLayout->setSpacing(0); + buttonLayout->setMargin(0); + + confirmBtn_ = new FlatButton("JOIN", 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); + + auto label = new QLabel(tr("Room alias to join:"), this); + label->setFont(font); + label->setStyleSheet("color: #333333"); + + roomAliasEdit_ = new QLineEdit(this); + + layout->addWidget(label); + layout->addWidget(roomAliasEdit_); + layout->addLayout(buttonLayout); + + connect(confirmBtn_, &QPushButton::clicked, [=]() { emit closing(true, roomAliasEdit_->text()); }); + connect(cancelBtn_, &QPushButton::clicked, [=]() { emit closing(false, nullptr); }); +} diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index 981a30c2..0729cbdc 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -462,6 +462,24 @@ MatrixClient::onMessagesResponse(QNetworkReply *reply) emit messagesRetrieved(room_id, msgs); } +void +MatrixClient::onJoinRoomResponse(QNetworkReply *reply) +{ + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto data = reply->readAll(); + QJsonDocument response = QJsonDocument::fromJson(data); + QString room_id = response.object()["room_id"].toString(); + emit joinedRoom(room_id); +} + void MatrixClient::onResponse(QNetworkReply *reply) { @@ -508,6 +526,9 @@ MatrixClient::onResponse(QNetworkReply *reply) case Endpoint::Messages: onMessagesResponse(reply); break; + case Endpoint::JoinRoom: + onJoinRoomResponse(reply); + break; default: break; } @@ -827,6 +848,13 @@ MatrixClient::uploadImage(const QString &roomid, const QString &filename) QFile file(filename); if (!file.open(QIODevice::ReadWrite)) { + QUrl endpoint(server_); + endpoint.setPath("/_matrix/client/versions"); + + QNetworkRequest request(endpoint); + + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast(Endpoint::Versions)); qDebug() << "Error while reading" << filename; return; } @@ -842,3 +870,20 @@ MatrixClient::uploadImage(const QString &roomid, const QString &filename) reply->setProperty("room_id", roomid); reply->setProperty("filename", filename); } + +void +MatrixClient::joinRoom(const QString &roomIdOrAlias) +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(clientApiUrl_ + QString("/join/%1").arg(roomIdOrAlias)); + endpoint.setQuery(query); + + QNetworkRequest request(endpoint); + request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader,"application/json"); + + QNetworkReply *reply = post(request, "{}"); + reply->setProperty("endpoint", static_cast(Endpoint::JoinRoom)); +} diff --git a/src/RoomList.cc b/src/RoomList.cc index 5c67d98f..fb636995 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc @@ -22,6 +22,7 @@ #include "RoomInfoListItem.h" #include "RoomList.h" #include "Sync.h" +#include "MainWindow.h" RoomList::RoomList(QSharedPointer client, QWidget *parent) : QWidget(parent) @@ -55,6 +56,27 @@ RoomList::RoomList(QSharedPointer client, QWidget *parent) scrollArea_->setWidget(scrollAreaContents_); topLayout_->addWidget(scrollArea_); + joinRoomButton_ = new QPushButton("Join room", this); + topLayout_->addWidget(joinRoomButton_); + + connect(joinRoomButton_, &QPushButton::clicked, this, [=]() { + if (joinRoomDialog_ == nullptr) { + joinRoomDialog_ = new JoinRoomDialog(this); + connect(joinRoomDialog_, + SIGNAL(closing(bool, QString)), + this, + SLOT(closeJoinRoomDialog(bool, QString))); + } + + if (joinRoomModal_ == nullptr) { + joinRoomModal_ = new OverlayModal(MainWindow::instance(), joinRoomDialog_); + joinRoomModal_->setDuration(100); + joinRoomModal_->setColor(QColor(55, 55, 55, 170)); + } + + joinRoomModal_->fadeIn(); + }); + connect(client_.data(), SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)), this, @@ -203,3 +225,13 @@ RoomList::updateRoomDescription(const QString &roomid, const DescInfo &info) rooms_.value(roomid)->setDescriptionMessage(info); } + +void +RoomList::closeJoinRoomDialog(bool isJoining, QString roomAlias) +{ + joinRoomModal_->fadeOut(); + + if (isJoining) { + client_->joinRoom(roomAlias); + } +}