diff options
author | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-10-04 11:33:34 +0300 |
---|---|---|
committer | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-10-04 11:33:34 +0300 |
commit | d60c2b76e30dcbdb1eae2a69b2d3ddff128d00c5 (patch) | |
tree | b54dfe5e789c3f42ce8ef26f988a2f30ab62ad4c /src | |
parent | Recover from corrupted cache data (diff) | |
download | nheko-d60c2b76e30dcbdb1eae2a69b2d3ddff128d00c5.tar.xz |
Receive typing notifications (#88)
Diffstat (limited to 'src')
-rw-r--r-- | src/ChatPage.cc | 31 | ||||
-rw-r--r-- | src/MatrixClient.cc | 5 | ||||
-rw-r--r-- | src/Sync.cc | 16 | ||||
-rw-r--r-- | src/TextInputWidget.cc | 16 | ||||
-rw-r--r-- | src/TypingDisplay.cc | 56 |
5 files changed, 113 insertions, 11 deletions
diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 9f983b9f..52468f64 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -101,8 +101,10 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) view_manager_ = new TimelineViewManager(client, this); mainContentLayout_->addWidget(view_manager_); - text_input_ = new TextInputWidget(this); + text_input_ = new TextInputWidget(this); + typingDisplay_ = new TypingDisplay(this); contentLayout_->addWidget(text_input_); + contentLayout_->addWidget(typingDisplay_); user_info_widget_ = new UserInfoWidget(sideBarTopWidget_); sideBarTopWidgetLayout_->addWidget(user_info_widget_); @@ -117,6 +119,15 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) connect( top_bar_, &TopRoomBar::leaveRoom, this, [=]() { client_->leaveRoom(current_room_); }); + connect(room_list_, &RoomList::roomChanged, this, [=](const QString &roomid) { + QStringList users; + + if (typingUsers_.contains(roomid)) + users = typingUsers_[roomid]; + + typingDisplay_->setUsers(users); + }); + connect(room_list_, &RoomList::roomChanged, this, &ChatPage::changeTopRoomInfo); connect(room_list_, &RoomList::roomChanged, text_input_, &TextInputWidget::focusLineEdit); connect( @@ -308,6 +319,8 @@ ChatPage::syncCompleted(const SyncResponse &response) auto joined = response.rooms().join(); for (auto it = joined.constBegin(); it != joined.constEnd(); it++) { + updateTypingUsers(it.key(), it.value().typingUserIDs()); + RoomState room_state; // Merge the new updates for rooms that we are tracking. @@ -620,6 +633,22 @@ ChatPage::removeRoom(const QString &room_id) room_list_->removeRoom(room_id, room_id == current_room_); } +void +ChatPage::updateTypingUsers(const QString &roomid, const QList<QString> &user_ids) +{ + QStringList users; + + for (const auto uid : user_ids) + users.append(TimelineViewManager::displayName(uid)); + + users.sort(); + + if (current_room_ == roomid) + typingDisplay_->setUsers(users); + + typingUsers_.insert(roomid, users); +} + ChatPage::~ChatPage() { sync_timer_->stop(); diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index bd43efd8..265b51ce 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -611,8 +611,9 @@ void MatrixClient::sync() noexcept { QJsonObject filter{ { "room", - QJsonObject{ { "include_leave", true }, - { "ephemeral", QJsonObject{ { "limit", 0 } } } } }, + QJsonObject{ + { "include_leave", true }, + } }, { "presence", QJsonObject{ { "limit", 0 } } } }; QUrlQuery query; diff --git a/src/Sync.cc b/src/Sync.cc index 90314352..39d84acb 100644 --- a/src/Sync.cc +++ b/src/Sync.cc @@ -168,7 +168,21 @@ JoinedRoom::deserialize(const QJsonValue &data) if (!ephemeral.value("events").isArray()) qWarning() << "join/ephemeral/events should be an array"; - // TODO: Implement ephemeral handling + auto ephemeralEvents = ephemeral.value("events").toArray(); + + for (const auto e : ephemeralEvents) { + auto obj = e.toObject(); + + if (obj.contains("type") && obj.value("type") == "m.typing") { + auto ids = obj.value("content") + .toObject() + .value("user_ids") + .toArray(); + + for (const auto uid : ids) + typingUserIDs_.push_back(uid.toString()); + } + } } } diff --git a/src/TextInputWidget.cc b/src/TextInputWidget.cc index 5f06d992..4d5f4d5f 100644 --- a/src/TextInputWidget.cc +++ b/src/TextInputWidget.cc @@ -45,13 +45,14 @@ TextInputWidget::TextInputWidget(QWidget *parent) { setFont(QFont("Emoji One")); + setFixedHeight(45); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); setCursor(Qt::ArrowCursor); - setStyleSheet("background-color: #fff; height: 45px;"); + setStyleSheet("background-color: #fff;"); topLayout_ = new QHBoxLayout(); - topLayout_->setSpacing(2); - topLayout_->setMargin(4); + topLayout_->setSpacing(0); + topLayout_->setContentsMargins(5, 15, 0, 5); QIcon send_file_icon; send_file_icon.addFile(":/icons/icons/clip-dark.png", QSize(), QIcon::Normal, QIcon::Off); @@ -63,18 +64,19 @@ TextInputWidget::TextInputWidget(QWidget *parent) spinner_ = new LoadingIndicator(this); spinner_->setColor("#acc7dc"); - spinner_->setFixedHeight(40); - spinner_->setFixedWidth(40); + spinner_->setFixedHeight(32); + spinner_->setFixedWidth(32); spinner_->hide(); QFont font; font.setPixelSize(conf::fontSize); input_ = new FilteredTextEdit(this); - input_->setFixedHeight(45); + input_->setFixedHeight(32); input_->setFont(font); + input_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); input_->setPlaceholderText(tr("Write a message...")); - input_->setStyleSheet("color: #333333; border-radius: 0; padding-top: 10px;"); + input_->setStyleSheet("color: #333333; border: none; margin: 0 5px"); sendMessageBtn_ = new FlatButton(this); sendMessageBtn_->setForegroundColor(QColor("#acc7dc")); diff --git a/src/TypingDisplay.cc b/src/TypingDisplay.cc new file mode 100644 index 00000000..619b70cb --- /dev/null +++ b/src/TypingDisplay.cc @@ -0,0 +1,56 @@ +#include <QDebug> +#include <QPainter> +#include <QPoint> + +#include "Config.h" +#include "TypingDisplay.h" + +TypingDisplay::TypingDisplay(QWidget *parent) + : QWidget(parent) + , leftPadding_{ 57 } +{ + QFont font; + font.setPixelSize(conf::typingNotificationFontSize); + + setFixedHeight(QFontMetrics(font).height() + 2); +} + +void +TypingDisplay::setUsers(const QStringList &uid) +{ + if (uid.isEmpty()) + text_.clear(); + else + text_ = uid.join(", "); + + if (uid.size() == 1) + text_ += tr(" is typing ..."); + else if (uid.size() > 1) + text_ += tr(" are typing ..."); + + update(); +} + +void +TypingDisplay::paintEvent(QPaintEvent *) +{ + QPen pen(QColor("#333")); + + QFont font; + font.setPixelSize(conf::typingNotificationFontSize); + font.setWeight(40); + font.setItalic(true); + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.setFont(font); + p.setPen(pen); + + QRect region = rect(); + region.translate(leftPadding_, 0); + + QFontMetrics fm(font); + text_ = fm.elidedText(text_, Qt::ElideRight, width() - 3 * leftPadding_); + + p.drawText(region, Qt::AlignTop, text_); +} |