sponsored_messages.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/timer.h"
  9. #include "history/history_item.h"
  10. #include "ui/image/image_location.h"
  11. #include "window/window_session_controller_link_info.h"
  12. class History;
  13. namespace Main {
  14. class Session;
  15. } // namespace Main
  16. namespace Ui {
  17. class RpWidget;
  18. } // namespace Ui
  19. namespace Data {
  20. class MediaPreload;
  21. struct SponsoredReportResult final {
  22. using Id = QByteArray;
  23. struct Option final {
  24. Id id = 0;
  25. QString text;
  26. };
  27. using Options = std::vector<Option>;
  28. enum class FinalStep {
  29. Hidden,
  30. Reported,
  31. Premium,
  32. Silence,
  33. };
  34. Options options;
  35. QString title;
  36. QString error;
  37. FinalStep result;
  38. };
  39. struct SponsoredFrom {
  40. QString title;
  41. QString link;
  42. QString buttonText;
  43. PhotoId photoId = PhotoId(0);
  44. PhotoId mediaPhotoId = PhotoId(0);
  45. DocumentId mediaDocumentId = DocumentId(0);
  46. uint64 backgroundEmojiId = 0;
  47. uint8 colorIndex : 6 = 0;
  48. bool isLinkInternal = false;
  49. bool isRecommended = false;
  50. bool canReport = false;
  51. };
  52. struct SponsoredMessage {
  53. QByteArray randomId;
  54. SponsoredFrom from;
  55. TextWithEntities textWithEntities;
  56. History *history = nullptr;
  57. QString link;
  58. TextWithEntities sponsorInfo;
  59. TextWithEntities additionalInfo;
  60. };
  61. class SponsoredMessages final {
  62. public:
  63. enum class AppendResult {
  64. None,
  65. Appended,
  66. MediaLoading,
  67. };
  68. enum class State {
  69. None,
  70. AppendToEnd,
  71. InjectToMiddle,
  72. AppendToTopBar,
  73. };
  74. struct Details {
  75. std::vector<TextWithEntities> info;
  76. QString link;
  77. QString buttonText;
  78. PhotoId photoId = PhotoId(0);
  79. PhotoId mediaPhotoId = PhotoId(0);
  80. DocumentId mediaDocumentId = DocumentId(0);
  81. uint64 backgroundEmojiId = 0;
  82. uint8 colorIndex : 6 = 0;
  83. bool isLinkInternal = false;
  84. bool canReport = false;
  85. };
  86. using RandomId = QByteArray;
  87. explicit SponsoredMessages(not_null<Main::Session*> session);
  88. ~SponsoredMessages();
  89. [[nodiscard]] bool canHaveFor(not_null<History*> history) const;
  90. [[nodiscard]] bool isTopBarFor(not_null<History*> history) const;
  91. void request(not_null<History*> history, Fn<void()> done);
  92. void clearItems(not_null<History*> history);
  93. [[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const;
  94. void clicked(const FullMsgId &fullId, bool isMedia, bool isFullscreen);
  95. [[nodiscard]] FullMsgId fillTopBar(
  96. not_null<History*> history,
  97. not_null<Ui::RpWidget*> widget);
  98. [[nodiscard]] rpl::producer<> itemRemoved(const FullMsgId &);
  99. [[nodiscard]] AppendResult append(not_null<History*> history);
  100. void inject(
  101. not_null<History*> history,
  102. MsgId injectAfterMsgId,
  103. int betweenHeight,
  104. int fallbackWidth);
  105. void view(const FullMsgId &fullId);
  106. [[nodiscard]] State state(not_null<History*> history) const;
  107. [[nodiscard]] auto createReportCallback(const FullMsgId &fullId)
  108. -> Fn<void(SponsoredReportResult::Id, Fn<void(SponsoredReportResult)>)>;
  109. void clear();
  110. private:
  111. using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>;
  112. struct Entry {
  113. OwnedItem item;
  114. FullMsgId itemFullId;
  115. SponsoredMessage sponsored;
  116. std::unique_ptr<MediaPreload> preload;
  117. std::unique_ptr<rpl::lifetime> optionalDestructionNotifier;
  118. };
  119. struct List {
  120. std::vector<Entry> entries;
  121. // Data between history displays.
  122. size_t injectedCount = 0;
  123. bool showedAll = false;
  124. //
  125. crl::time received = 0;
  126. int postsBetween = 0;
  127. State state = State::None;
  128. };
  129. struct Request {
  130. mtpRequestId requestId = 0;
  131. crl::time lastReceived = 0;
  132. };
  133. void parse(
  134. not_null<History*> history,
  135. const MTPmessages_sponsoredMessages &list);
  136. void append(
  137. not_null<History*> history,
  138. List &list,
  139. const MTPSponsoredMessage &message);
  140. void clearOldRequests();
  141. const Entry *find(const FullMsgId &fullId) const;
  142. const not_null<Main::Session*> _session;
  143. base::Timer _clearTimer;
  144. base::flat_map<not_null<History*>, List> _data;
  145. base::flat_map<not_null<History*>, Request> _requests;
  146. base::flat_map<RandomId, Request> _viewRequests;
  147. rpl::event_stream<FullMsgId> _itemRemoved;
  148. rpl::lifetime _lifetime;
  149. };
  150. } // namespace Data