api_invite_links.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  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. class ApiWrap;
  9. #include "data/data_subscriptions.h"
  10. namespace Api {
  11. struct InviteLink {
  12. QString link;
  13. QString label;
  14. Data::PeerSubscription subscription;
  15. not_null<UserData*> admin;
  16. TimeId date = 0;
  17. TimeId startDate = 0;
  18. TimeId expireDate = 0;
  19. int usageLimit = 0;
  20. int usage = 0;
  21. int requested = 0;
  22. bool requestApproval = false;
  23. bool permanent = false;
  24. bool revoked = false;
  25. };
  26. struct PeerInviteLinks {
  27. std::vector<InviteLink> links;
  28. int count = 0;
  29. };
  30. struct JoinedByLinkUser {
  31. not_null<UserData*> user;
  32. TimeId date = 0;
  33. bool viaFilterLink = false;
  34. };
  35. struct JoinedByLinkSlice {
  36. std::vector<JoinedByLinkUser> users;
  37. int count = 0;
  38. };
  39. struct InviteLinkUpdate {
  40. not_null<PeerData*> peer;
  41. not_null<UserData*> admin;
  42. QString was;
  43. std::optional<InviteLink> now;
  44. };
  45. [[nodiscard]] JoinedByLinkSlice ParseJoinedByLinkSlice(
  46. not_null<PeerData*> peer,
  47. const MTPmessages_ChatInviteImporters &slice);
  48. struct CreateInviteLinkArgs {
  49. not_null<PeerData*> peer;
  50. Fn<void(InviteLink)> done = nullptr;
  51. QString label;
  52. TimeId expireDate = 0;
  53. int usageLimit = 0;
  54. bool requestApproval = false;
  55. Data::PeerSubscription subscription;
  56. };
  57. class InviteLinks final {
  58. public:
  59. explicit InviteLinks(not_null<ApiWrap*> api);
  60. using Link = InviteLink;
  61. using Links = PeerInviteLinks;
  62. using Update = InviteLinkUpdate;
  63. void create(const CreateInviteLinkArgs &args);
  64. void edit(
  65. not_null<PeerData*> peer,
  66. not_null<UserData*> admin,
  67. const QString &link,
  68. const QString &label,
  69. TimeId expireDate,
  70. int usageLimit,
  71. bool requestApproval,
  72. Fn<void(Link)> done = nullptr);
  73. void editTitle(
  74. not_null<PeerData*> peer,
  75. not_null<UserData*> admin,
  76. const QString &link,
  77. const QString &label,
  78. Fn<void(Link)> done = nullptr);
  79. void revoke(
  80. not_null<PeerData*> peer,
  81. not_null<UserData*> admin,
  82. const QString &link,
  83. Fn<void(Link)> done = nullptr);
  84. void revokePermanent(
  85. not_null<PeerData*> peer,
  86. not_null<UserData*> admin,
  87. const QString &link,
  88. Fn<void()> done = nullptr);
  89. void destroy(
  90. not_null<PeerData*> peer,
  91. not_null<UserData*> admin,
  92. const QString &link,
  93. Fn<void()> done = nullptr);
  94. void destroyAllRevoked(
  95. not_null<PeerData*> peer,
  96. not_null<UserData*> admin,
  97. Fn<void()> done = nullptr);
  98. void setMyPermanent(
  99. not_null<PeerData*> peer,
  100. const MTPExportedChatInvite &invite);
  101. void clearMyPermanent(not_null<PeerData*> peer);
  102. void requestMyLinks(not_null<PeerData*> peer);
  103. [[nodiscard]] const Links &myLinks(not_null<PeerData*> peer) const;
  104. void processRequest(
  105. not_null<PeerData*> peer,
  106. const QString &link,
  107. not_null<UserData*> user,
  108. bool approved,
  109. Fn<void()> done,
  110. Fn<void()> fail);
  111. void applyExternalUpdate(not_null<PeerData*> peer, InviteLink updated);
  112. [[nodiscard]] rpl::producer<JoinedByLinkSlice> joinedFirstSliceValue(
  113. not_null<PeerData*> peer,
  114. const QString &link,
  115. int fullCount);
  116. [[nodiscard]] std::optional<JoinedByLinkSlice> joinedFirstSliceLoaded(
  117. not_null<PeerData*> peer,
  118. const QString &link) const;
  119. [[nodiscard]] rpl::producer<Update> updates(
  120. not_null<PeerData*> peer,
  121. not_null<UserData*> admin) const;
  122. [[nodiscard]] rpl::producer<> allRevokedDestroyed(
  123. not_null<PeerData*> peer,
  124. not_null<UserData*> admin) const;
  125. void requestMoreLinks(
  126. not_null<PeerData*> peer,
  127. not_null<UserData*> admin,
  128. TimeId lastDate,
  129. const QString &lastLink,
  130. bool revoked,
  131. Fn<void(Links)> done);
  132. private:
  133. struct LinkKey {
  134. not_null<PeerData*> peer;
  135. QString link;
  136. friend inline bool operator<(const LinkKey &a, const LinkKey &b) {
  137. return (a.peer == b.peer)
  138. ? (a.link < b.link)
  139. : (a.peer < b.peer);
  140. }
  141. friend inline bool operator==(const LinkKey &a, const LinkKey &b) {
  142. return (a.peer == b.peer) && (a.link == b.link);
  143. }
  144. };
  145. struct ProcessRequest {
  146. Fn<void()> done;
  147. Fn<void()> fail;
  148. };
  149. [[nodiscard]] Links parseSlice(
  150. not_null<PeerData*> peer,
  151. const MTPmessages_ExportedChatInvites &slice) const;
  152. [[nodiscard]] std::optional<Link> parse(
  153. not_null<PeerData*> peer,
  154. const MTPExportedChatInvite &invite) const;
  155. [[nodiscard]] Link *lookupMyPermanent(not_null<PeerData*> peer);
  156. [[nodiscard]] Link *lookupMyPermanent(Links &links);
  157. [[nodiscard]] const Link *lookupMyPermanent(const Links &links) const;
  158. std::optional<Link> prepend(
  159. not_null<PeerData*> peer,
  160. not_null<UserData*> admin,
  161. const MTPExportedChatInvite &invite);
  162. void prependMyToFirstSlice(
  163. not_null<PeerData*> peer,
  164. not_null<UserData*> admin,
  165. const Link &link);
  166. void notify(not_null<PeerData*> peer);
  167. void editPermanentLink(
  168. not_null<PeerData*> peer,
  169. const QString &link);
  170. void performEdit(
  171. not_null<PeerData*> peer,
  172. not_null<UserData*> admin,
  173. const QString &link,
  174. Fn<void(Link)> done,
  175. bool revoke,
  176. const QString &label = QString(),
  177. TimeId expireDate = 0,
  178. int usageLimit = 0,
  179. bool requestApproval = false,
  180. bool editOnlyTitle = false);
  181. void performCreate(
  182. const CreateInviteLinkArgs &args,
  183. bool revokeLegacyPermanent);
  184. void requestJoinedFirstSlice(LinkKey key);
  185. [[nodiscard]] std::optional<JoinedByLinkSlice> lookupJoinedFirstSlice(
  186. LinkKey key) const;
  187. const not_null<ApiWrap*> _api;
  188. base::flat_map<not_null<PeerData*>, Links> _firstSlices;
  189. base::flat_map<not_null<PeerData*>, mtpRequestId> _firstSliceRequests;
  190. base::flat_map<LinkKey, JoinedByLinkSlice> _firstJoined;
  191. base::flat_map<LinkKey, mtpRequestId> _firstJoinedRequests;
  192. rpl::event_stream<LinkKey> _joinedFirstSliceLoaded;
  193. base::flat_map<
  194. not_null<PeerData*>,
  195. std::vector<Fn<void(Link)>>> _createCallbacks;
  196. base::flat_map<LinkKey, std::vector<Fn<void(Link)>>> _editCallbacks;
  197. base::flat_map<LinkKey, std::vector<Fn<void()>>> _deleteCallbacks;
  198. base::flat_map<
  199. not_null<PeerData*>,
  200. std::vector<Fn<void()>>> _deleteRevokedCallbacks;
  201. base::flat_map<
  202. std::pair<not_null<PeerData*>, not_null<UserData*>>,
  203. ProcessRequest> _processRequests;
  204. rpl::event_stream<Update> _updates;
  205. struct AllRevokedDestroyed {
  206. not_null<PeerData*> peer;
  207. not_null<UserData*> admin;
  208. };
  209. rpl::event_stream<AllRevokedDestroyed> _allRevokedDestroyed;
  210. };
  211. } // namespace Api