File indexing completed on 2024-09-15 04:28:34
0001 // SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org> 0002 // SPDX-License-Identifier: GPL-3.0-only 0003 0004 #pragma once 0005 0006 #include <Quotient/room.h> 0007 0008 #include <QCache> 0009 #include <QObject> 0010 #include <QQmlEngine> 0011 #include <QTextCursor> 0012 0013 #include <QCoroTask> 0014 #include <Quotient/user.h> 0015 0016 #include "enums/pushrule.h" 0017 #include "events/pollevent.h" 0018 #include "pollhandler.h" 0019 0020 namespace Quotient 0021 { 0022 class User; 0023 } 0024 0025 class ChatBarCache; 0026 0027 /** 0028 * @class NeoChatRoom 0029 * 0030 * This class is designed to act as a wrapper over Quotient::Room to provide API and 0031 * functionality not available in Quotient::Room. 0032 * 0033 * The functions fall into two main categories: 0034 * - Helper functions to make functionality easily accessible in QML. 0035 * - Implement functions not yet available in Quotient::Room. 0036 * 0037 * @sa Quotient::Room 0038 */ 0039 class NeoChatRoom : public Quotient::Room 0040 { 0041 Q_OBJECT 0042 QML_ELEMENT 0043 QML_UNCREATABLE("") 0044 0045 /** 0046 * @brief A list of users currently typing in the room. 0047 * 0048 * The list does not include the local user. 0049 * 0050 * This is different to getting a list of Quotient::User objects 0051 * as neither of those can provide details like the displayName or avatarMediaId 0052 * without the room context as these can vary from room to room. This function 0053 * provides the room context and puts the result as a list of QVariantMap objects. 0054 * 0055 * @return a QVariantMap for the user with the following 0056 * parameters: 0057 * - id - User ID. 0058 * - avatarMediaId - Avatar id in the context of this room. 0059 * - displayName - Display name in the context of this room. 0060 * - display - Name in the context of this room. 0061 * 0062 * @sa Quotient::User 0063 */ 0064 Q_PROPERTY(QVariantList usersTyping READ getUsersTyping NOTIFY typingChanged) 0065 0066 /** 0067 * @brief Convenience function to get the QDateTime of the last event. 0068 * 0069 * @sa lastEvent() 0070 */ 0071 Q_PROPERTY(QDateTime lastActiveTime READ lastActiveTime NOTIFY lastActiveTimeChanged) 0072 0073 /** 0074 * @brief Whether a file is being uploaded to the server. 0075 */ 0076 Q_PROPERTY(bool hasFileUploading READ hasFileUploading WRITE setHasFileUploading NOTIFY hasFileUploadingChanged) 0077 0078 /** 0079 * @brief Progress of a file upload as a percentage 0 - 100%. 0080 * 0081 * The value will be 0 if no file is uploading. 0082 * 0083 * @sa hasFileUploading 0084 */ 0085 Q_PROPERTY(int fileUploadingProgress READ fileUploadingProgress NOTIFY fileUploadingProgressChanged) 0086 0087 /** 0088 * @brief Whether the read marker should be shown. 0089 */ 0090 Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged) 0091 0092 /** 0093 * @brief The avatar image to be used for the room. 0094 */ 0095 Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY avatarChanged STORED false) 0096 0097 /** 0098 * @brief Get a user object for the other person in a direct chat. 0099 */ 0100 Q_PROPERTY(Quotient::User *directChatRemoteUser READ directChatRemoteUser CONSTANT) 0101 0102 /** 0103 * @brief The Matrix IDs of this room's parents. 0104 * 0105 * Empty if no parent space is set. 0106 */ 0107 Q_PROPERTY(QList<QString> parentIds READ parentIds NOTIFY parentIdsChanged) 0108 0109 /** 0110 * @brief The current canonical parent for the room. 0111 * 0112 * Empty if no canonical parent is set. The write method can only be used to 0113 * set an existing parent as canonical; If you wish to add a new parent and set 0114 * it as canonical use the addParent method and pass true to the canonical 0115 * parameter. 0116 * 0117 * Setting will fail if the user doesn't have the required privileges (see 0118 * canModifyParent) or if the given room ID is not a parent room. 0119 * 0120 * @sa canModifyParent, addParent 0121 */ 0122 Q_PROPERTY(QString canonicalParent READ canonicalParent WRITE setCanonicalParent NOTIFY canonicalParentChanged) 0123 0124 /** 0125 * @brief If the room is a space. 0126 */ 0127 Q_PROPERTY(bool isSpace READ isSpace CONSTANT) 0128 0129 /** 0130 * @brief Whether the local user has an invite to the room. 0131 * 0132 * False for any other state including if the local user is a member. 0133 */ 0134 Q_PROPERTY(bool isInvite READ isInvite NOTIFY isInviteChanged) 0135 0136 /** 0137 * @brief Whether the local user can send messages in the room. 0138 */ 0139 Q_PROPERTY(bool readOnly READ readOnly NOTIFY readOnlyChanged) 0140 0141 /** 0142 * @brief The current join rule for the room as a QString. 0143 * 0144 * Possible values are [public, knock, invite, private, restricted]. 0145 * 0146 * @sa https://spec.matrix.org/v1.5/client-server-api/#mroomjoin_rules 0147 */ 0148 Q_PROPERTY(QString joinRule READ joinRule WRITE setJoinRule NOTIFY joinRuleChanged) 0149 0150 /** 0151 * @brief The space IDs that members of can join this room. 0152 * 0153 * Empty if the join rule is not restricted. 0154 */ 0155 Q_PROPERTY(QList<QString> restrictedIds READ restrictedIds NOTIFY joinRuleChanged) 0156 0157 /** 0158 * @brief Get the maximum room version that the server supports. 0159 * 0160 * Only returns main integer room versions (i.e. no msc room versions). 0161 */ 0162 Q_PROPERTY(int maxRoomVersion READ maxRoomVersion NOTIFY maxRoomVersionChanged) 0163 0164 /** 0165 * @brief The rule for which messages should generate notifications for the room. 0166 * 0167 * @sa PushNotificationState::State 0168 */ 0169 Q_PROPERTY(PushNotificationState::State pushNotificationState READ pushNotificationState WRITE setPushNotificationState NOTIFY pushNotificationStateChanged) 0170 0171 /** 0172 * @brief The current history visibilty setting for the room. 0173 * 0174 * Possible values are [invited, joined, shared, world_readable]. 0175 * 0176 * @sa https://spec.matrix.org/v1.5/client-server-api/#room-history-visibility 0177 */ 0178 Q_PROPERTY(QString historyVisibility READ historyVisibility WRITE setHistoryVisibility NOTIFY historyVisibilityChanged) 0179 0180 /** 0181 * @brief Set the default URL preview state for room members. 0182 * 0183 * Assumed false if the org.matrix.room.preview_urls state message has never been 0184 * set. Can only be set if the calling user has a high enough power level. 0185 */ 0186 Q_PROPERTY(bool defaultUrlPreviewState READ defaultUrlPreviewState WRITE setDefaultUrlPreviewState NOTIFY defaultUrlPreviewStateChanged) 0187 0188 /** 0189 * @brief Enable URL previews for the local user. 0190 */ 0191 Q_PROPERTY(bool urlPreviewEnabled READ urlPreviewEnabled WRITE setUrlPreviewEnabled NOTIFY urlPreviewEnabledChanged) 0192 0193 /** 0194 * @brief Whether the local user can encrypt the room. 0195 * 0196 * A local user can encrypt a room if they have permission to send the m.room.encryption 0197 * state event. 0198 * 0199 * @sa https://spec.matrix.org/v1.5/client-server-api/#mroomencryption 0200 */ 0201 Q_PROPERTY(bool canEncryptRoom READ canEncryptRoom NOTIFY canEncryptRoomChanged) 0202 0203 /** 0204 * @brief The default power level in the room for new users. 0205 */ 0206 Q_PROPERTY(int defaultUserPowerLevel READ defaultUserPowerLevel WRITE setDefaultUserPowerLevel NOTIFY defaultUserPowerLevelChanged) 0207 0208 /** 0209 * @brief The power level required to invite users to the room. 0210 */ 0211 Q_PROPERTY(int invitePowerLevel READ invitePowerLevel WRITE setInvitePowerLevel NOTIFY invitePowerLevelChanged) 0212 0213 /** 0214 * @brief The power level required to kick users from the room. 0215 */ 0216 Q_PROPERTY(int kickPowerLevel READ kickPowerLevel WRITE setKickPowerLevel NOTIFY kickPowerLevelChanged) 0217 0218 /** 0219 * @brief The power level required to ban users from the room. 0220 */ 0221 Q_PROPERTY(int banPowerLevel READ banPowerLevel WRITE setBanPowerLevel NOTIFY banPowerLevelChanged) 0222 0223 /** 0224 * @brief The power level required to delete other user messages. 0225 */ 0226 Q_PROPERTY(int redactPowerLevel READ redactPowerLevel WRITE setRedactPowerLevel NOTIFY redactPowerLevelChanged) 0227 0228 /** 0229 * @brief The default power level for state events that are not explicitly specified. 0230 */ 0231 Q_PROPERTY(int statePowerLevel READ statePowerLevel WRITE setStatePowerLevel NOTIFY statePowerLevelChanged) 0232 0233 /** 0234 * @brief The default power level for event that are not explicitly specified. 0235 */ 0236 Q_PROPERTY(int defaultEventPowerLevel READ defaultEventPowerLevel WRITE setDefaultEventPowerLevel NOTIFY defaultEventPowerLevelChanged) 0237 0238 /** 0239 * @brief The power level required to change power levels for the room. 0240 */ 0241 Q_PROPERTY(int powerLevelPowerLevel READ powerLevelPowerLevel WRITE setPowerLevelPowerLevel NOTIFY powerLevelPowerLevelChanged) 0242 0243 /** 0244 * @brief The power level required to change the room name. 0245 */ 0246 Q_PROPERTY(int namePowerLevel READ namePowerLevel WRITE setNamePowerLevel NOTIFY namePowerLevelChanged) 0247 0248 /** 0249 * @brief The power level required to change the room avatar. 0250 */ 0251 Q_PROPERTY(int avatarPowerLevel READ avatarPowerLevel WRITE setAvatarPowerLevel NOTIFY avatarPowerLevelChanged) 0252 0253 /** 0254 * @brief The power level required to change the room aliases. 0255 */ 0256 Q_PROPERTY(int canonicalAliasPowerLevel READ canonicalAliasPowerLevel WRITE setCanonicalAliasPowerLevel NOTIFY canonicalAliasPowerLevelChanged) 0257 0258 /** 0259 * @brief The power level required to change the room topic. 0260 */ 0261 Q_PROPERTY(int topicPowerLevel READ topicPowerLevel WRITE setTopicPowerLevel NOTIFY topicPowerLevelChanged) 0262 0263 /** 0264 * @brief The power level required to encrypt the room. 0265 */ 0266 Q_PROPERTY(int encryptionPowerLevel READ encryptionPowerLevel WRITE setEncryptionPowerLevel NOTIFY encryptionPowerLevelChanged) 0267 0268 /** 0269 * @brief The power level required to change the room history visibility. 0270 */ 0271 Q_PROPERTY(int historyVisibilityPowerLevel READ historyVisibilityPowerLevel WRITE setHistoryVisibilityPowerLevel NOTIFY historyVisibilityPowerLevelChanged) 0272 0273 /** 0274 * @brief The power level required to pin events in the room. 0275 */ 0276 Q_PROPERTY(int pinnedEventsPowerLevel READ pinnedEventsPowerLevel WRITE setPinnedEventsPowerLevel NOTIFY pinnedEventsPowerLevelChanged) 0277 0278 /** 0279 * @brief The power level required to upgrade the room. 0280 */ 0281 Q_PROPERTY(int tombstonePowerLevel READ tombstonePowerLevel WRITE setTombstonePowerLevel NOTIFY tombstonePowerLevelChanged) 0282 0283 /** 0284 * @brief The power level required to set the room server access control list (ACL). 0285 */ 0286 Q_PROPERTY(int serverAclPowerLevel READ serverAclPowerLevel WRITE setServerAclPowerLevel NOTIFY serverAclPowerLevelChanged) 0287 0288 /** 0289 * @brief The power level required to add children to a space. 0290 */ 0291 Q_PROPERTY(int spaceChildPowerLevel READ spaceChildPowerLevel WRITE setSpaceChildPowerLevel NOTIFY spaceChildPowerLevelChanged) 0292 0293 /** 0294 * @brief The power level required to set the room parent space. 0295 */ 0296 Q_PROPERTY(int spaceParentPowerLevel READ spaceParentPowerLevel WRITE setSpaceParentPowerLevel NOTIFY spaceParentPowerLevelChanged) 0297 0298 /** 0299 * @brief The cache for the main chat bar in the room. 0300 */ 0301 Q_PROPERTY(ChatBarCache *mainCache READ mainCache CONSTANT) 0302 0303 /** 0304 * @brief The cache for the edit chat bar in the room. 0305 */ 0306 Q_PROPERTY(ChatBarCache *editCache READ editCache CONSTANT) 0307 0308 public: 0309 /** 0310 * @brief Define the types on inline messages that can be shown. 0311 */ 0312 enum MessageType { 0313 Positive, /**< Positive message, typically green. */ 0314 Info, /**< Info message, typically highlight color. */ 0315 Error, /**< Error message, typically red. */ 0316 }; 0317 Q_ENUM(MessageType) 0318 0319 explicit NeoChatRoom(Quotient::Connection *connection, QString roomId, Quotient::JoinState joinState = {}); 0320 0321 /** 0322 * @brief Get a user in the context of this room. 0323 * 0324 * This is different to getting a Quotient::User object 0325 * as neither of those can provide details like the displayName or avatarMediaId 0326 * without the room context as these can vary from room to room. This function 0327 * provides the room context and outputs the result as QVariantMap. 0328 * 0329 * Can be called with an empty QString to return an empty user, which is a useful return 0330 * from models to avoid undefined properties. 0331 * 0332 * @param userID the ID of the user to output. 0333 * 0334 * @return a QVariantMap for the user with the following properties: 0335 * - isLocalUser - Whether the user is the local user. 0336 * - id - The matrix ID of the user. 0337 * - displayName - Display name in the context of this room. 0338 * - avatarSource - The mxc URL for the user's avatar in the current room. 0339 * - avatarMediaId - Avatar id in the context of this room. 0340 * - color - Color for the user. 0341 * - object - The Quotient::User object for the user. 0342 * 0343 * @sa Quotient::User 0344 */ 0345 Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const; 0346 0347 /** 0348 * @brief Get a user in the context of this room. 0349 * 0350 * This is different to getting a Quotient::User object 0351 * as neither of those can provide details like the displayName or avatarMediaId 0352 * without the room context as these can vary from room to room. This function 0353 * provides the room context and outputs the result as QVariantMap. 0354 * 0355 * Can be called with a nullptr to return an empty user, which is a useful return 0356 * from models to avoid undefined properties. 0357 * 0358 * @param user the user to output. 0359 * 0360 * @return a QVariantMap for the user with the following properties: 0361 * - isLocalUser - Whether the user is the local user. 0362 * - id - The matrix ID of the user. 0363 * - displayName - Display name in the context of this room. 0364 * - avatarSource - The mxc URL for the user's avatar in the current room. 0365 * - avatarMediaId - Avatar id in the context of this room. 0366 * - color - Color for the user. 0367 * - object - The Quotient::User object for the user. 0368 * 0369 * @sa Quotient::User 0370 */ 0371 Q_INVOKABLE [[nodiscard]] QVariantMap getUser(Quotient::User *user) const; 0372 0373 [[nodiscard]] QVariantList getUsersTyping() const; 0374 0375 [[nodiscard]] QDateTime lastActiveTime(); 0376 0377 /** 0378 * @brief Get the last interesting event. 0379 * 0380 * This function respects the user's state event setting and discards 0381 * other not interesting events. 0382 * 0383 * @warning This function can return an empty pointer if the room does not have 0384 * any RoomMessageEvents loaded. 0385 */ 0386 [[nodiscard]] const Quotient::RoomEvent *lastEvent() const; 0387 0388 /** 0389 * @brief Convenient way to check if the last event looks like it has spoilers. 0390 * 0391 * This does a basic check to see if the message contains a data-mx-spoiler 0392 * attribute within the text which makes it likely that the message has a spoiler 0393 * section. However this is not 100% reliable as during parsing it may be 0394 * removed if used within an illegal tag or on a tag for which data-mx-spoiler 0395 * is not a valid attribute. 0396 * 0397 * @sa lastEvent() 0398 */ 0399 [[nodiscard]] bool lastEventIsSpoiler() const; 0400 0401 [[nodiscard]] bool hasFileUploading() const; 0402 void setHasFileUploading(bool value); 0403 0404 [[nodiscard]] int fileUploadingProgress() const; 0405 void setFileUploadingProgress(int value); 0406 0407 /** 0408 * @brief Download a file for the given event to a local file location. 0409 */ 0410 Q_INVOKABLE void download(const QString &eventId, const QUrl &localFilename = {}); 0411 0412 /** 0413 * @brief Download a file for the given event as a temporary file. 0414 */ 0415 Q_INVOKABLE bool downloadTempFile(const QString &eventId); 0416 0417 /** 0418 * @brief Check if the given event is highlighted. 0419 * 0420 * An event is highlighted if it contains the local user's id but was not sent by the 0421 * local user. 0422 */ 0423 bool isEventHighlighted(const Quotient::RoomEvent *e) const; 0424 0425 /** 0426 * @brief Convenience function to find out if the room contains the given user. 0427 * 0428 * A room contains the user if the user can be found and their JoinState is 0429 * not JoinState::Leave. 0430 */ 0431 Q_INVOKABLE [[nodiscard]] bool containsUser(const QString &userID) const; 0432 0433 /** 0434 * @brief True if the given user ID is banned from the room. 0435 */ 0436 Q_INVOKABLE [[nodiscard]] bool isUserBanned(const QString &user) const; 0437 0438 /** 0439 * @brief True if the local user can send the given event type. 0440 */ 0441 Q_INVOKABLE [[nodiscard]] bool canSendEvent(const QString &eventType) const; 0442 0443 /** 0444 * @brief True if the local user can send the given state event type. 0445 */ 0446 Q_INVOKABLE [[nodiscard]] bool canSendState(const QString &eventType) const; 0447 0448 /** 0449 * @brief Send a report to the server for an event. 0450 * 0451 * @param eventId the ID of the event being reported. 0452 * @param reason the reason given for reporting the event. 0453 */ 0454 Q_INVOKABLE void reportEvent(const QString &eventId, const QString &reason); 0455 0456 Q_INVOKABLE QByteArray getEventJsonSource(const QString &eventId); 0457 0458 /** 0459 * @brief Open the media for the given event in an appropriate external app. 0460 * 0461 * Will do nothing if the event has no media. 0462 */ 0463 Q_INVOKABLE void openEventMediaExternally(const QString &eventId); 0464 0465 /** 0466 * @brief Copy the media for the given event to the clipboard. 0467 * 0468 * Will do nothing if the event has no media. 0469 */ 0470 Q_INVOKABLE void copyEventMedia(const QString &eventId); 0471 0472 [[nodiscard]] bool readMarkerLoaded() const; 0473 0474 [[nodiscard]] QString avatarMediaId() const; 0475 0476 Quotient::User *directChatRemoteUser() const; 0477 0478 /** 0479 * @brief Whether this room has one or more parent spaces set. 0480 */ 0481 Q_INVOKABLE bool hasParent() const; 0482 0483 QList<QString> parentIds() const; 0484 0485 /** 0486 * @brief Get a list of parent space objects for this room. 0487 * 0488 * Will only return retrun spaces that are know, i.e. the user has joined and 0489 * a valid NeoChatRoom is available. 0490 * 0491 * @param multiLevel whether the function should recursively gather all levels 0492 * of parents 0493 */ 0494 Q_INVOKABLE QList<NeoChatRoom *> parentObjects(bool multiLevel = false) const; 0495 0496 QString canonicalParent() const; 0497 void setCanonicalParent(const QString &parentId); 0498 0499 /** 0500 * @brief Whether the local user has permission to set the given space as a parent. 0501 * 0502 * @note This follows the rules determined in the Matrix spec 0503 * https://spec.matrix.org/v1.7/client-server-api/#mspaceparent-relationships 0504 */ 0505 Q_INVOKABLE bool canModifyParent(const QString &parentId) const; 0506 0507 /** 0508 * @brief Add the given room as a parent. 0509 * 0510 * Will fail if the user doesn't have the required privileges (see 0511 * canModifyParent()). 0512 * 0513 * @sa canModifyParent() 0514 */ 0515 Q_INVOKABLE void addParent(const QString &parentId, bool canonical = false, bool setParentChild = false); 0516 0517 /** 0518 * @brief Remove the given room as a parent. 0519 * 0520 * Will fail if the user doesn't have the required privileges (see 0521 * canModifyParent()). 0522 * 0523 * @sa canModifyParent() 0524 */ 0525 Q_INVOKABLE void removeParent(const QString &parentId); 0526 0527 [[nodiscard]] bool isSpace(); 0528 0529 /** 0530 * @brief Add the given room as a child. 0531 * 0532 * Will fail if the user doesn't have the required privileges or this room is 0533 * not a space. 0534 */ 0535 Q_INVOKABLE void addChild(const QString &childId, bool setChildParent = false, bool canonical = false, bool suggested = false); 0536 0537 /** 0538 * @brief Remove the given room as a child. 0539 * 0540 * Will fail if the user doesn't have the required privileges or this room is 0541 * not a space. 0542 */ 0543 Q_INVOKABLE void removeChild(const QString &childId, bool unsetChildParent = false); 0544 0545 /** 0546 * @brief Whether the given child is a suggested room in the space. 0547 */ 0548 Q_INVOKABLE bool isSuggested(const QString &childId); 0549 0550 /** 0551 * @brief Toggle whether the given child is a suggested room in the space. 0552 * 0553 * Will fail if the user doesn't have the required privileges, this room is 0554 * not a space or the given room is not a child of this space. 0555 */ 0556 Q_INVOKABLE void toggleChildSuggested(const QString &childId); 0557 0558 bool isInvite() const; 0559 0560 bool readOnly() const; 0561 0562 Q_INVOKABLE void clearInvitationNotification(); 0563 0564 [[nodiscard]] QString joinRule() const; 0565 0566 /** 0567 * @brief Set the join rule for the room. 0568 * 0569 * Will fail if the user doesn't have the required privileges. 0570 * 0571 * @param joinRule the join rule [public, knock, invite, private, restricted]. 0572 * @param allowedSpaces only used when the join rule is restricted. This is a 0573 * list of space Matrix IDs that members of can join without an invite. 0574 * If the rule is restricted and this list is empty it is treated as a join 0575 * rule of private instead. 0576 * 0577 * @sa https://spec.matrix.org/latest/client-server-api/#mroomjoin_rules 0578 */ 0579 Q_INVOKABLE void setJoinRule(const QString &joinRule, const QList<QString> &allowedSpaces = {}); 0580 0581 QList<QString> restrictedIds() const; 0582 0583 int maxRoomVersion() const; 0584 0585 /** 0586 * @brief Map an alias to the room and publish. 0587 * 0588 * The alias is first mapped to the room and then published as an 0589 * alternate alias. Publishing the alias will fail if the user does not have 0590 * permission to send m.room.canonical_alias event messages. 0591 * 0592 * @note This is different to Quotient::Room::setLocalAliases() as that can only 0593 * get the room to publish an alias that is already mapped. 0594 * 0595 * @property alias QString in the form #new_alias:server.org 0596 * 0597 * @sa Quotient::Room::setLocalAliases() 0598 */ 0599 Q_INVOKABLE void mapAlias(const QString &alias); 0600 0601 /** 0602 * @brief Unmap an alias from the room. 0603 * 0604 * An unmapped alias is also removed as either the canonical alias or an alternate 0605 * alias. 0606 * 0607 * @note This is different to Quotient::Room::setLocalAliases() as that can only 0608 * get the room to un-publish an alias, while the mapping still exists. 0609 * 0610 * @property alias QString in the form #mapped_alias:server.org 0611 * 0612 * @sa Quotient::Room::setLocalAliases() 0613 */ 0614 Q_INVOKABLE void unmapAlias(const QString &alias); 0615 0616 /** 0617 * @brief Set the canonical alias of the room to an available mapped alias. 0618 * 0619 * If the new alias was already published as an alternate alias it will be removed 0620 * from that list. 0621 * 0622 * @note This is an overload of the function Quotient::Room::setCanonicalAlias(). 0623 * This is to provide the functionality to remove the new canonical alias as a 0624 * published alt alias when set. 0625 * 0626 * @property newAlias QString in the form #new_alias:server.org 0627 * 0628 * @sa Quotient::Room::setCanonicalAlias() 0629 * */ 0630 Q_INVOKABLE void setCanonicalAlias(const QString &newAlias); 0631 0632 PushNotificationState::State pushNotificationState() const; 0633 void setPushNotificationState(PushNotificationState::State state); 0634 0635 [[nodiscard]] QString historyVisibility() const; 0636 void setHistoryVisibility(const QString &historyVisibilityRule); 0637 0638 [[nodiscard]] bool defaultUrlPreviewState() const; 0639 void setDefaultUrlPreviewState(const bool &defaultUrlPreviewState); 0640 0641 [[nodiscard]] bool urlPreviewEnabled() const; 0642 void setUrlPreviewEnabled(const bool &urlPreviewEnabled); 0643 0644 bool canEncryptRoom() const; 0645 0646 /** 0647 * @brief Get the power level for the given user ID in the room. 0648 * 0649 * Returns the default value for a user in the room if they have no escalated 0650 * privileges or if they are not a member so membership should be known before using. 0651 */ 0652 Q_INVOKABLE [[nodiscard]] int getUserPowerLevel(const QString &userId) const; 0653 0654 Q_INVOKABLE void setUserPowerLevel(const QString &userID, const int &powerLevel); 0655 0656 [[nodiscard]] int powerLevel(const QString &eventName, const bool &isStateEvent = false) const; 0657 void setPowerLevel(const QString &eventName, const int &newPowerLevel, const bool &isStateEvent = false); 0658 0659 [[nodiscard]] int defaultUserPowerLevel() const; 0660 void setDefaultUserPowerLevel(const int &newPowerLevel); 0661 0662 [[nodiscard]] int invitePowerLevel() const; 0663 void setInvitePowerLevel(const int &newPowerLevel); 0664 0665 [[nodiscard]] int kickPowerLevel() const; 0666 void setKickPowerLevel(const int &newPowerLevel); 0667 0668 [[nodiscard]] int banPowerLevel() const; 0669 void setBanPowerLevel(const int &newPowerLevel); 0670 0671 [[nodiscard]] int redactPowerLevel() const; 0672 void setRedactPowerLevel(const int &newPowerLevel); 0673 0674 [[nodiscard]] int statePowerLevel() const; 0675 void setStatePowerLevel(const int &newPowerLevel); 0676 0677 [[nodiscard]] int defaultEventPowerLevel() const; 0678 void setDefaultEventPowerLevel(const int &newPowerLevel); 0679 0680 [[nodiscard]] int powerLevelPowerLevel() const; 0681 void setPowerLevelPowerLevel(const int &newPowerLevel); 0682 0683 [[nodiscard]] int namePowerLevel() const; 0684 void setNamePowerLevel(const int &newPowerLevel); 0685 0686 [[nodiscard]] int avatarPowerLevel() const; 0687 void setAvatarPowerLevel(const int &newPowerLevel); 0688 0689 [[nodiscard]] int canonicalAliasPowerLevel() const; 0690 void setCanonicalAliasPowerLevel(const int &newPowerLevel); 0691 0692 [[nodiscard]] int topicPowerLevel() const; 0693 void setTopicPowerLevel(const int &newPowerLevel); 0694 0695 [[nodiscard]] int encryptionPowerLevel() const; 0696 void setEncryptionPowerLevel(const int &newPowerLevel); 0697 0698 [[nodiscard]] int historyVisibilityPowerLevel() const; 0699 void setHistoryVisibilityPowerLevel(const int &newPowerLevel); 0700 0701 [[nodiscard]] int pinnedEventsPowerLevel() const; 0702 void setPinnedEventsPowerLevel(const int &newPowerLevel); 0703 0704 [[nodiscard]] int tombstonePowerLevel() const; 0705 void setTombstonePowerLevel(const int &newPowerLevel); 0706 0707 [[nodiscard]] int serverAclPowerLevel() const; 0708 void setServerAclPowerLevel(const int &newPowerLevel); 0709 0710 [[nodiscard]] int spaceChildPowerLevel() const; 0711 void setSpaceChildPowerLevel(const int &newPowerLevel); 0712 0713 [[nodiscard]] int spaceParentPowerLevel() const; 0714 void setSpaceParentPowerLevel(const int &newPowerLevel); 0715 0716 ChatBarCache *mainCache() const; 0717 0718 ChatBarCache *editCache() const; 0719 0720 /** 0721 * @brief Reply to the last message sent in the timeline. 0722 * 0723 * @note This checks a maximum of the previous 35 message for performance reasons. 0724 */ 0725 Q_INVOKABLE void replyLastMessage(); 0726 0727 /** 0728 * @brief Edit the last message sent by the local user. 0729 * 0730 * @note This checks a maximum of the previous 35 message for performance reasons. 0731 */ 0732 Q_INVOKABLE void editLastMessage(); 0733 0734 /** 0735 * @brief Get a PollHandler object for the given event Id. 0736 * 0737 * Will return an existing PollHandler if one already exists for the event ID. 0738 * A new PollHandler will be created if one doesn't exist. 0739 * 0740 * @note Requires libQuotient 0.7. 0741 * 0742 * @sa PollHandler 0743 */ 0744 PollHandler *poll(const QString &eventId) const; 0745 0746 /** 0747 * @brief Create a PollHandler object for the given event. 0748 * 0749 * @sa PollHandler 0750 */ 0751 void createPollHandler(const Quotient::PollStartEvent *event); 0752 0753 /** 0754 * @brief Get the full Json data for a given room account data event. 0755 */ 0756 Q_INVOKABLE QByteArray roomAcountDataJson(const QString &eventType); 0757 0758 Q_INVOKABLE [[nodiscard]] QUrl avatarForMember(Quotient::User *user) const; 0759 0760 /** 0761 * @brief Returns the event that is being replied to. This includes events that were manually loaded using NeoChatRoom::loadReply. 0762 */ 0763 const Quotient::RoomEvent *getReplyForEvent(const Quotient::RoomEvent &event) const; 0764 0765 /** 0766 * Loads the event replyId with the given id from the server and saves it locally. 0767 * For models to update correctly, eventId must be the event that is replying to replyId. 0768 * Intended to load the replied-to event when it isn't available locally. 0769 */ 0770 Q_INVOKABLE void loadReply(const QString &eventId, const QString &replyId); 0771 0772 /** 0773 * If we're invited to this room, the user that invited us. Undefined in other cases. 0774 */ 0775 Q_INVOKABLE Quotient::User *invitingUser() const; 0776 0777 private: 0778 QSet<const Quotient::RoomEvent *> highlights; 0779 0780 bool m_hasFileUploading = false; 0781 int m_fileUploadingProgress = 0; 0782 0783 PushNotificationState::State m_currentPushNotificationState = PushNotificationState::Unknown; 0784 bool m_pushNotificationStateUpdating = false; 0785 0786 void checkForHighlights(const Quotient::TimelineItem &ti); 0787 0788 void onAddNewTimelineEvents(timeline_iter_t from) override; 0789 void onAddHistoricalTimelineEvents(rev_iter_t from) override; 0790 void onRedaction(const Quotient::RoomEvent &prevEvent, const Quotient::RoomEvent &after) override; 0791 0792 QCoro::Task<void> doDeleteMessagesByUser(const QString &user, QString reason); 0793 QCoro::Task<void> doUploadFile(QUrl url, QString body = QString()); 0794 0795 std::unique_ptr<Quotient::RoomEvent> m_cachedEvent; 0796 0797 ChatBarCache *m_mainCache; 0798 ChatBarCache *m_editCache; 0799 0800 QCache<QString, PollHandler> m_polls; 0801 std::vector<Quotient::event_ptr_tt<Quotient::RoomEvent>> m_extraEvents; 0802 0803 private Q_SLOTS: 0804 void updatePushNotificationState(QString type); 0805 0806 void cacheLastEvent(); 0807 0808 Q_SIGNALS: 0809 void cachedInputChanged(); 0810 void busyChanged(); 0811 void hasFileUploadingChanged(); 0812 void fileUploadingProgressChanged(); 0813 void backgroundChanged(); 0814 void readMarkerLoadedChanged(); 0815 void parentIdsChanged(); 0816 void canonicalParentChanged(); 0817 void lastActiveTimeChanged(); 0818 void isInviteChanged(); 0819 void readOnlyChanged(); 0820 void displayNameChanged(); 0821 void pushNotificationStateChanged(PushNotificationState::State state); 0822 void showMessage(MessageType messageType, const QString &message); 0823 void canEncryptRoomChanged(); 0824 void joinRuleChanged(); 0825 void historyVisibilityChanged(); 0826 void defaultUrlPreviewStateChanged(); 0827 void urlPreviewEnabledChanged(); 0828 void maxRoomVersionChanged(); 0829 void defaultUserPowerLevelChanged(); 0830 void invitePowerLevelChanged(); 0831 void kickPowerLevelChanged(); 0832 void banPowerLevelChanged(); 0833 void redactPowerLevelChanged(); 0834 void statePowerLevelChanged(); 0835 void defaultEventPowerLevelChanged(); 0836 void powerLevelPowerLevelChanged(); 0837 void namePowerLevelChanged(); 0838 void avatarPowerLevelChanged(); 0839 void canonicalAliasPowerLevelChanged(); 0840 void topicPowerLevelChanged(); 0841 void encryptionPowerLevelChanged(); 0842 void historyVisibilityPowerLevelChanged(); 0843 void pinnedEventsPowerLevelChanged(); 0844 void tombstonePowerLevelChanged(); 0845 void serverAclPowerLevelChanged(); 0846 void spaceChildPowerLevelChanged(); 0847 void spaceParentPowerLevelChanged(); 0848 void replyLoaded(const QString &eventId, const QString &replyId); 0849 0850 public Q_SLOTS: 0851 /** 0852 * @brief Upload a file to the matrix server and post the file to the room. 0853 * 0854 * @param url the location of the file to be uploaded. 0855 * @param body the caption that is to be given to the file. 0856 */ 0857 void uploadFile(const QUrl &url, const QString &body = QString()); 0858 0859 /** 0860 * @brief Accept an invitation for the local user to join the room. 0861 */ 0862 void acceptInvitation(); 0863 0864 /** 0865 * @brief Leave and forget the room for the local user. 0866 * 0867 * @note This means that not only will the user no longer receive events in 0868 * the room but the will forget any history up to this point. 0869 * 0870 * @sa https://spec.matrix.org/latest/client-server-api/#leaving-rooms 0871 */ 0872 void forget(); 0873 0874 /** 0875 * @brief Set the typing notification state on the room for the local user. 0876 */ 0877 void sendTypingNotification(bool isTyping); 0878 0879 /** 0880 * @brief Send a message to the room. 0881 * 0882 * @param rawText the text as it was typed. 0883 * @param cleanedText the text marked up as html. 0884 * @param type the type of message being sent. 0885 * @param replyEventId the id of the message being replied to if a reply. 0886 * @param relateToEventId the id of the message being edited if an edit. 0887 */ 0888 void postMessage(const QString &rawText, 0889 const QString &cleanedText, 0890 Quotient::MessageEventType type = Quotient::MessageEventType::Text, 0891 const QString &replyEventId = QString(), 0892 const QString &relateToEventId = QString(), 0893 const QString &threadRootId = QString()); 0894 0895 /** 0896 * @brief Send an html message to the room. 0897 * 0898 * @param text the text as it was typed. 0899 * @param html the text marked up as html. 0900 * @param type the type of message being sent. 0901 * @param replyEventId the id of the message being replied to if a reply. 0902 * @param relateToEventId the id of the message being edited if an edit. 0903 */ 0904 void postHtmlMessage(const QString &text, 0905 const QString &html, 0906 Quotient::MessageEventType type = Quotient::MessageEventType::Text, 0907 const QString &replyEventId = QString(), 0908 const QString &relateToEventId = QString(), 0909 const QString &threadRootId = QString()); 0910 0911 /** 0912 * @brief Set the room avatar. 0913 */ 0914 void changeAvatar(const QUrl &localFile); 0915 0916 /** 0917 * @brief Toggle the reaction state of the given reaction for the local user. 0918 */ 0919 void toggleReaction(const QString &eventId, const QString &reaction); 0920 0921 /** 0922 * @brief Delete recent messages by the given user. 0923 * 0924 * This will delete all messages by that user in this room that are currently loaded. 0925 */ 0926 void deleteMessagesByUser(const QString &user, const QString &reason); 0927 0928 /** 0929 * @brief Sends a location to a room 0930 * The event is sent in the migration format as specified in MSC3488 0931 * @param lat latitude 0932 * @param lon longitude 0933 * @param description description for the location 0934 */ 0935 void sendLocation(float lat, float lon, const QString &description); 0936 };