diff options
author | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-11-24 00:10:58 +0200 |
---|---|---|
committer | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2017-11-24 00:10:58 +0200 |
commit | 0f363b5f4424cc4cdf0e36d7aa5b62b8e8ea52bc (patch) | |
tree | b216baa489755bbb3343f350aa6c6d3e17725fba /src | |
parent | c6cf6c2b4148c30f5e1dd0ff744baf0293cfe1ff (diff) |
Send read receipts
Automatically dismiss unread notifications when the window regains
focus.
fixes #111
fixes #68
Diffstat (limited to 'src')
-rw-r--r-- | src/ChatPage.cc | 5 | ||||
-rw-r--r-- | src/MatrixClient.cc | 28 | ||||
-rw-r--r-- | src/RoomList.cc | 16 | ||||
-rw-r--r-- | src/TimelineItem.cc | 9 | ||||
-rw-r--r-- | src/TimelineView.cc | 52 | ||||
-rw-r--r-- | src/TimelineViewManager.cc | 8 |
6 files changed, 115 insertions, 3 deletions
diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 4dbda90d..82e694a1 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -126,6 +126,11 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) room_list_, &RoomList::roomChanged, view_manager_, &TimelineViewManager::setHistoryView); connect(view_manager_, + &TimelineViewManager::clearRoomMessageCount, + room_list_, + &RoomList::clearRoomMessageCount); + + connect(view_manager_, &TimelineViewManager::unreadMessages, this, [=](const QString &roomid, int count) { diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc index 5589bdc7..dcf241a6 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc @@ -847,3 +847,31 @@ MatrixClient::removeTypingNotification(const QString &roomid) put(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); } + +void +MatrixClient::readEvent(const QString &room_id, const QString &event_id) +{ + QUrlQuery query; + query.addQueryItem("access_token", token_); + + QUrl endpoint(server_); + endpoint.setPath(clientApiUrl_ + + QString("/rooms/%1/receipt/m.read/%2").arg(room_id).arg(event_id)); + endpoint.setQuery(query); + + QNetworkRequest request(QString(endpoint.toEncoded())); + request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, "application/json"); + + auto reply = post(request, "{}"); + + connect(reply, &QNetworkReply::finished, this, [this, reply]() { + reply->deleteLater(); + + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } + }); +} diff --git a/src/RoomList.cc b/src/RoomList.cc index b1d3a9ca..402633c3 100644 --- a/src/RoomList.cc +++ b/src/RoomList.cc @@ -204,6 +204,18 @@ RoomList::sync(const QMap<QString, RoomState> &states, } void +RoomList::clearRoomMessageCount(const QString &room_id) +{ + if (!rooms_.contains(room_id)) + return; + + auto room = rooms_[room_id]; + room->clearUnreadMessageCount(); + + calculateUnreadMessageCount(); +} + +void RoomList::highlightSelectedRoom(const QString &room_id) { emit roomChanged(room_id); @@ -213,9 +225,7 @@ RoomList::highlightSelectedRoom(const QString &room_id) return; } - // TODO: Send a read receipt for the last event. - auto room = rooms_[room_id]; - room->clearUnreadMessageCount(); + clearRoomMessageCount(room_id); calculateUnreadMessageCount(); diff --git a/src/TimelineItem.cc b/src/TimelineItem.cc index 8c21e61d..263eb70d 100644 --- a/src/TimelineItem.cc +++ b/src/TimelineItem.cc @@ -154,6 +154,8 @@ TimelineItem::TimelineItem(ImageItem *image, { init(); + event_id_ = event.eventId(); + auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp()); auto displayName = TimelineViewManager::displayName(event.sender()); @@ -193,6 +195,9 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Notice> &event, : QWidget(parent) { init(); + + event_id_ = event.eventId(); + descriptionMsg_ = {TimelineViewManager::displayName(event.sender()), event.sender(), " sent a notification", @@ -234,6 +239,8 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Emote> &event, { init(); + event_id_ = event.eventId(); + auto body = event.content().body().trimmed(); auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp()); auto displayName = TimelineViewManager::displayName(event.sender()); @@ -273,6 +280,8 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Text> &event, { init(); + event_id_ = event.eventId(); + auto body = event.content().body().trimmed(); auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp()); auto displayName = TimelineViewManager::displayName(event.sender()); diff --git a/src/TimelineView.cc b/src/TimelineView.cc index 267fbbff..44f3b9d8 100644 --- a/src/TimelineView.cc +++ b/src/TimelineView.cc @@ -379,6 +379,9 @@ TimelineView::addEvents(const Timeline &timeline) if (!timeline.events().isEmpty() && scroll_layout_->count() > 1) notifyForLastEvent(); + if (isActiveWindow() && isVisible() && timeline.events().size() > 0) + readLastEvent(); + return message_count; } @@ -648,3 +651,52 @@ TimelineView::paintEvent(QPaintEvent *) QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); } + +void +TimelineView::readLastEvent() const +{ + const auto eventId = getLastEventId(); + + if (!eventId.isEmpty()) + client_->readEvent(room_id_, eventId); +} + +QString +TimelineView::getLastEventId() const +{ + auto index = scroll_layout_->count(); + + // Search backwards for the first event that has a valid event id. + while (index > 0) { + --index; + + auto lastItem = scroll_layout_->itemAt(index); + auto *lastTimelineItem = qobject_cast<TimelineItem *>(lastItem->widget()); + + if (lastTimelineItem && !lastTimelineItem->eventId().isEmpty()) + return lastTimelineItem->eventId(); + } + + return QString(""); +} + +void +TimelineView::showEvent(QShowEvent *event) +{ + readLastEvent(); + + QWidget::showEvent(event); +} + +bool +TimelineView::event(QEvent *event) +{ + if (event->type() == QEvent::WindowActivate) { + QTimer::singleShot(1000, this, [=]() { + emit clearUnreadMessageCount(room_id_); + readLastEvent(); + }); + } + + return QWidget::event(event); +} diff --git a/src/TimelineViewManager.cc b/src/TimelineViewManager.cc index ec7b8446..1f047d7c 100644 --- a/src/TimelineViewManager.cc +++ b/src/TimelineViewManager.cc @@ -131,6 +131,10 @@ TimelineViewManager::addRoom(const JoinedRoom &room, const QString &room_id) &TimelineView::updateLastTimelineMessage, this, &TimelineViewManager::updateRoomsLastMessage); + connect(view, + &TimelineView::clearUnreadMessageCount, + this, + &TimelineViewManager::clearRoomMessageCount); // Add the view in the widget stack. addWidget(view); @@ -147,6 +151,10 @@ TimelineViewManager::addRoom(const QString &room_id) &TimelineView::updateLastTimelineMessage, this, &TimelineViewManager::updateRoomsLastMessage); + connect(view, + &TimelineView::clearUnreadMessageCount, + this, + &TimelineViewManager::clearRoomMessageCount); // Add the view in the widget stack. addWidget(view); |