diff options
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | include/ChatPage.h | 17 | ||||
-rw-r--r-- | include/LoginPage.h | 18 | ||||
-rw-r--r-- | include/MainWindow.h | 10 | ||||
-rw-r--r-- | include/MatrixClient.h | 9 | ||||
-rw-r--r-- | include/RegisterPage.h | 18 | ||||
-rw-r--r-- | include/RoomList.h | 9 | ||||
-rw-r--r-- | src/ChatPage.cc | 156 | ||||
-rw-r--r-- | src/LoginPage.cc | 15 | ||||
-rw-r--r-- | src/MainWindow.cc | 43 | ||||
-rw-r--r-- | src/MatrixClient.cc | 91 | ||||
-rw-r--r-- | src/Register.cc | 4 | ||||
-rw-r--r-- | src/RegisterPage.cc | 6 | ||||
-rw-r--r-- | src/RoomList.cc | 14 |
15 files changed, 214 insertions, 220 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f38328b4..3f1db3e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,14 @@ SET(PROJECT_VERSION ${CPACK_PACKAGE_VERSION}) MESSAGE(STATUS "Version: ${PROJECT_VERSION}") if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall -Wextra -Werror -pedantic") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \ + -std=gnu++11 \ + -Wall \ + -Wextra \ + -Werror \ + -fdiagnostics-color=always \ + -pedantic \ + -Wunreachable-code") endif() set(SRC_FILES @@ -104,7 +111,6 @@ qt5_wrap_cpp(MOC_HEADERS include/LoginPage.h include/MainWindow.h include/MatrixClient.h - include/Register.h include/RegisterPage.h include/RoomInfoListItem.h include/RoomList.h diff --git a/Makefile b/Makefile index eb8a6663..97431093 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ -run: debug - ./build/nheko - debug: - @cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug - @make -C build -j2 + @cmake -H. -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Debug + @cmake --build build release-debug: - @cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo - @make -C build -j2 + @cmake -H. -GNinja -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo + @cmake --build build + +run: + @./build/nheko clean: rm -rf build diff --git a/include/ChatPage.h b/include/ChatPage.h index 4ee7441b..e5d6ee7f 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -42,7 +42,7 @@ class ChatPage : public QWidget Q_OBJECT public: - explicit ChatPage(QWidget *parent = 0); + ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0); ~ChatPage(); // Initialize all the components of the UI. @@ -51,10 +51,10 @@ public: signals: void close(); -public slots: - // Updates the user info box. +private slots: + void updateTopBarAvatar(const QString &roomid, const QPixmap &img); void updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_name); - void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url); + void setOwnAvatar(const QPixmap &img); void initialSyncCompleted(const SyncResponse &response); void syncCompleted(const SyncResponse &response); void syncFailed(const QString &msg); @@ -67,8 +67,6 @@ public slots: private: Ui::ChatPage *ui; - void setOwnAvatar(const QByteArray &img); - RoomList *room_list_; HistoryViewManager *view_manager_; @@ -83,11 +81,8 @@ private: UserInfoWidget *user_info_widget_; - // Matrix client - MatrixClient *matrix_client_; - - // Used for one off media requests. - QNetworkAccessManager *content_downloader_; + // Matrix Client API provider. + QSharedPointer<MatrixClient> client_; }; #endif // CHATPAGE_H diff --git a/include/LoginPage.h b/include/LoginPage.h index a431a41e..8ed54def 100644 --- a/include/LoginPage.h +++ b/include/LoginPage.h @@ -20,11 +20,13 @@ #include <QHBoxLayout> #include <QLabel> +#include <QSharedPointer> #include <QVBoxLayout> #include <QWidget> #include "FlatButton.h" #include "InputValidator.h" +#include "MatrixClient.h" #include "RaisedButton.h" #include "TextField.h" @@ -33,7 +35,7 @@ class LoginPage : public QWidget Q_OBJECT public: - explicit LoginPage(QWidget *parent = 0); + LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0); ~LoginPage(); void reset(); @@ -41,14 +43,6 @@ public: signals: void backButtonClicked(); - // Emitted after the matrix ID validation. The handler should be - // responsible for performing the actual login with a remote server. - void userLogin(const QString &username, const QString &password, const QString home_server); - -public slots: - // Displays errors produced during the login. - void loginError(QString error_message); - private slots: // Callback for the back button. void onBackButtonClicked(); @@ -56,6 +50,9 @@ private slots: // Callback for the login button. void onLoginButtonClicked(); + // Displays errors produced during the login. + void loginError(QString error_message); + private: QVBoxLayout *top_layout_; @@ -77,6 +74,9 @@ private: TextField *password_input_; InputValidator *matrix_id_validator_; + + // Matrix client API provider. + QSharedPointer<MatrixClient> client_; }; #endif // LOGINPAGE_H diff --git a/include/MainWindow.h b/include/MainWindow.h index dbbda3f2..89d1df45 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -19,6 +19,7 @@ #define MAINWINDOW_H #include <QMainWindow> +#include <QSharedPointer> #include "ChatPage.h" #include "LoginPage.h" @@ -53,12 +54,6 @@ public slots: // Show the chat page and start communicating with the given access token. void showChatPage(QString user_id, QString home_server, QString token); - // Performs the actual login. - void matrixLogin(const QString &username, const QString &password, const QString &home_server); - - // Performs the actual registration. - void matrixRegister(const QString &username, const QString &password, const QString &server); - private: // The UI component of the main window. Ui::MainWindow *ui_; @@ -78,7 +73,8 @@ private: // The main chat area. ChatPage *chat_page_; - MatrixClient *matrix_client_; + // Matrix Client API provider. + QSharedPointer<MatrixClient> client_; }; #endif // MAINWINDOW_H diff --git a/include/MatrixClient.h b/include/MatrixClient.h index decd14ff..021a2594 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -40,6 +40,8 @@ public: void login(const QString &username, const QString &password) noexcept; void registerUser(const QString &username, const QString &password, const QString &server) noexcept; void versions() noexcept; + void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url); + void fetchOwnAvatar(const QUrl &avatar_url); inline QString getHomeServer(); inline void incrementTransactionId(); @@ -63,6 +65,9 @@ signals: void loginSuccess(const QString &userid, const QString &homeserver, const QString &token); void registerSuccess(const QString &userid, const QString &homeserver, const QString &token); + void roomAvatarRetrieved(const QString &roomid, const QPixmap &img); + void ownAvatarRetrieved(const QPixmap &img); + // Returned profile data for the user's account. void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name); void initialSyncCompleted(const SyncResponse &response); @@ -76,11 +81,13 @@ private slots: private: enum Endpoint { GetOwnProfile, + GetOwnAvatar, GetProfile, InitialSync, Login, Logout, Register, + RoomAvatar, SendTextMessage, Sync, Versions, @@ -92,9 +99,11 @@ private: void onRegisterResponse(QNetworkReply *reply); void onVersionsResponse(QNetworkReply *reply); void onGetOwnProfileResponse(QNetworkReply *reply); + void onGetOwnAvatarResponse(QNetworkReply *reply); void onSendTextMessageResponse(QNetworkReply *reply); void onInitialSyncResponse(QNetworkReply *reply); void onSyncResponse(QNetworkReply *reply); + void onRoomAvatarResponse(QNetworkReply *reply); // Client API prefix. QString api_url_; diff --git a/include/RegisterPage.h b/include/RegisterPage.h index 421cbd87..3e35959f 100644 --- a/include/RegisterPage.h +++ b/include/RegisterPage.h @@ -20,11 +20,13 @@ #include <QHBoxLayout> #include <QLabel> +#include <QSharedPointer> #include <QVBoxLayout> #include <QWidget> #include "FlatButton.h" #include "InputValidator.h" +#include "MatrixClient.h" #include "RaisedButton.h" #include "TextField.h" @@ -33,24 +35,19 @@ class RegisterPage : public QWidget Q_OBJECT public: - explicit RegisterPage(QWidget *parent = 0); + RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0); ~RegisterPage(); signals: void backButtonClicked(); - // Emitted after successful input validation. The handler should be - // responsible for the actual registering on the remote Matrix server. - void registerUser(const QString &username, const QString &password, const QString &server); - -public slots: - // Display registration specific errors to the user. - void registerError(const QString &msg); - private slots: void onBackButtonClicked(); void onRegisterButtonClicked(); + // Display registration specific errors to the user. + void registerError(const QString &msg); + private: QVBoxLayout *top_layout_; @@ -74,6 +71,9 @@ private: TextField *server_input_; InputValidator *validator_; + + // Matrix client API provider. + QSharedPointer<MatrixClient> client_; }; #endif // REGISTERPAGE_H diff --git a/include/RoomList.h b/include/RoomList.h index 313fab9e..42ded171 100644 --- a/include/RoomList.h +++ b/include/RoomList.h @@ -19,9 +19,11 @@ #define ROOMLIST_H #include <QImage> +#include <QSharedPointer> #include <QUrl> #include <QWidget> +#include "MatrixClient.h" #include "RoomInfo.h" #include "RoomInfoListItem.h" #include "Sync.h" @@ -36,26 +38,27 @@ class RoomList : public QWidget Q_OBJECT public: - explicit RoomList(QWidget *parent = 0); + RoomList(QSharedPointer<MatrixClient> client, QWidget *parent = 0); ~RoomList(); void setInitialRooms(const Rooms &rooms); - void updateRoomAvatar(const QString &roomid, const QImage &avatar_image); void clear(); RoomInfo extractRoomInfo(const State &room_state); signals: void roomChanged(const RoomInfo &info); - void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url); public slots: + void updateRoomAvatar(const QString &roomid, const QPixmap &img); void highlightSelectedRoom(const RoomInfo &info); private: Ui::RoomList *ui; QMap<QString, RoomInfoListItem *> rooms_; + + QSharedPointer<MatrixClient> client_; }; #endif // ROOMLIST_H diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 87aa8680..a2188cf1 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -28,16 +28,15 @@ #include "Sync.h" #include "UserInfoWidget.h" -ChatPage::ChatPage(QWidget *parent) +ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) : QWidget(parent) , ui(new Ui::ChatPage) , sync_interval_(2000) + , client_(client) { ui->setupUi(this); - matrix_client_ = new MatrixClient("matrix.org", parent); - content_downloader_ = new QNetworkAccessManager(parent); - room_list_ = new RoomList(this); + room_list_ = new RoomList(client, this); ui->sideBarMainLayout->addWidget(room_list_); top_bar_ = new TopRoomBar(this); @@ -56,8 +55,8 @@ ChatPage::ChatPage(QWidget *parent) sync_timer_->setSingleShot(true); connect(sync_timer_, SIGNAL(timeout()), this, SLOT(startSync())); - connect(user_info_widget_, SIGNAL(logout()), matrix_client_, SLOT(logout())); - connect(matrix_client_, SIGNAL(loggedOut()), this, SLOT(logout())); + connect(user_info_widget_, SIGNAL(logout()), client_.data(), SLOT(logout())); + connect(client_.data(), SIGNAL(loggedOut()), this, SLOT(logout())); connect(room_list_, SIGNAL(roomChanged(const RoomInfo &)), @@ -67,33 +66,38 @@ ChatPage::ChatPage(QWidget *parent) SIGNAL(roomChanged(const RoomInfo &)), view_manager_, SLOT(setHistoryView(const RoomInfo &))); - connect(room_list_, - SIGNAL(fetchRoomAvatar(const QString &, const QUrl &)), - this, - SLOT(fetchRoomAvatar(const QString &, const QUrl &))); connect(text_input_, SIGNAL(sendTextMessage(const QString &)), this, SLOT(sendTextMessage(const QString &))); - connect(matrix_client_, + connect(client_.data(), + SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)), + this, + SLOT(updateTopBarAvatar(const QString &, const QPixmap &))); + + connect(client_.data(), SIGNAL(initialSyncCompleted(const SyncResponse &)), this, SLOT(initialSyncCompleted(const SyncResponse &))); - connect(matrix_client_, + connect(client_.data(), SIGNAL(syncCompleted(const SyncResponse &)), this, SLOT(syncCompleted(const SyncResponse &))); - connect(matrix_client_, + connect(client_.data(), SIGNAL(syncFailed(const QString &)), this, SLOT(syncFailed(const QString &))); - connect(matrix_client_, + connect(client_.data(), SIGNAL(getOwnProfileResponse(const QUrl &, const QString &)), this, SLOT(updateOwnProfileInfo(const QUrl &, const QString &))); - connect(matrix_client_, + connect(client_.data(), + SIGNAL(ownAvatarRetrieved(const QPixmap &)), + this, + SLOT(setOwnAvatar(const QPixmap &))); + connect(client_.data(), SIGNAL(messageSent(QString, int)), this, SLOT(messageSent(QString, int))); @@ -115,7 +119,7 @@ void ChatPage::logout() top_bar_->reset(); user_info_widget_->reset(); - matrix_client_->reset(); + client_->reset(); room_avatars_.clear(); @@ -133,33 +137,28 @@ void ChatPage::messageSent(QString event_id, int txn_id) void ChatPage::sendTextMessage(const QString &msg) { auto room = current_room_; - matrix_client_->sendTextMessage(current_room_.id(), msg); + client_->sendTextMessage(current_room_.id(), msg); } void ChatPage::bootstrap(QString userid, QString homeserver, QString token) { Q_UNUSED(userid); - matrix_client_->setServer(homeserver); - matrix_client_->setAccessToken(token); + client_->setServer(homeserver); + client_->setAccessToken(token); - matrix_client_->getOwnProfile(); - matrix_client_->initialSync(); + client_->getOwnProfile(); + client_->initialSync(); } void ChatPage::startSync() { - matrix_client_->sync(); + client_->sync(); } -void ChatPage::setOwnAvatar(const QByteArray &img) +void ChatPage::setOwnAvatar(const QPixmap &img) { - if (img.size() == 0) - return; - - QPixmap pixmap; - pixmap.loadFromData(img); - user_info_widget_->setAvatar(pixmap.toImage()); + user_info_widget_->setAvatar(img.toImage()); } void ChatPage::syncFailed(const QString &msg) @@ -170,7 +169,7 @@ void ChatPage::syncFailed(const QString &msg) void ChatPage::syncCompleted(const SyncResponse &response) { - matrix_client_->setNextBatchToken(response.nextBatch()); + client_->setNextBatchToken(response.nextBatch()); /* room_list_->sync(response.rooms()); */ view_manager_->sync(response.rooms()); @@ -181,7 +180,7 @@ void ChatPage::syncCompleted(const SyncResponse &response) void ChatPage::initialSyncCompleted(const SyncResponse &response) { if (!response.nextBatch().isEmpty()) - matrix_client_->setNextBatchToken(response.nextBatch()); + client_->setNextBatchToken(response.nextBatch()); view_manager_->initialize(response.rooms()); room_list_->setInitialRooms(response.rooms()); @@ -189,61 +188,15 @@ void ChatPage::initialSyncCompleted(const SyncResponse &response) sync_timer_->start(sync_interval_); } -// TODO: This function should be part of the matrix client for generic media retrieval. -void ChatPage::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url) +void ChatPage::updateTopBarAvatar(const QString &roomid, const QPixmap &img) { - // TODO: move this into a Utils function - QList<QString> url_parts = avatar_url.toString().split("mxc://"); + room_avatars_.insert(roomid, img); - if (url_parts.size() != 2) { - qDebug() << "Invalid format for room avatar " << avatar_url.toString(); + if (current_room_.id() != roomid) return; - } - - QString media_params = url_parts[1]; - QString media_url = QString("%1/_matrix/media/r0/download/%2") - .arg(matrix_client_->getHomeServer(), media_params); - - QNetworkRequest avatar_request(media_url); - QNetworkReply *reply = content_downloader_->get(avatar_request); - reply->setProperty("media_params", media_params); - - connect(reply, &QNetworkReply::finished, [this, media_params, roomid, reply]() { - reply->deleteLater(); - - auto media = reply->property("media_params").toString(); - - if (media != media_params) - return; - - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - if (status == 0) { - qDebug() << reply->errorString(); - return; - } - - if (status >= 400) { - qWarning() << "Request " << reply->request().url() << " returned " << status; - return; - } - auto img = reply->readAll(); - - if (img.size() == 0) - return; - - QPixmap pixmap; - pixmap.loadFromData(img); - room_avatars_.insert(roomid, pixmap); - - this->room_list_->updateRoomAvatar(roomid, pixmap.toImage()); - - if (current_room_.id() == roomid) { - QIcon icon(pixmap); - this->top_bar_->updateRoomAvatar(icon); - } - }); + QIcon icon(img); + this->top_bar_->updateRoomAvatar(icon); } void ChatPage::updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_name) @@ -254,44 +207,7 @@ void ChatPage::updateOwnProfileInfo(const QUrl &avatar_url, const QString &displ user_info_widget_->setUserId(userid); user_info_widget_->setDisplayName(display_name); - // TODO: move this into a Utils function - QList<QString> url_parts = avatar_url.toString().split("mxc://"); - - if (url_parts.size() != 2) { - qDebug() << "Invalid format for media " << avatar_url.toString(); - return; - } - - QString media_params = url_parts[1]; - QString media_url = QString("%1/_matrix/media/r0/download/%2") - .arg(matrix_client_->getHomeServer(), media_params); - - QNetworkRequest avatar_request(media_url); - QNetworkReply *reply = content_downloader_->get(avatar_request); - reply->setProperty("media_params", media_params); - - connect(reply, &QNetworkReply::finished, [this, media_params, reply]() { - reply->deleteLater(); - - auto media = reply->property("media_params").toString(); - - if (media != media_params) - return; - - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - - if (status == 0) { - qDebug() << reply->errorString(); - return; - } - - if (status >= 400) { - qWarning() << "Request " << reply->request().url() << " returned " << status; - return; - } - - setOwnAvatar(reply->readAll()); - }); + client_->fetchOwnAvatar(avatar_url); } void ChatPage::changeTopRoomInfo(const RoomInfo &info) diff --git a/src/LoginPage.cc b/src/LoginPage.cc index 97497b7b..4195eda7 100644 --- a/src/LoginPage.cc +++ b/src/LoginPage.cc @@ -19,10 +19,12 @@ #include "LoginPage.h" -LoginPage::LoginPage(QWidget *parent) +LoginPage::LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent) : QWidget(parent) - , matrix_id_validator_(new InputValidator(parent)) + , client_(client) { + matrix_id_validator_ = new InputValidator(this); + top_layout_ = new QVBoxLayout(); back_layout_ = new QHBoxLayout(); @@ -105,19 +107,19 @@ LoginPage::LoginPage(QWidget *parent) top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter); top_layout_->addStretch(1); + setLayout(top_layout_); + connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked())); connect(login_button_, SIGNAL(clicked()), this, SLOT(onLoginButtonClicked())); connect(matrixid_input_, SIGNAL(returnPressed()), login_button_, SLOT(click())); connect(password_input_, SIGNAL(returnPressed()), login_button_, SLOT(click())); + connect(client_.data(), SIGNAL(loginError(QString)), this, SLOT(loginError(QString))); matrixid_input_->setValidator(matrix_id_validator_->id_); - - setLayout(top_layout_); } void LoginPage::loginError(QString error) { - qWarning() << "Error Message: " << error; error_label_->setText(error); } @@ -134,7 +136,8 @@ void LoginPage::onLoginButtonClicked() QString home_server = matrixid_input_->text().split(":").at(1); QString password = password_input_->text(); - emit userLogin(user, password, home_server); + client_->setServer(home_server); + client_->login(user, password); } } diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 146c4954..d0d01bcb 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -25,13 +25,15 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui_(new Ui::MainWindow) - , welcome_page_(new WelcomePage(parent)) - , login_page_(new LoginPage(parent)) - , register_page_(new RegisterPage(parent)) - , chat_page_(new ChatPage(parent)) - , matrix_client_(new MatrixClient("matrix.org", parent)) { ui_->setupUi(this); + client_ = QSharedPointer<MatrixClient>(new MatrixClient("matrix.org")); + + welcome_page_ = new WelcomePage(this); + + login_page_ = new LoginPage(client_, this); + register_page_ = new RegisterPage(client_, this); + chat_page_ = new ChatPage(client_, this); // Initialize sliding widget manager. sliding_stack_ = new SlidingStackWidget(this); @@ -46,39 +48,16 @@ MainWindow::MainWindow(QWidget *parent) connect(welcome_page_, SIGNAL(userRegister()), this, SLOT(showRegisterPage())); connect(login_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage())); - connect(login_page_, - SIGNAL(userLogin(const QString &, const QString &, const QString &)), - this, - SLOT(matrixLogin(const QString &, const QString &, const QString &))); - connect(register_page_, SIGNAL(backButtonClicked()), this, SLOT(showWelcomePage())); - connect(register_page_, - SIGNAL(registerUser(const QString &, const QString &, const QString &)), - this, - SLOT(matrixRegister(const QString &, const QString &, const QString &))); connect(chat_page_, SIGNAL(close()), this, SLOT(showWelcomePage())); - connect(matrix_client_, - SIGNAL(registerError(const QString &)), - register_page_, - SLOT(registerError(const QString &))); - - connect(matrix_client_, SIGNAL(loginError(QString)), login_page_, SLOT(loginError(QString))); - connect(matrix_client_, + connect(client_.data(), SIGNAL(loginSuccess(QString, QString, QString)), this, SLOT(showChatPage(QString, QString, QString))); } -void MainWindow::matrixLogin(const QString &username, const QString &password, const QString &home_server) -{ - qDebug() << "Logging in..." << username; - - matrix_client_->setServer(home_server); - matrix_client_->login(username, password); -} - void MainWindow::showChatPage(QString userid, QString homeserver, QString token) { QSettings settings; @@ -93,12 +72,6 @@ void MainWindow::showChatPage(QString userid, QString homeserver, QString token) chat_page_->bootstrap(userid, homeserver, token); } -void MainWindow::matrixRegister(const QString &username, const QString &password, const QString &server) -{ - qDebug() << "Registering" << username << "at" << server; - matrix_client_->registerUser(username, password, server); -} - void MainWindow::showWelcomePage() { int index = sliding_stack_->getWidgetIndex(welcome_page_); diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index fb7857c9..7b45646c 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -20,6 +20,7 @@ #include <QJsonObject> #include <QNetworkReply> #include <QNetworkRequest> +#include <QPixmap> #include <QSettings> #include <QUrl> #include <QUrlQuery> @@ -39,7 +40,6 @@ MatrixClient::MatrixClient(QString server, QObject *parent) QSettings settings; txn_id_ = settings.value("client/transaction_id", 1).toInt(); - // FIXME: Other QNetworkAccessManagers use the finish handler. connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(onResponse(QNetworkReply *))); } @@ -263,6 +263,52 @@ void MatrixClient::onSendTextMessageResponse(QNetworkReply *reply) incrementTransactionId(); } +void MatrixClient::onRoomAvatarResponse(QNetworkReply *reply) +{ + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto img = reply->readAll(); + + if (img.size() == 0) + return; + + auto roomid = reply->property("roomid").toString(); + + QPixmap pixmap; + pixmap.loadFromData(img); + + emit roomAvatarRetrieved(roomid, pixmap); +} + +void MatrixClient::onGetOwnAvatarResponse(QNetworkReply *reply) +{ + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } + + auto img = reply->readAll(); + + if (img.size() == 0) + return; + + QPixmap pixmap; + pixmap.loadFromData(img); + + emit ownAvatarRetrieved(pixmap); +} + void MatrixClient::onResponse(QNetworkReply *reply) { switch (reply->property("endpoint").toInt()) { @@ -290,6 +336,12 @@ void MatrixClient::onResponse(QNetworkReply *reply) case Endpoint::SendTextMessage: onSendTextMessageResponse(reply); break; + case Endpoint::RoomAvatar: + onRoomAvatarResponse(reply); + break; + case Endpoint::GetOwnAvatar: + onGetOwnAvatarResponse(reply); + break; default: break; } @@ -448,3 +500,40 @@ void MatrixClient::getOwnProfile() noexcept QNetworkReply *reply = get(request); reply->setProperty("endpoint", Endpoint::GetOwnProfile); } + +void MatrixClient::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url) +{ + QList<QString> url_parts = avatar_url.toString().split("mxc://"); + + if (url_parts.size() != 2) { + qDebug() << "Invalid format for room avatar " << avatar_url.toString(); + return; + } + + QString media_params = url_parts[1]; + QString media_url = QString("%1/_matrix/media/r0/download/%2").arg(getHomeServer(), media_params); + + QNetworkRequest avatar_request(media_url); + + QNetworkReply *reply = get(avatar_request); + reply->setProperty("roomid", roomid); + reply->setProperty("endpoint", Endpoint::RoomAvatar); +} + +void MatrixClient::fetchOwnAvatar(const QUrl &avatar_url) +{ + QList<QString> url_parts = avatar_url.toString().split("mxc://"); + + if (url_parts.size() != 2) { + qDebug() << "Invalid format for media " << avatar_url.toString(); + return; + } + + QString media_params = url_parts[1]; + QString media_url = QString("%1/_matrix/media/r0/download/%2").arg(getHomeServer(), media_params); + + QNetworkRequest avatar_request(media_url); + + QNetworkReply *reply = get(avatar_request); + reply->setProperty("endpoint", Endpoint::GetOwnAvatar); +} diff --git a/src/Register.cc b/src/Register.cc index 4f4e4ded..6100555c 100644 --- a/src/Register.cc +++ b/src/Register.cc @@ -22,10 +22,6 @@ #include "Deserializable.h" #include "Register.h" -RegisterRequest::RegisterRequest() -{ -} - RegisterRequest::RegisterRequest(const QString &username, const QString &password) : user_(username) , password_(password) diff --git a/src/RegisterPage.cc b/src/RegisterPage.cc index bad6eeb4..f992f6ac 100644 --- a/src/RegisterPage.cc +++ b/src/RegisterPage.cc @@ -20,9 +20,10 @@ #include "RegisterPage.h" -RegisterPage::RegisterPage(QWidget *parent) +RegisterPage::RegisterPage(QSharedPointer<MatrixClient> client, QWidget *parent) : QWidget(parent) , validator_(new InputValidator(parent)) + , client_(client) { top_layout_ = new QVBoxLayout(); @@ -125,6 +126,7 @@ RegisterPage::RegisterPage(QWidget *parent) connect(password_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); connect(password_confirmation_, SIGNAL(returnPressed()), register_button_, SLOT(click())); connect(server_input_, SIGNAL(returnPressed()), register_button_, SLOT(click())); + connect(client_.data(), SIGNAL(registerError(const QString &)), this, SLOT(registerError(const QString &))); username_input_->setValidator(validator_->localpart_); password_input_->setValidator(validator_->password_); @@ -160,7 +162,7 @@ void RegisterPage::onRegisterButtonClicked() QString password = password_input_->text(); QString server = server_input_->text(); - emit registerUser(username, password, server); + client_->registerUser(username, password, server); } } diff --git a/src/RoomList.cc b/src/RoomList.cc index 7800b34d..379b5223 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc @@ -26,12 +26,18 @@ #include "RoomList.h" #include "Sync.h" -RoomList::RoomList(QWidget *parent) +RoomList::RoomList(QSharedPointer<MatrixClient> client, QWidget *parent) : QWidget(parent) , ui(new Ui::RoomList) + , client_(client) { ui->setupUi(this); ui->scrollVerticalLayout->addStretch(1); + + connect(client_.data(), + SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)), + this, + SLOT(updateRoomAvatar(const QString &, const QPixmap &))); } RoomList::~RoomList() @@ -85,7 +91,7 @@ void RoomList::setInitialRooms(const Rooms &rooms) continue; if (!info.avatarUrl().isEmpty()) - emit fetchRoomAvatar(info.id(), info.avatarUrl()); + client_->fetchRoomAvatar(info.id(), info.avatarUrl()); RoomInfoListItem *room_item = new RoomInfoListItem(info, ui->scrollArea); connect(room_item, @@ -115,7 +121,7 @@ void RoomList::highlightSelectedRoom(const RoomInfo &info) } } -void RoomList::updateRoomAvatar(const QString &roomid, const QImage &avatar_image) +void RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img) { if (!rooms_.contains(roomid)) { qDebug() << "Avatar update on non existent room" << roomid; @@ -123,5 +129,5 @@ void RoomList::updateRoomAvatar(const QString &roomid, const QImage &avatar_imag } auto list_item = rooms_.value(roomid); - list_item->setAvatar(avatar_image); + list_item->setAvatar(img.toImage()); } |