/* 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 "data/data_pts_waiter.h" #include "base/timer.h" class ApiWrap; class History; namespace MTP { class Error; } // namespace MTP namespace Main { class Session; } // namespace Main namespace Api { class Updates final { public: explicit Updates(not_null session); [[nodiscard]] Main::Session &session() const; [[nodiscard]] ApiWrap &api() const; void applyUpdates( const MTPUpdates &updates, uint64 sentMessageRandomId = 0); void applyUpdatesNoPtsCheck(const MTPUpdates &updates); void applyUpdateNoPtsCheck(const MTPUpdate &update); [[nodiscard]] int32 pts() const; void updateOnline(); [[nodiscard]] bool isIdle() const; [[nodiscard]] rpl::producer isIdleValue() const; void checkIdleFinish(); bool lastWasOnline() const; crl::time lastSetOnline() const; bool isQuitPrevent(); bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates); bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update); bool updateAndApply(int32 pts, int32 ptsCount); void checkLastUpdate(bool afterSleep); // ms <= 0 - stop timer void ptsWaiterStartTimerFor(ChannelData *channel, crl::time ms); void getDifference(); void requestChannelRangeDifference(not_null history); void addActiveChat(rpl::producer chat); private: enum class ChannelDifferenceRequest { Unknown, PtsGapOrShortPoll, AfterFail, }; enum class SkipUpdatePolicy { SkipNone, SkipMessageIds, SkipExceptGroupCallParticipants, }; struct ActiveChatTracker { PeerData *peer = nullptr; rpl::lifetime lifetime; }; void channelRangeDifferenceSend( not_null channel, MsgRange range, int32 pts); void channelRangeDifferenceDone( not_null channel, MsgRange range, const MTPupdates_ChannelDifference &result); void updateOnline(bool gotOtherOffline); void sendPing(); void getDifferenceByPts(); void getDifferenceAfterFail(); [[nodiscard]] bool requestingDifference() const { return _ptsWaiter.requesting(); } void getChannelDifference( not_null channel, ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown); void differenceDone(const MTPupdates_Difference &result); void differenceFail(const MTP::Error &error); void feedDifference( const MTPVector &users, const MTPVector &chats, const MTPVector &msgs, const MTPVector &other); void stateDone(const MTPupdates_State &state); void setState(int32 pts, int32 date, int32 qts, int32 seq); void channelDifferenceDone( not_null channel, const MTPupdates_ChannelDifference &diff); void channelDifferenceFail( not_null channel, const MTP::Error &error); void failDifferenceStartTimerFor(ChannelData *channel); void feedChannelDifference(const MTPDupdates_channelDifference &data); void mtpUpdateReceived(const MTPUpdates &updates); void mtpNewSessionCreated(); void feedUpdateVector( const MTPVector &updates, SkipUpdatePolicy policy = SkipUpdatePolicy::SkipNone); // Doesn't call sendHistoryChangeNotifications itself. void feedMessageIds(const MTPVector &updates); // Doesn't call sendHistoryChangeNotifications itself. void feedUpdate(const MTPUpdate &update); void applyGroupCallParticipantUpdates(const MTPUpdates &updates); bool whenGetDiffChanged( ChannelData *channel, int32 ms, base::flat_map, crl::time> &whenMap, crl::time &curTime); void handleSendActionUpdate( PeerId peerId, MsgId rootId, PeerId fromId, const MTPSendMessageAction &action); const not_null _session; int32 _updatesDate = 0; int32 _updatesQts = -1; int32 _updatesSeq = 0; base::Timer _noUpdatesTimer; base::Timer _onlineTimer; PtsWaiter _ptsWaiter; base::flat_map, crl::time> _whenGetDiffByPts; base::flat_map, crl::time> _whenGetDiffAfterFail; crl::time _getDifferenceTimeByPts = 0; crl::time _getDifferenceTimeAfterFail = 0; base::Timer _byPtsTimer; base::flat_map _bySeqUpdates; base::Timer _bySeqTimer; base::Timer _byMinChannelTimer; // growing timeout for getDifference calls, if it fails crl::time _failDifferenceTimeout = 1; // growing timeout for getChannelDifference calls, if it fails base::flat_map< not_null, crl::time> _channelFailDifferenceTimeout; base::Timer _failDifferenceTimer; base::flat_map< not_null, mtpRequestId> _rangeDifferenceRequests; crl::time _lastUpdateTime = 0; bool _handlingChannelDifference = false; base::flat_map _activeChats; base::flat_map< not_null, base::flat_map> _pendingSpeakingCallParticipants; mtpRequestId _onlineRequest = 0; base::Timer _idleFinishTimer; crl::time _lastSetOnline = 0; bool _lastWasOnline = false; rpl::variable _isIdle = false; rpl::lifetime _lifetime; }; } // namespace Api