File: api_updates.h

package info (click to toggle)
telegram-desktop 4.6.5%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 53,300 kB
  • sloc: cpp: 605,857; python: 3,978; ansic: 1,636; sh: 965; makefile: 841; objc: 652; javascript: 187; xml: 165
file content (214 lines) | stat: -rw-r--r-- 5,910 bytes parent folder | download | duplicates (2)
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