diff options
author | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-12-08 15:37:16 +0900 |
---|---|---|
committer | Kitsune Ral <Kitsune-Ral@users.sf.net> | 2018-12-08 20:12:27 +0900 |
commit | 9272d21ce6e5439444794e6da58e08421e8973db (patch) | |
tree | 736e4e165f910d52e30104abd4313786c065b966 /lib | |
parent | 1ff8a0c26fc2738a085ca0302f0471ffa95a567e (diff) | |
download | libquotient-9272d21ce6e5439444794e6da58e08421e8973db.tar.gz libquotient-9272d21ce6e5439444794e6da58e08421e8973db.zip |
Room summaries
Diffstat (limited to 'lib')
-rw-r--r-- | lib/connection.cpp | 2 | ||||
-rw-r--r-- | lib/room.cpp | 48 | ||||
-rw-r--r-- | lib/room.h | 8 | ||||
-rw-r--r-- | lib/syncdata.cpp | 29 | ||||
-rw-r--r-- | lib/syncdata.h | 19 |
5 files changed, 104 insertions, 2 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp index 52609370..28156d11 100644 --- a/lib/connection.cpp +++ b/lib/connection.cpp @@ -562,7 +562,7 @@ void Connection::doInDirectChat(User* u, { Q_ASSERT(r->id() == roomId); // A direct chat with yourself should only involve yourself :) - if (userId == d->userId && r->memberCount() > 1) + if (userId == d->userId && r->totalMemberCount() > 1) continue; qCDebug(MAIN) << "Requested direct chat with" << userId << "is already available as" << r->id(); diff --git a/lib/room.cpp b/lib/room.cpp index 8b81bfb2..439baeb5 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -93,6 +93,7 @@ class Room::Private Connection* connection; QString id; JoinState joinState; + RoomSummary summary; /// The state of the room at timeline position before-0 /// \sa timelineBase std::unordered_map<StateEventKey, StateEventPtr> baseState; @@ -164,6 +165,8 @@ class Room::Private const RoomMessageEvent* getEventWithFile(const QString& eventId) const; QString fileNameToDownload(const RoomMessageEvent* event) const; + Changes setSummary(RoomSummary&& newSummary); + //void inviteUser(User* u); // We might get it at some point in time. void insertMemberIntoMap(User* u); void renameMember(User* u, QString oldName); @@ -596,6 +599,10 @@ void Room::setDisplayed(bool displayed) { resetHighlightCount(); resetNotificationCount(); +// if (d->lazyLoaded) +// { +// // TODO: Get all members +// } } } @@ -976,11 +983,41 @@ bool Room::usesEncryption() const return !d->getCurrentState<EncryptionEvent>()->algorithm().isEmpty(); } +int Room::joinedCount() const +{ + return d->summary.joinedMemberCount > 0 + ? d->summary.joinedMemberCount + : d->membersMap.size(); +} + +int Room::invitedCount() const +{ + // TODO: Store invited users in Room too + return d->summary.invitedMemberCount; +} + +int Room::totalMemberCount() const +{ + return joinedCount() + invitedCount(); +} + GetRoomEventsJob* Room::eventsHistoryJob() const { return d->eventsHistoryJob; } +Room::Changes Room::Private::setSummary(RoomSummary&& newSummary) +{ + if (summary == newSummary) + return Change::NoChange; + summary = move(newSummary); + qCDebug(MAIN).nospace() + << "Updated room summary: joined " << summary.joinedMemberCount + << ", invited " << summary.invitedMemberCount + << ", heroes: " << summary.heroes.join(','); + return Change::SummaryChange; +} + void Room::Private::insertMemberIntoMap(User *u) { const auto userName = u->name(q); @@ -1148,6 +1185,7 @@ void Room::updateData(SyncRoomData&& data, bool fromCache) if (roomChanges&NameChange) emit namesChanged(this); + d->setSummary(move(data.summary)); d->updateDisplayname(); for( auto&& ephemeralEvent: data.ephemeral ) @@ -2073,7 +2111,14 @@ QString Room::Private::calculateDisplayname() const // return q->aliases().at(0); // 3. Room members - dispName = roomNameFromMemberNames(membersMap.values()); + if (!summary.heroes.empty()) + { + QList<User*> users; users.reserve(summary.heroes.size()); + for (const auto& h: summary.heroes) + users.push_back(q->user(h)); + dispName = roomNameFromMemberNames(users); + } else + dispName = roomNameFromMemberNames(membersMap.values()); if (!dispName.isEmpty()) return dispName; @@ -2103,6 +2148,7 @@ QJsonObject Room::Private::toJson() const { QElapsedTimer et; et.start(); QJsonObject result; + addParam<IfNotEmpty>(result, QStringLiteral("summary"), summary); { QJsonArray stateEvents; @@ -84,6 +84,9 @@ namespace QMatrixClient Q_PROPERTY(int timelineSize READ timelineSize NOTIFY addedMessages) Q_PROPERTY(QStringList memberNames READ memberNames NOTIFY memberListChanged) Q_PROPERTY(int memberCount READ memberCount NOTIFY memberListChanged) + Q_PROPERTY(int joinedCount READ joinedCount NOTIFY memberListChanged) + Q_PROPERTY(int invitedCount READ invitedCount NOTIFY memberListChanged) + Q_PROPERTY(int totalMemberCount READ totalMemberCount NOTIFY memberListChanged) Q_PROPERTY(bool displayed READ displayed WRITE setDisplayed NOTIFY displayedChanged) Q_PROPERTY(QString firstDisplayedEventId READ firstDisplayedEventId WRITE setFirstDisplayedEventId NOTIFY firstDisplayedEventChanged) @@ -116,6 +119,7 @@ namespace QMatrixClient MembersChange = 0x80, EncryptionOn = 0x100, AccountDataChange = 0x200, + SummaryChange = 0x400, OtherChange = 0x1000, AnyChange = 0x1FFF }; @@ -143,9 +147,13 @@ namespace QMatrixClient Q_INVOKABLE QList<User*> users() const; QStringList memberNames() const; + [[deprecated("Use joinedCount(), invitedCount(), totalMemberCount()")]] int memberCount() const; int timelineSize() const; bool usesEncryption() const; + int joinedCount() const; + int invitedCount() const; + int totalMemberCount() const; GetRoomEventsJob* eventsHistoryJob() const; diff --git a/lib/syncdata.cpp b/lib/syncdata.cpp index 1023ed6a..a5f849b3 100644 --- a/lib/syncdata.cpp +++ b/lib/syncdata.cpp @@ -34,10 +34,39 @@ inline EventsArrayT load(const QJsonObject& batches, StrT keyName) return fromJson<EventsArrayT>(batches[keyName].toObject().value("events"_ls)); } +void JsonObjectConverter<RoomSummary>::dumpTo(QJsonObject& jo, + const RoomSummary& rs) +{ + if (rs.joinedMemberCount != 0) + jo.insert(QStringLiteral("m.joined_member_count"), + rs.joinedMemberCount); + if (rs.invitedMemberCount != 0) + jo.insert(QStringLiteral("m.invited_member_count"), + rs.invitedMemberCount); + if (!rs.heroes.empty()) + jo.insert(QStringLiteral("m.heroes"), toJson(rs.heroes)); +} + +void JsonObjectConverter<RoomSummary>::fillFrom(const QJsonObject& jo, + RoomSummary& rs) +{ + rs.joinedMemberCount = fromJson<int>(jo["m.joined_member_count"_ls]); + rs.joinedMemberCount = fromJson<int>(jo["m.invited_member_count"_ls]); + rs.heroes = fromJson<QStringList>(jo["m.heroes"]); +} + +bool RoomSummary::operator==(const RoomSummary& other) const +{ + return joinedMemberCount == other.joinedMemberCount && + invitedMemberCount == other.invitedMemberCount && + heroes == other.heroes; +} + SyncRoomData::SyncRoomData(const QString& roomId_, JoinState joinState_, const QJsonObject& room_) : roomId(roomId_) , joinState(joinState_) + , summary(fromJson<RoomSummary>(room_["summary"].toObject())) , state(load<StateEvents>(room_, joinState == JoinState::Invite ? "invite_state"_ls : "state"_ls)) { diff --git a/lib/syncdata.h b/lib/syncdata.h index aa8948bc..81a91ffc 100644 --- a/lib/syncdata.h +++ b/lib/syncdata.h @@ -22,11 +22,30 @@ #include "events/stateevent.h" namespace QMatrixClient { + struct RoomSummary + { + int joinedMemberCount = 0; + int invitedMemberCount = 0; + QStringList heroes; //< mxids of users to take part in the room name + + bool operator==(const RoomSummary& other) const; + bool operator!=(const RoomSummary& other) const + { return !(*this == other); } + }; + + template <> + struct JsonObjectConverter<RoomSummary> + { + static void dumpTo(QJsonObject& jo, const RoomSummary& rs); + static void fillFrom(const QJsonObject& jo, RoomSummary& rs); + }; + class SyncRoomData { public: QString roomId; JoinState joinState; + RoomSummary summary; StateEvents state; RoomEvents timeline; Events ephemeral; |