From aacc4bcb4a487871daae6717f77605aaba444341 Mon Sep 17 00:00:00 2001 From: Marc Deop Date: Sat, 2 Mar 2019 12:26:57 +0100 Subject: style: apply .clang-format to all .cpp and .h files --- lib/room.h | 1071 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 544 insertions(+), 527 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index f4ecef42..4645d02a 100644 --- a/lib/room.h +++ b/lib/room.h @@ -13,25 +13,24 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #pragma once #include "csapi/message_pagination.h" -#include "events/roommessageevent.h" -#include "events/accountdataevents.h" #include "eventitem.h" +#include "events/accountdataevents.h" +#include "events/roommessageevent.h" #include "joinstate.h" #include -#include #include +#include #include -namespace QMatrixClient -{ +namespace QMatrixClient { class Event; class Avatar; class SyncRoomData; @@ -50,553 +49,571 @@ namespace QMatrixClient */ class FileTransferInfo { - Q_GADGET - Q_PROPERTY(bool isUpload MEMBER isUpload CONSTANT) - Q_PROPERTY(bool active READ active CONSTANT) - Q_PROPERTY(bool started READ started CONSTANT) - Q_PROPERTY(bool completed READ completed CONSTANT) - Q_PROPERTY(bool failed READ failed CONSTANT) - Q_PROPERTY(int progress MEMBER progress CONSTANT) - Q_PROPERTY(int total MEMBER total CONSTANT) - Q_PROPERTY(QUrl localDir MEMBER localDir CONSTANT) - Q_PROPERTY(QUrl localPath MEMBER localPath CONSTANT) + Q_GADGET + Q_PROPERTY(bool isUpload MEMBER isUpload CONSTANT) + Q_PROPERTY(bool active READ active CONSTANT) + Q_PROPERTY(bool started READ started CONSTANT) + Q_PROPERTY(bool completed READ completed CONSTANT) + Q_PROPERTY(bool failed READ failed CONSTANT) + Q_PROPERTY(int progress MEMBER progress CONSTANT) + Q_PROPERTY(int total MEMBER total CONSTANT) + Q_PROPERTY(QUrl localDir MEMBER localDir CONSTANT) + Q_PROPERTY(QUrl localPath MEMBER localPath CONSTANT) public: - enum Status { None, Started, Completed, Failed, Cancelled }; - Status status = None; - bool isUpload = false; - int progress = 0; - int total = -1; - QUrl localDir { }; - QUrl localPath { }; - - bool started() const { return status == Started; } - bool completed() const { return status == Completed; } - bool active() const { return started() || completed(); } - bool failed() const { return status == Failed; } + enum Status { None, Started, Completed, Failed, Cancelled }; + Status status = None; + bool isUpload = false; + int progress = 0; + int total = -1; + QUrl localDir {}; + QUrl localPath {}; + + bool started() const { return status == Started; } + bool completed() const { return status == Completed; } + bool active() const { return started() || completed(); } + bool failed() const { return status == Failed; } }; - class Room: public QObject + class Room : public QObject { - Q_OBJECT - Q_PROPERTY(Connection* connection READ connection CONSTANT) - Q_PROPERTY(User* localUser READ localUser CONSTANT) - Q_PROPERTY(QString id READ id CONSTANT) - Q_PROPERTY(QString version READ version NOTIFY baseStateLoaded) - Q_PROPERTY(bool isUnstable READ isUnstable NOTIFY stabilityUpdated) - Q_PROPERTY(QString predecessorId READ predecessorId NOTIFY baseStateLoaded) - Q_PROPERTY(QString successorId READ successorId NOTIFY upgraded) - Q_PROPERTY(QString name READ name NOTIFY namesChanged) - Q_PROPERTY(QStringList aliases READ aliases NOTIFY namesChanged) - Q_PROPERTY(QString canonicalAlias READ canonicalAlias NOTIFY namesChanged) - Q_PROPERTY(QString displayName READ displayName NOTIFY namesChanged) - Q_PROPERTY(QString topic READ topic NOTIFY topicChanged) - Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false) - Q_PROPERTY(QUrl avatarUrl READ avatarUrl NOTIFY avatarChanged) - Q_PROPERTY(bool usesEncryption READ usesEncryption NOTIFY encryption) - - 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) - Q_PROPERTY(QString lastDisplayedEventId READ lastDisplayedEventId WRITE setLastDisplayedEventId NOTIFY lastDisplayedEventChanged) - - Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE markMessagesAsRead NOTIFY readMarkerMoved) - Q_PROPERTY(bool hasUnreadMessages READ hasUnreadMessages NOTIFY unreadMessagesChanged) - Q_PROPERTY(int unreadCount READ unreadCount NOTIFY unreadMessagesChanged) - Q_PROPERTY(QStringList tagNames READ tagNames NOTIFY tagsChanged) - Q_PROPERTY(bool isFavourite READ isFavourite NOTIFY tagsChanged) - Q_PROPERTY(bool isLowPriority READ isLowPriority NOTIFY tagsChanged) - - Q_PROPERTY(GetRoomEventsJob* eventsHistoryJob READ eventsHistoryJob NOTIFY eventsHistoryJobChanged) + Q_OBJECT + Q_PROPERTY(Connection* connection READ connection CONSTANT) + Q_PROPERTY(User* localUser READ localUser CONSTANT) + Q_PROPERTY(QString id READ id CONSTANT) + Q_PROPERTY(QString version READ version NOTIFY baseStateLoaded) + Q_PROPERTY(bool isUnstable READ isUnstable NOTIFY stabilityUpdated) + Q_PROPERTY( + QString predecessorId READ predecessorId NOTIFY baseStateLoaded) + Q_PROPERTY(QString successorId READ successorId NOTIFY upgraded) + Q_PROPERTY(QString name READ name NOTIFY namesChanged) + Q_PROPERTY(QStringList aliases READ aliases NOTIFY namesChanged) + Q_PROPERTY( + QString canonicalAlias READ canonicalAlias NOTIFY namesChanged) + Q_PROPERTY(QString displayName READ displayName NOTIFY namesChanged) + Q_PROPERTY(QString topic READ topic NOTIFY topicChanged) + Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged + STORED false) + Q_PROPERTY(QUrl avatarUrl READ avatarUrl NOTIFY avatarChanged) + Q_PROPERTY(bool usesEncryption READ usesEncryption NOTIFY encryption) + + 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) + Q_PROPERTY(QString lastDisplayedEventId READ lastDisplayedEventId WRITE + setLastDisplayedEventId NOTIFY + lastDisplayedEventChanged) + + Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE + markMessagesAsRead NOTIFY readMarkerMoved) + Q_PROPERTY(bool hasUnreadMessages READ hasUnreadMessages NOTIFY + unreadMessagesChanged) + Q_PROPERTY( + int unreadCount READ unreadCount NOTIFY unreadMessagesChanged) + Q_PROPERTY(QStringList tagNames READ tagNames NOTIFY tagsChanged) + Q_PROPERTY(bool isFavourite READ isFavourite NOTIFY tagsChanged) + Q_PROPERTY(bool isLowPriority READ isLowPriority NOTIFY tagsChanged) + + Q_PROPERTY(GetRoomEventsJob* eventsHistoryJob READ eventsHistoryJob + NOTIFY eventsHistoryJobChanged) public: - using Timeline = std::deque; - using PendingEvents = std::vector; - using rev_iter_t = Timeline::const_reverse_iterator; - using timeline_iter_t = Timeline::const_iterator; - - enum Change : uint { - NoChange = 0x0, - NameChange = 0x1, - CanonicalAliasChange = 0x2, - TopicChange = 0x4, - UnreadNotifsChange = 0x8, - AvatarChange = 0x10, - JoinStateChange = 0x20, - TagsChange = 0x40, - MembersChange = 0x80, - /* = 0x100, */ - AccountDataChange = 0x200, - SummaryChange = 0x400, - ReadMarkerChange = 0x800, - OtherChange = 0x8000, - AnyChange = 0xFFFF - }; - Q_DECLARE_FLAGS(Changes, Change) - Q_FLAG(Changes) - - Room(Connection* connection, QString id, JoinState initialJoinState); - ~Room() override; - - // Property accessors - - Connection* connection() const; - User* localUser() const; - const QString& id() const; - QString version() const; - bool isUnstable() const; - QString predecessorId() const; - QString successorId() const; - QString name() const; - QStringList aliases() const; - QString canonicalAlias() const; - QString displayName() const; - QString topic() const; - QString avatarMediaId() const; - QUrl avatarUrl() const; - const Avatar& avatarObject() const; - Q_INVOKABLE JoinState joinState() const; - Q_INVOKABLE QList usersTyping() const; - QList membersLeft() const; - - Q_INVOKABLE QList 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; - - /** - * Returns a square room avatar with the given size and requests it - * from the network if needed - * \return a pixmap with the avatar or a placeholder if there's none - * available yet - */ - Q_INVOKABLE QImage avatar(int dimension); - /** - * Returns a room avatar with the given dimensions and requests it - * from the network if needed - * \return a pixmap with the avatar or a placeholder if there's none - * available yet - */ - Q_INVOKABLE QImage avatar(int width, int height); - - /** - * \brief Get a user object for a given user id - * This is the recommended way to get a user object in a room - * context. The actual object type may be changed in further - * versions to provide room-specific user information (display name, - * avatar etc.). - * \note The method will return a valid user regardless of - * the membership. - */ - Q_INVOKABLE User* user(const QString& userId) const; - - /** - * \brief Check the join state of a given user in this room - * - * \note Banned and invited users are not tracked for now (Leave - * will be returned for them). - * - * \return either of Join, Leave, depending on the given - * user's state in the room - */ - Q_INVOKABLE JoinState memberJoinState(User* user) const; - - /** - * Get a disambiguated name for a given user in - * the context of the room - */ - Q_INVOKABLE QString roomMembername(const User* u) const; - /** - * Get a disambiguated name for a user with this id in - * the context of the room - */ - Q_INVOKABLE QString roomMembername(const QString& userId) const; - - const Timeline& messageEvents() const; - const PendingEvents& pendingEvents() const; - /** - * A convenience method returning the read marker to the position - * before the "oldest" event; same as messageEvents().crend() - */ - rev_iter_t historyEdge() const; - /** - * A convenience method returning the iterator beyond the latest - * arrived event; same as messageEvents().cend() - */ - Timeline::const_iterator syncEdge() const; - /// \deprecated Use historyEdge instead - rev_iter_t timelineEdge() const; - Q_INVOKABLE TimelineItem::index_t minTimelineIndex() const; - Q_INVOKABLE TimelineItem::index_t maxTimelineIndex() const; - Q_INVOKABLE bool isValidIndex(TimelineItem::index_t timelineIndex) const; - - rev_iter_t findInTimeline(TimelineItem::index_t index) const; - rev_iter_t findInTimeline(const QString& evtId) const; - PendingEvents::iterator findPendingEvent(const QString & txnId); - PendingEvents::const_iterator findPendingEvent(const QString & txnId) const; - - bool displayed() const; - /// Mark the room as currently displayed to the user - /** - * Marking the room displayed causes the room to obtain the full - * list of members if it's been lazy-loaded before; in the future - * it may do more things bound to "screen time" of the room, e.g. - * measure that "screen time". - */ - void setDisplayed(bool displayed = true); - QString firstDisplayedEventId() const; - rev_iter_t firstDisplayedMarker() const; - void setFirstDisplayedEventId(const QString& eventId); - void setFirstDisplayedEvent(TimelineItem::index_t index); - QString lastDisplayedEventId() const; - rev_iter_t lastDisplayedMarker() const; - void setLastDisplayedEventId(const QString& eventId); - void setLastDisplayedEvent(TimelineItem::index_t index); - - rev_iter_t readMarker(const User* user) const; - rev_iter_t readMarker() const; - QString readMarkerEventId() const; - QList usersAtEventId(const QString& eventId); - /** - * \brief Mark the event with uptoEventId as read - * - * 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. uptoEventId must be non-empty. - */ - void markMessagesAsRead(QString uptoEventId); - - /// Check whether there are unread messages in the room - bool hasUnreadMessages() const; - - /** Get the number of unread messages in the room - * Depending on the read marker state, this call may return either - * a precise or an estimate number of unread events. Only "notable" - * events (non-redacted message events from users other than local) - * are counted. - * - * In a case when readMarker() == timelineEdge() (the local read - * marker is beyond the local timeline) only the bottom limit of - * the unread messages number can be estimated (and even that may - * be slightly off due to, e.g., redactions of events not loaded - * to the local timeline). - * - * If all messages are read, this function will return -1 (_not_ 0, - * as zero may mean "zero or more unread messages" in a situation - * when the read marker is outside the local timeline. - */ - int unreadCount() const; - - Q_INVOKABLE int notificationCount() const; - Q_INVOKABLE void resetNotificationCount(); - Q_INVOKABLE int highlightCount() const; - Q_INVOKABLE void resetHighlightCount(); - - /** Check whether the room has account data of the given type - * Tags and read markers are not supported by this method _yet_. - */ - bool hasAccountData(const QString& type) const; - - /** Get a generic account data event of the given type - * This returns a generic hashmap for any room account data event - * stored on the server. Tags and read markers cannot be retrieved - * using this method _yet_. - */ - const EventPtr& accountData(const QString& type) const; - - QStringList tagNames() const; - TagsMap tags() const; - TagRecord tag(const QString& name) const; - - /** Add a new tag to this room - * If this room already has this tag, nothing happens. If it's a new - * tag for the room, the respective tag record is added to the set - * of tags and the new set is sent to the server to update other - * clients. - */ - void addTag(const QString& name, const TagRecord& record = {}); - Q_INVOKABLE void addTag(const QString& name, float order); - - /// Remove a tag from the room - Q_INVOKABLE void removeTag(const QString& name); - - /** 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 - * most other methods in Room, this one sends a signal about changes - * immediately, not waiting for confirmation from the server - * (because tags are saved in account data rather than in shared - * room state). - */ - void setTags(TagsMap newTags); - - /// Check whether the list of tags has m.favourite - bool isFavourite() const; - /// Check whether the list of tags has m.lowpriority - bool isLowPriority() const; - - /// Check whether this room is a direct chat - Q_INVOKABLE bool isDirectChat() const; - - /// Get the list of users this room is a direct chat with - QList directChatUsers() const; - - Q_INVOKABLE QUrl urlToThumbnail(const QString& eventId) const; - Q_INVOKABLE QUrl urlToDownload(const QString& eventId) const; - Q_INVOKABLE QString fileNameToDownload(const QString& eventId) const; - Q_INVOKABLE FileTransferInfo fileTransferInfo(const QString& id) const; - Q_INVOKABLE QUrl fileSource(const QString& id) const; - - /** Pretty-prints plain text into HTML - * As of now, it's exactly the same as QMatrixClient::prettyPrint(); - * in the future, it will also linkify room aliases, mxids etc. - * using the room context. - */ - QString prettyPrint(const QString& plainText) const; - - MemberSorter memberSorter() const; - - Q_INVOKABLE void inviteCall(const QString& callId, - const int lifetime, const QString& sdp); - Q_INVOKABLE void sendCallCandidates(const QString& callId, + using Timeline = std::deque; + using PendingEvents = std::vector; + using rev_iter_t = Timeline::const_reverse_iterator; + using timeline_iter_t = Timeline::const_iterator; + + enum Change : uint { + NoChange = 0x0, + NameChange = 0x1, + CanonicalAliasChange = 0x2, + TopicChange = 0x4, + UnreadNotifsChange = 0x8, + AvatarChange = 0x10, + JoinStateChange = 0x20, + TagsChange = 0x40, + MembersChange = 0x80, + /* = 0x100, */ + AccountDataChange = 0x200, + SummaryChange = 0x400, + ReadMarkerChange = 0x800, + OtherChange = 0x8000, + AnyChange = 0xFFFF + }; + Q_DECLARE_FLAGS(Changes, Change) + Q_FLAG(Changes) + + Room(Connection* connection, QString id, JoinState initialJoinState); + ~Room() override; + + // Property accessors + + Connection* connection() const; + User* localUser() const; + const QString& id() const; + QString version() const; + bool isUnstable() const; + QString predecessorId() const; + QString successorId() const; + QString name() const; + QStringList aliases() const; + QString canonicalAlias() const; + QString displayName() const; + QString topic() const; + QString avatarMediaId() const; + QUrl avatarUrl() const; + const Avatar& avatarObject() const; + Q_INVOKABLE JoinState joinState() const; + Q_INVOKABLE QList usersTyping() const; + QList membersLeft() const; + + Q_INVOKABLE QList 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; + + /** + * Returns a square room avatar with the given size and requests it + * from the network if needed + * \return a pixmap with the avatar or a placeholder if there's none + * available yet + */ + Q_INVOKABLE QImage avatar(int dimension); + /** + * Returns a room avatar with the given dimensions and requests it + * from the network if needed + * \return a pixmap with the avatar or a placeholder if there's none + * available yet + */ + Q_INVOKABLE QImage avatar(int width, int height); + + /** + * \brief Get a user object for a given user id + * This is the recommended way to get a user object in a room + * context. The actual object type may be changed in further + * versions to provide room-specific user information (display name, + * avatar etc.). + * \note The method will return a valid user regardless of + * the membership. + */ + Q_INVOKABLE User* user(const QString& userId) const; + + /** + * \brief Check the join state of a given user in this room + * + * \note Banned and invited users are not tracked for now (Leave + * will be returned for them). + * + * \return either of Join, Leave, depending on the given + * user's state in the room + */ + Q_INVOKABLE JoinState memberJoinState(User* user) const; + + /** + * Get a disambiguated name for a given user in + * the context of the room + */ + Q_INVOKABLE QString roomMembername(const User* u) const; + /** + * Get a disambiguated name for a user with this id in + * the context of the room + */ + Q_INVOKABLE QString roomMembername(const QString& userId) const; + + const Timeline& messageEvents() const; + const PendingEvents& pendingEvents() const; + /** + * A convenience method returning the read marker to the position + * before the "oldest" event; same as messageEvents().crend() + */ + rev_iter_t historyEdge() const; + /** + * A convenience method returning the iterator beyond the latest + * arrived event; same as messageEvents().cend() + */ + Timeline::const_iterator syncEdge() const; + /// \deprecated Use historyEdge instead + rev_iter_t timelineEdge() const; + Q_INVOKABLE TimelineItem::index_t minTimelineIndex() const; + Q_INVOKABLE TimelineItem::index_t maxTimelineIndex() const; + Q_INVOKABLE bool + isValidIndex(TimelineItem::index_t timelineIndex) const; + + rev_iter_t findInTimeline(TimelineItem::index_t index) const; + rev_iter_t findInTimeline(const QString& evtId) const; + PendingEvents::iterator findPendingEvent(const QString& txnId); + PendingEvents::const_iterator + findPendingEvent(const QString& txnId) const; + + bool displayed() const; + /// Mark the room as currently displayed to the user + /** + * Marking the room displayed causes the room to obtain the full + * list of members if it's been lazy-loaded before; in the future + * it may do more things bound to "screen time" of the room, e.g. + * measure that "screen time". + */ + void setDisplayed(bool displayed = true); + QString firstDisplayedEventId() const; + rev_iter_t firstDisplayedMarker() const; + void setFirstDisplayedEventId(const QString& eventId); + void setFirstDisplayedEvent(TimelineItem::index_t index); + QString lastDisplayedEventId() const; + rev_iter_t lastDisplayedMarker() const; + void setLastDisplayedEventId(const QString& eventId); + void setLastDisplayedEvent(TimelineItem::index_t index); + + rev_iter_t readMarker(const User* user) const; + rev_iter_t readMarker() const; + QString readMarkerEventId() const; + QList usersAtEventId(const QString& eventId); + /** + * \brief Mark the event with uptoEventId as read + * + * 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. uptoEventId must be non-empty. + */ + void markMessagesAsRead(QString uptoEventId); + + /// Check whether there are unread messages in the room + bool hasUnreadMessages() const; + + /** Get the number of unread messages in the room + * Depending on the read marker state, this call may return either + * a precise or an estimate number of unread events. Only "notable" + * events (non-redacted message events from users other than local) + * are counted. + * + * In a case when readMarker() == timelineEdge() (the local read + * marker is beyond the local timeline) only the bottom limit of + * the unread messages number can be estimated (and even that may + * be slightly off due to, e.g., redactions of events not loaded + * to the local timeline). + * + * If all messages are read, this function will return -1 (_not_ 0, + * as zero may mean "zero or more unread messages" in a situation + * when the read marker is outside the local timeline. + */ + int unreadCount() const; + + Q_INVOKABLE int notificationCount() const; + Q_INVOKABLE void resetNotificationCount(); + Q_INVOKABLE int highlightCount() const; + Q_INVOKABLE void resetHighlightCount(); + + /** Check whether the room has account data of the given type + * Tags and read markers are not supported by this method _yet_. + */ + bool hasAccountData(const QString& type) const; + + /** Get a generic account data event of the given type + * This returns a generic hashmap for any room account data event + * stored on the server. Tags and read markers cannot be retrieved + * using this method _yet_. + */ + const EventPtr& accountData(const QString& type) const; + + QStringList tagNames() const; + TagsMap tags() const; + TagRecord tag(const QString& name) const; + + /** Add a new tag to this room + * If this room already has this tag, nothing happens. If it's a new + * tag for the room, the respective tag record is added to the set + * of tags and the new set is sent to the server to update other + * clients. + */ + void addTag(const QString& name, const TagRecord& record = {}); + Q_INVOKABLE void addTag(const QString& name, float order); + + /// Remove a tag from the room + Q_INVOKABLE void removeTag(const QString& name); + + /** 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 + * most other methods in Room, this one sends a signal about changes + * immediately, not waiting for confirmation from the server + * (because tags are saved in account data rather than in shared + * room state). + */ + void setTags(TagsMap newTags); + + /// Check whether the list of tags has m.favourite + bool isFavourite() const; + /// Check whether the list of tags has m.lowpriority + bool isLowPriority() const; + + /// Check whether this room is a direct chat + Q_INVOKABLE bool isDirectChat() const; + + /// Get the list of users this room is a direct chat with + QList directChatUsers() const; + + Q_INVOKABLE QUrl urlToThumbnail(const QString& eventId) const; + Q_INVOKABLE QUrl urlToDownload(const QString& eventId) const; + Q_INVOKABLE QString fileNameToDownload(const QString& eventId) const; + Q_INVOKABLE FileTransferInfo fileTransferInfo(const QString& id) const; + Q_INVOKABLE QUrl fileSource(const QString& id) const; + + /** Pretty-prints plain text into HTML + * As of now, it's exactly the same as QMatrixClient::prettyPrint(); + * in the future, it will also linkify room aliases, mxids etc. + * using the room context. + */ + QString prettyPrint(const QString& plainText) const; + + MemberSorter memberSorter() const; + + Q_INVOKABLE void inviteCall(const QString& callId, const int lifetime, + const QString& sdp); + Q_INVOKABLE void sendCallCandidates(const QString& callId, const QJsonArray& candidates); - Q_INVOKABLE void answerCall(const QString& callId, const int lifetime, - const QString& sdp); - Q_INVOKABLE void answerCall(const QString& callId, - const QString& sdp); - Q_INVOKABLE void hangupCall(const QString& callId); - Q_INVOKABLE bool supportsCalls() const; + Q_INVOKABLE void answerCall(const QString& callId, const int lifetime, + const QString& sdp); + Q_INVOKABLE void answerCall(const QString& callId, const QString& sdp); + Q_INVOKABLE void hangupCall(const QString& callId); + Q_INVOKABLE bool supportsCalls() const; public slots: - /** Check whether the room should be upgraded */ - void checkVersion(); - - QString postMessage(const QString& plainText, MessageEventType type); - QString postPlainText(const QString& plainText); - QString postHtmlMessage(const QString& plainText, - const QString& html, - MessageEventType type = MessageEventType::Text); - QString postHtmlText(const QString& plainText, const QString& html); - QString postFile(const QString& plainText, const QUrl& localPath, - bool asGenericFile = false); - /** Post a pre-created room message event - * - * Takes ownership of the event, deleting it once the matching one - * arrives with the sync - * \return transaction id associated with the event. - */ - QString postEvent(RoomEvent* event); - QString postJson(const QString& matrixType, - const QJsonObject& eventContent); - QString retryMessage(const QString& txnId); - void discardMessage(const QString& txnId); - void setName(const QString& newName); - void setCanonicalAlias(const QString& newAlias); - void setAliases(const QStringList& aliases); - void setTopic(const QString& newTopic); - - void getPreviousContent(int limit = 10); - - void inviteToRoom(const QString& memberId); - LeaveRoomJob* leaveRoom(); - SetRoomStateWithKeyJob* setMemberState( - const QString& memberId, const RoomMemberEvent& event) const; - void kickMember(const QString& memberId, const QString& reason = {}); - void ban(const QString& userId, const QString& reason = {}); - void unban(const QString& userId); - void redactEvent(const QString& eventId, - const QString& reason = {}); - - void uploadFile(const QString& id, const QUrl& localFilename, - const QString& overrideContentType = {}); - // If localFilename is empty a temporary file is created - void downloadFile(const QString& eventId, - const QUrl& localFilename = {}); - void cancelFileTransfer(const QString& id); - - /// Mark all messages in the room as read - void markAllMessagesAsRead(); - - /// Whether the current user is allowed to upgrade the room - bool canSwitchVersions() const; - - /// Switch the room's version (aka upgrade) - void switchVersion(QString newVersion); + /** Check whether the room should be upgraded */ + void checkVersion(); + + QString postMessage(const QString& plainText, MessageEventType type); + QString postPlainText(const QString& plainText); + QString postHtmlMessage(const QString& plainText, const QString& html, + MessageEventType type = MessageEventType::Text); + QString postHtmlText(const QString& plainText, const QString& html); + QString postFile(const QString& plainText, const QUrl& localPath, + bool asGenericFile = false); + /** Post a pre-created room message event + * + * Takes ownership of the event, deleting it once the matching one + * arrives with the sync + * \return transaction id associated with the event. + */ + QString postEvent(RoomEvent* event); + QString postJson(const QString& matrixType, + const QJsonObject& eventContent); + QString retryMessage(const QString& txnId); + void discardMessage(const QString& txnId); + void setName(const QString& newName); + void setCanonicalAlias(const QString& newAlias); + void setAliases(const QStringList& aliases); + void setTopic(const QString& newTopic); + + void getPreviousContent(int limit = 10); + + void inviteToRoom(const QString& memberId); + LeaveRoomJob* leaveRoom(); + SetRoomStateWithKeyJob* + setMemberState(const QString& memberId, + const RoomMemberEvent& event) const; + void kickMember(const QString& memberId, const QString& reason = {}); + void ban(const QString& userId, const QString& reason = {}); + void unban(const QString& userId); + void redactEvent(const QString& eventId, const QString& reason = {}); + + void uploadFile(const QString& id, const QUrl& localFilename, + const QString& overrideContentType = {}); + // If localFilename is empty a temporary file is created + void downloadFile(const QString& eventId, + const QUrl& localFilename = {}); + void cancelFileTransfer(const QString& id); + + /// Mark all messages in the room as read + void markAllMessagesAsRead(); + + /// Whether the current user is allowed to upgrade the room + bool canSwitchVersions() const; + + /// Switch the room's version (aka upgrade) + void switchVersion(QString newVersion); signals: - /// Initial set of state events has been loaded - /** - * The initial set is what comes from the initial sync for the room. - * This includes all basic things like RoomCreateEvent, - * RoomNameEvent, a (lazy-loaded, not full) set of RoomMemberEvents - * etc. This is a per-room reflection of Connection::loadedRoomState - * \sa Connection::loadedRoomState - */ - void baseStateLoaded(); - void eventsHistoryJobChanged(); - void aboutToAddHistoricalMessages(RoomEventsRange events); - void aboutToAddNewMessages(RoomEventsRange events); - void addedMessages(int fromIndex, int toIndex); - /// The event is about to be appended to the list of pending events - void pendingEventAboutToAdd(RoomEvent* event); - /// An event has been appended to the list of pending events - void pendingEventAdded(); - /// The remote echo has arrived with the sync and will be merged - /// with its local counterpart - /** NB: Requires a sync loop to be emitted */ - void pendingEventAboutToMerge(RoomEvent* serverEvent, - int pendingEventIndex); - /// The remote and local copies of the event have been merged - /** NB: Requires a sync loop to be emitted */ - void pendingEventMerged(); - /// An event will be removed from the list of pending events - void pendingEventAboutToDiscard(int pendingEventIndex); - /// An event has just been removed from the list of pending events - void pendingEventDiscarded(); - /// The status of a pending event has changed - /** \sa PendingEventItem::deliveryStatus */ - void pendingEventChanged(int pendingEventIndex); - /// The server accepted the message - /** This is emitted when an event sending request has successfully - * completed. This does not mean that the event is already in the - * local timeline, only that the server has accepted it. - * \param txnId transaction id assigned by the client during sending - * \param eventId event id assigned by the server upon acceptance - * \sa postEvent, postPlainText, postMessage, postHtmlMessage - * \sa pendingEventMerged, aboutToAddNewMessages - */ - void messageSent(QString txnId, QString eventId); - - /** A common signal for various kinds of changes in the room - * Aside from all changes in the room state - * @param changes a set of flags describing what changes occured - * upon the last sync - * \sa StateChange - */ - void changed(Changes changes); - /** - * \brief The room name, the canonical alias or other aliases changed - * - * Not triggered when displayname changes. - */ - void namesChanged(Room* room); - void displaynameAboutToChange(Room* room); - void displaynameChanged(Room* room, QString oldName); - void topicChanged(); - void avatarChanged(); - void userAdded(User* user); - void userRemoved(User* user); - void memberAboutToRename(User* user, QString newName); - void memberRenamed(User* user); - /// The list of members has changed - /** Emitted no more than once per sync, this is a good signal to - * for cases when some action should be done upon any change in - * the member list. If you need per-item granularity you should use - * userAdded, userRemoved and memberAboutToRename / memberRenamed - * instead. - */ - void memberListChanged(); - /// The previously lazy-loaded members list is now loaded entirely - /// \sa setDisplayed - void allMembersLoaded(); - void encryption(); - - void joinStateChanged(JoinState oldState, JoinState newState); - void typingChanged(); - - void highlightCountChanged(Room* room); - void notificationCountChanged(Room* room); - - void displayedChanged(bool displayed); - void firstDisplayedEventChanged(); - void lastDisplayedEventChanged(); - void lastReadEventChanged(User* user); - void readMarkerMoved(QString fromEventId, QString toEventId); - void readMarkerForUserMoved(User* user, QString fromEventId, QString toEventId); - void unreadMessagesChanged(Room* room); - - void accountDataAboutToChange(QString type); - void accountDataChanged(QString type); - void tagsAboutToChange(); - void tagsChanged(); - - void replacedEvent(const RoomEvent* newEvent, - const RoomEvent* oldEvent); - - void newFileTransfer(QString id, QUrl localFile); - void fileTransferProgress(QString id, qint64 progress, qint64 total); - void fileTransferCompleted(QString id, QUrl localFile, QUrl mxcUrl); - void fileTransferFailed(QString id, QString errorMessage = {}); - void fileTransferCancelled(QString id); - - void callEvent(Room* room, const RoomEvent* event); - - /// The room's version stability may have changed - void stabilityUpdated(QString recommendedDefault, - QStringList stableVersions); - /// This room has been upgraded and won't receive updates anymore - void upgraded(QString serverMessage, Room* successor); - /// An attempted room upgrade has failed - void upgradeFailed(QString errorMessage); - - /// The room is about to be deleted - void beforeDestruction(Room*); + /// Initial set of state events has been loaded + /** + * The initial set is what comes from the initial sync for the room. + * This includes all basic things like RoomCreateEvent, + * RoomNameEvent, a (lazy-loaded, not full) set of RoomMemberEvents + * etc. This is a per-room reflection of Connection::loadedRoomState + * \sa Connection::loadedRoomState + */ + void baseStateLoaded(); + void eventsHistoryJobChanged(); + void aboutToAddHistoricalMessages(RoomEventsRange events); + void aboutToAddNewMessages(RoomEventsRange events); + void addedMessages(int fromIndex, int toIndex); + /// The event is about to be appended to the list of pending events + void pendingEventAboutToAdd(RoomEvent* event); + /// An event has been appended to the list of pending events + void pendingEventAdded(); + /// The remote echo has arrived with the sync and will be merged + /// with its local counterpart + /** NB: Requires a sync loop to be emitted */ + void pendingEventAboutToMerge(RoomEvent* serverEvent, + int pendingEventIndex); + /// The remote and local copies of the event have been merged + /** NB: Requires a sync loop to be emitted */ + void pendingEventMerged(); + /// An event will be removed from the list of pending events + void pendingEventAboutToDiscard(int pendingEventIndex); + /// An event has just been removed from the list of pending events + void pendingEventDiscarded(); + /// The status of a pending event has changed + /** \sa PendingEventItem::deliveryStatus */ + void pendingEventChanged(int pendingEventIndex); + /// The server accepted the message + /** This is emitted when an event sending request has successfully + * completed. This does not mean that the event is already in the + * local timeline, only that the server has accepted it. + * \param txnId transaction id assigned by the client during sending + * \param eventId event id assigned by the server upon acceptance + * \sa postEvent, postPlainText, postMessage, postHtmlMessage + * \sa pendingEventMerged, aboutToAddNewMessages + */ + void messageSent(QString txnId, QString eventId); + + /** A common signal for various kinds of changes in the room + * Aside from all changes in the room state + * @param changes a set of flags describing what changes occured + * upon the last sync + * \sa StateChange + */ + void changed(Changes changes); + /** + * \brief The room name, the canonical alias or other aliases changed + * + * Not triggered when displayname changes. + */ + void namesChanged(Room* room); + void displaynameAboutToChange(Room* room); + void displaynameChanged(Room* room, QString oldName); + void topicChanged(); + void avatarChanged(); + void userAdded(User* user); + void userRemoved(User* user); + void memberAboutToRename(User* user, QString newName); + void memberRenamed(User* user); + /// The list of members has changed + /** Emitted no more than once per sync, this is a good signal to + * for cases when some action should be done upon any change in + * the member list. If you need per-item granularity you should use + * userAdded, userRemoved and memberAboutToRename / memberRenamed + * instead. + */ + void memberListChanged(); + /// The previously lazy-loaded members list is now loaded entirely + /// \sa setDisplayed + void allMembersLoaded(); + void encryption(); + + void joinStateChanged(JoinState oldState, JoinState newState); + void typingChanged(); + + void highlightCountChanged(Room* room); + void notificationCountChanged(Room* room); + + void displayedChanged(bool displayed); + void firstDisplayedEventChanged(); + void lastDisplayedEventChanged(); + void lastReadEventChanged(User* user); + void readMarkerMoved(QString fromEventId, QString toEventId); + void readMarkerForUserMoved(User* user, QString fromEventId, + QString toEventId); + void unreadMessagesChanged(Room* room); + + void accountDataAboutToChange(QString type); + void accountDataChanged(QString type); + void tagsAboutToChange(); + void tagsChanged(); + + void replacedEvent(const RoomEvent* newEvent, + const RoomEvent* oldEvent); + + void newFileTransfer(QString id, QUrl localFile); + void fileTransferProgress(QString id, qint64 progress, qint64 total); + void fileTransferCompleted(QString id, QUrl localFile, QUrl mxcUrl); + void fileTransferFailed(QString id, QString errorMessage = {}); + void fileTransferCancelled(QString id); + + void callEvent(Room* room, const RoomEvent* event); + + /// The room's version stability may have changed + void stabilityUpdated(QString recommendedDefault, + QStringList stableVersions); + /// This room has been upgraded and won't receive updates anymore + void upgraded(QString serverMessage, Room* successor); + /// An attempted room upgrade has failed + void upgradeFailed(QString errorMessage); + + /// The room is about to be deleted + void beforeDestruction(Room*); protected: - /// Returns true if any of room names/aliases has changed - virtual Changes processStateEvent(const RoomEvent& e); - virtual Changes processEphemeralEvent(EventPtr&& event); - virtual Changes processAccountDataEvent(EventPtr&& event); - virtual void onAddNewTimelineEvents(timeline_iter_t /*from*/) { } - virtual void onAddHistoricalTimelineEvents(rev_iter_t /*from*/) { } - virtual void onRedaction(const RoomEvent& /*prevEvent*/, - const RoomEvent& /*after*/) { } - virtual QJsonObject toJson() const; - virtual void updateData(SyncRoomData&& data, bool fromCache = false); + /// Returns true if any of room names/aliases has changed + virtual Changes processStateEvent(const RoomEvent& e); + virtual Changes processEphemeralEvent(EventPtr&& event); + virtual Changes processAccountDataEvent(EventPtr&& event); + virtual void onAddNewTimelineEvents(timeline_iter_t /*from*/) {} + virtual void onAddHistoricalTimelineEvents(rev_iter_t /*from*/) {} + virtual void onRedaction(const RoomEvent& /*prevEvent*/, + const RoomEvent& /*after*/) + { + } + virtual QJsonObject toJson() const; + virtual void updateData(SyncRoomData&& data, bool fromCache = false); private: - friend class Connection; + friend class Connection; - class Private; - Private* d; + class Private; + Private* d; - // This is called from Connection, reflecting a state change that - // arrived from the server. Clients should use - // Connection::joinRoom() and Room::leaveRoom() to change the state. - void setJoinState(JoinState state); + // This is called from Connection, reflecting a state change that + // arrived from the server. Clients should use + // Connection::joinRoom() and Room::leaveRoom() to change the state. + void setJoinState(JoinState state); }; class MemberSorter { public: - explicit MemberSorter(const Room* r) : room(r) { } + explicit MemberSorter(const Room* r) : room(r) {} - bool operator()(User* u1, User* u2) const; - bool operator()(User* u1, const QString& u2name) const; + bool operator()(User* u1, User* u2) const; + bool operator()(User* u1, const QString& u2name) const; - template - typename ContT::size_type lowerBoundIndex(const ContT& c, - const ValT& v) const - { - return std::lower_bound(c.begin(), c.end(), v, *this) - c.begin(); - } + template + typename ContT::size_type lowerBoundIndex(const ContT& c, + const ValT& v) const + { + return std::lower_bound(c.begin(), c.end(), v, *this) - c.begin(); + } private: - const Room* room; + const Room* room; }; -} // namespace QMatrixClient +} // namespace QMatrixClient Q_DECLARE_METATYPE(QMatrixClient::FileTransferInfo) Q_DECLARE_OPERATORS_FOR_FLAGS(QMatrixClient::Room::Changes) -- cgit v1.2.3 From ced57b074d0dc4e6e582a4bddca7a07e41d2063f Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 12 Mar 2019 21:16:54 +0900 Subject: Make Room::prettyPrint Q_INVOKABLE So that it can be called from QML code --- lib/room.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index f4ecef42..f7add412 100644 --- a/lib/room.h +++ b/lib/room.h @@ -365,7 +365,7 @@ namespace QMatrixClient * in the future, it will also linkify room aliases, mxids etc. * using the room context. */ - QString prettyPrint(const QString& plainText) const; + Q_INVOKABLE QString prettyPrint(const QString& plainText) const; MemberSorter memberSorter() const; -- cgit v1.2.3 From b6b4b5e82c8984c0c7e29c4ccf5c2d25cda563f9 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 13 Mar 2019 18:07:03 +0900 Subject: Room: make notificationCount, highlightCount Q_PROPERTYs Closes #299. Due to restrictions for the NOTIFY signal notificationCountChanged and highlightCountChanged no more carry Room* as a parameter, breaking back-compatibility. --- lib/room.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index f7add412..352c098b 100644 --- a/lib/room.h +++ b/lib/room.h @@ -108,6 +108,8 @@ namespace QMatrixClient Q_PROPERTY(QString readMarkerEventId READ readMarkerEventId WRITE markMessagesAsRead NOTIFY readMarkerMoved) Q_PROPERTY(bool hasUnreadMessages READ hasUnreadMessages NOTIFY unreadMessagesChanged) 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(QStringList tagNames READ tagNames NOTIFY tagsChanged) Q_PROPERTY(bool isFavourite READ isFavourite NOTIFY tagsChanged) Q_PROPERTY(bool isLowPriority READ isLowPriority NOTIFY tagsChanged) @@ -517,8 +519,8 @@ namespace QMatrixClient void joinStateChanged(JoinState oldState, JoinState newState); void typingChanged(); - void highlightCountChanged(Room* room); - void notificationCountChanged(Room* room); + void highlightCountChanged(); + void notificationCountChanged(); void displayedChanged(bool displayed); void firstDisplayedEventChanged(); -- cgit v1.2.3 From 266f4b8a82fa437bbd49c8e3d85313677e068699 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 21 Mar 2019 15:41:06 +0900 Subject: Room::displayName: fix NOTIFY signal for Q_PROPERTY --- lib/room.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 352c098b..85c67bfb 100644 --- a/lib/room.h +++ b/lib/room.h @@ -88,7 +88,7 @@ namespace QMatrixClient Q_PROPERTY(QString name READ name NOTIFY namesChanged) Q_PROPERTY(QStringList aliases READ aliases NOTIFY namesChanged) Q_PROPERTY(QString canonicalAlias READ canonicalAlias NOTIFY namesChanged) - Q_PROPERTY(QString displayName READ displayName NOTIFY namesChanged) + Q_PROPERTY(QString displayName READ displayName NOTIFY displaynameChanged) Q_PROPERTY(QString topic READ topic NOTIFY topicChanged) Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false) Q_PROPERTY(QUrl avatarUrl READ avatarUrl NOTIFY avatarChanged) -- cgit v1.2.3 From 27ba75b458d2418051b170eb811ab88c00c336db Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 31 Mar 2019 18:41:12 +0900 Subject: Room::refreshDisplayName() - for debugging purposes only Clients should not need to call this method explicitly. --- lib/room.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 85c67bfb..8440543e 100644 --- a/lib/room.h +++ b/lib/room.h @@ -410,6 +410,9 @@ namespace QMatrixClient void setAliases(const QStringList& aliases); void setTopic(const QString& newTopic); + /// You shouldn't normally call this method; it's here for debugging + void refreshDisplayName(); + void getPreviousContent(int limit = 10); void inviteToRoom(const QString& memberId); -- cgit v1.2.3 From 008207f178475531c0a8a86b2192c09d7134ad0e Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 3 Apr 2019 19:33:24 +0900 Subject: room.h: more doc-comments --- lib/room.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 8440543e..db4336ea 100644 --- a/lib/room.h +++ b/lib/room.h @@ -358,8 +358,28 @@ namespace QMatrixClient Q_INVOKABLE QUrl urlToThumbnail(const QString& eventId) const; Q_INVOKABLE QUrl urlToDownload(const QString& eventId) const; + + /// Get a file name for downloading for a given event id + /*! + * The event MUST be RoomMessageEvent and have content + * for downloading. \sa RoomMessageEvent::hasContent + */ Q_INVOKABLE QString fileNameToDownload(const QString& eventId) const; + + /// Get information on file upload/download + /*! + * \param id uploads are identified by the corresponding event's + * transactionId (because uploads are done before + * the event is even sent), while downloads are using + * the normal event id for identifier. + */ Q_INVOKABLE FileTransferInfo fileTransferInfo(const QString& id) const; + + /// Get the URL to the actual file source in a unified way + /*! + * For uploads it will return a URL to a local file; for downloads + * the URL will be taken from the corresponding room event. + */ Q_INVOKABLE QUrl fileSource(const QString& id) const; /** Pretty-prints plain text into HTML -- cgit v1.2.3 From 2d39b1e51e500fa17788630cd0e6a57a451eb475 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 4 May 2019 08:34:18 +0900 Subject: Room::allHistoryLoaded --- lib/room.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index db4336ea..055da3da 100644 --- a/lib/room.h +++ b/lib/room.h @@ -110,6 +110,7 @@ namespace QMatrixClient 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(bool allHistoryLoaded READ allHistoryLoaded NOTIFY addedMessages STORED false) Q_PROPERTY(QStringList tagNames READ tagNames NOTIFY tagsChanged) Q_PROPERTY(bool isFavourite READ isFavourite NOTIFY tagsChanged) Q_PROPERTY(bool isLowPriority READ isLowPriority NOTIFY tagsChanged) @@ -228,6 +229,14 @@ namespace QMatrixClient const Timeline& messageEvents() const; const PendingEvents& pendingEvents() const; + + /// Check whether all historical messages are already loaded + /** + * \return true if the "oldest" event in the timeline is + * a room creation event and there's no further history + * to load; false otherwise + */ + bool allHistoryLoaded() const; /** * A convenience method returning the read marker to the position * before the "oldest" event; same as messageEvents().crend() -- cgit v1.2.3 From 7ea51059b86d8124c077ed84ad3b91770af8d610 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 2 Jun 2019 13:22:11 +0900 Subject: lib/room.*: Spelling fixes in comments [ci skip] --- lib/room.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 055da3da..d4a1b959 100644 --- a/lib/room.h +++ b/lib/room.h @@ -322,7 +322,7 @@ namespace QMatrixClient bool hasAccountData(const QString& type) const; /** Get a generic account data event of the given type - * This returns a generic hashmap for any room account data event + * This returns a generic hash map for any room account data event * stored on the server. Tags and read markers cannot be retrieved * using this method _yet_. */ @@ -516,7 +516,7 @@ namespace QMatrixClient /** A common signal for various kinds of changes in the room * Aside from all changes in the room state - * @param changes a set of flags describing what changes occured + * @param changes a set of flags describing what changes occurred * upon the last sync * \sa StateChange */ @@ -524,7 +524,7 @@ namespace QMatrixClient /** * \brief The room name, the canonical alias or other aliases changed * - * Not triggered when displayname changes. + * Not triggered when display name changes. */ void namesChanged(Room* room); void displaynameAboutToChange(Room* room); @@ -581,7 +581,7 @@ namespace QMatrixClient /// The room's version stability may have changed void stabilityUpdated(QString recommendedDefault, QStringList stableVersions); - /// This room has been upgraded and won't receive updates anymore + /// This room has been upgraded and won't receive updates any more void upgraded(QString serverMessage, Room* successor); /// An attempted room upgrade has failed void upgradeFailed(QString errorMessage); -- cgit v1.2.3 From 6a6857b9d4dbf22402f2871494bdd06cdccdf366 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 3 Jul 2019 23:28:09 +0900 Subject: Room/Connection: make room aliases work properly Closes #301. --- lib/room.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index d4a1b959..7c85e4ed 100644 --- a/lib/room.h +++ b/lib/room.h @@ -86,7 +86,8 @@ namespace QMatrixClient Q_PROPERTY(QString predecessorId READ predecessorId NOTIFY baseStateLoaded) Q_PROPERTY(QString successorId READ successorId NOTIFY upgraded) Q_PROPERTY(QString name READ name NOTIFY namesChanged) - Q_PROPERTY(QStringList aliases READ aliases NOTIFY namesChanged) + Q_PROPERTY(QStringList localAliases READ localAliases NOTIFY namesChanged) + Q_PROPERTY(QStringList remoteAliases READ remoteAliases NOTIFY namesChanged) Q_PROPERTY(QString canonicalAlias READ canonicalAlias NOTIFY namesChanged) Q_PROPERTY(QString displayName READ displayName NOTIFY displaynameChanged) Q_PROPERTY(QString topic READ topic NOTIFY topicChanged) @@ -156,7 +157,12 @@ namespace QMatrixClient QString predecessorId() const; QString successorId() const; QString name() const; - QStringList aliases() const; + /// Room aliases defined on the current user's server + /// \sa remoteAliases, setLocalAliases + QStringList localAliases() const; + /// Room aliases defined on other servers + /// \sa localAliases + QStringList remoteAliases() const; QString canonicalAlias() const; QString displayName() const; QString topic() const; @@ -436,7 +442,8 @@ namespace QMatrixClient void discardMessage(const QString& txnId); void setName(const QString& newName); void setCanonicalAlias(const QString& newAlias); - void setAliases(const QStringList& aliases); + /// Set room aliases on the user's current server + void setLocalAliases(const QStringList& aliases); void setTopic(const QString& newTopic); /// You shouldn't normally call this method; it's here for debugging @@ -590,7 +597,6 @@ namespace QMatrixClient void beforeDestruction(Room*); protected: - /// Returns true if any of room names/aliases has changed virtual Changes processStateEvent(const RoomEvent& e); virtual Changes processEphemeralEvent(EventPtr&& event); virtual Changes processAccountDataEvent(EventPtr&& event); -- cgit v1.2.3 From 025e5ab7d90ce8cf474567457301de32d5a3e34a Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 6 Jul 2019 20:13:38 +0900 Subject: Be stricter on usage of stateKey A few places in the library dealt with state events without any notion of state_key inside events, including StateEvent[Base] and relevant functions in Room. A number of workarounds have been made; e.g., Room::setMemberState() accepted userId as a separate parameter, ignoring the state key inside the RoomMemberEvent already passed to it, and Room::setLocalAliases() had a bug in the initial version where the function still tried to pass aliases in an event with an empty state key. This commit fixes this shortcoming: StateEventBase now gets stateKey as one more parameter, Room::Private::getCurrentState() respects stateKey and returns properly constructed stub events, and Room::setMemberState() gives way to a more generic Room::setState() that works uniformly with whatever state event you pass to it. --- lib/room.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 7c85e4ed..3abf262d 100644 --- a/lib/room.h +++ b/lib/room.h @@ -440,6 +440,9 @@ namespace QMatrixClient const QJsonObject& eventContent); QString retryMessage(const QString& txnId); void discardMessage(const QString& txnId); + + /// Send a request to update the room state with the given event + SetRoomStateWithKeyJob* setState(const StateEventBase& evt) const; void setName(const QString& newName); void setCanonicalAlias(const QString& newAlias); /// Set room aliases on the user's current server @@ -453,6 +456,7 @@ namespace QMatrixClient void inviteToRoom(const QString& memberId); LeaveRoomJob* leaveRoom(); + /// \deprecated - use setState() instead") SetRoomStateWithKeyJob* setMemberState( const QString& memberId, const RoomMemberEvent& event) const; void kickMember(const QString& memberId, const QString& reason = {}); -- cgit v1.2.3 From f0c1269bf592f5ba1ccde3b667e6737fe75a335d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 8 Jul 2019 19:37:23 +0900 Subject: Room: Set roomId and sender on pending events Also: refactoring to streamline state events submission. --- lib/room.h | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 3abf262d..c79ca1e0 100644 --- a/lib/room.h +++ b/lib/room.h @@ -18,6 +18,7 @@ #pragma once +#include "connection.h" #include "csapi/message_pagination.h" #include "events/roommessageevent.h" #include "events/accountdataevents.h" @@ -36,7 +37,6 @@ namespace QMatrixClient class Avatar; class SyncRoomData; class RoomMemberEvent; - class Connection; class User; class MemberSorter; class LeaveRoomJob; @@ -406,17 +406,14 @@ namespace QMatrixClient MemberSorter memberSorter() const; - Q_INVOKABLE void inviteCall(const QString& callId, - const int lifetime, const QString& sdp); - Q_INVOKABLE void sendCallCandidates(const QString& callId, - const QJsonArray& candidates); - Q_INVOKABLE void answerCall(const QString& callId, const int lifetime, - const QString& sdp); - Q_INVOKABLE void answerCall(const QString& callId, - const QString& sdp); - Q_INVOKABLE void hangupCall(const QString& callId); Q_INVOKABLE bool supportsCalls() const; + template + auto setState(ArgTs&&... args) const + { + return setState(EvT(std::forward(args)...)); + } + public slots: /** Check whether the room should be upgraded */ void checkVersion(); @@ -481,6 +478,15 @@ namespace QMatrixClient /// Switch the room's version (aka upgrade) void switchVersion(QString newVersion); + void inviteCall(const QString& callId, + const int lifetime, const QString& sdp); + void sendCallCandidates(const QString& callId, + const QJsonArray& candidates); + void answerCall(const QString& callId, const int lifetime, + const QString& sdp); + void answerCall(const QString& callId, const QString& sdp); + void hangupCall(const QString& callId); + signals: /// Initial set of state events has been loaded /** -- cgit v1.2.3 From 2737dc00334ad3a56c1b311435dbe84453ee389e Mon Sep 17 00:00:00 2001 From: Alexey Andreyev Date: Sun, 14 Jul 2019 03:54:19 +0300 Subject: E2EE: introduce EncryptedEvent --- lib/room.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index c79ca1e0..e09556b6 100644 --- a/lib/room.h +++ b/lib/room.h @@ -24,8 +24,10 @@ #include "events/accountdataevents.h" #include "eventitem.h" #include "joinstate.h" +#include "events/encryptedevent.h" #include +#include #include #include @@ -179,6 +181,10 @@ namespace QMatrixClient int memberCount() const; int timelineSize() const; bool usesEncryption() const; + const RoomEvent *decryptMessage(EncryptedEvent* encryptedEvent) const; + const QString decryptMessage(QJsonObject personalCipherObject, QByteArray senderKey) const; + const QString sessionKey(const QString &senderKey, const QString &deviceId, const QString &sessionId) const; + const QString decryptMessage(QByteArray cipher, const QString& senderKey, const QString& deviceId, const QString& sessionId) const; int joinedCount() const; int invitedCount() const; int totalMemberCount() const; -- cgit v1.2.3 From b89d5c43746ed672d98bf350db2a9e1b0878e2d0 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sat, 18 May 2019 13:52:54 +0900 Subject: Support for receiving m.reaction events * struct EventRelation; class ReactionEvent; Room::relatedEvents() * Reaction events are processed in both history and sync batches * Redacting a reaction removes it from the list of related events * QMCTest::sendReaction() --- lib/room.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index c79ca1e0..65b9070a 100644 --- a/lib/room.h +++ b/lib/room.h @@ -121,6 +121,7 @@ namespace QMatrixClient public: using Timeline = std::deque; using PendingEvents = std::vector; + using RelatedEvents = QVector; using rev_iter_t = Timeline::const_reverse_iterator; using timeline_iter_t = Timeline::const_iterator; @@ -264,6 +265,11 @@ namespace QMatrixClient PendingEvents::iterator findPendingEvent(const QString & txnId); PendingEvents::const_iterator findPendingEvent(const QString & txnId) const; + const RelatedEvents relatedEvents(const QString& evtId, + const char* relType) const; + const RelatedEvents relatedEvents(const RoomEvent& evt, + const char* relType) const; + bool displayed() const; /// Mark the room as currently displayed to the user /** @@ -584,6 +590,7 @@ namespace QMatrixClient void tagsAboutToChange(); void tagsChanged(); + void updatedEvent(QString eventId); void replacedEvent(const RoomEvent* newEvent, const RoomEvent* oldEvent); -- cgit v1.2.3 From 1ea94b918569dd26452f285c408e605f9dc15343 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 30 Jul 2019 07:53:34 +0900 Subject: Room::postReaction() --- lib/room.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 65b9070a..470bb7f9 100644 --- a/lib/room.h +++ b/lib/room.h @@ -430,6 +430,8 @@ namespace QMatrixClient const QString& html, MessageEventType type = MessageEventType::Text); QString postHtmlText(const QString& plainText, const QString& html); + /// Send a reaction on a given event with a given key + QString postReaction(const QString& eventId, const QString& key); QString postFile(const QString& plainText, const QUrl& localPath, bool asGenericFile = false); /** Post a pre-created room message event -- cgit v1.2.3 From c05ade838f0fce81f2bbe80a3295618a8a26ff52 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Fri, 2 Aug 2019 19:59:40 +0900 Subject: Apply the new brace wrapping to source files --- lib/room.h | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index f5433fb6..d6fb8a61 100644 --- a/lib/room.h +++ b/lib/room.h @@ -35,8 +35,7 @@ #include #include -namespace QMatrixClient -{ +namespace QMatrixClient { class Event; class Avatar; class SyncRoomData; @@ -52,8 +51,7 @@ class RedactEventJob; * This is specifically tuned to work with QML exposing all traits as * Q_PROPERTY values. */ -class FileTransferInfo -{ +class FileTransferInfo { Q_GADGET Q_PROPERTY(bool isUpload MEMBER isUpload CONSTANT) Q_PROPERTY(bool active READ active CONSTANT) @@ -65,14 +63,7 @@ class FileTransferInfo Q_PROPERTY(QUrl localDir MEMBER localDir CONSTANT) Q_PROPERTY(QUrl localPath MEMBER localPath CONSTANT) public: - enum Status - { - None, - Started, - Completed, - Failed, - Cancelled - }; + enum Status { None, Started, Completed, Failed, Cancelled }; Status status = None; bool isUpload = false; int progress = 0; @@ -86,8 +77,7 @@ public: bool failed() const { return status == Failed; } }; -class Room : public QObject -{ +class Room : public QObject { Q_OBJECT Q_PROPERTY(Connection* connection READ connection CONSTANT) Q_PROPERTY(User* localUser READ localUser CONSTANT) @@ -146,8 +136,7 @@ public: using rev_iter_t = Timeline::const_reverse_iterator; using timeline_iter_t = Timeline::const_iterator; - enum Change : uint - { + enum Change : uint { NoChange = 0x0, NameChange = 0x1, CanonicalAliasChange = 0x2, @@ -663,12 +652,9 @@ private: void setJoinState(JoinState state); }; -class MemberSorter -{ +class MemberSorter { public: - explicit MemberSorter(const Room* r) - : room(r) - {} + explicit MemberSorter(const Room* r) : room(r) {} bool operator()(User* u1, User* u2) const; bool operator()(User* u1, const QString& u2name) const; -- cgit v1.2.3 From 27ca32a1e5a56e09b9cc1d94224d2831004dcf3d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 7 Jul 2019 19:32:34 +0900 Subject: Namespace: QMatrixClient -> Quotient (with back comp alias) --- lib/room.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index d6fb8a61..8448815d 100644 --- a/lib/room.h +++ b/lib/room.h @@ -35,7 +35,7 @@ #include #include -namespace QMatrixClient { +namespace Quotient { class Event; class Avatar; class SyncRoomData; @@ -423,7 +423,7 @@ public: Q_INVOKABLE QUrl fileSource(const QString& id) const; /** Pretty-prints plain text into HTML - * As of now, it's exactly the same as QMatrixClient::prettyPrint(); + * As of now, it's exactly the same as Quotient::prettyPrint(); * in the future, it will also linkify room aliases, mxids etc. * using the room context. */ @@ -668,6 +668,6 @@ public: private: const Room* room; }; -} // namespace QMatrixClient -Q_DECLARE_METATYPE(QMatrixClient::FileTransferInfo) -Q_DECLARE_OPERATORS_FOR_FLAGS(QMatrixClient::Room::Changes) +} // namespace Quotient +Q_DECLARE_METATYPE(Quotient::FileTransferInfo) +Q_DECLARE_OPERATORS_FOR_FLAGS(Quotient::Room::Changes) -- cgit v1.2.3 From fadce11be92abe76cecfe6356b3b38f25dd93e8d Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 13 Aug 2019 20:28:56 +0900 Subject: Support for server notices rooms (MSC1452) Closes #326. --- lib/room.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 8448815d..2139f28b 100644 --- a/lib/room.h +++ b/lib/room.h @@ -389,6 +389,8 @@ public: bool isFavourite() const; /// Check whether the list of tags has m.lowpriority bool isLowPriority() const; + /// Check whether this room is for server notices (MSC1452) + bool isServerNoticeRoom() const; /// Check whether this room is a direct chat Q_INVOKABLE bool isDirectChat() const; -- cgit v1.2.3 From a9eef2c6b2f73ebc921b07fe37009bccf31038c8 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 18 Aug 2019 19:26:37 +0900 Subject: Room::decryptMessage: now with the header file changes --- lib/room.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 2139f28b..9113654b 100644 --- a/lib/room.h +++ b/lib/room.h @@ -191,14 +191,13 @@ public: memberCount() const; int timelineSize() const; bool usesEncryption() const; - const RoomEvent* decryptMessage(EncryptedEvent* encryptedEvent) const; - const QString decryptMessage(QJsonObject personalCipherObject, - QByteArray senderKey) const; - const QString sessionKey(const QString& senderKey, const QString& deviceId, - const QString& sessionId) const; - const QString decryptMessage(QByteArray cipher, const QString& senderKey, - const QString& deviceId, - const QString& sessionId) const; + RoomEventPtr decryptMessage(EncryptedEvent* encryptedEvent); + QString decryptMessage(QJsonObject personalCipherObject, + QByteArray senderKey); + QString sessionKey(const QString& senderKey, const QString& deviceId, + const QString& sessionId) const; + QString decryptMessage(QByteArray cipher, const QString& senderKey, + const QString& deviceId, const QString& sessionId); int joinedCount() const; int invitedCount() const; int totalMemberCount() const; -- cgit v1.2.3 From c9f99699761e97b16bdb44f584f07baec5488b47 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 24 Sep 2019 19:56:31 +0900 Subject: Room: cleanup --- lib/room.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 9113654b..ac169550 100644 --- a/lib/room.h +++ b/lib/room.h @@ -557,7 +557,7 @@ signals: * Aside from all changes in the room state * @param changes a set of flags describing what changes occurred * upon the last sync - * \sa StateChange + * \sa Changes */ void changed(Changes changes); /** -- cgit v1.2.3 From 8f1bfa5c5764e399259c13b260661647363cf5d9 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 29 Sep 2019 17:46:28 +0900 Subject: Fix formatting weirdness Alas, clang-format is not terrifically good around [[attributes]] --- lib/room.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index ac169550..698f74c8 100644 --- a/lib/room.h +++ b/lib/room.h @@ -187,8 +187,8 @@ public: Q_INVOKABLE QList users() const; QStringList memberNames() const; - [[deprecated("Use joinedCount(), invitedCount(), totalMemberCount()")]] int - memberCount() const; + [[deprecated("Use joinedCount(), invitedCount(), totalMemberCount()")]] + int memberCount() const; int timelineSize() const; bool usesEncryption() const; RoomEventPtr decryptMessage(EncryptedEvent* encryptedEvent); -- cgit v1.2.3 From f71d16b56ab90e494d6a41c276210a4ce593987e Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Tue, 1 Oct 2019 13:14:30 +0900 Subject: Room::getCurrentState() --- lib/room.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 698f74c8..cded7eb9 100644 --- a/lib/room.h +++ b/lib/room.h @@ -434,6 +434,24 @@ public: Q_INVOKABLE bool supportsCalls() const; + /// Get a state event with the given event type and state key + /*! This method returns a (potentially empty) state event corresponding + * to the pair of event type \p evtType and state key \p stateKey. + */ + Q_INVOKABLE const StateEventBase* + getCurrentState(const QString& evtType, const QString& stateKey = {}) const; + + template + const EvT* getCurrentState(const QString& stateKey = {}) const + { + const auto* evt = + eventCast(getCurrentState(EvT::matrixTypeId(), stateKey)); + Q_ASSERT(evt); + Q_ASSERT(evt->matrixTypeId() == EvT::matrixTypeId() + && evt->stateKey() == stateKey); + return evt; + } + template auto setState(ArgTs&&... args) const { -- cgit v1.2.3 From 8b9207d5a04386957d8eab8dd251421eaaa7c0d2 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 20 Oct 2019 19:13:56 +0900 Subject: Qualify types in signals and Q_INVOKABLEs Because https://doc.qt.io/qt-5/moc.html#limitations . For direct connections that doesn't matter but it very much does for queued ones. Along with this DirectChatsMap and IgnoredUsersList have been moved from Connection:: to Quotient::. --- lib/room.h | 64 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 34 insertions(+), 30 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index cded7eb9..80e305f0 100644 --- a/lib/room.h +++ b/lib/room.h @@ -181,11 +181,11 @@ public: QString avatarMediaId() const; QUrl avatarUrl() const; const Avatar& avatarObject() const; - Q_INVOKABLE JoinState joinState() const; - Q_INVOKABLE QList usersTyping() const; + Q_INVOKABLE Quotient::JoinState joinState() const; + Q_INVOKABLE QList usersTyping() const; QList membersLeft() const; - Q_INVOKABLE QList users() const; + Q_INVOKABLE QList users() const; QStringList memberNames() const; [[deprecated("Use joinedCount(), invitedCount(), totalMemberCount()")]] int memberCount() const; @@ -228,7 +228,7 @@ public: * \note The method will return a valid user regardless of * the membership. */ - Q_INVOKABLE User* user(const QString& userId) const; + Q_INVOKABLE Quotient::User* user(const QString& userId) const; /** * \brief Check the join state of a given user in this room @@ -236,16 +236,15 @@ public: * \note Banned and invited users are not tracked for now (Leave * will be returned for them). * - * \return either of Join, Leave, depending on the given - * user's state in the room + * \return Join if the user is a room member; Leave otherwise */ - Q_INVOKABLE JoinState memberJoinState(User* user) const; + Q_INVOKABLE Quotient::JoinState memberJoinState(Quotient::User* user) const; /** * Get a disambiguated name for a given user in * the context of the room */ - Q_INVOKABLE QString roomMembername(const User* u) const; + Q_INVOKABLE QString roomMembername(const Quotient::User* u) const; /** * Get a disambiguated name for a user with this id in * the context of the room @@ -274,9 +273,10 @@ public: Timeline::const_iterator syncEdge() const; /// \deprecated Use historyEdge instead rev_iter_t timelineEdge() const; - Q_INVOKABLE TimelineItem::index_t minTimelineIndex() const; - Q_INVOKABLE TimelineItem::index_t maxTimelineIndex() const; - Q_INVOKABLE bool isValidIndex(TimelineItem::index_t timelineIndex) const; + Q_INVOKABLE Quotient::TimelineItem::index_t minTimelineIndex() const; + Q_INVOKABLE Quotient::TimelineItem::index_t maxTimelineIndex() const; + Q_INVOKABLE bool + isValidIndex(Quotient::TimelineItem::index_t timelineIndex) const; rev_iter_t findInTimeline(TimelineItem::index_t index) const; rev_iter_t findInTimeline(const QString& evtId) const; @@ -414,7 +414,8 @@ public: * the event is even sent), while downloads are using * the normal event id for identifier. */ - Q_INVOKABLE FileTransferInfo fileTransferInfo(const QString& id) const; + Q_INVOKABLE Quotient::FileTransferInfo + fileTransferInfo(const QString& id) const; /// Get the URL to the actual file source in a unified way /*! @@ -438,7 +439,7 @@ public: /*! This method returns a (potentially empty) state event corresponding * to the pair of event type \p evtType and state key \p stateKey. */ - Q_INVOKABLE const StateEventBase* + Q_INVOKABLE const Quotient::StateEventBase* getCurrentState(const QString& evtType, const QString& stateKey = {}) const; template @@ -549,7 +550,8 @@ signals: /// The remote echo has arrived with the sync and will be merged /// with its local counterpart /** NB: Requires a sync loop to be emitted */ - void pendingEventAboutToMerge(RoomEvent* serverEvent, int pendingEventIndex); + void pendingEventAboutToMerge(Quotient::RoomEvent* serverEvent, + int pendingEventIndex); /// The remote and local copies of the event have been merged /** NB: Requires a sync loop to be emitted */ void pendingEventMerged(); @@ -577,21 +579,21 @@ signals: * upon the last sync * \sa Changes */ - void changed(Changes changes); + void changed(Quotient::Room::Changes changes); /** * \brief The room name, the canonical alias or other aliases changed * * Not triggered when display name changes. */ - void namesChanged(Room* room); - void displaynameAboutToChange(Room* room); - void displaynameChanged(Room* room, QString oldName); + void namesChanged(Quotient::Room* room); + void displaynameAboutToChange(Quotient::Room* room); + void displaynameChanged(Quotient::Room* room, QString oldName); void topicChanged(); void avatarChanged(); - void userAdded(User* user); - void userRemoved(User* user); - void memberAboutToRename(User* user, QString newName); - void memberRenamed(User* user); + void userAdded(Quotient::User* user); + void userRemoved(Quotient::User* user); + void memberAboutToRename(Quotient::User* user, QString newName); + void memberRenamed(Quotient::User* user); /// The list of members has changed /** Emitted no more than once per sync, this is a good signal to * for cases when some action should be done upon any change in @@ -605,7 +607,8 @@ signals: void allMembersLoaded(); void encryption(); - void joinStateChanged(JoinState oldState, JoinState newState); + void joinStateChanged(Quotient::JoinState oldState, + Quotient::JoinState newState); void typingChanged(); void highlightCountChanged(); @@ -614,11 +617,11 @@ signals: void displayedChanged(bool displayed); void firstDisplayedEventChanged(); void lastDisplayedEventChanged(); - void lastReadEventChanged(User* user); + void lastReadEventChanged(Quotient::User* user); void readMarkerMoved(QString fromEventId, QString toEventId); - void readMarkerForUserMoved(User* user, QString fromEventId, + void readMarkerForUserMoved(Quotient::User* user, QString fromEventId, QString toEventId); - void unreadMessagesChanged(Room* room); + void unreadMessagesChanged(Quotient::Room* room); void accountDataAboutToChange(QString type); void accountDataChanged(QString type); @@ -626,7 +629,8 @@ signals: void tagsChanged(); void updatedEvent(QString eventId); - void replacedEvent(const RoomEvent* newEvent, const RoomEvent* oldEvent); + void replacedEvent(const Quotient::RoomEvent* newEvent, + const Quotient::RoomEvent* oldEvent); void newFileTransfer(QString id, QUrl localFile); void fileTransferProgress(QString id, qint64 progress, qint64 total); @@ -634,18 +638,18 @@ signals: void fileTransferFailed(QString id, QString errorMessage = {}); void fileTransferCancelled(QString id); - void callEvent(Room* room, const RoomEvent* event); + void callEvent(Quotient::Room* room, const Quotient::RoomEvent* event); /// The room's version stability may have changed void stabilityUpdated(QString recommendedDefault, QStringList stableVersions); /// This room has been upgraded and won't receive updates any more - void upgraded(QString serverMessage, Room* successor); + void upgraded(QString serverMessage, Quotient::Room* successor); /// An attempted room upgrade has failed void upgradeFailed(QString errorMessage); /// The room is about to be deleted - void beforeDestruction(Room*); + void beforeDestruction(Quotient::Room*); protected: virtual Changes processStateEvent(const RoomEvent& e); -- cgit v1.2.3 From f0d241c6bb8fb3219736ec6ead20564bcea9a991 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 25 Nov 2019 15:20:12 +0900 Subject: Remove extraneous qualification --- lib/room.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 80e305f0..7e419823 100644 --- a/lib/room.h +++ b/lib/room.h @@ -181,7 +181,7 @@ public: QString avatarMediaId() const; QUrl avatarUrl() const; const Avatar& avatarObject() const; - Q_INVOKABLE Quotient::JoinState joinState() const; + Q_INVOKABLE JoinState joinState() const; Q_INVOKABLE QList usersTyping() const; QList membersLeft() const; -- cgit v1.2.3 From 105ff3874baf0792616e1b330ce97f0b725adaf5 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Mon, 9 Dec 2019 18:14:43 +0300 Subject: Room: more doc-comments --- lib/room.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 7e419823..2c958033 100644 --- a/lib/room.h +++ b/lib/room.h @@ -442,6 +442,10 @@ public: Q_INVOKABLE const Quotient::StateEventBase* getCurrentState(const QString& evtType, const QString& stateKey = {}) const; + /// Get a state event with the given event type and state key + /*! This is a typesafe overload that accepts a C++ event type instead of + * its Matrix name. + */ template const EvT* getCurrentState(const QString& stateKey = {}) const { @@ -453,6 +457,14 @@ public: return evt; } + /// Set a state event of the given type with the given arguments + /*! This typesafe overload attempts to send a state event with the type + * \p EvT and the content defined by \p args. Specifically, the function + * creates a temporary object of type \p EvT passing \p args to + * the constructor, and sends a request to the homeserver using + * the Matrix event type defined by \p EvT and the event content produced + * via EvT::contentJson(). + */ template auto setState(ArgTs&&... args) const { -- cgit v1.2.3 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.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'lib/room.h') 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/room.h') 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.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'lib/room.h') 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 From 715a0c0aa094eedbe24516e19a7b37dde71ba994 Mon Sep 17 00:00:00 2001 From: Alexey Andreyev Date: Fri, 23 Aug 2019 17:14:09 +0300 Subject: E2EE: add connection session decrypt, handle to-device and device_one_time_keys_count Signed-off-by: Alexey Andreev --- lib/room.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index ad19792e..2243ec6b 100644 --- a/lib/room.h +++ b/lib/room.h @@ -26,6 +26,7 @@ #include "events/accountdataevents.h" #include "events/encryptedevent.h" +#include "events/roomkeyevent.h" #include "events/roommessageevent.h" #include "events/roomcreateevent.h" #include "events/roomtombstoneevent.h" @@ -215,6 +216,7 @@ public: const QString& sessionId) const; QString decryptMessage(QByteArray cipher, const QString& senderKey, const QString& deviceId, const QString& sessionId); + void handleRoomKeyEvent(RoomKeyEvent* roomKeyEvent, QString senderKey); int joinedCount() const; int invitedCount() const; int totalMemberCount() const; -- cgit v1.2.3 From 6a3cd81b5179a38b5731f09b62f56b24ada7ff0f Mon Sep 17 00:00:00 2001 From: Alexey Andreyev Date: Fri, 23 Aug 2019 17:15:44 +0300 Subject: E2EE: implement megolm inbound session decrypt for room Signed-off-by: Alexey Andreev --- lib/room.h | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 2243ec6b..d78a7bfc 100644 --- a/lib/room.h +++ b/lib/room.h @@ -209,13 +209,7 @@ public: int memberCount() const; int timelineSize() const; bool usesEncryption() const; - RoomEventPtr decryptMessage(EncryptedEvent* encryptedEvent); - QString decryptMessage(QJsonObject personalCipherObject, - QByteArray senderKey); - QString sessionKey(const QString& senderKey, const QString& deviceId, - const QString& sessionId) const; - QString decryptMessage(QByteArray cipher, const QString& senderKey, - const QString& deviceId, const QString& sessionId); + RoomEventPtr decryptMessage(const EncryptedEvent& encryptedEvent); void handleRoomKeyEvent(RoomKeyEvent* roomKeyEvent, QString senderKey); int joinedCount() const; int invitedCount() const; -- cgit v1.2.3 From 99c7e1c5e2a78c6babba50418789bd4c4f0e9db3 Mon Sep 17 00:00:00 2001 From: Ram Nad Date: Fri, 20 Mar 2020 02:29:45 +0530 Subject: made suggested changes --- lib/room.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index ad19792e..4d2527f7 100644 --- a/lib/room.h +++ b/lib/room.h @@ -188,11 +188,14 @@ public: QString name() const; /// Room aliases defined on the current user's server /// \sa remoteAliases, setLocalAliases + [[deprecated("Use aliases()")]] QStringList localAliases() const; /// Room aliases defined on other servers /// \sa localAliases + [[deprecated("Use aliases()")]] QStringList remoteAliases() const; QString canonicalAlias() const; + QStringList aliases() const; QString displayName() const; QString topic() const; QString avatarMediaId() const; -- cgit v1.2.3 From a2177b704c06bccc4840607803bca4fbe747830b Mon Sep 17 00:00:00 2001 From: Ram Nad Date: Fri, 20 Mar 2020 13:12:42 +0530 Subject: added altAliases() --- lib/room.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 4d2527f7..d5fea94f 100644 --- a/lib/room.h +++ b/lib/room.h @@ -141,7 +141,8 @@ public: enum Change : uint { NoChange = 0x0, NameChange = 0x1, - CanonicalAliasChange = 0x2, + AliasesChange = 0x2, + CanonicalAliasChange = AliasesChange, TopicChange = 0x4, UnreadNotifsChange = 0x8, AvatarChange = 0x10, @@ -195,6 +196,7 @@ public: [[deprecated("Use aliases()")]] QStringList remoteAliases() const; QString canonicalAlias() const; + QStringList altAliases() const; QStringList aliases() const; QString displayName() const; QString topic() const; -- cgit v1.2.3 From 79a3e9e2accd0de0ac8bf35d8b77f36ca211899f Mon Sep 17 00:00:00 2001 From: Black Hat Date: Mon, 23 Mar 2020 22:48:02 -0700 Subject: Expose aliases() and altAliases() as properties --- lib/room.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 6f5751f9..4e4d029f 100644 --- a/lib/room.h +++ b/lib/room.h @@ -90,8 +90,8 @@ class Room : public QObject { Q_PROPERTY(QString predecessorId READ predecessorId NOTIFY baseStateLoaded) Q_PROPERTY(QString successorId READ successorId NOTIFY upgraded) Q_PROPERTY(QString name READ name NOTIFY namesChanged) - Q_PROPERTY(QStringList localAliases READ localAliases NOTIFY namesChanged) - Q_PROPERTY(QStringList remoteAliases READ remoteAliases NOTIFY namesChanged) + Q_PROPERTY(QStringList aliases READ aliases NOTIFY namesChanged) + Q_PROPERTY(QStringList altAliases READ altAliases NOTIFY namesChanged) Q_PROPERTY(QString canonicalAlias READ canonicalAlias NOTIFY namesChanged) Q_PROPERTY(QString displayName READ displayName NOTIFY displaynameChanged) Q_PROPERTY(QString topic READ topic NOTIFY topicChanged) -- cgit v1.2.3 From ec4110c63443e29c78fdf0f72af08f5395ec48f7 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Thu, 26 Mar 2020 13:25:09 +0100 Subject: Refactoring around Connection::onSyncSuccess() The method grew large and a bit unwieldy over the years. --- lib/room.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 4e4d029f..a5b933c2 100644 --- a/lib/room.h +++ b/lib/room.h @@ -215,7 +215,7 @@ public: int timelineSize() const; bool usesEncryption() const; RoomEventPtr decryptMessage(const EncryptedEvent& encryptedEvent); - void handleRoomKeyEvent(RoomKeyEvent* roomKeyEvent, QString senderKey); + void handleRoomKeyEvent(const RoomKeyEvent& roomKeyEvent, const QString& senderKey); int joinedCount() const; int invitedCount() const; int totalMemberCount() const; -- cgit v1.2.3 From feb5e82fbe96269f1f7683470b02fbc9c70acaa0 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 12 Apr 2020 10:01:18 +0200 Subject: Room::canSwitchVersions(): refactor and make Q_INVOKABLE --- lib/room.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index a5b933c2..66a8df7a 100644 --- a/lib/room.h +++ b/lib/room.h @@ -474,6 +474,9 @@ public: Q_INVOKABLE bool supportsCalls() const; + /// Whether the current user is allowed to upgrade the room + Q_INVOKABLE bool canSwitchVersions() const; + /// Get a state event with the given event type and state key /*! This method returns a (potentially empty) state event corresponding * to the pair of event type \p evtType and state key \p stateKey. @@ -566,9 +569,6 @@ public slots: /// Mark all messages in the room as read void markAllMessagesAsRead(); - /// Whether the current user is allowed to upgrade the room - bool canSwitchVersions() const; - /// Switch the room's version (aka upgrade) void switchVersion(QString newVersion); -- cgit v1.2.3 From 0c96ae749c749a5a36e9f28a91bb69f7702d94c5 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Sun, 12 Apr 2020 12:15:08 +0200 Subject: Room::safeMemberName() Pulled from Quaternion code. --- lib/room.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/room.h') diff --git a/lib/room.h b/lib/room.h index 66a8df7a..1ddff517 100644 --- a/lib/room.h +++ b/lib/room.h @@ -269,6 +269,13 @@ public: */ Q_INVOKABLE QString roomMembername(const QString& userId) const; + /** Get a display-safe member name in the context of this room + * + * Display-safe means HTML-safe + without RLO/LRO markers + * (see https://github.com/quotient-im/Quaternion/issues/545). + */ + Q_INVOKABLE QString safeMemberName(const QString& userId) const; + const Timeline& messageEvents() const; const PendingEvents& pendingEvents() const; -- cgit v1.2.3