| 1 | // SPDX-FileCopyrightText: 2015 Felix Rohrbach <kde@fxrh.de> |
| 2 | // SPDX-FileCopyrightText: 2016 Kitsune Ral <Kitsune-Ral@users.sf.net> |
| 3 | // SPDX-License-Identifier: LGPL-2.1-or-later |
| 4 | |
| 5 | #pragma once |
| 6 | |
| 7 | #include "avatar.h" |
| 8 | #include "util.h" |
| 9 | |
| 10 | #include <QtCore/QObject> |
| 11 | |
| 12 | namespace Quotient { |
| 13 | class Connection; |
| 14 | class Room; |
| 15 | class RoomMemberEvent; |
| 16 | |
| 17 | class QUOTIENT_API User : public QObject { |
| 18 | Q_OBJECT |
| 19 | Q_PROPERTY(QString id READ id CONSTANT) |
| 20 | Q_PROPERTY(bool isGuest READ isGuest CONSTANT) |
| 21 | Q_PROPERTY(int hue READ hue CONSTANT) |
| 22 | Q_PROPERTY(qreal hueF READ hueF CONSTANT) |
| 23 | Q_PROPERTY(QString name READ name NOTIFY defaultNameChanged) |
| 24 | Q_PROPERTY(QString displayName READ displayname NOTIFY defaultNameChanged STORED false) |
| 25 | Q_PROPERTY(QString fullName READ fullName NOTIFY defaultNameChanged STORED false) |
| 26 | Q_PROPERTY(QString avatarMediaId READ avatarMediaId NOTIFY defaultAvatarChanged STORED false) |
| 27 | Q_PROPERTY(QUrl avatarUrl READ avatarUrl NOTIFY defaultAvatarChanged) |
| 28 | public: |
| 29 | User(QString userId, Connection* connection); |
| 30 | |
| 31 | Connection* connection() const; |
| 32 | |
| 33 | /** Get unique stable user id |
| 34 | * User id is generated by the server and is not changed ever. |
| 35 | */ |
| 36 | QString id() const; |
| 37 | |
| 38 | /** Get the name chosen by the user |
| 39 | * This may be empty if the user didn't choose the name or cleared |
| 40 | * it. If the user is bridged, the bridge postfix (such as '(IRC)') |
| 41 | * is stripped out. No disambiguation for the room is done. |
| 42 | * \sa displayName |
| 43 | */ |
| 44 | QString name(const Room* room = nullptr) const; |
| 45 | |
| 46 | /** Get the displayed user name |
| 47 | * When \p room is null, this method returns result of name() if |
| 48 | * the name is non-empty; otherwise it returns user id. |
| 49 | * When \p room is non-null, this call is equivalent to |
| 50 | * Room::roomMembername invocation for the user (i.e. the user's |
| 51 | * disambiguated room-specific name is returned). |
| 52 | * \sa name, id, fullName, Room::roomMembername |
| 53 | */ |
| 54 | QString displayname(const Room* room = nullptr) const; |
| 55 | |
| 56 | /** Get user name and id in one string |
| 57 | * The constructed string follows the format 'name (id)' |
| 58 | * which the spec recommends for users disambiguation in |
| 59 | * a room context and in other places. |
| 60 | * \sa displayName, Room::roomMembername |
| 61 | */ |
| 62 | QString fullName(const Room* room = nullptr) const; |
| 63 | |
| 64 | /** Whether the user is a guest |
| 65 | * As of now, the function relies on the convention used in Synapse |
| 66 | * that guests and only guests have all-numeric IDs. This may or |
| 67 | * may not work with non-Synapse servers. |
| 68 | */ |
| 69 | bool isGuest() const; |
| 70 | |
| 71 | /** Hue color component of this user based on id. |
| 72 | * The implementation is based on XEP-0392: |
| 73 | * https://xmpp.org/extensions/xep-0392.html |
| 74 | * Naming and ranges are the same as QColor's hue methods: |
| 75 | * https://doc.qt.io/qt-5/qcolor.html#integer-vs-floating-point-precision |
| 76 | */ |
| 77 | int hue() const; |
| 78 | qreal hueF() const; |
| 79 | |
| 80 | /// Get a reference to a user avatar object for a given room |
| 81 | /*! This reference should be considered short-lived: processing the next |
| 82 | * room member event for this user may (or may not) invalidate it. |
| 83 | */ |
| 84 | const Avatar& avatarObject(const Room* room = nullptr) const; |
| 85 | Q_INVOKABLE QImage avatar(int dimension, |
| 86 | const Quotient::Room* room = nullptr) const; |
| 87 | Q_INVOKABLE QImage avatar(int requestedWidth, int requestedHeight, |
| 88 | const Quotient::Room* room = nullptr) const; |
| 89 | QImage avatar(int width, int height, const Room* room, |
| 90 | const Avatar::get_callback_t& callback) const; |
| 91 | |
| 92 | QString avatarMediaId(const Room* room = nullptr) const; |
| 93 | QUrl avatarUrl(const Room* room = nullptr) const; |
| 94 | |
| 95 | public Q_SLOTS: |
| 96 | /// Set a new name in the global user profile |
| 97 | void rename(const QString& newName); |
| 98 | /// Set a new name for the user in one room |
| 99 | void rename(const QString& newName, Room* r); |
| 100 | /// Upload the file and use it as an avatar |
| 101 | bool setAvatar(const QString& fileName); |
| 102 | /// Upload contents of the QIODevice and set that as an avatar |
| 103 | bool setAvatar(QIODevice* source); |
| 104 | /// Removes the avatar from the profile |
| 105 | void removeAvatar(); |
| 106 | /// Create or find a direct chat with this user |
| 107 | /*! The resulting chat is returned asynchronously via |
| 108 | * Connection::directChatAvailable() |
| 109 | */ |
| 110 | void requestDirectChat(); |
| 111 | /// Add the user to the ignore list |
| 112 | void ignore(); |
| 113 | /// Remove the user from the ignore list |
| 114 | void unmarkIgnore(); |
| 115 | /// Check whether the user is in ignore list |
| 116 | bool isIgnored() const; |
| 117 | /// Force loading displayName and avartar url. This is required in |
| 118 | /// some cases where the you need to use an user independent of the |
| 119 | /// room. |
| 120 | void load(); |
| 121 | |
| 122 | Q_SIGNALS: |
| 123 | void defaultNameChanged(); |
| 124 | void defaultAvatarChanged(); |
| 125 | |
| 126 | private: |
| 127 | class Private; |
| 128 | ImplPtr<Private> d; |
| 129 | |
| 130 | template <typename SourceT> |
| 131 | bool doSetAvatar(SourceT&& source); |
| 132 | }; |
| 133 | } // namespace Quotient |
| 134 | |