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