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_pts_waiter.h" 11 #include "base/timer.h" 12 13 class ApiWrap; 14 class History; 15 16 namespace MTP { 17 class Error; 18 } // namespace MTP 19 20 namespace Main { 21 class Session; 22 } // namespace Main 23 24 namespace ChatHelpers { 25 struct EmojiInteractionsBunch; 26 } // namespace ChatHelpers 27 28 namespace Api { 29 30 class Updates final { 31 public: 32 explicit Updates(not_null<Main::Session*> session); 33 34 [[nodiscard]] Main::Session &session() const; 35 [[nodiscard]] ApiWrap &api() const; 36 37 void applyUpdates( 38 const MTPUpdates &updates, 39 uint64 sentMessageRandomId = 0); 40 void applyUpdatesNoPtsCheck(const MTPUpdates &updates); 41 void applyUpdateNoPtsCheck(const MTPUpdate &update); 42 43 [[nodiscard]] int32 pts() const; 44 45 void updateOnline(crl::time lastNonIdleTime = 0); 46 [[nodiscard]] bool isIdle() const; 47 [[nodiscard]] rpl::producer<bool> isIdleValue() const; 48 void checkIdleFinish(crl::time lastNonIdleTime = 0); 49 bool lastWasOnline() const; 50 crl::time lastSetOnline() const; 51 bool isQuitPrevent(); 52 53 bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdates &updates); 54 bool updateAndApply(int32 pts, int32 ptsCount, const MTPUpdate &update); 55 bool updateAndApply(int32 pts, int32 ptsCount); 56 57 void checkLastUpdate(bool afterSleep); 58 59 // ms <= 0 - stop timer 60 void ptsWaiterStartTimerFor(ChannelData *channel, crl::time ms); 61 62 void getDifference(); 63 void requestChannelRangeDifference(not_null<History*> history); 64 65 void addActiveChat(rpl::producer<PeerData*> chat); 66 67 private: 68 enum class ChannelDifferenceRequest { 69 Unknown, 70 PtsGapOrShortPoll, 71 AfterFail, 72 }; 73 74 enum class SkipUpdatePolicy { 75 SkipNone, 76 SkipMessageIds, 77 SkipExceptGroupCallParticipants, 78 }; 79 80 struct ActiveChatTracker { 81 PeerData *peer = nullptr; 82 rpl::lifetime lifetime; 83 }; 84 85 void channelRangeDifferenceSend( 86 not_null<ChannelData*> channel, 87 MsgRange range, 88 int32 pts); 89 void channelRangeDifferenceDone( 90 not_null<ChannelData*> channel, 91 MsgRange range, 92 const MTPupdates_ChannelDifference &result); 93 94 void updateOnline(crl::time lastNonIdleTime, bool gotOtherOffline); 95 void sendPing(); 96 void getDifferenceByPts(); 97 void getDifferenceAfterFail(); 98 requestingDifference()99 [[nodiscard]] bool requestingDifference() const { 100 return _ptsWaiter.requesting(); 101 } 102 void getChannelDifference( 103 not_null<ChannelData*> channel, 104 ChannelDifferenceRequest from = ChannelDifferenceRequest::Unknown); 105 void differenceDone(const MTPupdates_Difference &result); 106 void differenceFail(const MTP::Error &error); 107 void feedDifference( 108 const MTPVector<MTPUser> &users, 109 const MTPVector<MTPChat> &chats, 110 const MTPVector<MTPMessage> &msgs, 111 const MTPVector<MTPUpdate> &other); 112 void stateDone(const MTPupdates_State &state); 113 void setState(int32 pts, int32 date, int32 qts, int32 seq); 114 void channelDifferenceDone( 115 not_null<ChannelData*> channel, 116 const MTPupdates_ChannelDifference &diff); 117 void channelDifferenceFail( 118 not_null<ChannelData*> channel, 119 const MTP::Error &error); 120 void failDifferenceStartTimerFor(ChannelData *channel); 121 void feedChannelDifference(const MTPDupdates_channelDifference &data); 122 123 void mtpUpdateReceived(const MTPUpdates &updates); 124 void mtpNewSessionCreated(); 125 void feedUpdateVector( 126 const MTPVector<MTPUpdate> &updates, 127 SkipUpdatePolicy policy = SkipUpdatePolicy::SkipNone); 128 // Doesn't call sendHistoryChangeNotifications itself. 129 void feedMessageIds(const MTPVector<MTPUpdate> &updates); 130 // Doesn't call sendHistoryChangeNotifications itself. 131 void feedUpdate(const MTPUpdate &update); 132 133 void applyGroupCallParticipantUpdates(const MTPUpdates &updates); 134 135 bool whenGetDiffChanged( 136 ChannelData *channel, 137 int32 ms, 138 base::flat_map<not_null<ChannelData*>, crl::time> &whenMap, 139 crl::time &curTime); 140 141 void handleSendActionUpdate( 142 PeerId peerId, 143 MsgId rootId, 144 PeerId fromId, 145 const MTPSendMessageAction &action); 146 void handleEmojiInteraction( 147 not_null<PeerData*> peer, 148 const MTPDsendMessageEmojiInteraction &data); 149 void handleSpeakingInCall( 150 not_null<PeerData*> peer, 151 PeerId participantPeerId, 152 PeerData *participantPeerLoaded); 153 void handleEmojiInteraction( 154 not_null<PeerData*> peer, 155 MsgId messageId, 156 const QString &emoticon, 157 ChatHelpers::EmojiInteractionsBunch bunch); 158 void handleEmojiInteraction( 159 not_null<PeerData*> peer, 160 const QString &emoticon); 161 162 const not_null<Main::Session*> _session; 163 164 int32 _updatesDate = 0; 165 int32 _updatesQts = -1; 166 int32 _updatesSeq = 0; 167 base::Timer _noUpdatesTimer; 168 base::Timer _onlineTimer; 169 170 PtsWaiter _ptsWaiter; 171 172 base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffByPts; 173 base::flat_map<not_null<ChannelData*>, crl::time> _whenGetDiffAfterFail; 174 crl::time _getDifferenceTimeByPts = 0; 175 crl::time _getDifferenceTimeAfterFail = 0; 176 177 base::Timer _byPtsTimer; 178 179 base::flat_map<int32, MTPUpdates> _bySeqUpdates; 180 base::Timer _bySeqTimer; 181 182 base::Timer _byMinChannelTimer; 183 184 // growing timeout for getDifference calls, if it fails 185 crl::time _failDifferenceTimeout = 1; 186 // growing timeout for getChannelDifference calls, if it fails 187 base::flat_map< 188 not_null<ChannelData*>, 189 crl::time> _channelFailDifferenceTimeout; 190 base::Timer _failDifferenceTimer; 191 192 base::flat_map< 193 not_null<ChannelData*>, 194 mtpRequestId> _rangeDifferenceRequests; 195 196 crl::time _lastUpdateTime = 0; 197 bool _handlingChannelDifference = false; 198 199 base::flat_map<int, ActiveChatTracker> _activeChats; 200 base::flat_map< 201 not_null<PeerData*>, 202 base::flat_map<PeerId, crl::time>> _pendingSpeakingCallParticipants; 203 204 mtpRequestId _onlineRequest = 0; 205 base::Timer _idleFinishTimer; 206 crl::time _lastSetOnline = 0; 207 bool _lastWasOnline = false; 208 rpl::variable<bool> _isIdle = false; 209 210 rpl::lifetime _lifetime; 211 212 }; 213 214 } // namespace Api 215