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