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 "base/value_ordering.h"
11 #include "ui/text/text.h" // For QFIXED_MAX
12 #include "data/data_peer_id.h"
13 #include "data/data_msg_id.h"
14 
15 class HistoryItem;
16 using HistoryItemsList = std::vector<not_null<HistoryItem*>>;
17 
18 class StorageImageLocation;
19 class WebFileLocation;
20 struct GeoPointLocation;
21 
22 namespace Storage {
23 namespace Cache {
24 struct Key;
25 } // namespace Cache
26 } // namespace Storage
27 
28 namespace Ui {
29 class InputField;
30 } // namespace Ui
31 
32 namespace Images {
33 enum class Option;
34 using Options = base::flags<Option>;
35 } // namespace Images
36 
37 namespace Data {
38 
39 struct UploadState {
UploadStateUploadState40 	UploadState(int size) : size(size) {
41 	}
42 	int offset = 0;
43 	int size = 0;
44 	bool waitingForAlbum = false;
45 };
46 
47 Storage::Cache::Key DocumentCacheKey(int32 dcId, uint64 id);
48 Storage::Cache::Key DocumentThumbCacheKey(int32 dcId, uint64 id);
49 Storage::Cache::Key WebDocumentCacheKey(const WebFileLocation &location);
50 Storage::Cache::Key UrlCacheKey(const QString &location);
51 Storage::Cache::Key GeoPointCacheKey(const GeoPointLocation &location);
52 
53 constexpr auto kImageCacheTag = uint8(0x01);
54 constexpr auto kStickerCacheTag = uint8(0x02);
55 constexpr auto kVoiceMessageCacheTag = uint8(0x03);
56 constexpr auto kVideoMessageCacheTag = uint8(0x04);
57 constexpr auto kAnimationCacheTag = uint8(0x05);
58 
59 struct FileOrigin;
60 
61 } // namespace Data
62 
63 struct MessageGroupId {
64 	PeerId peer = 0;
65 	uint64 value = 0;
66 
67 	MessageGroupId() = default;
FromRawMessageGroupId68 	static MessageGroupId FromRaw(PeerId peer, uint64 value) {
69 		auto result = MessageGroupId();
70 		result.peer = peer;
71 		result.value = value;
72 		return result;
73 	}
74 
emptyMessageGroupId75 	bool empty() const {
76 		return !value;
77 	}
78 	explicit operator bool() const {
79 		return !empty();
80 	}
rawMessageGroupId81 	uint64 raw() const {
82 		return value;
83 	}
84 
value_ordering_helperMessageGroupId85 	friend inline std::pair<uint64, uint64> value_ordering_helper(MessageGroupId value) {
86 		return std::make_pair(value.value, value.peer.value);
87 	}
88 
89 };
90 
91 class PeerData;
92 class UserData;
93 class ChatData;
94 class ChannelData;
95 struct BotCommand;
96 struct BotInfo;
97 
98 namespace Data {
99 class Folder;
100 } // namespace Data
101 
102 using FolderId = int32;
103 using FilterId = int32;
104 
105 using MessageIdsList = std::vector<FullMsgId>;
106 
107 PeerId PeerFromMessage(const MTPmessage &message);
108 MTPDmessage::Flags FlagsFromMessage(const MTPmessage &message);
109 MsgId IdFromMessage(const MTPmessage &message);
110 TimeId DateFromMessage(const MTPmessage &message);
111 
MTP_int(MsgId id)112 [[nodiscard]] inline MTPint MTP_int(MsgId id) noexcept {
113 	return MTP_int(id.bare);
114 }
115 
116 class DocumentData;
117 class PhotoData;
118 struct WebPageData;
119 struct GameData;
120 struct PollData;
121 
122 using PhotoId = uint64;
123 using VideoId = uint64;
124 using AudioId = uint64;
125 using DocumentId = uint64;
126 using WebPageId = uint64;
127 using GameId = uint64;
128 using PollId = uint64;
129 using WallPaperId = uint64;
130 using CallId = uint64;
131 constexpr auto CancelledWebPageId = WebPageId(0xFFFFFFFFFFFFFFFFULL);
132 
133 struct PreparedPhotoThumb {
134 	QImage image;
135 	QByteArray bytes;
136 };
137 using PreparedPhotoThumbs = base::flat_map<char, PreparedPhotoThumb>;
138 
139 // [0] == -1 -- counting, [0] == -2 -- could not count
140 using VoiceWaveform = QVector<signed char>;
141 
142 enum LocationType {
143 	UnknownFileLocation = 0,
144 	// 1, 2, etc are used as "version" value in mediaKey() method.
145 
146 	DocumentFileLocation = 0x4e45abe9, // mtpc_inputDocumentFileLocation
147 	AudioFileLocation = 0x74dc404d, // mtpc_inputAudioFileLocation
148 	VideoFileLocation = 0x3d0364ec, // mtpc_inputVideoFileLocation
149 	SecureFileLocation = 0xcbc7ee28, // mtpc_inputSecureFileLocation
150 };
151 
152 enum FileStatus {
153 	FileDownloadFailed = -2,
154 	FileUploadFailed = -1,
155 	FileReady = 1,
156 };
157 
158 // Don't change the values. This type is used for serialization.
159 enum DocumentType {
160 	FileDocument = 0,
161 	VideoDocument = 1,
162 	SongDocument = 2,
163 	StickerDocument = 3,
164 	AnimatedDocument = 4,
165 	VoiceDocument = 5,
166 	RoundVideoDocument = 6,
167 	WallPaperDocument = 7,
168 };
169 
170 inline constexpr auto kStickerSideSize = 512;
171 [[nodiscard]] bool GoodStickerDimensions(int width, int height);
172 
173 using MediaKey = QPair<uint64, uint64>;
174 
175 struct MessageCursor {
176 	MessageCursor() = default;
MessageCursorMessageCursor177 	MessageCursor(int position, int anchor, int scroll)
178 	: position(position)
179 	, anchor(anchor)
180 	, scroll(scroll) {
181 	}
MessageCursorMessageCursor182 	MessageCursor(not_null<const Ui::InputField*> field) {
183 		fillFrom(field);
184 	}
185 
186 	void fillFrom(not_null<const Ui::InputField*> field);
187 	void applyTo(not_null<Ui::InputField*> field);
188 
189 	int position = 0;
190 	int anchor = 0;
191 	int scroll = QFIXED_MAX;
192 
193 };
194 
195 inline bool operator==(
196 		const MessageCursor &a,
197 		const MessageCursor &b) {
198 	return (a.position == b.position)
199 		&& (a.anchor == b.anchor)
200 		&& (a.scroll == b.scroll);
201 }
202 
203 inline bool operator!=(
204 		const MessageCursor &a,
205 		const MessageCursor &b) {
206 	return !(a == b);
207 }
208 
209 struct StickerSetIdentifier {
210 	uint64 id = 0;
211 	uint64 accessHash = 0;
212 	QString shortName;
213 
emptyStickerSetIdentifier214 	[[nodiscard]] bool empty() const {
215 		return !id && shortName.isEmpty();
216 	}
217 	[[nodiscard]] explicit operator bool() const {
218 		return !empty();
219 	}
220 };
221 
222 enum class MessageFlag : uint32 {
223 	HideEdited            = (1U << 0),
224 	Legacy                = (1U << 1),
225 	HasReplyMarkup        = (1U << 2),
226 	HasFromId             = (1U << 3),
227 	HasPostAuthor         = (1U << 4),
228 	HasViews              = (1U << 5),
229 	HasReplyInfo          = (1U << 6),
230 	HasViaBot             = (1U << 7),
231 	AdminLogEntry         = (1U << 8),
232 	Post                  = (1U << 9),
233 	Silent                = (1U << 10),
234 	Outgoing              = (1U << 11),
235 	Pinned                = (1U << 12),
236 	MediaIsUnread         = (1U << 13),
237 	MentionsMe            = (1U << 14),
238 	IsOrWasScheduled      = (1U << 15),
239 
240 	// Needs to return back to inline mode.
241 	HasSwitchInlineButton = (1U << 16),
242 
243 	// For "shared links" indexing.
244 	HasTextLinks          = (1U << 17),
245 
246 	// Group / channel create or migrate service message.
247 	IsGroupEssential      = (1U << 18),
248 
249 	// Edited media is generated on the client
250 	// and should not update media from server.
251 	IsLocalUpdateMedia    = (1U << 19),
252 
253 	// Sent from inline bot, need to re-set media when sent.
254 	FromInlineBot         = (1U << 20),
255 
256 	// Generated on the client side and should be unread.
257 	ClientSideUnread      = (1U << 21),
258 
259 	// In a supergroup.
260 	HasAdminBadge         = (1U << 22),
261 
262 	// Outgoing message that is being sent.
263 	BeingSent             = (1U << 23),
264 
265 	// Outgoing message and failed to be sent.
266 	SendingFailed         = (1U << 24),
267 
268 	// No media and only a several emoji text.
269 	IsolatedEmoji         = (1U << 25),
270 
271 	// Message existing in the message history.
272 	HistoryEntry          = (1U << 26),
273 
274 	// Local message, not existing on the server.
275 	Local                 = (1U << 27),
276 
277 	// Fake message for some UI element.
278 	FakeHistoryItem       = (1U << 28),
279 
280 	// Contact sign-up message, notification should be skipped for Silent.
281 	IsContactSignUp       = (1U << 29),
282 
283 	// In channels.
284 	IsSponsored           = (1U << 30),
285 };
is_flag_type(MessageFlag)286 inline constexpr bool is_flag_type(MessageFlag) { return true; }
287 using MessageFlags = base::flags<MessageFlag>;
288