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 "data/data_pts_waiter.h"
12 #include "data/data_location.h"
13
14 struct ChannelLocation {
15 QString address;
16 Data::LocationPoint point;
17
18 friend inline bool operator==(
19 const ChannelLocation &a,
20 const ChannelLocation &b) {
21 return a.address.isEmpty()
22 ? b.address.isEmpty()
23 : (a.address == b.address && a.point == b.point);
24 }
25 friend inline bool operator!=(
26 const ChannelLocation &a,
27 const ChannelLocation &b) {
28 return !(a == b);
29 }
30 };
31
32 enum class ChannelDataFlag {
33 Left = (1 << 0),
34 Creator = (1 << 1),
35 Forbidden = (1 << 2),
36 CallActive = (1 << 3),
37 CallNotEmpty = (1 << 4),
38 Signatures = (1 << 5),
39 Verified = (1 << 6),
40 Scam = (1 << 7),
41 Fake = (1 << 8),
42 Megagroup = (1 << 9),
43 Broadcast = (1 << 10),
44 Gigagroup = (1 << 11),
45 Username = (1 << 12),
46 Location = (1 << 13),
47 CanSetUsername = (1 << 14),
48 CanSetStickers = (1 << 15),
49 PreHistoryHidden = (1 << 16),
50 CanViewParticipants = (1 << 17),
51 HasLink = (1 << 18),
52 SlowmodeEnabled = (1 << 19),
53 };
is_flag_type(ChannelDataFlag)54 inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
55 using ChannelDataFlags = base::flags<ChannelDataFlag>;
56
57 class MegagroupInfo {
58 public:
59 struct Admin {
AdminAdmin60 explicit Admin(ChatAdminRightsInfo rights)
61 : rights(rights) {
62 }
AdminAdmin63 Admin(ChatAdminRightsInfo rights, bool canEdit)
64 : rights(rights)
65 , canEdit(canEdit) {
66 }
67 ChatAdminRightsInfo rights;
68 bool canEdit = false;
69 };
70
71 struct Restricted {
RestrictedRestricted72 explicit Restricted(ChatRestrictionsInfo rights)
73 : rights(rights) {
74 }
75 ChatRestrictionsInfo rights;
76 };
77
78 ChatData *getMigrateFromChat() const;
79 void setMigrateFromChat(ChatData *chat);
80
81 const ChannelLocation *getLocation() const;
82 void setLocation(const ChannelLocation &location);
83
84 bool updateBotCommands(const MTPVector<MTPBotInfo> &data);
85 bool updateBotCommands(
86 UserId botId,
87 const MTPVector<MTPBotCommand> &data);
88 [[nodiscard]] auto botCommands() const
89 -> const base::flat_map<UserId, std::vector<BotCommand>> & {
90 return _botCommands;
91 }
92
93 std::deque<not_null<UserData*>> lastParticipants;
94 base::flat_map<not_null<UserData*>, Admin> lastAdmins;
95 base::flat_map<not_null<UserData*>, Restricted> lastRestricted;
96 base::flat_set<not_null<PeerData*>> markupSenders;
97 base::flat_set<not_null<UserData*>> bots;
98
99 // For admin badges, full admins list with ranks.
100 base::flat_map<UserId, QString> admins;
101
102 UserData *creator = nullptr; // nullptr means unknown
103 QString creatorRank;
104 int botStatus = 0; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other
105 bool joinedMessageFound = false;
106 StickerSetIdentifier stickerSet;
107
108 enum LastParticipantsStatus {
109 LastParticipantsUpToDate = 0x00,
110 LastParticipantsOnceReceived = 0x01,
111 LastParticipantsCountOutdated = 0x02,
112 };
113 mutable int lastParticipantsStatus = LastParticipantsUpToDate;
114 int lastParticipantsCount = 0;
115
116 private:
117 ChatData *_migratedFrom = nullptr;
118 ChannelLocation _location;
119 base::flat_map<UserId, std::vector<BotCommand>> _botCommands;
120
121 };
122
123 class ChannelData : public PeerData {
124 public:
125 using Flag = ChannelDataFlag;
126 using Flags = Data::Flags<ChannelDataFlags>;
127
128 using AdminRight = ChatAdminRight;
129 using Restriction = ChatRestriction;
130 using AdminRights = ChatAdminRights;
131 using Restrictions = ChatRestrictions;
132 using AdminRightFlags = Data::Flags<AdminRights>;
133 using RestrictionFlags = Data::Flags<Restrictions>;
134
135 ChannelData(not_null<Data::Session*> owner, PeerId id);
136
137 void setName(const QString &name, const QString &username);
138 void setPhoto(const MTPChatPhoto &photo);
139 void setAccessHash(uint64 accessHash);
140
setFlags(ChannelDataFlags which)141 void setFlags(ChannelDataFlags which) {
142 _flags.set(which);
143 }
addFlags(ChannelDataFlags which)144 void addFlags(ChannelDataFlags which) {
145 _flags.add(which);
146 }
removeFlags(ChannelDataFlags which)147 void removeFlags(ChannelDataFlags which) {
148 _flags.remove(which);
149 }
flags()150 [[nodiscard]] auto flags() const {
151 return _flags.current();
152 }
flagsValue()153 [[nodiscard]] auto flagsValue() const {
154 return _flags.value();
155 }
156
membersCount()157 [[nodiscard]] int membersCount() const {
158 return std::max(_membersCount, 1);
159 }
160 void setMembersCount(int newMembersCount);
membersCountKnown()161 [[nodiscard]] bool membersCountKnown() const {
162 return (_membersCount >= 0);
163 }
164
adminsCount()165 [[nodiscard]] int adminsCount() const {
166 return _adminsCount;
167 }
168 void setAdminsCount(int newAdminsCount);
169
restrictedCount()170 [[nodiscard]] int restrictedCount() const {
171 return _restrictedCount;
172 }
173 void setRestrictedCount(int newRestrictedCount);
174
kickedCount()175 [[nodiscard]] int kickedCount() const {
176 return _kickedCount;
177 }
178 void setKickedCount(int newKickedCount);
179
pendingRequestsCount()180 [[nodiscard]] int pendingRequestsCount() const {
181 return _pendingRequestsCount;
182 }
recentRequesters()183 [[nodiscard]] const std::vector<UserId> &recentRequesters() const {
184 return _recentRequesters;
185 }
186 void setPendingRequestsCount(
187 int count,
188 const QVector<MTPlong> &recentRequesters);
189 void setPendingRequestsCount(
190 int count,
191 std::vector<UserId> recentRequesters);
192
haveLeft()193 [[nodiscard]] bool haveLeft() const {
194 return flags() & Flag::Left;
195 }
amIn()196 [[nodiscard]] bool amIn() const {
197 return !isForbidden() && !haveLeft();
198 }
addsSignature()199 [[nodiscard]] bool addsSignature() const {
200 return flags() & Flag::Signatures;
201 }
isForbidden()202 [[nodiscard]] bool isForbidden() const {
203 return flags() & Flag::Forbidden;
204 }
isVerified()205 [[nodiscard]] bool isVerified() const {
206 return flags() & Flag::Verified;
207 }
isScam()208 [[nodiscard]] bool isScam() const {
209 return flags() & Flag::Scam;
210 }
isFake()211 [[nodiscard]] bool isFake() const {
212 return flags() & Flag::Fake;
213 }
214
215 [[nodiscard]] static ChatRestrictionsInfo KickedRestrictedRights(
216 not_null<PeerData*> participant);
217 static constexpr auto kRestrictUntilForever = TimeId(INT_MAX);
IsRestrictedForever(TimeId until)218 [[nodiscard]] static bool IsRestrictedForever(TimeId until) {
219 return !until || (until == kRestrictUntilForever);
220 }
221 void applyEditAdmin(
222 not_null<UserData*> user,
223 ChatAdminRightsInfo oldRights,
224 ChatAdminRightsInfo newRights,
225 const QString &rank);
226 void applyEditBanned(
227 not_null<PeerData*> participant,
228 ChatRestrictionsInfo oldRights,
229 ChatRestrictionsInfo newRights);
230
231 void markForbidden();
232
233 [[nodiscard]] bool isGroupAdmin(not_null<UserData*> user) const;
234 [[nodiscard]] bool lastParticipantsRequestNeeded() const;
isMegagroup()235 [[nodiscard]] bool isMegagroup() const {
236 return flags() & Flag::Megagroup;
237 }
isBroadcast()238 [[nodiscard]] bool isBroadcast() const {
239 return flags() & Flag::Broadcast;
240 }
isGigagroup()241 [[nodiscard]] bool isGigagroup() const {
242 return flags() & Flag::Gigagroup;
243 }
hasUsername()244 [[nodiscard]] bool hasUsername() const {
245 return flags() & Flag::Username;
246 }
hasLocation()247 [[nodiscard]] bool hasLocation() const {
248 return flags() & Flag::Location;
249 }
isPublic()250 [[nodiscard]] bool isPublic() const {
251 return hasUsername() || hasLocation();
252 }
amCreator()253 [[nodiscard]] bool amCreator() const {
254 return flags() & Flag::Creator;
255 }
256
adminRights()257 [[nodiscard]] auto adminRights() const {
258 return _adminRights.current();
259 }
adminRightsValue()260 [[nodiscard]] auto adminRightsValue() const {
261 return _adminRights.value();
262 }
263 void setAdminRights(ChatAdminRights rights);
hasAdminRights()264 [[nodiscard]] bool hasAdminRights() const {
265 return (adminRights() != 0);
266 }
267
restrictions()268 [[nodiscard]] auto restrictions() const {
269 return _restrictions.current();
270 }
restrictionsValue()271 [[nodiscard]] auto restrictionsValue() const {
272 return _restrictions.value();
273 }
restrictedUntil()274 [[nodiscard]] TimeId restrictedUntil() const {
275 return _restrictedUntil;
276 }
277 void setRestrictions(ChatRestrictionsInfo rights);
hasRestrictions()278 [[nodiscard]] bool hasRestrictions() const {
279 return (restrictions() != 0);
280 }
hasRestrictions(TimeId now)281 [[nodiscard]] bool hasRestrictions(TimeId now) const {
282 return hasRestrictions()
283 && (restrictedUntil() > now);
284 }
285
defaultRestrictions()286 [[nodiscard]] auto defaultRestrictions() const {
287 return _defaultRestrictions.current();
288 }
defaultRestrictionsValue()289 [[nodiscard]] auto defaultRestrictionsValue() const {
290 return _defaultRestrictions.value();
291 }
292 void setDefaultRestrictions(ChatRestrictions rights);
293
294 // Like in ChatData.
295 [[nodiscard]] bool canWrite() const;
296 [[nodiscard]] bool canEditInformation() const;
297 [[nodiscard]] bool canEditPermissions() const;
298 [[nodiscard]] bool canEditUsername() const;
299 [[nodiscard]] bool canEditPreHistoryHidden() const;
300 [[nodiscard]] bool canAddMembers() const;
301 [[nodiscard]] bool canAddAdmins() const;
302 [[nodiscard]] bool canBanMembers() const;
303 [[nodiscard]] bool canSendPolls() const;
304 [[nodiscard]] bool anyoneCanAddMembers() const;
305
306 [[nodiscard]] bool canEditMessages() const;
307 [[nodiscard]] bool canDeleteMessages() const;
308 [[nodiscard]] bool hiddenPreHistory() const;
309 [[nodiscard]] bool canPublish() const;
310 [[nodiscard]] bool canViewMembers() const;
311 [[nodiscard]] bool canViewAdmins() const;
312 [[nodiscard]] bool canViewBanned() const;
313 [[nodiscard]] bool canEditSignatures() const;
314 [[nodiscard]] bool canEditStickers() const;
315 [[nodiscard]] bool canDelete() const;
316 [[nodiscard]] bool canEditAdmin(not_null<UserData*> user) const;
317 [[nodiscard]] bool canRestrictParticipant(
318 not_null<PeerData*> participant) const;
319
320 void setInviteLink(const QString &newInviteLink);
inviteLink()321 [[nodiscard]] QString inviteLink() const {
322 return _inviteLink;
323 }
324 [[nodiscard]] bool canHaveInviteLink() const;
325
326 void setLocation(const MTPChannelLocation &data);
327 [[nodiscard]] const ChannelLocation *getLocation() const;
328
329 void setLinkedChat(ChannelData *linked);
330 [[nodiscard]] ChannelData *linkedChat() const;
331 [[nodiscard]] bool linkedChatKnown() const;
332
ptsInit(int32 pts)333 void ptsInit(int32 pts) {
334 _ptsWaiter.init(pts);
335 }
ptsReceived(int32 pts)336 void ptsReceived(int32 pts) {
337 _ptsWaiter.updateAndApply(this, pts, 0);
338 }
ptsUpdateAndApply(int32 pts,int32 count)339 bool ptsUpdateAndApply(int32 pts, int32 count) {
340 return _ptsWaiter.updateAndApply(this, pts, count);
341 }
ptsUpdateAndApply(int32 pts,int32 count,const MTPUpdate & update)342 bool ptsUpdateAndApply(
343 int32 pts,
344 int32 count,
345 const MTPUpdate &update) {
346 return _ptsWaiter.updateAndApply(this, pts, count, update);
347 }
ptsUpdateAndApply(int32 pts,int32 count,const MTPUpdates & updates)348 bool ptsUpdateAndApply(
349 int32 pts,
350 int32 count,
351 const MTPUpdates &updates) {
352 return _ptsWaiter.updateAndApply(this, pts, count, updates);
353 }
pts()354 [[nodiscard]] int32 pts() const {
355 return _ptsWaiter.current();
356 }
ptsInited()357 [[nodiscard]] bool ptsInited() const {
358 return _ptsWaiter.inited();
359 }
ptsRequesting()360 [[nodiscard]] bool ptsRequesting() const {
361 return _ptsWaiter.requesting();
362 }
ptsSetRequesting(bool isRequesting)363 void ptsSetRequesting(bool isRequesting) {
364 return _ptsWaiter.setRequesting(isRequesting);
365 }
366 // < 0 - not waiting
ptsWaitingForShortPoll(int32 ms)367 void ptsWaitingForShortPoll(int32 ms) {
368 return _ptsWaiter.setWaitingForShortPoll(this, ms);
369 }
ptsWaitingForSkipped()370 [[nodiscard]] bool ptsWaitingForSkipped() const {
371 return _ptsWaiter.waitingForSkipped();
372 }
ptsWaitingForShortPoll()373 [[nodiscard]] bool ptsWaitingForShortPoll() const {
374 return _ptsWaiter.waitingForShortPoll();
375 }
376
377 void setUnavailableReasons(
378 std::vector<Data::UnavailableReason> &&reason);
379
availableMinId()380 [[nodiscard]] MsgId availableMinId() const {
381 return _availableMinId;
382 }
383 void setAvailableMinId(MsgId availableMinId);
384
385 [[nodiscard]] ChatData *getMigrateFromChat() const;
386 void setMigrateFromChat(ChatData *chat);
387
388 [[nodiscard]] int slowmodeSeconds() const;
389 void setSlowmodeSeconds(int seconds);
390 [[nodiscard]] TimeId slowmodeLastMessage() const;
391 void growSlowmodeLastMessage(TimeId when);
392
393 void setInvitePeek(const QString &hash, TimeId expires);
394 void clearInvitePeek();
395 [[nodiscard]] TimeId invitePeekExpires() const;
396 [[nodiscard]] QString invitePeekHash() const;
397 void privateErrorReceived();
398
groupCall()399 [[nodiscard]] Data::GroupCall *groupCall() const {
400 return _call.get();
401 }
402 void migrateCall(std::unique_ptr<Data::GroupCall> call);
403 void setGroupCall(
404 const MTPInputGroupCall &call,
405 TimeId scheduleDate = 0);
406 void clearGroupCall();
407 void setGroupCallDefaultJoinAs(PeerId peerId);
408 [[nodiscard]] PeerId groupCallDefaultJoinAs() const;
409
410 // Still public data members.
411 uint64 access = 0;
412
413 MTPinputChannel inputChannel = MTP_inputChannelEmpty();
414
415 QString username;
416
417 int32 date = 0;
418 std::unique_ptr<MegagroupInfo> mgInfo;
419
420 // > 0 - user who invited me to channel, < 0 - not in channel.
421 UserId inviter = 0;
422 TimeId inviteDate = 0;
423 bool inviteViaRequest = false;
424
425 private:
426 struct InvitePeek {
427 QString hash;
428 TimeId expires = 0;
429 };
430
431 auto unavailableReasons() const
432 -> const std::vector<Data::UnavailableReason> & override;
433 bool canEditLastAdmin(not_null<UserData*> user) const;
434
435 Flags _flags = ChannelDataFlags(Flag::Forbidden);
436
437 PtsWaiter _ptsWaiter;
438
439 int _membersCount = -1;
440 int _adminsCount = 1;
441 int _restrictedCount = 0;
442 int _kickedCount = 0;
443 int _pendingRequestsCount = 0;
444 std::vector<UserId> _recentRequesters;
445 MsgId _availableMinId = 0;
446
447 RestrictionFlags _defaultRestrictions;
448 AdminRightFlags _adminRights;
449 RestrictionFlags _restrictions;
450 TimeId _restrictedUntil;
451
452 std::vector<Data::UnavailableReason> _unavailableReasons;
453 std::unique_ptr<InvitePeek> _invitePeek;
454 QString _inviteLink;
455 std::optional<ChannelData*> _linkedChat;
456
457 std::unique_ptr<Data::GroupCall> _call;
458 PeerId _callDefaultJoinAs = 0;
459
460 int _slowmodeSeconds = 0;
461 TimeId _slowmodeLastMessage = 0;
462
463 rpl::lifetime _lifetime;
464
465 };
466
467 namespace Data {
468
469 void ApplyMigration(
470 not_null<ChatData*> chat,
471 not_null<ChannelData*> channel);
472
473 void ApplyChannelUpdate(
474 not_null<ChannelData*> channel,
475 const MTPDupdateChatDefaultBannedRights &update);
476
477 void ApplyChannelUpdate(
478 not_null<ChannelData*> channel,
479 const MTPDchannelFull &update);
480
481 void ApplyMegagroupAdmins(
482 not_null<ChannelData*> channel,
483 const MTPDchannels_channelParticipants &data);
484
485 } // namespace Data
486