tdesktop/Telegram/SourceFiles/api/api_invite_links.h
2023-04-11 19:17:38 +04:00

237 lines
6.0 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;
bool viaFilterLink = false;
};
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]] std::optional<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;
std::optional<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