aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-21 06:03:49 +0100
committerAlexey Rusakov <Kitsune-Ral@users.sf.net>2021-11-21 07:07:00 +0100
commit96f3daf7a2c4ec875904c11350c93612265e2eed (patch)
treec53404fd7c888ec5bd14fd51fabe18c8eb1ba8d6
parentbf5f209d2d237301c65cc0973f1707b9386f3110 (diff)
downloadlibquotient-96f3daf7a2c4ec875904c11350c93612265e2eed.tar.gz
libquotient-96f3daf7a2c4ec875904c11350c93612265e2eed.zip
SyncData: support MSC2654; partiallyReadCount
Since MSC2654's unread count is counted from the m.read receipt, and the course is to follow the spec's terminology and use "unread count" for the number of notable events since m.read, this required to move the existing number of notable events since m.fully_read to another field, henceforth called partiallyReadCount. At the same time, SyncData::notificationCount is dropped completely since MSC2654 claims to supersede it. Also: Room::resetNotificationCount() and Room::resetHighlightCount() are deprecated, as these never worked properly overwriting values that can be calculated or sourced from the server, only for these values to be set back again the next time the room is updated from /sync.
-rw-r--r--lib/room.cpp33
-rw-r--r--lib/room.h24
-rw-r--r--lib/syncdata.cpp44
-rw-r--r--lib/syncdata.h15
4 files changed, 65 insertions, 51 deletions
diff --git a/lib/room.cpp b/lib/room.cpp
index 67f65472..bc686962 100644
--- a/lib/room.cpp
+++ b/lib/room.cpp
@@ -117,7 +117,7 @@ public:
QString displayname;
Avatar avatar;
QHash<QString, Notification> notifications;
- int highlightCount = 0;
+ qsizetype serverHighlightCount = 0;
int notificationCount = 0;
members_map_t membersMap;
QList<User*> usersTyping;
@@ -1072,13 +1072,13 @@ void Room::resetNotificationCount()
emit notificationCountChanged();
}
-int Room::highlightCount() const { return d->highlightCount; }
+qsizetype Room::highlightCount() const { return d->serverHighlightCount; }
void Room::resetHighlightCount()
{
- if (d->highlightCount == 0)
+ if (d->serverHighlightCount == 0)
return;
- d->highlightCount = 0;
+ d->serverHighlightCount = 0;
emit highlightCountChanged();
}
@@ -1673,16 +1673,16 @@ void Room::updateData(SyncRoomData&& data, bool fromCache)
roomChanges |= processEphemeralEvent(move(ephemeralEvent));
// See https://github.com/quotient-im/libQuotient/wiki/unread_count
- if (merge(d->unreadMessages, data.unreadCount)) {
- qCDebug(MESSAGES) << "Loaded unread_count:" << *data.unreadCount //
- << "in" << objectName();
+ if (merge(d->unreadMessages, data.partiallyReadCount)) {
+ qCDebug(MESSAGES) << "Loaded partially read count:"
+ << *data.partiallyReadCount << "in" << objectName();
emit unreadMessagesChanged(this);
}
- if (merge(d->highlightCount, data.highlightCount))
+ if (merge(d->serverHighlightCount, data.highlightCount))
emit highlightCountChanged();
- if (merge(d->notificationCount, data.notificationCount))
+ if (merge(d->notificationCount, data.unreadCount))
emit notificationCountChanged();
if (roomChanges) {
@@ -3077,16 +3077,15 @@ QJsonObject Room::Private::toJson() const
.fullJson() } } });
}
- QJsonObject unreadNotifObj { { SyncRoomData::UnreadCountKey,
- unreadMessages } };
+ QJsonObject unreadNotifObj { { PartiallyReadCountKey, unreadMessages } };
- if (highlightCount > 0)
- unreadNotifObj.insert(QStringLiteral("highlight_count"), highlightCount);
- if (notificationCount > 0)
- unreadNotifObj.insert(QStringLiteral("notification_count"),
- notificationCount);
+ if (serverHighlightCount > 0)
+ unreadNotifObj.insert(HighlightCountKey, serverHighlightCount);
+
+ result.insert(UnreadNotificationsKey, unreadNotifObj);
- result.insert(QStringLiteral("unread_notifications"), unreadNotifObj);
+ if (notificationCount > 0)
+ unreadNotifObj.insert(NewUnreadCountKey, notificationCount);
if (et.elapsed() > 30)
qCDebug(PROFILER) << "Room::toJson() for" << q->objectName() << "took"
diff --git a/lib/room.h b/lib/room.h
index 124c8cb4..a75311fb 100644
--- a/lib/room.h
+++ b/lib/room.h
@@ -149,10 +149,10 @@ class Room : public QObject {
Q_PROPERTY(bool hasUnreadMessages READ hasUnreadMessages NOTIFY
unreadMessagesChanged STORED false)
Q_PROPERTY(int unreadCount READ unreadCount NOTIFY unreadMessagesChanged)
- Q_PROPERTY(int highlightCount READ highlightCount NOTIFY
- highlightCountChanged RESET resetHighlightCount)
- Q_PROPERTY(int notificationCount READ notificationCount NOTIFY
- notificationCountChanged RESET resetNotificationCount)
+ Q_PROPERTY(qsizetype highlightCount READ highlightCount
+ NOTIFY highlightCountChanged)
+ Q_PROPERTY(qsizetype notificationCount READ notificationCount
+ NOTIFY notificationCountChanged)
Q_PROPERTY(bool allHistoryLoaded READ allHistoryLoaded NOTIFY addedMessages
STORED false)
Q_PROPERTY(QStringList tagNames READ tagNames NOTIFY tagsChanged)
@@ -538,9 +538,21 @@ public:
*/
int unreadCount() const;
- Q_INVOKABLE int notificationCount() const;
+ //! \brief Get the number of notifications since the last read receipt
+ //!
+ //! \sa lastLocalReadReceipt
+ qsizetype notificationCount() const;
+
+ //! \deprecated Use setReadReceipt() to drive changes in notification count
Q_INVOKABLE void resetNotificationCount();
- Q_INVOKABLE int highlightCount() const;
+
+ //! \brief Get the number of highlights since the last read receipt
+ //!
+ //! As of 0.7, this is defined by the homeserver as Quotient doesn't process
+ //! push rules.
+ qsizetype highlightCount() const;
+
+ //! \deprecated Use setReadReceipt() to drive changes in highlightCount
Q_INVOKABLE void resetHighlightCount();
/** Check whether the room has account data of the given type
diff --git a/lib/syncdata.cpp b/lib/syncdata.cpp
index e86d3100..396e77eb 100644
--- a/lib/syncdata.cpp
+++ b/lib/syncdata.cpp
@@ -10,9 +10,6 @@
using namespace Quotient;
-const QString SyncRoomData::UnreadCountKey =
- QStringLiteral("x-quotient.unread_count");
-
bool RoomSummary::isEmpty() const
{
return !joinedMemberCount && !invitedMemberCount && !heroes;
@@ -64,23 +61,23 @@ inline EventsArrayT load(const QJsonObject& batches, StrT keyName)
return fromJson<EventsArrayT>(batches[keyName].toObject().value("events"_ls));
}
-SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_,
- const QJsonObject& room_)
- : roomId(roomId_)
- , joinState(joinState_)
- , summary(fromJson<RoomSummary>(room_["summary"_ls]))
- , state(load<StateEvents>(room_, joinState == JoinState::Invite
+SyncRoomData::SyncRoomData(QString roomId_, JoinState joinState,
+ const QJsonObject& roomJson)
+ : roomId(std::move(roomId_))
+ , joinState(joinState)
+ , summary(fromJson<RoomSummary>(roomJson["summary"_ls]))
+ , state(load<StateEvents>(roomJson, joinState == JoinState::Invite
? "invite_state"_ls
: "state"_ls))
{
switch (joinState) {
case JoinState::Join:
- ephemeral = load<Events>(room_, "ephemeral"_ls);
+ ephemeral = load<Events>(roomJson, "ephemeral"_ls);
[[fallthrough]];
case JoinState::Leave: {
- accountData = load<Events>(room_, "account_data"_ls);
- timeline = load<RoomEvents>(room_, "timeline"_ls);
- const auto timelineJson = room_.value("timeline"_ls).toObject();
+ accountData = load<Events>(roomJson, "account_data"_ls);
+ timeline = load<RoomEvents>(roomJson, "timeline"_ls);
+ const auto timelineJson = roomJson.value("timeline"_ls).toObject();
timelineLimited = timelineJson.value("limited"_ls).toBool();
timelinePrevBatch = timelineJson.value("prev_batch"_ls).toString();
@@ -89,14 +86,17 @@ SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_,
default: /* nothing on top of state */;
}
- const auto unreadJson = room_.value("unread_notifications"_ls).toObject();
- fromJson(unreadJson.value(UnreadCountKey), unreadCount);
- fromJson(unreadJson.value("highlight_count"_ls), highlightCount);
- fromJson(unreadJson.value("notification_count"_ls), notificationCount);
- if (highlightCount.has_value() || notificationCount.has_value())
- qCDebug(SYNCJOB) << "Room" << roomId_
- << "has highlights:" << *highlightCount
- << "and notifications:" << *notificationCount;
+ const auto unreadJson = roomJson.value(UnreadNotificationsKey).toObject();
+
+ fromJson(unreadJson.value(PartiallyReadCountKey), partiallyReadCount);
+ if (!partiallyReadCount.has_value())
+ fromJson(unreadJson.value("x-quotient.unread_count"_ls),
+ partiallyReadCount);
+
+ fromJson(roomJson.value(NewUnreadCountKey), unreadCount);
+ if (!unreadCount.has_value())
+ fromJson(unreadJson.value("notification_count"_ls), unreadCount);
+ fromJson(unreadJson.value(HighlightCountKey), highlightCount);
}
SyncData::SyncData(const QString& cacheFileName)
@@ -130,7 +130,7 @@ Events&& SyncData::takeToDeviceEvents() { return std::move(toDeviceEvents); }
std::pair<int, int> SyncData::cacheVersion()
{
- return { MajorCacheVersion, 1 };
+ return { MajorCacheVersion, 2 };
}
QJsonObject SyncData::loadJson(const QString& fileName)
diff --git a/lib/syncdata.h b/lib/syncdata.h
index b869a541..36d2e0bf 100644
--- a/lib/syncdata.h
+++ b/lib/syncdata.h
@@ -8,6 +8,12 @@
#include "events/stateevent.h"
namespace Quotient {
+
+constexpr auto UnreadNotificationsKey = "unread_notifications"_ls;
+constexpr auto PartiallyReadCountKey = "x-quotient.since_fully_read_count"_ls;
+constexpr auto NewUnreadCountKey = "org.matrix.msc2654.unread_count"_ls;
+constexpr auto HighlightCountKey = "highlight_count"_ls;
+
/// Room summary, as defined in MSC688
/**
* Every member of this structure is an Omittable; as per the MSC, only
@@ -29,7 +35,6 @@ struct RoomSummary {
};
QDebug operator<<(QDebug dbg, const RoomSummary& rs);
-
template <>
struct JsonObjectConverter<RoomSummary> {
static void dumpTo(QJsonObject& jo, const RoomSummary& rs);
@@ -48,16 +53,14 @@ public:
bool timelineLimited;
QString timelinePrevBatch;
+ Omittable<int> partiallyReadCount;
Omittable<int> unreadCount;
Omittable<int> highlightCount;
- Omittable<int> notificationCount;
- SyncRoomData(const QString& roomId, JoinState joinState_,
- const QJsonObject& room_);
+ SyncRoomData(QString roomId, JoinState joinState,
+ const QJsonObject& roomJson);
SyncRoomData(SyncRoomData&&) = default;
SyncRoomData& operator=(SyncRoomData&&) = default;
-
- static const QString UnreadCountKey;
};
// QVector cannot work with non-copyable objects, std::vector can.