/* 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 class ApiWrap; namespace Api { struct InviteLink { QString link; not_null admin; TimeId date = 0; TimeId startDate = 0; TimeId expireDate = 0; int usageLimit = 0; int usage = 0; int requested = 0; bool requestApproval = false; bool permanent = false; bool revoked = false; }; struct PeerInviteLinks { std::vector links; int count = 0; }; struct JoinedByLinkUser { not_null user; TimeId date = 0; }; struct JoinedByLinkSlice { std::vector users; int count = 0; }; struct InviteLinkUpdate { not_null peer; not_null admin; QString was; std::optional now; }; [[nodiscard]] JoinedByLinkSlice ParseJoinedByLinkSlice( not_null peer, const MTPmessages_ChatInviteImporters &slice); class InviteLinks final { public: explicit InviteLinks(not_null api); using Link = InviteLink; using Links = PeerInviteLinks; using Update = InviteLinkUpdate; void create( not_null peer, Fn done = nullptr, TimeId expireDate = 0, int usageLimit = 0, bool requestApproval = false); void edit( not_null peer, not_null admin, const QString &link, TimeId expireDate, int usageLimit, bool requestApproval, Fn done = nullptr); void revoke( not_null peer, not_null admin, const QString &link, Fn done = nullptr); void revokePermanent( not_null peer, not_null admin, const QString &link, Fn done = nullptr); void destroy( not_null peer, not_null admin, const QString &link, Fn done = nullptr); void destroyAllRevoked( not_null peer, not_null admin, Fn done = nullptr); void setMyPermanent( not_null peer, const MTPExportedChatInvite &invite); void clearMyPermanent(not_null peer); void requestMyLinks(not_null peer); [[nodiscard]] const Links &myLinks(not_null peer) const; void processRequest( not_null peer, const QString &link, not_null user, bool approved, Fn done, Fn fail); void applyExternalUpdate(not_null peer, InviteLink updated); [[nodiscard]] rpl::producer joinedFirstSliceValue( not_null peer, const QString &link, int fullCount); [[nodiscard]] std::optional joinedFirstSliceLoaded( not_null peer, const QString &link) const; [[nodiscard]] rpl::producer updates( not_null peer, not_null admin) const; [[nodiscard]] rpl::producer<> allRevokedDestroyed( not_null peer, not_null admin) const; void requestMoreLinks( not_null peer, not_null admin, TimeId lastDate, const QString &lastLink, bool revoked, Fn done); struct RecentRequests { not_null peer; std::vector> users; }; void pushRecentRequests(RecentRequests &&requests); [[nodiscard]] rpl::producer recentRequestsLocal() const; private: struct LinkKey { not_null peer; QString link; friend inline bool operator<(const LinkKey &a, const LinkKey &b) { return (a.peer == b.peer) ? (a.link < b.link) : (a.peer < b.peer); } friend inline bool operator==(const LinkKey &a, const LinkKey &b) { return (a.peer == b.peer) && (a.link == b.link); } }; struct ProcessRequest { Fn done; Fn fail; }; [[nodiscard]] Links parseSlice( not_null peer, const MTPmessages_ExportedChatInvites &slice) const; [[nodiscard]] Link parse( not_null peer, const MTPExportedChatInvite &invite) const; [[nodiscard]] Link *lookupMyPermanent(not_null peer); [[nodiscard]] Link *lookupMyPermanent(Links &links); [[nodiscard]] const Link *lookupMyPermanent(const Links &links) const; Link prepend( not_null peer, not_null admin, const MTPExportedChatInvite &invite); void prependMyToFirstSlice( not_null peer, not_null admin, const Link &link); void notify(not_null peer); void editPermanentLink( not_null peer, const QString &link); void performEdit( not_null peer, not_null admin, const QString &link, Fn done, bool revoke, TimeId expireDate = 0, int usageLimit = 0, bool requestApproval = false); void performCreate( not_null peer, Fn done, bool revokeLegacyPermanent, TimeId expireDate = 0, int usageLimit = 0, bool requestApproval = false); void requestJoinedFirstSlice(LinkKey key); [[nodiscard]] std::optional lookupJoinedFirstSlice( LinkKey key) const; const not_null _api; base::flat_map, Links> _firstSlices; base::flat_map, mtpRequestId> _firstSliceRequests; base::flat_map _firstJoined; base::flat_map _firstJoinedRequests; rpl::event_stream _joinedFirstSliceLoaded; base::flat_map< not_null, std::vector>> _createCallbacks; base::flat_map>> _editCallbacks; base::flat_map>> _deleteCallbacks; base::flat_map< not_null, std::vector>> _deleteRevokedCallbacks; base::flat_map< std::pair, not_null>, ProcessRequest> _processRequests; rpl::event_stream _recentRequestsLocal; rpl::event_stream _updates; struct AllRevokedDestroyed { not_null peer; not_null admin; }; rpl::event_stream _allRevokedDestroyed; }; } // namespace Api