data_histories.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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. class History;
  10. class HistoryItem;
  11. namespace Main {
  12. class Session;
  13. } // namespace Main
  14. namespace MTP {
  15. class Error;
  16. struct Response;
  17. } // namespace MTP
  18. namespace Data {
  19. class Session;
  20. class Folder;
  21. struct WebPageDraft;
  22. [[nodiscard]] MTPInputReplyTo ReplyToForMTP(
  23. not_null<History*> history,
  24. FullReplyTo replyTo);
  25. [[nodiscard]] MTPInputMedia WebPageForMTP(
  26. const Data::WebPageDraft &draft,
  27. bool required = false);
  28. class Histories final {
  29. public:
  30. enum class RequestType : uchar {
  31. None,
  32. History,
  33. ReadInbox,
  34. Delete,
  35. Send,
  36. };
  37. explicit Histories(not_null<Session*> owner);
  38. [[nodiscard]] Session &owner() const;
  39. [[nodiscard]] Main::Session &session() const;
  40. [[nodiscard]] History *find(PeerId peerId);
  41. [[nodiscard]] not_null<History*> findOrCreate(PeerId peerId);
  42. void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
  43. void unloadAll();
  44. void clearAll();
  45. void readInbox(not_null<History*> history);
  46. void readInboxTill(not_null<HistoryItem*> item);
  47. void readInboxTill(not_null<History*> history, MsgId tillId);
  48. void readInboxOnNewMessage(not_null<HistoryItem*> item);
  49. void readClientSideMessage(not_null<HistoryItem*> item);
  50. void sendPendingReadInbox(not_null<History*> history);
  51. void reportDelivery(not_null<HistoryItem*> item);
  52. void requestDialogEntry(not_null<Data::Folder*> folder);
  53. void requestDialogEntry(
  54. not_null<History*> history,
  55. Fn<void()> callback = nullptr);
  56. void dialogEntryApplied(not_null<History*> history);
  57. void changeDialogUnreadMark(not_null<History*> history, bool unread);
  58. void requestFakeChatListMessage(not_null<History*> history);
  59. void requestGroupAround(not_null<HistoryItem*> item);
  60. void deleteMessages(
  61. not_null<History*> history,
  62. const QVector<MTPint> &ids,
  63. bool revoke);
  64. void deleteAllMessages(
  65. not_null<History*> history,
  66. MsgId deleteTillId,
  67. bool justClear,
  68. bool revoke);
  69. void deleteMessagesByDates(
  70. not_null<History*> history,
  71. QDate firstDayToDelete,
  72. QDate lastDayToDelete,
  73. bool revoke);
  74. void deleteMessagesByDates(
  75. not_null<History*> history,
  76. TimeId minDate,
  77. TimeId maxDate,
  78. bool revoke);
  79. void deleteMessages(const MessageIdsList &ids, bool revoke);
  80. int sendRequest(
  81. not_null<History*> history,
  82. RequestType type,
  83. Fn<mtpRequestId(Fn<void()> finish)> generator);
  84. void cancelRequest(int id);
  85. using PreparedMessage = std::variant<
  86. MTPmessages_SendMessage,
  87. MTPmessages_SendMedia,
  88. MTPmessages_SendInlineBotResult,
  89. MTPmessages_SendMultiMedia>;
  90. int sendPreparedMessage(
  91. not_null<History*> history,
  92. FullReplyTo replyTo,
  93. uint64 randomId,
  94. Fn<PreparedMessage(not_null<History*>, FullReplyTo)> message,
  95. Fn<void(const MTPUpdates&, const MTP::Response&)> done,
  96. Fn<void(const MTP::Error&, const MTP::Response&)> fail);
  97. struct ReplyToPlaceholder {
  98. };
  99. template <typename RequestType, typename ...Args>
  100. static auto PrepareMessage(const Args &...args)
  101. -> Fn<Histories::PreparedMessage(not_null<History*>, FullReplyTo)> {
  102. return [=](not_null<History*> history, FullReplyTo replyTo)
  103. -> RequestType {
  104. return { ReplaceReplyIds(history, args, replyTo)... };
  105. };
  106. }
  107. void checkTopicCreated(FullMsgId rootId, MsgId realRoot);
  108. [[nodiscard]] FullMsgId convertTopicReplyToId(
  109. not_null<History*> history,
  110. FullMsgId replyToId) const;
  111. [[nodiscard]] MsgId convertTopicReplyToId(
  112. not_null<History*> history,
  113. MsgId replyToId) const;
  114. private:
  115. struct PostponedHistoryRequest {
  116. Fn<mtpRequestId(Fn<void()> finish)> generator;
  117. };
  118. struct SentRequest {
  119. Fn<mtpRequestId(Fn<void()> finish)> generator;
  120. mtpRequestId id = 0;
  121. RequestType type = RequestType::None;
  122. };
  123. struct State {
  124. base::flat_map<int, PostponedHistoryRequest> postponed;
  125. base::flat_map<int, SentRequest> sent;
  126. MsgId willReadTill = 0;
  127. MsgId sentReadTill = 0;
  128. crl::time willReadWhen = 0;
  129. bool sentReadDone = false;
  130. bool postponedRequestEntry = false;
  131. };
  132. struct ChatListGroupRequest {
  133. MsgId aroundId = 0;
  134. mtpRequestId requestId = 0;
  135. };
  136. struct DelayedByTopicMessage {
  137. uint64 randomId = 0;
  138. FullMsgId replyTo;
  139. Fn<PreparedMessage(not_null<History*>, FullReplyTo)> message;
  140. Fn<void(const MTPUpdates&, const MTP::Response&)> done;
  141. Fn<void(const MTP::Error&, const MTP::Response&)> fail;
  142. int requestId = 0;
  143. };
  144. struct GroupRequestKey {
  145. not_null<History*> history;
  146. MsgId rootId = 0;
  147. friend inline auto operator<=>(
  148. GroupRequestKey,
  149. GroupRequestKey) = default;
  150. };
  151. template <typename Arg>
  152. static auto ReplaceReplyIds(
  153. not_null<History*> history,
  154. Arg arg,
  155. FullReplyTo replyTo) {
  156. if constexpr (std::is_same_v<Arg, ReplyToPlaceholder>) {
  157. return ReplyToForMTP(history, replyTo);
  158. } else {
  159. return arg;
  160. }
  161. }
  162. void readInboxTill(not_null<History*> history, MsgId tillId, bool force);
  163. void sendReadRequests();
  164. void sendReadRequest(not_null<History*> history, State &state);
  165. [[nodiscard]] State *lookup(not_null<History*> history);
  166. void checkEmptyState(not_null<History*> history);
  167. void checkPostponed(not_null<History*> history, int id);
  168. void finishSentRequest(
  169. not_null<History*> history,
  170. not_null<State*> state,
  171. int id);
  172. [[nodiscard]] bool postponeHistoryRequest(const State &state) const;
  173. [[nodiscard]] bool postponeEntryRequest(const State &state) const;
  174. void postponeRequestDialogEntries();
  175. void sendDialogRequests();
  176. void reportPendingDeliveries();
  177. [[nodiscard]] bool isCreatingTopic(
  178. not_null<History*> history,
  179. MsgId rootId) const;
  180. void sendCreateTopicRequest(not_null<History*> history, MsgId rootId);
  181. void cancelDelayedByTopicRequest(int id);
  182. const not_null<Session*> _owner;
  183. std::unordered_map<PeerId, std::unique_ptr<History>> _map;
  184. base::flat_map<not_null<History*>, State> _states;
  185. base::flat_map<int, not_null<History*>> _historyByRequest;
  186. int _requestAutoincrement = 0;
  187. base::Timer _readRequestsTimer;
  188. base::flat_set<not_null<Data::Folder*>> _dialogFolderRequests;
  189. base::flat_map<
  190. not_null<History*>,
  191. std::vector<Fn<void()>>> _dialogRequests;
  192. base::flat_map<
  193. not_null<History*>,
  194. std::vector<Fn<void()>>> _dialogRequestsPending;
  195. base::flat_set<not_null<History*>> _fakeChatListRequests;
  196. base::flat_map<
  197. GroupRequestKey,
  198. ChatListGroupRequest> _chatListGroupRequests;
  199. base::flat_map<
  200. FullMsgId,
  201. std::vector<DelayedByTopicMessage>> _creatingTopics;
  202. base::flat_map<FullMsgId, MsgId> _createdTopicIds;
  203. base::flat_set<mtpRequestId> _creatingTopicRequests;
  204. base::flat_map<
  205. not_null<PeerData*>,
  206. base::flat_set<MsgId>> _pendingDeliveryReport;
  207. base::flat_set<not_null<PeerData*>> _deliveryReportSent;
  208. };
  209. } // namespace Data