aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--room.cpp31
-rw-r--r--room.h22
2 files changed, 32 insertions, 21 deletions
diff --git a/room.cpp b/room.cpp
index 85ab1720..366073c7 100644
--- a/room.cpp
+++ b/room.cpp
@@ -170,13 +170,14 @@ void Room::setLastReadEvent(User* user, QString eventId)
emit lastReadEventChanged(user);
}
-bool Room::promoteReadMarker(QString newLastReadEventId)
+Room::Timeline::const_iterator Room::promoteReadMarker(QString eventId)
{
User* localUser = connection()->user();
QString prevLastReadId = lastReadEvent(localUser);
int stillUnreadMessagesCount = 0;
+ auto it = d->messageEvents.end();
// Older Qt doesn't provide rbegin()/rend() for Qt containers
- for (auto it = messageEvents().end(); it != messageEvents().begin();)
+ while (it != d->messageEvents.begin())
{
--it;
// Check that the new read event is not before the previously set - only
@@ -186,9 +187,10 @@ bool Room::promoteReadMarker(QString newLastReadEventId)
// Found the message to mark as read; for the local user,
// if we don't have other notable events below this one, reset unreadMessages
- if (newLastReadEventId == (*it)->id())
+ if (eventId == (*it)->id())
{
- setLastReadEvent(localUser, newLastReadEventId);
+ setLastReadEvent(localUser, eventId);
+ emit readMarkerPromoted();
break;
}
@@ -205,15 +207,17 @@ bool Room::promoteReadMarker(QString newLastReadEventId)
if (stillUnreadMessagesCount > 0)
qDebug() << "Room" << displayName()
<< ": still" << stillUnreadMessagesCount << "unread message(s)";
- return newLastReadEventId.isEmpty() || lastReadEvent(localUser) == newLastReadEventId;
+ return it;
}
-void Room::markMessagesAsRead(Timeline::const_iterator last)
+void Room::markMessagesAsRead(QString uptoEventId)
{
- QString prevLastReadId = lastReadEvent(connection()->user());
- if ( !promoteReadMarker( (*last)->id()) )
+ if (d->messageEvents.empty())
return;
+ QString prevLastReadId = lastReadEvent(connection()->user());
+ auto last = promoteReadMarker(uptoEventId);
+
// We shouldn't send read receipts for messages from the local user - so
// shift back (if necessary) to the nearest message not from the local user
// or the so far last read message, whichever comes first.
@@ -221,7 +225,7 @@ void Room::markMessagesAsRead(Timeline::const_iterator last)
{
if ((*last)->senderId() != connection()->userId())
{
- d->connection->postReceipt(this, (*last));
+ d->connection->postReceipt(this, *last);
break;
}
if (last == messageEvents().begin())
@@ -232,7 +236,7 @@ void Room::markMessagesAsRead(Timeline::const_iterator last)
void Room::markMessagesAsRead()
{
if (!messageEvents().empty())
- markMessagesAsRead(messageEvents().end() - 1);
+ markMessagesAsRead(messageEvents().back()->id());
}
bool Room::hasUnreadMessages()
@@ -240,11 +244,16 @@ bool Room::hasUnreadMessages()
return d->unreadMessages;
}
-QString Room::lastReadEvent(User* user)
+QString Room::lastReadEvent(User* user) const
{
return d->lastReadEvent.value(user);
}
+QString Room::readMarkerEventId() const
+{
+ return lastReadEvent(d->connection->user());
+}
+
int Room::notificationCount() const
{
return d->notificationCount;
diff --git a/room.h b/room.h
index 79c765ba..a518ae42 100644
--- a/room.h
+++ b/room.h
@@ -37,6 +37,7 @@ namespace QMatrixClient
class Room: public QObject
{
Q_OBJECT
+ Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE markMessagesAsRead NOTIFY readMarkerPromoted)
public:
using Timeline = Owning<Events>;
@@ -70,19 +71,19 @@ namespace QMatrixClient
Q_INVOKABLE void updateData(SyncRoomData& data );
Q_INVOKABLE void setJoinState( JoinState state );
- Q_INVOKABLE QString lastReadEvent(User* user);
+ Q_INVOKABLE QString lastReadEvent(User* user) const;
+ QString readMarkerEventId() const;
/**
- * @brief Mark the message at the iterator as read
+ * @brief Mark the event with uptoEventId as read
*
- * Marks the message at the iterator as read; also posts a read
- * receipt to the server either for this message or, if it's from
- * the local user, for the nearest non-local message before.
+ * Finds in the timeline and marks as read the event with
+ * the specified id; also posts a read receipt to the server either
+ * for this message or, if it's from the local user, for
+ * the nearest non-local message before.
*/
- Q_INVOKABLE void markMessagesAsRead(Timeline::const_iterator last);
+ Q_INVOKABLE void markMessagesAsRead(QString uptoEventId);
/**
- * @brief Mark the most recent message in the timeline as read
- *
- * This effectively marks everything in the room as read.
+ * @brief Mark the whole room timeline as read
*/
Q_INVOKABLE void markMessagesAsRead();
@@ -121,6 +122,7 @@ namespace QMatrixClient
void highlightCountChanged(Room* room);
void notificationCountChanged(Room* room);
void lastReadEventChanged(User* user);
+ void readMarkerPromoted();
void unreadMessagesChanged(Room* room);
protected:
@@ -130,7 +132,7 @@ namespace QMatrixClient
virtual void processStateEvents(const Events& events);
virtual void processEphemeralEvent(Event* event);
- bool promoteReadMarker(QString newLastReadEventId);
+ Timeline::const_iterator promoteReadMarker(QString eventId);
private:
class Private;