1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #pragma once
9
10 #include "data/data_peer.h"
11 #include "dialogs/dialogs_key.h"
12
13 struct BotInfo {
14 bool inited = false;
15 bool readsAllHistory = false;
16 bool cantJoinGroups = false;
17 int version = 0;
18 QString description, inlinePlaceholder;
19 std::vector<BotCommand> commands;
20 Ui::Text::String text = { int(st::msgMinWidth) }; // description
21
22 QString startToken, startGroupToken, shareGameShortName;
23 Dialogs::EntryState inlineReturnTo;
24 };
25
26 enum class UserDataFlag {
27 Contact = (1 << 0),
28 MutualContact = (1 << 1),
29 Deleted = (1 << 2),
30 Verified = (1 << 3),
31 Scam = (1 << 4),
32 Fake = (1 << 5),
33 BotInlineGeo = (1 << 6),
34 Blocked = (1 << 7),
35 HasPhoneCalls = (1 << 8),
36 PhoneCallsPrivate = (1 << 9),
37 Support = (1 << 10),
38 CanPinMessages = (1 << 11),
39 DiscardMinPhoto = (1 << 12),
40 };
is_flag_type(UserDataFlag)41 inline constexpr bool is_flag_type(UserDataFlag) { return true; };
42 using UserDataFlags = base::flags<UserDataFlag>;
43
44 class UserData : public PeerData {
45 public:
46 using Flag = UserDataFlag;
47 using Flags = Data::Flags<UserDataFlags>;
48
49 UserData(not_null<Data::Session*> owner, PeerId id);
50 void setPhoto(const MTPUserProfilePhoto &photo);
51
52 void setName(
53 const QString &newFirstName,
54 const QString &newLastName,
55 const QString &newPhoneName,
56 const QString &newUsername);
57
58 void setPhone(const QString &newPhone);
59 void setBotInfoVersion(int version);
60 void setBotInfo(const MTPBotInfo &info);
61
62 void setNameOrPhone(const QString &newNameOrPhone);
63
64 void madeAction(TimeId when); // pseudo-online
65
accessHash()66 uint64 accessHash() const {
67 return _accessHash;
68 }
69 void setAccessHash(uint64 accessHash);
70
setFlags(UserDataFlags which)71 void setFlags(UserDataFlags which) {
72 _flags.set(which);
73 }
addFlags(UserDataFlags which)74 void addFlags(UserDataFlags which) {
75 _flags.add(which);
76 }
removeFlags(UserDataFlags which)77 void removeFlags(UserDataFlags which) {
78 _flags.remove(which);
79 }
flags()80 auto flags() const {
81 return _flags.current();
82 }
flagsValue()83 auto flagsValue() const {
84 return _flags.value();
85 }
86
isVerified()87 [[nodiscard]] bool isVerified() const {
88 return flags() & UserDataFlag::Verified;
89 }
isScam()90 [[nodiscard]] bool isScam() const {
91 return flags() & UserDataFlag::Scam;
92 }
isFake()93 [[nodiscard]] bool isFake() const {
94 return flags() & UserDataFlag::Fake;
95 }
isBotInlineGeo()96 [[nodiscard]] bool isBotInlineGeo() const {
97 return flags() & UserDataFlag::BotInlineGeo;
98 }
isBot()99 [[nodiscard]] bool isBot() const {
100 return botInfo != nullptr;
101 }
isSupport()102 [[nodiscard]] bool isSupport() const {
103 return flags() & UserDataFlag::Support;
104 }
isInaccessible()105 [[nodiscard]] bool isInaccessible() const {
106 return flags() & UserDataFlag::Deleted;
107 }
canWrite()108 [[nodiscard]] bool canWrite() const {
109 // Duplicated in Data::CanWriteValue().
110 return !isInaccessible() && !isRepliesChat();
111 }
applyMinPhoto()112 [[nodiscard]] bool applyMinPhoto() const {
113 return !(flags() & UserDataFlag::DiscardMinPhoto);
114 }
115
116 [[nodiscard]] bool canShareThisContact() const;
canAddContact()117 [[nodiscard]] bool canAddContact() const {
118 return canShareThisContact() && !isContact();
119 }
120
121 // In Data::Session::processUsers() we check only that.
122 // When actually trying to share contact we perform
123 // a full check by canShareThisContact() call.
canShareThisContactFast()124 [[nodiscard]] bool canShareThisContactFast() const {
125 return !_phone.isEmpty();
126 }
127
128 MTPInputUser inputUser = MTP_inputUserEmpty();
129
130 QString firstName;
131 QString lastName;
132 QString username;
phone()133 [[nodiscard]] const QString &phone() const {
134 return _phone;
135 }
136 QString nameOrPhone;
137 Ui::Text::String phoneText;
138 TimeId onlineTill = 0;
139
140 enum class ContactStatus : char {
141 Unknown,
142 Contact,
143 NotContact,
144 };
contactStatus()145 [[nodiscard]] ContactStatus contactStatus() const {
146 return _contactStatus;
147 }
isContact()148 [[nodiscard]] bool isContact() const {
149 return (contactStatus() == ContactStatus::Contact);
150 }
151 void setIsContact(bool is);
152
153 enum class CallsStatus : char {
154 Unknown,
155 Enabled,
156 Disabled,
157 Private,
158 };
callsStatus()159 CallsStatus callsStatus() const {
160 return _callsStatus;
161 }
162 bool hasCalls() const;
163 void setCallsStatus(CallsStatus callsStatus);
164
165 std::unique_ptr<BotInfo> botInfo;
166
167 void setUnavailableReasons(
168 std::vector<Data::UnavailableReason> &&reasons);
169
commonChatsCount()170 int commonChatsCount() const {
171 return _commonChatsCount;
172 }
173 void setCommonChatsCount(int count);
174
175 private:
176 auto unavailableReasons() const
177 -> const std::vector<Data::UnavailableReason> & override;
178
179 Flags _flags;
180
181 std::vector<Data::UnavailableReason> _unavailableReasons;
182 QString _phone;
183 ContactStatus _contactStatus = ContactStatus::Unknown;
184 CallsStatus _callsStatus = CallsStatus::Unknown;
185 int _commonChatsCount = 0;
186
187 uint64 _accessHash = 0;
188 static constexpr auto kInaccessibleAccessHashOld
189 = 0xFFFFFFFFFFFFFFFFULL;
190
191 };
192
193 namespace Data {
194
195 void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update);
196
197 } // namespace Data
198