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 "storage/storage_databases.h"
11 #include "dialogs/dialogs_key.h"
12 #include "dialogs/dialogs_indexed_list.h"
13 #include "dialogs/dialogs_main_list.h"
14 #include "data/data_groups.h"
15 #include "data/data_cloud_file.h"
16 #include "data/data_notify_settings.h"
17 #include "history/history_location_manager.h"
18 #include "base/timer.h"
19 #include "base/flags.h"
20 
21 class Image;
22 class HistoryItem;
23 class HistoryMessage;
24 class HistoryService;
25 struct WebPageCollage;
26 enum class WebPageType;
27 enum class NewMessageType;
28 
29 namespace HistoryView {
30 struct Group;
31 class Element;
32 class ElementDelegate;
33 } // namespace HistoryView
34 
35 namespace Main {
36 class Session;
37 } // namespace Main
38 
39 namespace Ui {
40 class BoxContent;
41 } // namespace Ui
42 
43 namespace Passport {
44 struct SavedCredentials;
45 } // namespace Passport
46 
47 namespace Data {
48 
49 class Folder;
50 class LocationPoint;
51 class WallPaper;
52 class ScheduledMessages;
53 class SendActionManager;
54 class SponsoredMessages;
55 class ChatFilters;
56 class CloudThemes;
57 class Streaming;
58 class MediaRotation;
59 class Histories;
60 class DocumentMedia;
61 class PhotoMedia;
62 class Stickers;
63 class GroupCall;
64 
65 class Session final {
66 public:
67 	using ViewElement = HistoryView::Element;
68 
69 	struct SentData {
70 		PeerId peerId = 0;
71 		QString text;
72 	};
73 
74 	explicit Session(not_null<Main::Session*> session);
75 	~Session();
76 
session()77 	[[nodiscard]] Main::Session &session() const {
78 		return *_session;
79 	}
80 
81 	[[nodiscard]] QString nameSortKey(const QString &name) const;
82 
groups()83 	[[nodiscard]] Groups &groups() {
84 		return _groups;
85 	}
groups()86 	[[nodiscard]] const Groups &groups() const {
87 		return _groups;
88 	}
chatsFilters()89 	[[nodiscard]] ChatFilters &chatsFilters() const {
90 		return *_chatsFilters;
91 	}
scheduledMessages()92 	[[nodiscard]] ScheduledMessages &scheduledMessages() const {
93 		return *_scheduledMessages;
94 	}
sendActionManager()95 	[[nodiscard]] SendActionManager &sendActionManager() const {
96 		return *_sendActionManager;
97 	}
cloudThemes()98 	[[nodiscard]] CloudThemes &cloudThemes() const {
99 		return *_cloudThemes;
100 	}
streaming()101 	[[nodiscard]] Streaming &streaming() const {
102 		return *_streaming;
103 	}
mediaRotation()104 	[[nodiscard]] MediaRotation &mediaRotation() const {
105 		return *_mediaRotation;
106 	}
histories()107 	[[nodiscard]] Histories &histories() const {
108 		return *_histories;
109 	}
stickers()110 	[[nodiscard]] Stickers &stickers() const {
111 		return *_stickers;
112 	}
sponsoredMessages()113 	[[nodiscard]] SponsoredMessages &sponsoredMessages() const {
114 		return *_sponsoredMessages;
115 	}
nextNonHistoryEntryId()116 	[[nodiscard]] MsgId nextNonHistoryEntryId() {
117 		return ++_nonHistoryEntryId;
118 	}
119 
120 	void clear();
121 
122 	void keepAlive(std::shared_ptr<PhotoMedia> media);
123 	void keepAlive(std::shared_ptr<DocumentMedia> media);
124 
125 	void suggestStartExport(TimeId availableAt);
126 	void clearExportSuggestion();
127 
128 	[[nodiscard]] auto passportCredentials() const
129 	-> const Passport::SavedCredentials*;
130 	void rememberPassportCredentials(
131 		Passport::SavedCredentials data,
132 		crl::time rememberFor);
133 	void forgetPassportCredentials();
134 
135 	[[nodiscard]] Storage::Cache::Database &cache();
136 	[[nodiscard]] Storage::Cache::Database &cacheBigFile();
137 
138 	[[nodiscard]] not_null<PeerData*> peer(PeerId id);
139 	[[nodiscard]] not_null<PeerData*> peer(UserId id) = delete;
140 	[[nodiscard]] not_null<UserData*> user(UserId id);
141 	[[nodiscard]] not_null<ChatData*> chat(ChatId id);
142 	[[nodiscard]] not_null<ChannelData*> channel(ChannelId id);
143 	[[nodiscard]] not_null<UserData*> user(PeerId id) = delete;
144 	[[nodiscard]] not_null<ChatData*> chat(PeerId id) = delete;
145 	[[nodiscard]] not_null<ChannelData*> channel(PeerId id) = delete;
146 
147 	[[nodiscard]] PeerData *peerLoaded(PeerId id) const;
148 	[[nodiscard]] PeerData *peerLoaded(UserId id) const = delete;
149 	[[nodiscard]] UserData *userLoaded(UserId id) const;
150 	[[nodiscard]] ChatData *chatLoaded(ChatId id) const;
151 	[[nodiscard]] ChannelData *channelLoaded(ChannelId id) const;
152 	[[nodiscard]] UserData *userLoaded(PeerId id) const = delete;
153 	[[nodiscard]] ChatData *chatLoaded(PeerId id) const = delete;
154 	[[nodiscard]] ChannelData *channelLoaded(PeerId id) const = delete;
155 
156 	not_null<UserData*> processUser(const MTPUser &data);
157 	not_null<PeerData*> processChat(const MTPChat &data);
158 
159 	// Returns last user, if there were any.
160 	UserData *processUsers(const MTPVector<MTPUser> &data);
161 	PeerData *processChats(const MTPVector<MTPChat> &data);
162 
163 	void applyMaximumChatVersions(const MTPVector<MTPChat> &data);
164 
165 	void registerGroupCall(not_null<GroupCall*> call);
166 	void unregisterGroupCall(not_null<GroupCall*> call);
167 	GroupCall *groupCall(CallId callId) const;
168 
169 	[[nodiscard]] auto invitedToCallUsers(CallId callId) const
170 		-> const base::flat_set<not_null<UserData*>> &;
171 	void registerInvitedToCallUser(
172 		CallId callId,
173 		not_null<PeerData*> peer,
174 		not_null<UserData*> user);
175 	void unregisterInvitedToCallUser(CallId callId, not_null<UserData*> user);
176 
177 	struct InviteToCall {
178 		CallId id = 0;
179 		not_null<UserData*> user;
180 	};
invitesToCalls()181 	[[nodiscard]] rpl::producer<InviteToCall> invitesToCalls() const {
182 		return _invitesToCalls.events();
183 	}
184 
185 	void enumerateUsers(Fn<void(not_null<UserData*>)> action) const;
186 	void enumerateGroups(Fn<void(not_null<PeerData*>)> action) const;
187 	void enumerateChannels(Fn<void(not_null<ChannelData*>)> action) const;
188 	[[nodiscard]] PeerData *peerByUsername(const QString &username) const;
189 
190 	[[nodiscard]] not_null<History*> history(PeerId peerId);
191 	[[nodiscard]] History *historyLoaded(PeerId peerId) const;
192 	[[nodiscard]] not_null<History*> history(UserId userId) = delete;
193 	[[nodiscard]] History *historyLoaded(UserId userId) const = delete;
194 	[[nodiscard]] not_null<History*> history(not_null<const PeerData*> peer);
195 	[[nodiscard]] History *historyLoaded(const PeerData *peer);
196 
197 	void deleteConversationLocally(not_null<PeerData*> peer);
198 
199 	void cancelForwarding(not_null<History*> history);
200 
contactsLoaded()201 	[[nodiscard]] rpl::variable<bool> &contactsLoaded() {
202 		return _contactsLoaded;
203 	}
chatsListChanges()204 	[[nodiscard]] rpl::producer<Data::Folder*> chatsListChanges() const {
205 		return _chatsListChanged.events();
206 	}
207 	[[nodiscard]] bool chatsListLoaded(Data::Folder *folder = nullptr);
chatsListLoadedEvents()208 	[[nodiscard]] rpl::producer<Data::Folder*> chatsListLoadedEvents() const {
209 		return _chatsListLoadedEvents.events();
210 	}
211 	void chatsListChanged(FolderId folderId);
212 	void chatsListChanged(Data::Folder *folder);
213 	void chatsListDone(Data::Folder *folder);
214 
215 	void userIsBotChanged(not_null<UserData*> user);
216 	[[nodiscard]] rpl::producer<not_null<UserData*>> userIsBotChanges() const;
217 	void botCommandsChanged(not_null<PeerData*> peer);
218 	[[nodiscard]] rpl::producer<not_null<PeerData*>> botCommandsChanges() const;
219 
220 	struct ItemVisibilityQuery {
221 		not_null<HistoryItem*> item;
222 		not_null<bool*> isVisible;
223 	};
queryItemVisibility()224 	[[nodiscard]] base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
225 		return _queryItemVisibility;
226 	}
227 	struct IdChange {
228 		not_null<HistoryItem*> item;
229 		MsgId oldId = 0;
230 	};
231 	void notifyItemIdChange(IdChange event);
232 	[[nodiscard]] rpl::producer<IdChange> itemIdChanged() const;
233 	void notifyItemLayoutChange(not_null<const HistoryItem*> item);
234 	[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
235 	void notifyViewLayoutChange(not_null<const ViewElement*> view);
236 	[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
237 	void notifyNewItemAdded(not_null<HistoryItem*> item);
238 	[[nodiscard]] rpl::producer<not_null<HistoryItem*>> newItemAdded() const;
239 	void requestItemRepaint(not_null<const HistoryItem*> item);
240 	[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
241 	void requestViewRepaint(not_null<const ViewElement*> view);
242 	[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewRepaintRequest() const;
243 	void requestItemResize(not_null<const HistoryItem*> item);
244 	[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const;
245 	void requestViewResize(not_null<ViewElement*> view);
246 	[[nodiscard]] rpl::producer<not_null<ViewElement*>> viewResizeRequest() const;
247 	void requestItemViewRefresh(not_null<HistoryItem*> item);
248 	[[nodiscard]] rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const;
249 	void requestItemTextRefresh(not_null<HistoryItem*> item);
250 	void requestAnimationPlayInline(not_null<HistoryItem*> item);
251 	[[nodiscard]] rpl::producer<not_null<HistoryItem*>> animationPlayInlineRequest() const;
252 	void notifyHistoryUnloaded(not_null<const History*> history);
253 	[[nodiscard]] rpl::producer<not_null<const History*>> historyUnloaded() const;
254 
255 	[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
256 	[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRemoved(
257 		FullMsgId itemId) const;
258 	void notifyViewRemoved(not_null<const ViewElement*> view);
259 	[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewRemoved() const;
260 	void notifyHistoryCleared(not_null<const History*> history);
261 	[[nodiscard]] rpl::producer<not_null<const History*>> historyCleared() const;
262 	void notifyHistoryChangeDelayed(not_null<History*> history);
263 	[[nodiscard]] rpl::producer<not_null<History*>> historyChanged() const;
264 	void sendHistoryChangeNotifications();
265 
266 	void notifyPinnedDialogsOrderUpdated();
267 	[[nodiscard]] rpl::producer<> pinnedDialogsOrderUpdated() const;
268 
269 	void registerHeavyViewPart(not_null<ViewElement*> view);
270 	void unregisterHeavyViewPart(not_null<ViewElement*> view);
271 	void unloadHeavyViewParts(
272 		not_null<HistoryView::ElementDelegate*> delegate);
273 	void unloadHeavyViewParts(
274 		not_null<HistoryView::ElementDelegate*> delegate,
275 		int from,
276 		int till);
277 
278 	using MegagroupParticipant = std::tuple<
279 		not_null<ChannelData*>,
280 		not_null<UserData*>>;
281 	void removeMegagroupParticipant(
282 		not_null<ChannelData*> channel,
283 		not_null<UserData*> user);
284 	[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
285 	[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
286 		not_null<ChannelData*> channel) const;
287 	void addNewMegagroupParticipant(
288 		not_null<ChannelData*> channel,
289 		not_null<UserData*> user);
290 	[[nodiscard]] rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
291 	[[nodiscard]] rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
292 		not_null<ChannelData*> channel) const;
293 
294 	HistoryItemsList idsToItems(const MessageIdsList &ids) const;
295 	MessageIdsList itemsToIds(const HistoryItemsList &items) const;
296 	MessageIdsList itemOrItsGroup(not_null<HistoryItem*> item) const;
297 
298 	void applyUpdate(const MTPDupdateMessagePoll &update);
299 	void applyUpdate(const MTPDupdateChatParticipants &update);
300 	void applyUpdate(const MTPDupdateChatParticipantAdd &update);
301 	void applyUpdate(const MTPDupdateChatParticipantDelete &update);
302 	void applyUpdate(const MTPDupdateChatParticipantAdmin &update);
303 	void applyUpdate(const MTPDupdateChatDefaultBannedRights &update);
304 
305 	void applyDialogs(
306 		Data::Folder *requestFolder,
307 		const QVector<MTPMessage> &messages,
308 		const QVector<MTPDialog> &dialogs,
309 		std::optional<int> count = std::nullopt);
310 
311 	int pinnedChatsCount(Data::Folder *folder, FilterId filterId) const;
312 	int pinnedChatsLimit(Data::Folder *folder, FilterId filterId) const;
313 	const std::vector<Dialogs::Key> &pinnedChatsOrder(
314 		Data::Folder *folder,
315 		FilterId filterId) const;
316 	void setChatPinned(
317 		const Dialogs::Key &key,
318 		FilterId filterId,
319 		bool pinned);
320 	void clearPinnedChats(Data::Folder *folder);
321 	void applyPinnedChats(
322 		Data::Folder *folder,
323 		const QVector<MTPDialogPeer> &list);
324 	void reorderTwoPinnedChats(
325 		FilterId filterId,
326 		const Dialogs::Key &key1,
327 		const Dialogs::Key &key2);
328 
329 	void setSuggestToGigagroup(not_null<ChannelData*> group, bool suggest);
330 	[[nodiscard]] bool suggestToGigagroup(
331 		not_null<ChannelData*> group) const;
332 
333 	void registerMessage(not_null<HistoryItem*> item);
334 	void unregisterMessage(not_null<HistoryItem*> item);
335 
336 	void registerMessageTTL(TimeId when, not_null<HistoryItem*> item);
337 	void unregisterMessageTTL(TimeId when, not_null<HistoryItem*> item);
338 
339 	// Returns true if item found and it is not detached.
340 	bool checkEntitiesAndViewsUpdate(const MTPDmessage &data);
341 	void updateEditedMessage(const MTPMessage &data);
342 	void processMessages(
343 		const QVector<MTPMessage> &data,
344 		NewMessageType type);
345 	void processMessages(
346 		const MTPVector<MTPMessage> &data,
347 		NewMessageType type);
348 	void processExistingMessages(
349 		ChannelData *channel,
350 		const MTPmessages_Messages &data);
351 	void processMessagesDeleted(
352 		ChannelId channelId,
353 		const QVector<MTPint> &data);
354 
355 	[[nodiscard]] MsgId nextLocalMessageId();
356 	[[nodiscard]] HistoryItem *message(
357 		ChannelId channelId,
358 		MsgId itemId) const;
359 	[[nodiscard]] HistoryItem *message(
360 		const ChannelData *channel,
361 		MsgId itemId) const;
362 	[[nodiscard]] HistoryItem *message(FullMsgId itemId) const;
363 
364 	void updateDependentMessages(not_null<HistoryItem*> item);
365 	void registerDependentMessage(
366 		not_null<HistoryItem*> dependent,
367 		not_null<HistoryItem*> dependency);
368 	void unregisterDependentMessage(
369 		not_null<HistoryItem*> dependent,
370 		not_null<HistoryItem*> dependency);
371 
372 	void destroyAllCallItems();
373 
374 	void registerMessageRandomId(uint64 randomId, FullMsgId itemId);
375 	void unregisterMessageRandomId(uint64 randomId);
376 	[[nodiscard]] FullMsgId messageIdByRandomId(uint64 randomId) const;
377 	void registerMessageSentData(
378 		uint64 randomId,
379 		PeerId peerId,
380 		const QString &text);
381 	void unregisterMessageSentData(uint64 randomId);
382 	[[nodiscard]] SentData messageSentData(uint64 randomId) const;
383 
384 	void photoLoadSettingsChanged();
385 	void documentLoadSettingsChanged();
386 
387 	void notifyPhotoLayoutChanged(not_null<const PhotoData*> photo);
388 	void requestPhotoViewRepaint(not_null<const PhotoData*> photo);
389 	void notifyDocumentLayoutChanged(
390 		not_null<const DocumentData*> document);
391 	void requestDocumentViewRepaint(not_null<const DocumentData*> document);
392 	void markMediaRead(not_null<const DocumentData*> document);
393 	void requestPollViewRepaint(not_null<const PollData*> poll);
394 
395 	void photoLoadProgress(not_null<PhotoData*> photo);
396 	void photoLoadDone(not_null<PhotoData*> photo);
397 	void photoLoadFail(not_null<PhotoData*> photo, bool started);
398 
399 	void documentLoadProgress(not_null<DocumentData*> document);
400 	void documentLoadDone(not_null<DocumentData*> document);
401 	void documentLoadFail(not_null<DocumentData*> document, bool started);
402 
403 	HistoryItem *addNewMessage(
404 		const MTPMessage &data,
405 		MessageFlags localFlags,
406 		NewMessageType type);
407 	HistoryItem *addNewMessage( // Override message id.
408 		MsgId id,
409 		const MTPMessage &data,
410 		MessageFlags localFlags,
411 		NewMessageType type);
412 
413 	[[nodiscard]] int unreadBadge() const;
414 	[[nodiscard]] bool unreadBadgeMuted() const;
415 	[[nodiscard]] int unreadBadgeIgnoreOne(const Dialogs::Key &key) const;
416 	[[nodiscard]] bool unreadBadgeMutedIgnoreOne(
417 		const Dialogs::Key &key) const;
418 	[[nodiscard]] int unreadOnlyMutedBadge() const;
419 	[[nodiscard]] rpl::producer<> unreadBadgeChanges() const;
420 	void notifyUnreadBadgeChanged();
421 
422 	[[nodiscard]] std::optional<int> countUnreadRepliesLocally(
423 		not_null<HistoryItem*> root,
424 		MsgId afterId) const;
425 	struct UnreadRepliesCountRequest {
426 		not_null<HistoryItem*> root;
427 		MsgId afterId = 0;
428 		not_null<std::optional<int>*> result;
429 	};
430 	[[nodiscard]] auto unreadRepliesCountRequests() const
431 		-> rpl::producer<UnreadRepliesCountRequest>;
432 
433 	void selfDestructIn(not_null<HistoryItem*> item, crl::time delay);
434 
435 	[[nodiscard]] not_null<PhotoData*> photo(PhotoId id);
436 	not_null<PhotoData*> processPhoto(const MTPPhoto &data);
437 	not_null<PhotoData*> processPhoto(const MTPDphoto &data);
438 	not_null<PhotoData*> processPhoto(
439 		const MTPPhoto &data,
440 		const PreparedPhotoThumbs &thumbs);
441 	[[nodiscard]] not_null<PhotoData*> photo(
442 		PhotoId id,
443 		const uint64 &access,
444 		const QByteArray &fileReference,
445 		TimeId date,
446 		int32 dc,
447 		bool hasStickers,
448 		const QByteArray &inlineThumbnailBytes,
449 		const ImageWithLocation &small,
450 		const ImageWithLocation &thumbnail,
451 		const ImageWithLocation &large,
452 		const ImageWithLocation &video,
453 		crl::time videoStartTime);
454 	void photoConvert(
455 		not_null<PhotoData*> original,
456 		const MTPPhoto &data);
457 	[[nodiscard]] PhotoData *photoFromWeb(
458 		const MTPWebDocument &data,
459 		const ImageLocation &thumbnailLocation);
460 
461 	[[nodiscard]] not_null<DocumentData*> document(DocumentId id);
462 	not_null<DocumentData*> processDocument(const MTPDocument &data);
463 	not_null<DocumentData*> processDocument(const MTPDdocument &data);
464 	not_null<DocumentData*> processDocument(
465 		const MTPdocument &data,
466 		const ImageWithLocation &thumbnail);
467 	[[nodiscard]] not_null<DocumentData*> document(
468 		DocumentId id,
469 		const uint64 &access,
470 		const QByteArray &fileReference,
471 		TimeId date,
472 		const QVector<MTPDocumentAttribute> &attributes,
473 		const QString &mime,
474 		const InlineImageLocation &inlineThumbnail,
475 		const ImageWithLocation &thumbnail,
476 		const ImageWithLocation &videoThumbnail,
477 		int32 dc,
478 		int32 size);
479 	void documentConvert(
480 		not_null<DocumentData*> original,
481 		const MTPDocument &data);
482 	[[nodiscard]] DocumentData *documentFromWeb(
483 		const MTPWebDocument &data,
484 		const ImageLocation &thumbnailLocation,
485 		const ImageLocation &videoThumbnailLocation);
486 
487 	[[nodiscard]] not_null<WebPageData*> webpage(WebPageId id);
488 	not_null<WebPageData*> processWebpage(const MTPWebPage &data);
489 	not_null<WebPageData*> processWebpage(const MTPDwebPage &data);
490 	not_null<WebPageData*> processWebpage(const MTPDwebPagePending &data);
491 	[[nodiscard]] not_null<WebPageData*> webpage(
492 		WebPageId id,
493 		const QString &siteName,
494 		const TextWithEntities &content);
495 	[[nodiscard]] not_null<WebPageData*> webpage(
496 		WebPageId id,
497 		WebPageType type,
498 		const QString &url,
499 		const QString &displayUrl,
500 		const QString &siteName,
501 		const QString &title,
502 		const TextWithEntities &description,
503 		PhotoData *photo,
504 		DocumentData *document,
505 		WebPageCollage &&collage,
506 		int duration,
507 		const QString &author,
508 		TimeId pendingTill);
509 
510 	[[nodiscard]] not_null<GameData*> game(GameId id);
511 	not_null<GameData*> processGame(const MTPDgame &data);
512 	[[nodiscard]] not_null<GameData*> game(
513 		GameId id,
514 		const uint64 &accessHash,
515 		const QString &shortName,
516 		const QString &title,
517 		const QString &description,
518 		PhotoData *photo,
519 		DocumentData *document);
520 	void gameConvert(
521 		not_null<GameData*> original,
522 		const MTPGame &data);
523 
524 	[[nodiscard]] not_null<PollData*> poll(PollId id);
525 	not_null<PollData*> processPoll(const MTPPoll &data);
526 	not_null<PollData*> processPoll(const MTPDmessageMediaPoll &data);
527 
528 	[[nodiscard]] not_null<Data::CloudImage*> location(
529 		const LocationPoint &point);
530 
531 	void registerPhotoItem(
532 		not_null<const PhotoData*> photo,
533 		not_null<HistoryItem*> item);
534 	void unregisterPhotoItem(
535 		not_null<const PhotoData*> photo,
536 		not_null<HistoryItem*> item);
537 	void registerDocumentItem(
538 		not_null<const DocumentData*> document,
539 		not_null<HistoryItem*> item);
540 	void unregisterDocumentItem(
541 		not_null<const DocumentData*> document,
542 		not_null<HistoryItem*> item);
543 	void registerWebPageView(
544 		not_null<const WebPageData*> page,
545 		not_null<ViewElement*> view);
546 	void unregisterWebPageView(
547 		not_null<const WebPageData*> page,
548 		not_null<ViewElement*> view);
549 	void registerWebPageItem(
550 		not_null<const WebPageData*> page,
551 		not_null<HistoryItem*> item);
552 	void unregisterWebPageItem(
553 		not_null<const WebPageData*> page,
554 		not_null<HistoryItem*> item);
555 	void registerGameView(
556 		not_null<const GameData*> game,
557 		not_null<ViewElement*> view);
558 	void unregisterGameView(
559 		not_null<const GameData*> game,
560 		not_null<ViewElement*> view);
561 	void registerPollView(
562 		not_null<const PollData*> poll,
563 		not_null<ViewElement*> view);
564 	void unregisterPollView(
565 		not_null<const PollData*> poll,
566 		not_null<ViewElement*> view);
567 	void registerContactView(
568 		UserId contactId,
569 		not_null<ViewElement*> view);
570 	void unregisterContactView(
571 		UserId contactId,
572 		not_null<ViewElement*> view);
573 	void registerContactItem(
574 		UserId contactId,
575 		not_null<HistoryItem*> item);
576 	void unregisterContactItem(
577 		UserId contactId,
578 		not_null<HistoryItem*> item);
579 	void registerCallItem(not_null<HistoryItem*> item);
580 	void unregisterCallItem(not_null<HistoryItem*> item);
581 
582 	void documentMessageRemoved(not_null<DocumentData*> document);
583 
584 	void checkPlayingAnimations();
585 
586 	HistoryItem *findWebPageItem(not_null<WebPageData*> page) const;
587 	QString findContactPhone(not_null<UserData*> contact) const;
588 	QString findContactPhone(UserId contactId) const;
589 
590 	void notifyWebPageUpdateDelayed(not_null<WebPageData*> page);
591 	void notifyGameUpdateDelayed(not_null<GameData*> game);
592 	void notifyPollUpdateDelayed(not_null<PollData*> poll);
593 	[[nodiscard]] bool hasPendingWebPageGamePollNotification() const;
594 	void sendWebPageGamePollNotifications();
595 	[[nodiscard]] rpl::producer<not_null<WebPageData*>> webPageUpdates() const;
596 
597 	void channelDifferenceTooLong(not_null<ChannelData*> channel);
598 	[[nodiscard]] rpl::producer<not_null<ChannelData*>> channelDifferenceTooLong() const;
599 
600 	void registerItemView(not_null<ViewElement*> view);
601 	void unregisterItemView(not_null<ViewElement*> view);
602 
603 	[[nodiscard]] not_null<Folder*> folder(FolderId id);
604 	[[nodiscard]] Folder *folderLoaded(FolderId id) const;
605 	not_null<Folder*> processFolder(const MTPFolder &data);
606 	not_null<Folder*> processFolder(const MTPDfolder &data);
607 
608 	[[nodiscard]] not_null<Dialogs::MainList*> chatsList(
609 		Data::Folder *folder = nullptr);
610 	[[nodiscard]] not_null<const Dialogs::MainList*> chatsList(
611 		Data::Folder *folder = nullptr) const;
612 	[[nodiscard]] not_null<Dialogs::IndexedList*> contactsList();
613 	[[nodiscard]] not_null<Dialogs::IndexedList*> contactsNoChatsList();
614 
615 	struct ChatListEntryRefresh {
616 		Dialogs::Key key;
617 		Dialogs::PositionChange moved;
618 		FilterId filterId = 0;
619 		bool existenceChanged = false;
620 
621 		explicit operator bool() const {
622 			return existenceChanged || (moved.from != moved.to);
623 		}
624 	};
625 	void refreshChatListEntry(Dialogs::Key key);
626 	void removeChatListEntry(Dialogs::Key key);
627 	[[nodiscard]] auto chatListEntryRefreshes() const
628 		-> rpl::producer<ChatListEntryRefresh>;
629 
630 	struct DialogsRowReplacement {
631 		not_null<Dialogs::Row*> old;
632 		Dialogs::Row *now = nullptr;
633 	};
634 	void dialogsRowReplaced(DialogsRowReplacement replacement);
635 	rpl::producer<DialogsRowReplacement> dialogsRowReplacements() const;
636 
637 	void requestNotifySettings(not_null<PeerData*> peer);
638 	void applyNotifySetting(
639 		const MTPNotifyPeer &notifyPeer,
640 		const MTPPeerNotifySettings &settings);
641 	void updateNotifySettings(
642 		not_null<PeerData*> peer,
643 		std::optional<int> muteForSeconds,
644 		std::optional<bool> silentPosts = std::nullopt);
645 	void resetNotifySettingsToDefault(not_null<PeerData*> peer);
646 	bool notifyIsMuted(
647 		not_null<const PeerData*> peer,
648 		crl::time *changesIn = nullptr) const;
649 	bool notifySilentPosts(not_null<const PeerData*> peer) const;
650 	bool notifyMuteUnknown(not_null<const PeerData*> peer) const;
651 	bool notifySilentPostsUnknown(not_null<const PeerData*> peer) const;
652 	bool notifySettingsUnknown(not_null<const PeerData*> peer) const;
653 	rpl::producer<> defaultUserNotifyUpdates() const;
654 	rpl::producer<> defaultChatNotifyUpdates() const;
655 	rpl::producer<> defaultBroadcastNotifyUpdates() const;
656 	rpl::producer<> defaultNotifyUpdates(
657 		not_null<const PeerData*> peer) const;
658 
659 	void serviceNotification(
660 		const TextWithEntities &message,
661 		const MTPMessageMedia &media = MTP_messageMediaEmpty());
662 
663 	void setMimeForwardIds(MessageIdsList &&list);
664 	MessageIdsList takeMimeForwardIds();
665 
666 	void setTopPromoted(
667 		History *promoted,
668 		const QString &type,
669 		const QString &message);
670 
671 	bool updateWallpapers(const MTPaccount_WallPapers &data);
672 	void removeWallpaper(const WallPaper &paper);
673 	const std::vector<WallPaper> &wallpapers() const;
674 	uint64 wallpapersHash() const;
675 
676 	void clearLocalStorage();
677 
678 private:
679 	using Messages = std::unordered_map<MsgId, not_null<HistoryItem*>>;
680 
681 	void suggestStartExport();
682 
683 	void setupMigrationViewer();
684 	void setupChannelLeavingViewer();
685 	void setupPeerNameViewer();
686 	void setupUserIsContactViewer();
687 
688 	void checkSelfDestructItems();
689 
690 	void scheduleNextTTLs();
691 	void checkTTLs();
692 
693 	int computeUnreadBadge(const Dialogs::UnreadState &state) const;
694 	bool computeUnreadBadgeMuted(const Dialogs::UnreadState &state) const;
695 
696 	void applyDialog(Data::Folder *requestFolder, const MTPDdialog &data);
697 	void applyDialog(
698 		Data::Folder *requestFolder,
699 		const MTPDdialogFolder &data);
700 
701 	const Messages *messagesList(ChannelId channelId) const;
702 	not_null<Messages*> messagesListForInsert(ChannelId channelId);
703 	not_null<HistoryItem*> registerMessage(
704 		std::unique_ptr<HistoryItem> item);
705 	void changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId);
706 	void removeDependencyMessage(not_null<HistoryItem*> item);
707 
708 	void photoApplyFields(
709 		not_null<PhotoData*> photo,
710 		const MTPPhoto &data);
711 	void photoApplyFields(
712 		not_null<PhotoData*> photo,
713 		const MTPDphoto &data);
714 	void photoApplyFields(
715 		not_null<PhotoData*> photo,
716 		const uint64 &access,
717 		const QByteArray &fileReference,
718 		TimeId date,
719 		int32 dc,
720 		bool hasStickers,
721 		const QByteArray &inlineThumbnailBytes,
722 		const ImageWithLocation &small,
723 		const ImageWithLocation &thumbnail,
724 		const ImageWithLocation &large,
725 		const ImageWithLocation &video,
726 		crl::time videoStartTime);
727 
728 	void documentApplyFields(
729 		not_null<DocumentData*> document,
730 		const MTPDocument &data);
731 	void documentApplyFields(
732 		not_null<DocumentData*> document,
733 		const MTPDdocument &data);
734 	void documentApplyFields(
735 		not_null<DocumentData*> document,
736 		const uint64 &access,
737 		const QByteArray &fileReference,
738 		TimeId date,
739 		const QVector<MTPDocumentAttribute> &attributes,
740 		const QString &mime,
741 		const InlineImageLocation &inlineThumbnail,
742 		const ImageWithLocation &thumbnail,
743 		const ImageWithLocation &videoThumbnail,
744 		int32 dc,
745 		int32 size);
746 	DocumentData *documentFromWeb(
747 		const MTPDwebDocument &data,
748 		const ImageLocation &thumbnailLocation,
749 		const ImageLocation &videoThumbnailLocation);
750 	DocumentData *documentFromWeb(
751 		const MTPDwebDocumentNoProxy &data,
752 		const ImageLocation &thumbnailLocation,
753 		const ImageLocation &videoThumbnailLocation);
754 
755 	void webpageApplyFields(
756 		not_null<WebPageData*> page,
757 		const MTPDwebPage &data);
758 	void webpageApplyFields(
759 		not_null<WebPageData*> page,
760 		WebPageType type,
761 		const QString &url,
762 		const QString &displayUrl,
763 		const QString &siteName,
764 		const QString &title,
765 		const TextWithEntities &description,
766 		PhotoData *photo,
767 		DocumentData *document,
768 		WebPageCollage &&collage,
769 		int duration,
770 		const QString &author,
771 		TimeId pendingTill);
772 
773 	void gameApplyFields(
774 		not_null<GameData*> game,
775 		const MTPDgame &data);
776 	void gameApplyFields(
777 		not_null<GameData*> game,
778 		const uint64 &accessHash,
779 		const QString &shortName,
780 		const QString &title,
781 		const QString &description,
782 		PhotoData *photo,
783 		DocumentData *document);
784 
785 	void folderApplyFields(
786 		not_null<Folder*> folder,
787 		const MTPDfolder &data);
788 
789 	void setPinnedFromDialog(const Dialogs::Key &key, bool pinned);
790 
791 	NotifySettings &defaultNotifySettings(not_null<const PeerData*> peer);
792 	const NotifySettings &defaultNotifySettings(
793 		not_null<const PeerData*> peer) const;
794 	void unmuteByFinished();
795 	void unmuteByFinishedDelayed(crl::time delay);
796 	void updateNotifySettingsLocal(not_null<PeerData*> peer);
797 
798 	template <typename Method>
799 	void enumerateItemViews(
800 		not_null<const HistoryItem*> item,
801 		Method method);
802 
803 	void insertCheckedServiceNotification(
804 		const TextWithEntities &message,
805 		const MTPMessageMedia &media,
806 		TimeId date);
807 
808 	void setWallpapers(const QVector<MTPWallPaper> &data, uint64 hash);
809 
810 	void checkPollsClosings();
811 
812 	const not_null<Main::Session*> _session;
813 
814 	Storage::DatabasePointer _cache;
815 	Storage::DatabasePointer _bigFileCache;
816 
817 	TimeId _exportAvailableAt = 0;
818 	QPointer<Ui::BoxContent> _exportSuggestion;
819 
820 	rpl::variable<bool> _contactsLoaded = false;
821 	rpl::event_stream<Data::Folder*> _chatsListLoadedEvents;
822 	rpl::event_stream<Data::Folder*> _chatsListChanged;
823 	rpl::event_stream<not_null<UserData*>> _userIsBotChanges;
824 	rpl::event_stream<not_null<PeerData*>> _botCommandsChanges;
825 	base::Observable<ItemVisibilityQuery> _queryItemVisibility;
826 	rpl::event_stream<IdChange> _itemIdChanges;
827 	rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;
828 	rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;
829 	rpl::event_stream<not_null<HistoryItem*>> _newItemAdded;
830 	rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
831 	rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest;
832 	rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
833 	rpl::event_stream<not_null<ViewElement*>> _viewResizeRequest;
834 	rpl::event_stream<not_null<HistoryItem*>> _itemViewRefreshRequest;
835 	rpl::event_stream<not_null<HistoryItem*>> _itemTextRefreshRequest;
836 	rpl::event_stream<not_null<HistoryItem*>> _animationPlayInlineRequest;
837 	rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
838 	rpl::event_stream<not_null<const ViewElement*>> _viewRemoved;
839 	rpl::event_stream<not_null<const History*>> _historyUnloaded;
840 	rpl::event_stream<not_null<const History*>> _historyCleared;
841 	base::flat_set<not_null<History*>> _historiesChanged;
842 	rpl::event_stream<not_null<History*>> _historyChanged;
843 	rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved;
844 	rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded;
845 	rpl::event_stream<DialogsRowReplacement> _dialogsRowReplacements;
846 	rpl::event_stream<ChatListEntryRefresh> _chatListEntryRefreshes;
847 	rpl::event_stream<> _unreadBadgeChanges;
848 	rpl::event_stream<UnreadRepliesCountRequest> _unreadRepliesCountRequests;
849 
850 	Dialogs::MainList _chatsList;
851 	Dialogs::IndexedList _contactsList;
852 	Dialogs::IndexedList _contactsNoChatsList;
853 
854 	MsgId _localMessageIdCounter = StartClientMsgId;
855 	Messages _messages;
856 	std::map<ChannelId, Messages> _channelMessages;
857 	std::map<
858 		not_null<HistoryItem*>,
859 		base::flat_set<not_null<HistoryItem*>>> _dependentMessages;
860 	std::map<TimeId, base::flat_set<not_null<HistoryItem*>>> _ttlMessages;
861 	base::Timer _ttlCheckTimer;
862 
863 	base::flat_map<uint64, FullMsgId> _messageByRandomId;
864 	base::flat_map<uint64, SentData> _sentMessagesData;
865 
866 	base::Timer _selfDestructTimer;
867 	std::vector<FullMsgId> _selfDestructItems;
868 
869 	std::unordered_map<
870 		PhotoId,
871 		std::unique_ptr<PhotoData>> _photos;
872 	std::unordered_map<
873 		not_null<const PhotoData*>,
874 		base::flat_set<not_null<HistoryItem*>>> _photoItems;
875 	std::unordered_map<
876 		DocumentId,
877 		std::unique_ptr<DocumentData>> _documents;
878 	std::unordered_map<
879 		not_null<const DocumentData*>,
880 		base::flat_set<not_null<HistoryItem*>>> _documentItems;
881 	std::unordered_map<
882 		WebPageId,
883 		std::unique_ptr<WebPageData>> _webpages;
884 	std::unordered_map<
885 		not_null<const WebPageData*>,
886 		base::flat_set<not_null<HistoryItem*>>> _webpageItems;
887 	std::unordered_map<
888 		not_null<const WebPageData*>,
889 		base::flat_set<not_null<ViewElement*>>> _webpageViews;
890 	std::unordered_map<
891 		LocationPoint,
892 		std::unique_ptr<Data::CloudImage>> _locations;
893 	std::unordered_map<
894 		PollId,
895 		std::unique_ptr<PollData>> _polls;
896 	std::unordered_map<
897 		GameId,
898 		std::unique_ptr<GameData>> _games;
899 	std::unordered_map<
900 		not_null<const GameData*>,
901 		base::flat_set<not_null<ViewElement*>>> _gameViews;
902 	std::unordered_map<
903 		not_null<const PollData*>,
904 		base::flat_set<not_null<ViewElement*>>> _pollViews;
905 	std::unordered_map<
906 		UserId,
907 		base::flat_set<not_null<HistoryItem*>>> _contactItems;
908 	std::unordered_map<
909 		UserId,
910 		base::flat_set<not_null<ViewElement*>>> _contactViews;
911 	std::unordered_set<not_null<HistoryItem*>> _callItems;
912 
913 	base::flat_set<not_null<WebPageData*>> _webpagesUpdated;
914 	base::flat_set<not_null<GameData*>> _gamesUpdated;
915 	base::flat_set<not_null<PollData*>> _pollsUpdated;
916 
917 	rpl::event_stream<not_null<WebPageData*>> _webpageUpdates;
918 	rpl::event_stream<not_null<ChannelData*>> _channelDifferenceTooLong;
919 	base::flat_set<not_null<ChannelData*>> _suggestToGigagroup;
920 
921 	base::flat_multi_map<TimeId, not_null<PollData*>> _pollsClosings;
922 	base::Timer _pollsClosingTimer;
923 
924 	base::flat_map<FolderId, std::unique_ptr<Folder>> _folders;
925 
926 	std::unordered_map<
927 		not_null<const HistoryItem*>,
928 		std::vector<not_null<ViewElement*>>> _views;
929 
930 	rpl::event_stream<> _pinnedDialogsOrderUpdated;
931 
932 	base::flat_set<not_null<ViewElement*>> _heavyViewParts;
933 
934 	base::flat_map<uint64, not_null<GroupCall*>> _groupCalls;
935 	rpl::event_stream<InviteToCall> _invitesToCalls;
936 	base::flat_map<uint64, base::flat_set<not_null<UserData*>>> _invitedToCallUsers;
937 
938 	History *_topPromoted = nullptr;
939 
940 	NotifySettings _defaultUserNotifySettings;
941 	NotifySettings _defaultChatNotifySettings;
942 	NotifySettings _defaultBroadcastNotifySettings;
943 	rpl::event_stream<> _defaultUserNotifyUpdates;
944 	rpl::event_stream<> _defaultChatNotifyUpdates;
945 	rpl::event_stream<> _defaultBroadcastNotifyUpdates;
946 	std::unordered_set<not_null<const PeerData*>> _mutedPeers;
947 	base::Timer _unmuteByFinishedTimer;
948 
949 	std::unordered_map<PeerId, std::unique_ptr<PeerData>> _peers;
950 
951 	MessageIdsList _mimeForwardIds;
952 
953 	using CredentialsWithGeneration = std::pair<
954 		const Passport::SavedCredentials,
955 		int>;
956 	std::unique_ptr<CredentialsWithGeneration> _passportCredentials;
957 
958 	std::vector<WallPaper> _wallpapers;
959 	uint64 _wallpapersHash = 0;
960 
961 	Groups _groups;
962 	std::unique_ptr<ChatFilters> _chatsFilters;
963 	std::unique_ptr<ScheduledMessages> _scheduledMessages;
964 	std::unique_ptr<CloudThemes> _cloudThemes;
965 	std::unique_ptr<SendActionManager> _sendActionManager;
966 	std::unique_ptr<Streaming> _streaming;
967 	std::unique_ptr<MediaRotation> _mediaRotation;
968 	std::unique_ptr<Histories> _histories;
969 	std::unique_ptr<Stickers> _stickers;
970 	std::unique_ptr<SponsoredMessages> _sponsoredMessages;
971 	MsgId _nonHistoryEntryId = ServerMaxMsgId;
972 
973 	rpl::lifetime _lifetime;
974 
975 };
976 
977 } // namespace Data
978