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