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 | |