From 3e81ba0da47278f383ce8c329010602f84a50482 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 9 Dec 2019 18:30:36 +0300 Subject: Room::predecessor() and Room::successor() --- lib/room.cpp | 20 ++++++++++++++++++++ lib/room.h | 15 +++++++++++++++ 2 files changed, 35 insertions(+) (limited to 'lib') diff --git a/lib/room.cpp b/lib/room.cpp index fe50aa9a..41a8888c 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -387,11 +387,31 @@ QString Room::predecessorId() const return d->getCurrentState()->predecessor().roomId; } +Room* Room::predecessor(JoinStates statesFilter) const +{ + if (const auto& predId = predecessorId(); !predId.isEmpty()) + if (auto* r = connection()->room(predId, statesFilter); + r && r->successorId() == id()) + return r; + + return nullptr; +} + QString Room::successorId() const { return d->getCurrentState()->successorRoomId(); } +Room* Room::successor(JoinStates statesFilter) const +{ + if (const auto& succId = successorId(); !succId.isEmpty()) + if (auto* r = connection()->room(succId, statesFilter); + r && r->predecessorId() == id()) + return r; + + return nullptr; +} + const Room::Timeline& Room::messageEvents() const { return d->timeline; } const Room::PendingEvents& Room::pendingEvents() const diff --git a/lib/room.h b/lib/room.h index 2c958033..fa3c6ff3 100644 --- a/lib/room.h +++ b/lib/room.h @@ -167,7 +167,22 @@ public: QString version() const; bool isUnstable() const; QString predecessorId() const; + /// Room predecessor + /** This function validates that the predecessor has a tombstone and + * the tombstone refers to the current room. If that's not the case, + * or if the predecessor is in a join state not matching \p stateFilter, + * the function returns nullptr. + */ + Room* predecessor(JoinStates statesFilter = JoinState::Invite + | JoinState::Join) const; QString successorId() const; + /// Room successor + /** This function validates that the successor room's creation event + * refers to the current room. If that's not the case, or if the successor + * is in a join state not matching \p stateFilter, it returns nullptr. + */ + Room* successor(JoinStates statesFilter = JoinState::Invite + | JoinState::Join) const; QString name() const; /// Room aliases defined on the current user's server /// \sa remoteAliases, setLocalAliases -- cgit v1.2.3 From 4b56d47284500ab61f8e0c5cd7c807c58e1b53cb Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 9 Dec 2019 18:22:37 +0300 Subject: Room::creation() and Room::tombstone() --- lib/room.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib') diff --git a/lib/room.h b/lib/room.h index fa3c6ff3..10f18742 100644 --- a/lib/room.h +++ b/lib/room.h @@ -27,6 +27,8 @@ #include "events/accountdataevents.h" #include "events/encryptedevent.h" #include "events/roommessageevent.h" +#include "events/roomcreateevent.h" +#include "events/roomtombstoneevent.h" #include #include @@ -303,6 +305,11 @@ public: const RelatedEvents relatedEvents(const RoomEvent& evt, const char* relType) const; + const RoomCreateEvent* creation() const + { return getCurrentState(); } + const RoomTombstoneEvent* tombstone() const + { return getCurrentState(); } + bool displayed() const; /// Mark the room as currently displayed to the user /** -- cgit v1.2.3 From 6b2847de2325f2b818dc336c9339d50de58604ea Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 9 Dec 2019 18:31:59 +0300 Subject: Pass action scope to Room::setTags The tags can now be applied not only to the current room but also propagated to its predecessors and successors. --- lib/room.cpp | 17 ++++++++++++++++- lib/room.h | 18 +++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/room.cpp b/lib/room.cpp index 41a8888c..60b9a684 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -948,12 +948,27 @@ void Room::removeTag(const QString& name) << "not found, nothing to remove"; } -void Room::setTags(TagsMap newTags) +void Room::setTags(TagsMap newTags, ActionScope applyOn) { + bool propagate = applyOn != ActionScope::ThisRoomOnly; + auto joinStates = + applyOn == ActionScope::WithinSameState ? joinState() : + applyOn == ActionScope::OmitLeftState ? JoinState::Join|JoinState::Invite : + JoinState::Join|JoinState::Invite|JoinState::Leave; + if (propagate) { + for (auto* r = this; (r = r->predecessor(joinStates));) + r->setTags(newTags, ActionScope::ThisRoomOnly); + } + d->setTags(move(newTags)); connection()->callApi( localUser()->id(), id(), TagEvent::matrixTypeId(), TagEvent(d->tags).contentJson()); + + if (propagate) { + for (auto* r = this; (r = r->successor(joinStates));) + r->setTags(newTags, ActionScope::ThisRoomOnly); + } } void Room::Private::setTags(TagsMap newTags) diff --git a/lib/room.h b/lib/room.h index 10f18742..ad19792e 100644 --- a/lib/room.h +++ b/lib/room.h @@ -396,6 +396,19 @@ public: /// Remove a tag from the room Q_INVOKABLE void removeTag(const QString& name); + /// The scope to apply an action on + /*! This enumeration is used to pick a strategy to propagate certain + * actions on the room to its predecessors and successors. + */ + enum ActionScope { + ThisRoomOnly, //< Do not apply to predecessors and successors + WithinSameState, //< Apply to predecessors and successors in the same + //< state as the current one + OmitLeftState, //< Apply to all reachable predecessors and successors + //< except those in Leave state + WholeSequence //< Apply to all reachable predecessors and successors + }; + /** Overwrite the room's tags * This completely replaces the existing room's tags with a set * of new ones and updates the new set on the server. Unlike @@ -403,8 +416,11 @@ public: * immediately, not waiting for confirmation from the server * (because tags are saved in account data rather than in shared * room state). + * \param applyOn setting this to Room::OnAllConversations will set tags + * on this and all _known_ predecessors and successors; + * by default only the current room is changed */ - void setTags(TagsMap newTags); + void setTags(TagsMap newTags, ActionScope applyOn = ThisRoomOnly); /// Check whether the list of tags has m.favourite bool isFavourite() const; -- cgit v1.2.3