aboutsummaryrefslogtreecommitdiff
path: root/room.cpp
diff options
context:
space:
mode:
authorKitsuneRal <Kitsune-Ral@users.sf.net>2016-10-24 09:04:35 +0900
committerGitHub <noreply@github.com>2016-10-24 09:04:35 +0900
commit9a1270dbf8cf6c2dc9337c33a3c59b437676548c (patch)
tree8c77a5ebf5d7660bf78add62498a1e57298f84ab /room.cpp
parenta5962ee1fb1ccfa641217778e6bf7f4e9c53dff1 (diff)
parentcaaddebae6acf1a1c5281a5beba43782a8c899fc (diff)
downloadlibquotient-9a1270dbf8cf6c2dc9337c33a3c59b437676548c.tar.gz
libquotient-9a1270dbf8cf6c2dc9337c33a3c59b437676548c.zip
Merge pull request #44 from Fxrh/kitsune-read-receipts
Room: added setLastReadEvent accessor and a signal for it; don't post receipts for own messages to the server
Diffstat (limited to 'room.cpp')
-rw-r--r--room.cpp54
1 files changed, 51 insertions, 3 deletions
diff --git a/room.cpp b/room.cpp
index e07426a7..c2a1ce70 100644
--- a/room.cpp
+++ b/room.cpp
@@ -163,9 +163,57 @@ void Room::setJoinState(JoinState state)
emit joinStateChanged(oldState, state);
}
-void Room::markMessageAsRead(Event* event)
+void Room::setLastReadEvent(User* user, QString eventId)
{
- d->connection->postReceipt(this, event);
+ d->lastReadEvent.insert(user, eventId);
+ emit lastReadEventChanged(user);
+}
+
+bool Room::promoteReadMarker(User* user, QString eventId)
+{
+ // Check that the new read event is not before the previously set - only
+ // allow the read marker to move down the timeline, not up.
+ QString prevLastReadId = lastReadEvent(user);
+ // Older Qt doesn't provide rbegin()/rend() for Qt containers
+ for (auto it = messageEvents().end(); it != messageEvents().begin();)
+ {
+ --it;
+ if (prevLastReadId == (*it)->id())
+ return false;
+ if (eventId == (*it)->id())
+ {
+ setLastReadEvent(user, eventId);
+ return true;
+ }
+ }
+ return false;
+}
+
+void Room::markMessagesAsRead(Timeline::const_iterator last)
+{
+ QString prevLastReadId = lastReadEvent(connection()->user());
+ if ( !promoteReadMarker(connection()->user(), (*last)->id()) )
+ return;
+
+ // 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.
+ for (; (*last)->id() != prevLastReadId; --last)
+ {
+ if ((*last)->senderId() != connection()->userId())
+ {
+ d->connection->postReceipt(this, (*last));
+ break;
+ }
+ if (last == messageEvents().begin())
+ break;
+ }
+}
+
+void Room::markMessagesAsRead()
+{
+ if (!messageEvents().empty())
+ markMessagesAsRead(messageEvents().end() - 1);
}
QString Room::lastReadEvent(User* user)
@@ -489,7 +537,7 @@ void Room::processEphemeralEvent(Event* event)
for( const Receipt& r: receipts )
{
if (auto m = d->member(r.userId))
- d->lastReadEvent.insert(m, eventId);
+ promoteReadMarker(m, eventId);
}
}
}