From 239780557f6641c225828e0cb6508f47c0bc15aa Mon Sep 17 00:00:00 2001 From: Konstantinos Sideris Date: Sun, 9 Apr 2017 02:17:04 +0300 Subject: [PATCH] Add logout button Logout from the current session and invalidate the current token --- include/ChatPage.h | 4 +++ include/HistoryView.h | 1 + include/HistoryViewManager.h | 1 + include/MatrixClient.h | 8 ++++- include/RoomList.h | 5 +-- include/TopRoomBar.h | 2 ++ include/UserInfoWidget.h | 7 +++- resources/icons/power-button-off.png | Bin 0 -> 773 bytes resources/res.qrc | 1 + src/ChatPage.cc | 26 ++++++++++++++ src/HistoryView.cc | 14 +++++--- src/HistoryViewManager.cc | 11 ++++++ src/MainWindow.cc | 2 ++ src/MatrixClient.cc | 43 +++++++++++++++++++++++ src/RoomList.cc | 49 ++++++++++++++------------- src/TopRoomBar.cc | 7 ++++ src/UserInfoWidget.cc | 26 +++++++++----- 17 files changed, 166 insertions(+), 41 deletions(-) create mode 100644 resources/icons/power-button-off.png diff --git a/include/ChatPage.h b/include/ChatPage.h index 165d7808..d53d1a7f 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -48,6 +48,9 @@ public: // Initialize all the components of the UI. void bootstrap(QString userid, QString homeserver, QString token); +signals: + void close(); + public slots: // Updates the user info box. void updateOwnProfileInfo(const QUrl &avatar_url, const QString &display_name); @@ -58,6 +61,7 @@ public slots: void sendTextMessage(const QString &msg); void messageSent(const QString event_id, int txn_id); void startSync(); + void logout(); private: Ui::ChatPage *ui; diff --git a/include/HistoryView.h b/include/HistoryView.h index 284b6a8c..f5fabbb6 100644 --- a/include/HistoryView.h +++ b/include/HistoryView.h @@ -38,6 +38,7 @@ public: void addHistoryItem(const Event &event, const QString &color, bool with_sender); void addEvents(const QList &events); + void clear(); public slots: void sliderRangeChanged(int min, int max); diff --git a/include/HistoryViewManager.h b/include/HistoryViewManager.h index 8405d005..dcca609b 100644 --- a/include/HistoryViewManager.h +++ b/include/HistoryViewManager.h @@ -36,6 +36,7 @@ public: void initialize(const Rooms &rooms); void sync(const Rooms &rooms); + void clearAll(); public slots: void setHistoryView(const RoomInfo &info); diff --git a/include/MatrixClient.h b/include/MatrixClient.h index 9d3b837b..dd7f92f9 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -44,9 +44,11 @@ public: inline QString getHomeServer(); inline void incrementTransactionId(); + void reset(); + public slots: - // Profile void getOwnProfile(); + void logout(); inline void setServer(const QString &server); inline void setAccessToken(const QString &token); @@ -56,6 +58,8 @@ signals: void loginError(const QString &error); void registerError(const QString &error); + void loggedOut(); + void loginSuccess(const QString &userid, const QString &homeserver, const QString &token); void registerSuccess(const QString &userid, const QString &homeserver, const QString &token); @@ -74,6 +78,7 @@ private: GetProfile, InitialSync, Login, + Logout, Register, SendTextMessage, Sync, @@ -82,6 +87,7 @@ private: // Response handlers. void onLoginResponse(QNetworkReply *reply); + void onLogoutResponse(QNetworkReply *reply); void onRegisterResponse(QNetworkReply *reply); void onVersionsResponse(QNetworkReply *reply); void onGetOwnProfileResponse(QNetworkReply *reply); diff --git a/include/RoomList.h b/include/RoomList.h index d679c785..313fab9e 100644 --- a/include/RoomList.h +++ b/include/RoomList.h @@ -39,9 +39,10 @@ public: explicit RoomList(QWidget *parent = 0); ~RoomList(); - void appendRoom(QString name); void setInitialRooms(const Rooms &rooms); void updateRoomAvatar(const QString &roomid, const QImage &avatar_image); + void clear(); + RoomInfo extractRoomInfo(const State &room_state); signals: @@ -54,7 +55,7 @@ public slots: private: Ui::RoomList *ui; - QMap available_rooms_; + QMap rooms_; }; #endif // ROOMLIST_H diff --git a/include/TopRoomBar.h b/include/TopRoomBar.h index 247cb9a2..bfc5a08f 100644 --- a/include/TopRoomBar.h +++ b/include/TopRoomBar.h @@ -40,6 +40,8 @@ public: inline void updateRoomName(const QString &name); inline void updateRoomTopic(const QString &topic); + void reset(); + protected: void paintEvent(QPaintEvent *event) override; diff --git a/include/UserInfoWidget.h b/include/UserInfoWidget.h index 8cd4b765..15837cd5 100644 --- a/include/UserInfoWidget.h +++ b/include/UserInfoWidget.h @@ -38,6 +38,11 @@ public: void setDisplayName(const QString &name); void setUserId(const QString &userid); + void reset(); + +signals: + void logout(); + private: Avatar *userAvatar_; @@ -46,7 +51,7 @@ private: QVBoxLayout *textLayout_; QHBoxLayout *buttonLayout_; - FlatButton *settingsButton_; + FlatButton *logoutButton_; QLabel *displayNameLabel_; QLabel *userIdLabel_; diff --git a/resources/icons/power-button-off.png b/resources/icons/power-button-off.png new file mode 100644 index 0000000000000000000000000000000000000000..2409032f4999116c870fe83dd80d657869d485c1 GIT binary patch literal 773 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VW5Sk5Uj7}P}D}aLRC7!;n>6h8q?WW4O@;uvCax_7c|_U!Yc1_bk{phb7~TuCGtoyxh?2r zob(f(g~zVFT#y}Jw)B#5%)-z6&hLGGhyMh}-3!xy1)2Z2e<4;ks>Iwoc;=DMS7z{g zD6TjiFWkZPD(D15)2^N2*OyHfbL3jKeBIgFfOsah-LK|IUAS79wilIEuo_9y>JBEmE>%*U9X3Ps@elT&Gu^;of8DjkmSC*xV8O)YZXFWafwZ8e= zUqvkp1vzGuMWaqy6-DKy=ca7cUB2y)m`2BUA;o`l$|o4B-eYDxXUyPs@9myX@9W(d z-cJ)$Ik#wy1iypcoC>}T)F8+3`eE2S>pMxZLd%&pRI*4h)q?;S_{kKR|bI*D5d2`f{G<}5wGo%;zWzPF) zSo_h$htc5HkFOKATgKK`eyS_ou)#^_p!8SH@{?;Gm&d7>wsgPRU{m?hB=ZtWP0h#d zcz zhCy^%87RdeH00)|WTsW()}Up5ZYNNKB*=!~{Irtt#G+J&^73-M%)IR4icons/clip-dark.png icons/share-dark.png icons/user-shape.png + icons/power-button-off.png diff --git a/src/ChatPage.cc b/src/ChatPage.cc index b5707cb9..e6b05c1d 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -53,6 +53,9 @@ ChatPage::ChatPage(QWidget *parent) sync_timer_ = new QTimer(this); 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(room_list_, SIGNAL(roomChanged(const RoomInfo &)), this, @@ -94,6 +97,29 @@ ChatPage::ChatPage(QWidget *parent) SLOT(messageSent(QString, int))); } +void ChatPage::logout() +{ + sync_timer_->stop(); + + QSettings settings; + settings.remove("auth/access_token"); + settings.remove("auth/home_server"); + settings.remove("auth/user_id"); + settings.remove("client/transaction_id"); + + // Clear the environment. + room_list_->clear(); + view_manager_->clearAll(); + + top_bar_->reset(); + user_info_widget_->reset(); + matrix_client_->reset(); + + room_avatars_.clear(); + + emit close(); +} + void ChatPage::messageSent(QString event_id, int txn_id) { Q_UNUSED(event_id); diff --git a/src/HistoryView.cc b/src/HistoryView.cc index 3775db9a..c54e139f 100644 --- a/src/HistoryView.cc +++ b/src/HistoryView.cc @@ -63,6 +63,14 @@ HistoryView::HistoryView(QWidget *parent) init(); } +void HistoryView::clear() +{ + nick_colors_.clear(); + + for (const auto msg : scroll_layout_->children()) + msg->deleteLater(); +} + void HistoryView::sliderRangeChanged(int min, int max) { Q_UNUSED(min); @@ -80,9 +88,7 @@ QString HistoryView::chooseRandomColor() void HistoryView::addEvents(const QList &events) { - for (int i = 0; i < events.size(); i++) { - auto event = events[i]; - + for (const auto &event : events) { if (event.type() == "m.room.message") { auto msg_type = event.content().value("msgtype").toString(); @@ -97,8 +103,6 @@ void HistoryView::addEvents(const QList &events) addHistoryItem(event, color, with_sender); last_sender_ = event.sender(); - } else { - qDebug() << "Ignoring message" << msg_type; } } } diff --git a/src/HistoryViewManager.cc b/src/HistoryViewManager.cc index c7292747..2091f98b 100644 --- a/src/HistoryViewManager.cc +++ b/src/HistoryViewManager.cc @@ -37,6 +37,17 @@ HistoryViewManager::~HistoryViewManager() { } +void HistoryViewManager::clearAll() +{ + for (const auto &view: views_) { + view->clear(); + removeWidget(view); + view->deleteLater(); + } + + views_.clear(); +} + void HistoryViewManager::initialize(const Rooms &rooms) { for (auto it = rooms.join().constBegin(); it != rooms.join().constEnd(); it++) { diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 2b4103ff..12d680a0 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -57,6 +57,8 @@ MainWindow::MainWindow(QWidget *parent) 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_, diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index c376a53f..f7c1b0d4 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -43,6 +43,15 @@ MatrixClient::MatrixClient(QString server, QObject *parent) connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(onResponse(QNetworkReply *))); } +void MatrixClient::reset() +{ + next_batch_ = ""; + server_ = ""; + token_ = ""; + + txn_id_ = 0; +} + void MatrixClient::onVersionsResponse(QNetworkReply *reply) { reply->deleteLater(); @@ -93,6 +102,20 @@ void MatrixClient::onLoginResponse(QNetworkReply *reply) } } +void MatrixClient::onLogoutResponse(QNetworkReply *reply) +{ + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status != 200) { + qWarning() << "Logout error: " << reply->errorString(); + return; + } + + emit loggedOut(); +} + void MatrixClient::onRegisterResponse(QNetworkReply *reply) { reply->deleteLater(); @@ -249,6 +272,9 @@ void MatrixClient::onResponse(QNetworkReply *reply) case Endpoint::Login: onLoginResponse(reply); break; + case Endpoint::Logout: + onLogoutResponse(reply); + break; case Endpoint::Register: onRegisterResponse(reply); break; @@ -283,6 +309,23 @@ void MatrixClient::login(const QString &username, const QString &password) reply->setProperty("endpoint", Endpoint::Login); } +void MatrixClient::logout() +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/logout"); + endpoint.setQuery(query); + + QNetworkRequest request(endpoint); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + + QJsonObject body{}; + QNetworkReply *reply = post(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); + reply->setProperty("endpoint", Endpoint::Logout); +} + void MatrixClient::registerUser(const QString &user, const QString &pass, const QString &server) { setServer(server); diff --git a/src/RoomList.cc b/src/RoomList.cc index 1e147a48..4d0b9713 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc @@ -30,6 +30,7 @@ RoomList::RoomList(QWidget *parent) , ui(new Ui::RoomList) { ui->setupUi(this); + ui->scrollVerticalLayout->addStretch(1); } RoomList::~RoomList() @@ -37,22 +38,30 @@ RoomList::~RoomList() delete ui; } +void RoomList::clear() +{ + for (const auto &room : rooms_) + room->deleteLater(); + + rooms_.clear(); +} + RoomInfo RoomList::extractRoomInfo(const State &room_state) { RoomInfo info; auto events = room_state.events(); - for (int i = 0; i < events.count(); i++) { - if (events[i].type() == "m.room.name") { - info.setName(events[i].content().value("name").toString()); - } else if (events[i].type() == "m.room.topic") { - info.setTopic(events[i].content().value("topic").toString()); - } else if (events[i].type() == "m.room.avatar") { - info.setAvatarUrl(QUrl(events[i].content().value("url").toString())); - } else if (events[i].type() == "m.room.canonical_alias") { + for (const auto &event : events) { + if (event.type() == "m.room.name") { + info.setName(event.content().value("name").toString()); + } else if (event.type() == "m.room.topic") { + info.setTopic(event.content().value("topic").toString()); + } else if (event.type() == "m.room.avatar") { + info.setAvatarUrl(QUrl(event.content().value("url").toString())); + } else if (event.type() == "m.room.canonical_alias") { if (info.name().isEmpty()) - info.setName(events[i].content().value("alias").toString()); + info.setName(event.content().value("alias").toString()); } } @@ -61,7 +70,7 @@ RoomInfo RoomList::extractRoomInfo(const State &room_state) void RoomList::setInitialRooms(const Rooms &rooms) { - available_rooms_.clear(); + rooms_.clear(); for (auto it = rooms.join().constBegin(); it != rooms.join().constEnd(); it++) { RoomInfo info = RoomList::extractRoomInfo(it.value().state()); @@ -79,24 +88,23 @@ void RoomList::setInitialRooms(const Rooms &rooms) this, SLOT(highlightSelectedRoom(const RoomInfo &))); - available_rooms_.insert(it.key(), room_item); + rooms_.insert(it.key(), room_item); - ui->scrollVerticalLayout->addWidget(room_item); + int pos = ui->scrollVerticalLayout->count() - 1; + ui->scrollVerticalLayout->insertWidget(pos, room_item); } // TODO: Move this into its own function. - auto first_room = available_rooms_.first(); + auto first_room = rooms_.first(); first_room->setPressedState(true); emit roomChanged(first_room->info()); - - ui->scrollVerticalLayout->addStretch(1); } void RoomList::highlightSelectedRoom(const RoomInfo &info) { emit roomChanged(info); - for (auto it = available_rooms_.constBegin(); it != available_rooms_.constEnd(); it++) { + for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) { if (it.key() != info.id()) it.value()->setPressedState(false); } @@ -104,16 +112,11 @@ void RoomList::highlightSelectedRoom(const RoomInfo &info) void RoomList::updateRoomAvatar(const QString &roomid, const QImage &avatar_image) { - if (!available_rooms_.contains(roomid)) { + if (!rooms_.contains(roomid)) { qDebug() << "Avatar update on non existent room" << roomid; return; } - auto list_item = available_rooms_.value(roomid); + auto list_item = rooms_.value(roomid); list_item->setAvatar(avatar_image); } - -void RoomList::appendRoom(QString name) -{ - Q_UNUSED(name); -} diff --git a/src/TopRoomBar.cc b/src/TopRoomBar.cc index 7e390bdf..3c05a953 100644 --- a/src/TopRoomBar.cc +++ b/src/TopRoomBar.cc @@ -77,6 +77,13 @@ TopRoomBar::TopRoomBar(QWidget *parent) setLayout(top_layout_); } +void TopRoomBar::reset() +{ + name_label_->setText(""); + topic_label_->setText(""); + avatar_->setLetter(QChar('?')); +} + void TopRoomBar::paintEvent(QPaintEvent *event) { Q_UNUSED(event); diff --git a/src/UserInfoWidget.cc b/src/UserInfoWidget.cc index a617d212..90f67a49 100644 --- a/src/UserInfoWidget.cc +++ b/src/UserInfoWidget.cc @@ -24,7 +24,6 @@ UserInfoWidget::UserInfoWidget(QWidget *parent) , userid_("@user:homeserver.org") { QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - setSizePolicy(sizePolicy); setMinimumSize(QSize(0, 65)); @@ -65,26 +64,35 @@ UserInfoWidget::UserInfoWidget(QWidget *parent) buttonLayout_ = new QHBoxLayout(); - settingsButton_ = new FlatButton(this); - settingsButton_->setForegroundColor(QColor("#ebebeb")); - settingsButton_->setCursor(QCursor(Qt::PointingHandCursor)); - settingsButton_->setStyleSheet("width: 30px; height: 30px;"); + logoutButton_ = new FlatButton(this); + logoutButton_->setForegroundColor(QColor("#ebebeb")); + logoutButton_->setCursor(QCursor(Qt::PointingHandCursor)); + logoutButton_->setStyleSheet("width: 30px; height: 30px;"); QIcon icon; - icon.addFile(":/icons/icons/user-shape.png", QSize(), QIcon::Normal, QIcon::Off); + icon.addFile(":/icons/icons/power-button-off.png", QSize(), QIcon::Normal, QIcon::Off); - settingsButton_->setIcon(icon); - settingsButton_->setIconSize(QSize(16, 16)); + logoutButton_->setIcon(icon); + logoutButton_->setIconSize(QSize(16, 16)); - buttonLayout_->addWidget(settingsButton_); + buttonLayout_->addWidget(logoutButton_); topLayout_->addLayout(buttonLayout_); + + connect(logoutButton_, SIGNAL(clicked()), this, SIGNAL(logout())); } UserInfoWidget::~UserInfoWidget() { } +void UserInfoWidget::reset() +{ + displayNameLabel_->setText(""); + userIdLabel_->setText(""); + userAvatar_->setLetter(QChar('?')); +} + void UserInfoWidget::setAvatar(const QImage &img) { avatar_image_ = img;