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 "ui/text/text_isolated_emoji.h"
11 #include "ui/image/image.h"
12 #include "base/timer.h"
13 
14 #include <crl/crl_object_on_queue.h>
15 
16 class HistoryItem;
17 class DocumentData;
18 
19 namespace Main {
20 class Session;
21 } // namespace Main
22 
23 namespace Lottie {
24 struct ColorReplacements;
25 } // namespace Lottie
26 
27 namespace Ui {
28 namespace Text {
29 class String;
30 } // namespace Text
31 namespace Emoji {
32 class UniversalImages;
33 } // namespace Emoji
34 } // namespace Ui
35 
36 namespace Stickers {
37 
38 using IsolatedEmoji = Ui::Text::IsolatedEmoji;
39 
40 struct LargeEmojiImage {
41 	std::optional<Image> image;
42 	FnMut<void()> load;
43 
44 	[[nodiscard]] static QSize Size();
45 };
46 
47 class EmojiPack final {
48 public:
49 	struct Sticker {
50 		DocumentData *document = nullptr;
51 		const Lottie::ColorReplacements *replacements = nullptr;
52 
emptySticker53 		[[nodiscard]] bool empty() const {
54 			return (document == nullptr);
55 		}
56 		[[nodiscard]] explicit operator bool() const {
57 			return !empty();
58 		}
59 	};
60 
61 	explicit EmojiPack(not_null<Main::Session*> session);
62 	~EmojiPack();
63 
64 	bool add(not_null<HistoryItem*> item);
65 	void remove(not_null<const HistoryItem*> item);
66 
67 	[[nodiscard]] Sticker stickerForEmoji(const IsolatedEmoji &emoji);
68 	[[nodiscard]] std::shared_ptr<LargeEmojiImage> image(EmojiPtr emoji);
69 
70 	[[nodiscard]] auto animationsForEmoji(EmojiPtr emoji) const
71 		-> const base::flat_map<int, not_null<DocumentData*>> &;
72 
73 private:
74 	class ImageLoader;
75 
76 	void refresh();
77 	void refreshDelayed();
78 	void refreshAnimations();
79 	void applySet(const MTPDmessages_stickerSet &data);
80 	void applyPack(
81 		const MTPDstickerPack &data,
82 		const base::flat_map<uint64, not_null<DocumentData*>> &map);
83 	void applyAnimationsSet(const MTPDmessages_stickerSet &data);
84 	[[nodiscard]] auto collectStickers(const QVector<MTPDocument> &list) const
85 		-> base::flat_map<uint64, not_null<DocumentData*>>;
86 	[[nodiscard]] auto collectAnimationsIndices(
87 		const QVector<MTPStickerPack> &packs) const
88 		-> base::flat_map<uint64, base::flat_set<int>>;
89 	void refreshAll();
90 	void refreshItems(EmojiPtr emoji);
91 	void refreshItems(const base::flat_set<not_null<HistoryItem*>> &list);
92 
93 	not_null<Main::Session*> _session;
94 	base::flat_map<EmojiPtr, not_null<DocumentData*>> _map;
95 	base::flat_map<
96 		IsolatedEmoji,
97 		base::flat_set<not_null<HistoryItem*>>> _items;
98 	base::flat_map<EmojiPtr, std::weak_ptr<LargeEmojiImage>> _images;
99 	mtpRequestId _requestId = 0;
100 
101 	base::flat_map<
102 		EmojiPtr,
103 		base::flat_map<int, not_null<DocumentData*>>> _animations;
104 	mtpRequestId _animationsRequestId = 0;
105 
106 	rpl::lifetime _lifetime;
107 
108 };
109 
110 } // namespace Stickers
111