/* 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/stickers/data_stickers_set.h" #include "ui/text/custom_emoji_instance.h" #include "base/timer.h" #include "base/weak_ptr.h" struct StickerSetIdentifier; namespace Main { class Session; } // namespace Main namespace Data { class Session; class CustomEmojiLoader; struct CustomEmojiId { DocumentId id = 0; }; class CustomEmojiManager final : public base::has_weak_ptr { public: enum class SizeTag { Normal, Large, Isolated, kCount, }; CustomEmojiManager(not_null owner); ~CustomEmojiManager(); [[nodiscard]] std::unique_ptr create( QStringView data, Fn update, SizeTag tag = SizeTag::Normal); [[nodiscard]] std::unique_ptr create( DocumentId documentId, Fn update, SizeTag tag = SizeTag::Normal); [[nodiscard]] std::unique_ptr create( not_null document, Fn update, SizeTag tag = SizeTag::Normal); class Listener { public: virtual void customEmojiResolveDone( not_null document) = 0; }; void resolve(QStringView data, not_null listener); void resolve(DocumentId documentId, not_null listener); void unregisterListener(not_null listener); [[nodiscard]] std::unique_ptr createLoader( not_null document, SizeTag tag); [[nodiscard]] std::unique_ptr createLoader( DocumentId documentId, SizeTag tag); [[nodiscard]] QString lookupSetName(uint64 setId); [[nodiscard]] Main::Session &session() const; [[nodiscard]] Session &owner() const; private: static constexpr auto kSizeCount = int(SizeTag::kCount); struct RepaintBunch { crl::time when = 0; std::vector> instances; }; void request(); void requestFinished(); void repaintLater( not_null instance, Ui::CustomEmoji::RepaintRequest request); void scheduleRepaintTimer(); void invokeRepaints(); void requestSetFor(not_null document); [[nodiscard]] Ui::CustomEmoji::Preview prepareNonExactPreview( DocumentId documentId, SizeTag tag) const; template [[nodiscard]] std::unique_ptr create( DocumentId documentId, Fn update, SizeTag tag, LoaderFactory factory); [[nodiscard]] static int SizeIndex(SizeTag tag); const not_null _owner; std::array< base::flat_map< DocumentId, std::unique_ptr>, kSizeCount> _instances; std::array< base::flat_map< DocumentId, std::vector>>, kSizeCount> _loaders; base::flat_map< DocumentId, base::flat_set>> _resolvers; base::flat_map< not_null, base::flat_set> _listeners; base::flat_set _pendingForRequest; mtpRequestId _requestId = 0; base::flat_map _repaints; crl::time _repaintNext = 0; base::Timer _repaintTimer; bool _repaintTimerScheduled = false; bool _requestSetsScheduled = false; }; [[nodiscard]] int FrameSizeFromTag(CustomEmojiManager::SizeTag tag); [[nodiscard]] QString SerializeCustomEmojiId(const CustomEmojiId &id); [[nodiscard]] QString SerializeCustomEmojiId( not_null document); [[nodiscard]] CustomEmojiId ParseCustomEmojiData(QStringView data); [[nodiscard]] bool AllowEmojiWithoutPremium(not_null peer); void InsertCustomEmoji( not_null field, not_null document); } // namespace Data