diff --git a/include/ChatPage.h b/include/ChatPage.h index ad1ec9e332944f97773ef3323755d736626c9f91..04464bc56805268b3219d6d2857b387321ea025f 100644 --- a/include/ChatPage.h +++ b/include/ChatPage.h @@ -54,6 +54,7 @@ signals: void close(); void changeWindowTitle(const QString &msg); void unreadMessages(int count); + void showNotification(const QString &msg); private slots: void showUnreadMessageNotification(int count); diff --git a/include/MainWindow.h b/include/MainWindow.h index a7a2b2e6e304e787b13a1396bf3f1d29f8df2c5e..0c2316a3d1058b92bd7f00814c90e85f71bead23 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -26,6 +26,7 @@ #include "MatrixClient.h" #include "OverlayModal.h" #include "RegisterPage.h" +#include "SnackBar.h" #include "TrayIcon.h" #include "WelcomePage.h" @@ -91,4 +92,7 @@ private: // Tray icon that shows the unread message count. TrayIcon *trayIcon_; + + // Notifications display. + QSharedPointer<SnackBar> snackBar_; }; diff --git a/include/MatrixClient.h b/include/MatrixClient.h index c87f06683aa8a38eecdd4cb52abd0799c243a8ab..927fe3a6539d18d7b455f9830af4e12607ca998b 100644 --- a/include/MatrixClient.h +++ b/include/MatrixClient.h @@ -93,6 +93,7 @@ signals: void initialSyncCompleted(const SyncResponse &response); void syncCompleted(const SyncResponse &response); void syncFailed(const QString &msg); + void joinFailed(const QString &msg); 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); diff --git a/include/TextInputWidget.h b/include/TextInputWidget.h index 732f4f61a54d504e67c0b99f7dab7735219cea30..772bdd46d40ba2ea18b6d5ff0c1d4c7c94fdf14d 100644 --- a/include/TextInputWidget.h +++ b/include/TextInputWidget.h @@ -30,6 +30,7 @@ namespace msgs = matrix::events::messages; static const QString EMOTE_COMMAND("/me "); +static const QString JOIN_COMMAND("/join "); class FilteredTextEdit : public QTextEdit { @@ -63,10 +64,12 @@ signals: void sendTextMessage(QString msg); void sendEmoteMessage(QString msg); void uploadImage(QString filename); + void sendJoinRoomRequest(const QString &room); private: void showUploadSpinner(); QString parseEmoteCommand(const QString &cmd); + QString parseJoinCommand(const QString &cmd); QHBoxLayout *topLayout_; FilteredTextEdit *input_; diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 5648a83078d8dce13d9e7929e3a37cd610d0f48b..92692fc17e08958c1551eaba49890fde43461099 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -166,10 +166,16 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) view_manager_, SLOT(sendEmoteMessage(const QString &))); + connect(text_input_, + &TextInputWidget::sendJoinRoomRequest, + client_.data(), + &MatrixClient::joinRoom); + connect(text_input_, &TextInputWidget::uploadImage, this, [=](QString filename) { client_->uploadImage(current_room_, filename); }); + connect(client_.data(), &MatrixClient::joinFailed, this, &ChatPage::showNotification); connect(client_.data(), &MatrixClient::imageUploaded, this, @@ -203,10 +209,9 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) SIGNAL(ownAvatarRetrieved(const QPixmap &)), this, SLOT(setOwnAvatar(const QPixmap &))); - connect(client_.data(), - SIGNAL(joinedRoom(const QString &)), - this, - SLOT(addRoom(const QString &))); + connect(client_.data(), &MatrixClient::joinedRoom, this, [=]() { + emit showNotification("You joined the room."); + }); connect(client_.data(), SIGNAL(leftRoom(const QString &)), this, @@ -636,9 +641,9 @@ ChatPage::addRoom(const QString &room_id) QSharedPointer<RoomSettings>(new RoomSettings(room_id))); room_list_->addRoom(settingsManager_[room_id], state_manager_[room_id], room_id); - - this->changeTopRoomInfo(room_id); room_list_->highlightSelectedRoom(room_id); + + changeTopRoomInfo(room_id); } } diff --git a/src/MainWindow.cc b/src/MainWindow.cc index 8072668356734e9e1a9c6a71d77f5696fd057a98..06f8245c7813a97c174ec3855073002d8a111d83 100644 --- a/src/MainWindow.cc +++ b/src/MainWindow.cc @@ -15,8 +15,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Config.h" #include "MainWindow.h" +#include "Config.h" #include <QApplication> #include <QLayout> @@ -142,6 +142,15 @@ MainWindow::removeOverlayProgressBar() spinner_.reset(); }); + // FIXME: Snackbar doesn't work if it's initialized in the constructor. + QTimer::singleShot(100, this, [=]() { + snackBar_ = QSharedPointer<SnackBar>(new SnackBar(this)); + connect(chat_page_, + &ChatPage::showNotification, + snackBar_.data(), + &SnackBar::showMessage); + }); + timer->start(500); } diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index 708e1176d5e5dabcbcc77b5d84f61ed6a8bdb4c9..e9e47fcb5ad3a900e2fe1a34ac5d73cadeabf446 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -477,13 +477,22 @@ MatrixClient::onJoinRoomResponse(QNetworkReply *reply) int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); + auto data = reply->readAll(); + auto response = QJsonDocument::fromJson(data); + auto json = response.object(); + + if (json.contains("error")) + emit joinFailed(json["error"].toString()); + else + qDebug() << reply->errorString(); + return; } - auto data = reply->readAll(); - QJsonDocument response = QJsonDocument::fromJson(data); - QString room_id = response.object()["room_id"].toString(); + auto data = reply->readAll(); + auto response = QJsonDocument::fromJson(data); + auto room_id = response.object()["room_id"].toString(); + emit joinedRoom(room_id); } @@ -899,6 +908,7 @@ MatrixClient::joinRoom(const QString &roomIdOrAlias) QNetworkReply *reply = post(request, "{}"); reply->setProperty("endpoint", static_cast<int>(Endpoint::JoinRoom)); + reply->setProperty("room", roomIdOrAlias); } void diff --git a/src/TextInputWidget.cc b/src/TextInputWidget.cc index f894a247d02628802760cc608ddf7605fcc399c0..b90a7caab1ba9236e7f08d1818730b33670eb3b3 100644 --- a/src/TextInputWidget.cc +++ b/src/TextInputWidget.cc @@ -148,6 +148,11 @@ TextInputWidget::onSendButtonClicked() if (!text.isEmpty()) emit sendEmoteMessage(text); + } else if (msgText.startsWith(JOIN_COMMAND)) { + auto room = parseJoinCommand(msgText); + + if (!room.isEmpty()) + emit sendJoinRoomRequest(room); } else { emit sendTextMessage(msgText); } @@ -155,6 +160,17 @@ TextInputWidget::onSendButtonClicked() input_->clear(); } +QString +TextInputWidget::parseJoinCommand(const QString &cmd) +{ + auto room = cmd.right(cmd.size() - JOIN_COMMAND.size()).trimmed(); + + if (!room.isEmpty()) + return room; + + return QString(""); +} + QString TextInputWidget::parseEmoteCommand(const QString &cmd) { diff --git a/src/ui/SnackBar.cc b/src/ui/SnackBar.cc index 673c2f934307c32caf96c2f002b91794e47e8277..39566e99f6a71e484652e582c63e3afa3c0c9455 100644 --- a/src/ui/SnackBar.cc +++ b/src/ui/SnackBar.cc @@ -84,7 +84,7 @@ SnackBar::showMessage(const QString &msg) void SnackBar::onTimeout() { - offset_ -= 0.5; + offset_ -= 1.1; if (offset_ <= 0.0) { showTimer_->stop();