/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "storage/storage_databases.h" #include "dialogs/dialogs_key.h" #include "dialogs/dialogs_indexed_list.h" #include "dialogs/dialogs_main_list.h" #include "data/data_groups.h" #include "data/data_cloud_file.h" #include "data/data_notify_settings.h" #include "history/history_location_manager.h" #include "base/timer.h" #include "base/flags.h" #include "ui/effects/animations.h" class Image; class HistoryItem; class HistoryMessage; class HistoryService; struct WebPageCollage; enum class WebPageType; enum class NewMessageType; namespace HistoryView { struct Group; class Element; class ElementDelegate; class SendActionPainter; } // namespace HistoryView namespace Main { class Session; } // namespace Main namespace Ui { class BoxContent; } // namespace Ui namespace Passport { struct SavedCredentials; } // namespace Passport namespace Data { class Folder; class LocationPoint; class WallPaper; class ScheduledMessages; class ChatFilters; class CloudThemes; class Streaming; class MediaRotation; class Histories; class DocumentMedia; class PhotoMedia; class Stickers; class GroupCall; class Session final { public: using ViewElement = HistoryView::Element; struct SentData { PeerId peerId = 0; QString text; }; explicit Session(not_null session); ~Session(); [[nodiscard]] Main::Session &session() const { return *_session; } [[nodiscard]] QString nameSortKey(const QString &name) const; [[nodiscard]] Groups &groups() { return _groups; } [[nodiscard]] const Groups &groups() const { return _groups; } [[nodiscard]] ChatFilters &chatsFilters() const { return *_chatsFilters; } [[nodiscard]] ScheduledMessages &scheduledMessages() const { return *_scheduledMessages; } [[nodiscard]] CloudThemes &cloudThemes() const { return *_cloudThemes; } [[nodiscard]] Streaming &streaming() const { return *_streaming; } [[nodiscard]] MediaRotation &mediaRotation() const { return *_mediaRotation; } [[nodiscard]] Histories &histories() const { return *_histories; } [[nodiscard]] Stickers &stickers() const { return *_stickers; } [[nodiscard]] MsgId nextNonHistoryEntryId() { return ++_nonHistoryEntryId; } void clear(); void keepAlive(std::shared_ptr media); void keepAlive(std::shared_ptr media); void suggestStartExport(TimeId availableAt); void clearExportSuggestion(); [[nodiscard]] auto passportCredentials() const -> const Passport::SavedCredentials*; void rememberPassportCredentials( Passport::SavedCredentials data, crl::time rememberFor); void forgetPassportCredentials(); [[nodiscard]] Storage::Cache::Database &cache(); [[nodiscard]] Storage::Cache::Database &cacheBigFile(); [[nodiscard]] not_null peer(PeerId id); [[nodiscard]] not_null peer(UserId id) = delete; [[nodiscard]] not_null user(UserId id); [[nodiscard]] not_null chat(ChatId id); [[nodiscard]] not_null channel(ChannelId id); [[nodiscard]] not_null user(PeerId id) = delete; [[nodiscard]] not_null chat(PeerId id) = delete; [[nodiscard]] not_null channel(PeerId id) = delete; [[nodiscard]] PeerData *peerLoaded(PeerId id) const; [[nodiscard]] PeerData *peerLoaded(UserId id) const = delete; [[nodiscard]] UserData *userLoaded(UserId id) const; [[nodiscard]] ChatData *chatLoaded(ChatId id) const; [[nodiscard]] ChannelData *channelLoaded(ChannelId id) const; [[nodiscard]] UserData *userLoaded(PeerId id) const = delete; [[nodiscard]] ChatData *chatLoaded(PeerId id) const = delete; [[nodiscard]] ChannelData *channelLoaded(PeerId id) const = delete; not_null processUser(const MTPUser &data); not_null processChat(const MTPChat &data); // Returns last user, if there were any. UserData *processUsers(const MTPVector &data); PeerData *processChats(const MTPVector &data); void applyMaximumChatVersions(const MTPVector &data); void registerGroupCall(not_null call); void unregisterGroupCall(not_null call); GroupCall *groupCall(uint64 callId) const; [[nodiscard]] auto invitedToCallUsers(uint64 callId) const -> const base::flat_set> &; void registerInvitedToCallUser( uint64 callId, not_null peer, not_null user); void unregisterInvitedToCallUser(uint64 callId, not_null user); struct InviteToCall { uint64 id = 0; not_null user; }; [[nodiscard]] rpl::producer invitesToCalls() const { return _invitesToCalls.events(); } void enumerateUsers(Fn)> action) const; void enumerateGroups(Fn)> action) const; void enumerateChannels(Fn)> action) const; [[nodiscard]] PeerData *peerByUsername(const QString &username) const; [[nodiscard]] not_null history(PeerId peerId); [[nodiscard]] History *historyLoaded(PeerId peerId) const; [[nodiscard]] not_null history(UserId userId) = delete; [[nodiscard]] History *historyLoaded(UserId userId) const = delete; [[nodiscard]] not_null history(not_null peer); [[nodiscard]] History *historyLoaded(const PeerData *peer); void deleteConversationLocally(not_null peer); void cancelForwarding(not_null history); void registerSendAction( not_null history, MsgId rootId, not_null user, const MTPSendMessageAction &action, TimeId when); [[nodiscard]] rpl::variable &contactsLoaded() { return _contactsLoaded; } [[nodiscard]] rpl::producer chatsListChanges() const { return _chatsListChanged.events(); } [[nodiscard]] bool chatsListLoaded(Data::Folder *folder = nullptr); [[nodiscard]] rpl::producer chatsListLoadedEvents() const { return _chatsListLoadedEvents.events(); } void chatsListChanged(FolderId folderId); void chatsListChanged(Data::Folder *folder); void chatsListDone(Data::Folder *folder); void userIsBotChanged(not_null user); [[nodiscard]] rpl::producer> userIsBotChanges() const; void botCommandsChanged(not_null peer); [[nodiscard]] rpl::producer> botCommandsChanges() const; struct ItemVisibilityQuery { not_null item; not_null isVisible; }; [[nodiscard]] base::Observable &queryItemVisibility() { return _queryItemVisibility; } struct IdChange { not_null item; MsgId oldId = 0; }; void notifyItemIdChange(IdChange event); [[nodiscard]] rpl::producer itemIdChanged() const; void notifyItemLayoutChange(not_null item); [[nodiscard]] rpl::producer> itemLayoutChanged() const; void notifyViewLayoutChange(not_null view); [[nodiscard]] rpl::producer> viewLayoutChanged() const; void notifyNewItemAdded(not_null item); [[nodiscard]] rpl::producer> newItemAdded() const; void requestItemRepaint(not_null item); [[nodiscard]] rpl::producer> itemRepaintRequest() const; void requestViewRepaint(not_null view); [[nodiscard]] rpl::producer> viewRepaintRequest() const; void requestItemResize(not_null item); [[nodiscard]] rpl::producer> itemResizeRequest() const; void requestViewResize(not_null view); [[nodiscard]] rpl::producer> viewResizeRequest() const; void requestItemViewRefresh(not_null item); [[nodiscard]] rpl::producer> itemViewRefreshRequest() const; void requestItemTextRefresh(not_null item); void requestAnimationPlayInline(not_null item); [[nodiscard]] rpl::producer> animationPlayInlineRequest() const; void notifyHistoryUnloaded(not_null history); [[nodiscard]] rpl::producer> historyUnloaded() const; [[nodiscard]] rpl::producer> itemRemoved() const; [[nodiscard]] rpl::producer> itemRemoved( FullMsgId itemId) const; void notifyViewRemoved(not_null view); [[nodiscard]] rpl::producer> viewRemoved() const; void notifyHistoryCleared(not_null history); [[nodiscard]] rpl::producer> historyCleared() const; void notifyHistoryChangeDelayed(not_null history); [[nodiscard]] rpl::producer> historyChanged() const; void sendHistoryChangeNotifications(); void notifyPinnedDialogsOrderUpdated(); [[nodiscard]] rpl::producer<> pinnedDialogsOrderUpdated() const; void registerHeavyViewPart(not_null view); void unregisterHeavyViewPart(not_null view); void unloadHeavyViewParts( not_null delegate); void unloadHeavyViewParts( not_null delegate, int from, int till); using MegagroupParticipant = std::tuple< not_null, not_null>; void removeMegagroupParticipant( not_null channel, not_null user); [[nodiscard]] rpl::producer megagroupParticipantRemoved() const; [[nodiscard]] rpl::producer> megagroupParticipantRemoved( not_null channel) const; void addNewMegagroupParticipant( not_null channel, not_null user); [[nodiscard]] rpl::producer megagroupParticipantAdded() const; [[nodiscard]] rpl::producer> megagroupParticipantAdded( not_null channel) const; HistoryItemsList idsToItems(const MessageIdsList &ids) const; MessageIdsList itemsToIds(const HistoryItemsList &items) const; MessageIdsList itemOrItsGroup(not_null item) const; void applyUpdate(const MTPDupdateMessagePoll &update); void applyUpdate(const MTPDupdateChatParticipants &update); void applyUpdate(const MTPDupdateChatParticipantAdd &update); void applyUpdate(const MTPDupdateChatParticipantDelete &update); void applyUpdate(const MTPDupdateChatParticipantAdmin &update); void applyUpdate(const MTPDupdateChatDefaultBannedRights &update); void applyDialogs( Data::Folder *requestFolder, const QVector &messages, const QVector &dialogs, std::optional count = std::nullopt); int pinnedChatsCount(Data::Folder *folder, FilterId filterId) const; int pinnedChatsLimit(Data::Folder *folder, FilterId filterId) const; const std::vector &pinnedChatsOrder( Data::Folder *folder, FilterId filterId) const; void setChatPinned( const Dialogs::Key &key, FilterId filterId, bool pinned); void clearPinnedChats(Data::Folder *folder); void applyPinnedChats( Data::Folder *folder, const QVector &list); void reorderTwoPinnedChats( FilterId filterId, const Dialogs::Key &key1, const Dialogs::Key &key2); void setSuggestToGigagroup(not_null group, bool suggest); [[nodiscard]] bool suggestToGigagroup( not_null group) const; void registerMessage(not_null item); void unregisterMessage(not_null item); void registerMessageTTL(TimeId when, not_null item); void unregisterMessageTTL(TimeId when, not_null item); // Returns true if item found and it is not detached. bool checkEntitiesAndViewsUpdate(const MTPDmessage &data); void updateEditedMessage(const MTPMessage &data); void processMessages( const QVector &data, NewMessageType type); void processMessages( const MTPVector &data, NewMessageType type); void processMessagesDeleted( ChannelId channelId, const QVector &data); [[nodiscard]] MsgId nextLocalMessageId(); [[nodiscard]] HistoryItem *message( ChannelId channelId, MsgId itemId) const; [[nodiscard]] HistoryItem *message( const ChannelData *channel, MsgId itemId) const; [[nodiscard]] HistoryItem *message(FullMsgId itemId) const; void updateDependentMessages(not_null item); void registerDependentMessage( not_null dependent, not_null dependency); void unregisterDependentMessage( not_null dependent, not_null dependency); void destroyAllCallItems(); void registerMessageRandomId(uint64 randomId, FullMsgId itemId); void unregisterMessageRandomId(uint64 randomId); [[nodiscard]] FullMsgId messageIdByRandomId(uint64 randomId) const; void registerMessageSentData( uint64 randomId, PeerId peerId, const QString &text); void unregisterMessageSentData(uint64 randomId); [[nodiscard]] SentData messageSentData(uint64 randomId) const; void photoLoadSettingsChanged(); void documentLoadSettingsChanged(); void notifyPhotoLayoutChanged(not_null photo); void requestPhotoViewRepaint(not_null photo); void notifyDocumentLayoutChanged( not_null document); void requestDocumentViewRepaint(not_null document); void markMediaRead(not_null document); void requestPollViewRepaint(not_null poll); void photoLoadProgress(not_null photo); void photoLoadDone(not_null photo); void photoLoadFail(not_null photo, bool started); void documentLoadProgress(not_null document); void documentLoadDone(not_null document); void documentLoadFail(not_null document, bool started); HistoryItem *addNewMessage( const MTPMessage &data, MessageFlags localFlags, NewMessageType type); struct SendActionAnimationUpdate { not_null history; int width = 0; int height = 0; bool textUpdated = false; }; [[nodiscard]] auto sendActionAnimationUpdated() const -> rpl::producer; void updateSendActionAnimation(SendActionAnimationUpdate &&update); [[nodiscard]] auto speakingAnimationUpdated() const -> rpl::producer>; void updateSpeakingAnimation(not_null history); using SendActionPainter = HistoryView::SendActionPainter; [[nodiscard]] std::shared_ptr repliesSendActionPainter( not_null history, MsgId rootId); void repliesSendActionPainterRemoved( not_null history, MsgId rootId); void repliesSendActionPaintersClear( not_null history, not_null user); [[nodiscard]] int unreadBadge() const; [[nodiscard]] bool unreadBadgeMuted() const; [[nodiscard]] int unreadBadgeIgnoreOne(const Dialogs::Key &key) const; [[nodiscard]] bool unreadBadgeMutedIgnoreOne(const Dialogs::Key &key) const; [[nodiscard]] int unreadOnlyMutedBadge() const; [[nodiscard]] rpl::producer<> unreadBadgeChanges() const; void notifyUnreadBadgeChanged(); void selfDestructIn(not_null item, crl::time delay); [[nodiscard]] not_null photo(PhotoId id); not_null processPhoto(const MTPPhoto &data); not_null processPhoto(const MTPDphoto &data); not_null processPhoto( const MTPPhoto &data, const PreparedPhotoThumbs &thumbs); [[nodiscard]] not_null photo( PhotoId id, const uint64 &access, const QByteArray &fileReference, TimeId date, int32 dc, bool hasStickers, const QByteArray &inlineThumbnailBytes, const ImageWithLocation &small, const ImageWithLocation &thumbnail, const ImageWithLocation &large, const ImageWithLocation &video, crl::time videoStartTime); void photoConvert( not_null original, const MTPPhoto &data); [[nodiscard]] PhotoData *photoFromWeb( const MTPWebDocument &data, const ImageLocation &thumbnailLocation); [[nodiscard]] not_null document(DocumentId id); not_null processDocument(const MTPDocument &data); not_null processDocument(const MTPDdocument &data); not_null processDocument( const MTPdocument &data, const ImageWithLocation &thumbnail); [[nodiscard]] not_null document( DocumentId id, const uint64 &access, const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, const InlineImageLocation &inlineThumbnail, const ImageWithLocation &thumbnail, const ImageWithLocation &videoThumbnail, int32 dc, int32 size); void documentConvert( not_null original, const MTPDocument &data); [[nodiscard]] DocumentData *documentFromWeb( const MTPWebDocument &data, const ImageLocation &thumbnailLocation, const ImageLocation &videoThumbnailLocation); [[nodiscard]] not_null webpage(WebPageId id); not_null processWebpage(const MTPWebPage &data); not_null processWebpage(const MTPDwebPage &data); not_null processWebpage(const MTPDwebPagePending &data); [[nodiscard]] not_null webpage( WebPageId id, const QString &siteName, const TextWithEntities &content); [[nodiscard]] not_null webpage( WebPageId id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, WebPageCollage &&collage, int duration, const QString &author, TimeId pendingTill); [[nodiscard]] not_null game(GameId id); not_null processGame(const MTPDgame &data); [[nodiscard]] not_null game( GameId id, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document); void gameConvert( not_null original, const MTPGame &data); [[nodiscard]] not_null poll(PollId id); not_null processPoll(const MTPPoll &data); not_null processPoll(const MTPDmessageMediaPoll &data); [[nodiscard]] not_null location( const LocationPoint &point); void registerPhotoItem( not_null photo, not_null item); void unregisterPhotoItem( not_null photo, not_null item); void registerDocumentItem( not_null document, not_null item); void unregisterDocumentItem( not_null document, not_null item); void registerWebPageView( not_null page, not_null view); void unregisterWebPageView( not_null page, not_null view); void registerWebPageItem( not_null page, not_null item); void unregisterWebPageItem( not_null page, not_null item); void registerGameView( not_null game, not_null view); void unregisterGameView( not_null game, not_null view); void registerPollView( not_null poll, not_null view); void unregisterPollView( not_null poll, not_null view); void registerContactView( UserId contactId, not_null view); void unregisterContactView( UserId contactId, not_null view); void registerContactItem( UserId contactId, not_null item); void unregisterContactItem( UserId contactId, not_null item); void registerCallItem(not_null item); void unregisterCallItem(not_null item); void documentMessageRemoved(not_null document); void checkPlayingAnimations(); HistoryItem *findWebPageItem(not_null page) const; QString findContactPhone(not_null contact) const; QString findContactPhone(UserId contactId) const; void notifyWebPageUpdateDelayed(not_null page); void notifyGameUpdateDelayed(not_null game); void notifyPollUpdateDelayed(not_null poll); [[nodiscard]] bool hasPendingWebPageGamePollNotification() const; void sendWebPageGamePollNotifications(); [[nodiscard]] rpl::producer> webPageUpdates() const; void channelDifferenceTooLong(not_null channel); [[nodiscard]] rpl::producer> channelDifferenceTooLong() const; void registerItemView(not_null view); void unregisterItemView(not_null view); [[nodiscard]] not_null folder(FolderId id); [[nodiscard]] Folder *folderLoaded(FolderId id) const; not_null processFolder(const MTPFolder &data); not_null processFolder(const MTPDfolder &data); [[nodiscard]] not_null chatsList( Data::Folder *folder = nullptr); [[nodiscard]] not_null chatsList( Data::Folder *folder = nullptr) const; [[nodiscard]] not_null contactsList(); [[nodiscard]] not_null contactsNoChatsList(); struct ChatListEntryRefresh { Dialogs::Key key; Dialogs::PositionChange moved; FilterId filterId = 0; bool existenceChanged = false; explicit operator bool() const { return existenceChanged || (moved.from != moved.to); } }; void refreshChatListEntry(Dialogs::Key key); void removeChatListEntry(Dialogs::Key key); [[nodiscard]] auto chatListEntryRefreshes() const -> rpl::producer; struct DialogsRowReplacement { not_null old; Dialogs::Row *now = nullptr; }; void dialogsRowReplaced(DialogsRowReplacement replacement); rpl::producer dialogsRowReplacements() const; void requestNotifySettings(not_null peer); void applyNotifySetting( const MTPNotifyPeer ¬ifyPeer, const MTPPeerNotifySettings &settings); void updateNotifySettings( not_null peer, std::optional muteForSeconds, std::optional silentPosts = std::nullopt); void resetNotifySettingsToDefault(not_null peer); bool notifyIsMuted( not_null peer, crl::time *changesIn = nullptr) const; bool notifySilentPosts(not_null peer) const; bool notifyMuteUnknown(not_null peer) const; bool notifySilentPostsUnknown(not_null peer) const; bool notifySettingsUnknown(not_null peer) const; rpl::producer<> defaultUserNotifyUpdates() const; rpl::producer<> defaultChatNotifyUpdates() const; rpl::producer<> defaultBroadcastNotifyUpdates() const; rpl::producer<> defaultNotifyUpdates( not_null peer) const; void serviceNotification( const TextWithEntities &message, const MTPMessageMedia &media = MTP_messageMediaEmpty()); void setMimeForwardIds(MessageIdsList &&list); MessageIdsList takeMimeForwardIds(); void setTopPromoted( History *promoted, const QString &type, const QString &message); bool updateWallpapers(const MTPaccount_WallPapers &data); void removeWallpaper(const WallPaper &paper); const std::vector &wallpapers() const; int32 wallpapersHash() const; void clearLocalStorage(); private: using Messages = std::unordered_map>; void suggestStartExport(); void setupMigrationViewer(); void setupChannelLeavingViewer(); void setupPeerNameViewer(); void setupUserIsContactViewer(); void checkSelfDestructItems(); void scheduleNextTTLs(); void checkTTLs(); int computeUnreadBadge(const Dialogs::UnreadState &state) const; bool computeUnreadBadgeMuted(const Dialogs::UnreadState &state) const; void applyDialog(Data::Folder *requestFolder, const MTPDdialog &data); void applyDialog( Data::Folder *requestFolder, const MTPDdialogFolder &data); const Messages *messagesList(ChannelId channelId) const; not_null messagesListForInsert(ChannelId channelId); not_null registerMessage( std::unique_ptr item); void changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId); void removeDependencyMessage(not_null item); void photoApplyFields( not_null photo, const MTPPhoto &data); void photoApplyFields( not_null photo, const MTPDphoto &data); void photoApplyFields( not_null photo, const uint64 &access, const QByteArray &fileReference, TimeId date, int32 dc, bool hasStickers, const QByteArray &inlineThumbnailBytes, const ImageWithLocation &small, const ImageWithLocation &thumbnail, const ImageWithLocation &large, const ImageWithLocation &video, crl::time videoStartTime); void documentApplyFields( not_null document, const MTPDocument &data); void documentApplyFields( not_null document, const MTPDdocument &data); void documentApplyFields( not_null document, const uint64 &access, const QByteArray &fileReference, TimeId date, const QVector &attributes, const QString &mime, const InlineImageLocation &inlineThumbnail, const ImageWithLocation &thumbnail, const ImageWithLocation &videoThumbnail, int32 dc, int32 size); DocumentData *documentFromWeb( const MTPDwebDocument &data, const ImageLocation &thumbnailLocation, const ImageLocation &videoThumbnailLocation); DocumentData *documentFromWeb( const MTPDwebDocumentNoProxy &data, const ImageLocation &thumbnailLocation, const ImageLocation &videoThumbnailLocation); void webpageApplyFields( not_null page, const MTPDwebPage &data); void webpageApplyFields( not_null page, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, WebPageCollage &&collage, int duration, const QString &author, TimeId pendingTill); void gameApplyFields( not_null game, const MTPDgame &data); void gameApplyFields( not_null game, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document); void folderApplyFields( not_null folder, const MTPDfolder &data); void setPinnedFromDialog(const Dialogs::Key &key, bool pinned); NotifySettings &defaultNotifySettings(not_null peer); const NotifySettings &defaultNotifySettings( not_null peer) const; void unmuteByFinished(); void unmuteByFinishedDelayed(crl::time delay); void updateNotifySettingsLocal(not_null peer); template void enumerateItemViews( not_null item, Method method); void insertCheckedServiceNotification( const TextWithEntities &message, const MTPMessageMedia &media, TimeId date); bool sendActionsAnimationCallback(crl::time now); [[nodiscard]] SendActionPainter *lookupSendActionPainter( not_null history, MsgId rootId); void setWallpapers(const QVector &data, int32 hash); void checkPollsClosings(); const not_null _session; Storage::DatabasePointer _cache; Storage::DatabasePointer _bigFileCache; TimeId _exportAvailableAt = 0; QPointer _exportSuggestion; rpl::variable _contactsLoaded = false; rpl::event_stream _chatsListLoadedEvents; rpl::event_stream _chatsListChanged; rpl::event_stream> _userIsBotChanges; rpl::event_stream> _botCommandsChanges; base::Observable _queryItemVisibility; rpl::event_stream _itemIdChanges; rpl::event_stream> _itemLayoutChanges; rpl::event_stream> _viewLayoutChanges; rpl::event_stream> _newItemAdded; rpl::event_stream> _itemRepaintRequest; rpl::event_stream> _viewRepaintRequest; rpl::event_stream> _itemResizeRequest; rpl::event_stream> _viewResizeRequest; rpl::event_stream> _itemViewRefreshRequest; rpl::event_stream> _itemTextRefreshRequest; rpl::event_stream> _animationPlayInlineRequest; rpl::event_stream> _itemRemoved; rpl::event_stream> _viewRemoved; rpl::event_stream> _historyUnloaded; rpl::event_stream> _historyCleared; base::flat_set> _historiesChanged; rpl::event_stream> _historyChanged; rpl::event_stream _megagroupParticipantRemoved; rpl::event_stream _megagroupParticipantAdded; rpl::event_stream _dialogsRowReplacements; rpl::event_stream _chatListEntryRefreshes; rpl::event_stream<> _unreadBadgeChanges; Dialogs::MainList _chatsList; Dialogs::IndexedList _contactsList; Dialogs::IndexedList _contactsNoChatsList; MsgId _localMessageIdCounter = StartClientMsgId; Messages _messages; std::map _channelMessages; std::map< not_null, base::flat_set>> _dependentMessages; std::map>> _ttlMessages; base::Timer _ttlCheckTimer; base::flat_map _messageByRandomId; base::flat_map _sentMessagesData; base::Timer _selfDestructTimer; std::vector _selfDestructItems; // When typing in this history started. base::flat_map< std::pair, MsgId>, crl::time> _sendActions; Ui::Animations::Basic _sendActionsAnimation; std::unordered_map< PhotoId, std::unique_ptr> _photos; std::unordered_map< not_null, base::flat_set>> _photoItems; std::unordered_map< DocumentId, std::unique_ptr> _documents; std::unordered_map< not_null, base::flat_set>> _documentItems; std::unordered_map< WebPageId, std::unique_ptr> _webpages; std::unordered_map< not_null, base::flat_set>> _webpageItems; std::unordered_map< not_null, base::flat_set>> _webpageViews; std::unordered_map< LocationPoint, std::unique_ptr> _locations; std::unordered_map< PollId, std::unique_ptr> _polls; std::unordered_map< GameId, std::unique_ptr> _games; std::unordered_map< not_null, base::flat_set>> _gameViews; std::unordered_map< not_null, base::flat_set>> _pollViews; std::unordered_map< UserId, base::flat_set>> _contactItems; std::unordered_map< UserId, base::flat_set>> _contactViews; std::unordered_set> _callItems; base::flat_set> _webpagesUpdated; base::flat_set> _gamesUpdated; base::flat_set> _pollsUpdated; rpl::event_stream> _webpageUpdates; rpl::event_stream> _channelDifferenceTooLong; base::flat_set> _suggestToGigagroup; base::flat_multi_map> _pollsClosings; base::Timer _pollsClosingTimer; base::flat_map> _folders; std::unordered_map< not_null, std::vector>> _views; rpl::event_stream<> _pinnedDialogsOrderUpdated; base::flat_set> _heavyViewParts; base::flat_map> _groupCalls; rpl::event_stream _invitesToCalls; base::flat_map>> _invitedToCallUsers; History *_topPromoted = nullptr; NotifySettings _defaultUserNotifySettings; NotifySettings _defaultChatNotifySettings; NotifySettings _defaultBroadcastNotifySettings; rpl::event_stream<> _defaultUserNotifyUpdates; rpl::event_stream<> _defaultChatNotifyUpdates; rpl::event_stream<> _defaultBroadcastNotifyUpdates; std::unordered_set> _mutedPeers; base::Timer _unmuteByFinishedTimer; std::unordered_map> _peers; MessageIdsList _mimeForwardIds; using CredentialsWithGeneration = std::pair< const Passport::SavedCredentials, int>; std::unique_ptr _passportCredentials; rpl::event_stream _sendActionAnimationUpdate; rpl::event_stream> _speakingAnimationUpdate; std::vector _wallpapers; int32 _wallpapersHash = 0; Groups _groups; std::unique_ptr _chatsFilters; std::unique_ptr _scheduledMessages; std::unique_ptr _cloudThemes; std::unique_ptr _streaming; std::unique_ptr _mediaRotation; std::unique_ptr _histories; base::flat_map< not_null, base::flat_map< MsgId, std::weak_ptr>> _sendActionPainters; std::unique_ptr _stickers; MsgId _nonHistoryEntryId = ServerMaxMsgId; rpl::lifetime _lifetime; }; } // namespace Data