/* 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 "base/timer.h" #include "history/history_item.h" #include "ui/image/image_location.h" #include "window/window_session_controller_link_info.h" class History; namespace Main { class Session; } // namespace Main namespace Data { class Session; struct SponsoredFrom { PeerData *peer = nullptr; QString title; bool isBroadcast = false; bool isMegagroup = false; bool isChannel = false; bool isPublic = false; std::optional botLinkInfo; bool isExactPost = false; bool isRecommended = false; QString externalLink; PhotoId webpageOrBotPhotoId = PhotoId(0); bool isForceUserpicDisplay = false; QString buttonText; bool canReport = false; }; struct SponsoredMessage { QByteArray randomId; SponsoredFrom from; TextWithEntities textWithEntities; History *history = nullptr; MsgId msgId; QString chatInviteHash; QString externalLink; TextWithEntities sponsorInfo; TextWithEntities additionalInfo; }; class SponsoredMessages final { public: enum class State { None, AppendToEnd, InjectToMiddle, }; struct Details { std::optional hash; PeerData *peer = nullptr; MsgId msgId; std::vector info; QString externalLink; bool isForceUserpicDisplay = false; QString buttonText; std::optional botLinkInfo; bool canReport = false; }; using RandomId = QByteArray; explicit SponsoredMessages(not_null owner); SponsoredMessages(const SponsoredMessages &other) = delete; SponsoredMessages &operator=(const SponsoredMessages &other) = delete; ~SponsoredMessages(); [[nodiscard]] bool canHaveFor(not_null history) const; void request(not_null history, Fn done); void clearItems(not_null history); [[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const; void clicked(const FullMsgId &fullId); [[nodiscard]] bool append(not_null history); void inject( not_null history, MsgId injectAfterMsgId, int betweenHeight, int fallbackWidth); void view(const FullMsgId &fullId); [[nodiscard]] State state(not_null history) const; private: using OwnedItem = std::unique_ptr; struct Entry { OwnedItem item; FullMsgId itemFullId; SponsoredMessage sponsored; }; struct List { std::vector entries; // Data between history displays. size_t injectedCount = 0; bool showedAll = false; // crl::time received = 0; int postsBetween = 0; State state = State::None; }; struct Request { mtpRequestId requestId = 0; crl::time lastReceived = 0; }; void parse( not_null history, const MTPmessages_sponsoredMessages &list); void append( not_null history, List &list, const MTPSponsoredMessage &message); void clearOldRequests(); const Entry *find(const FullMsgId &fullId) const; const not_null _session; base::Timer _clearTimer; base::flat_map, List> _data; base::flat_map, Request> _requests; base::flat_map _viewRequests; rpl::lifetime _lifetime; }; } // namespace Data