mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-08-31 22:46:10 +00:00
Show recently joined by permanent link userpics.
This commit is contained in:
@@ -20,6 +20,7 @@ namespace {
|
||||
|
||||
constexpr auto kFirstPage = 10;
|
||||
constexpr auto kPerPage = 50;
|
||||
constexpr auto kJoinedFirstPage = 10;
|
||||
|
||||
void BringPermanentToFront(PeerInviteLinks &links) {
|
||||
auto &list = links.links;
|
||||
@@ -145,7 +146,7 @@ void InviteLinks::performEdit(
|
||||
bool revoke,
|
||||
TimeId expireDate,
|
||||
int usageLimit) {
|
||||
const auto key = EditKey{ peer, link };
|
||||
const auto key = LinkKey{ peer, link };
|
||||
if (const auto i = _editCallbacks.find(key); i != end(_editCallbacks)) {
|
||||
if (done) {
|
||||
i->second.push_back(std::move(done));
|
||||
@@ -250,6 +251,58 @@ void InviteLinks::requestLinks(not_null<PeerData*> peer) {
|
||||
_firstSliceRequests.emplace(peer, requestId);
|
||||
}
|
||||
|
||||
JoinedByLinkSlice InviteLinks::lookupJoinedFirstSlice(LinkKey key) const {
|
||||
const auto i = _firstJoined.find(key);
|
||||
return (i != end(_firstJoined)) ? i->second : JoinedByLinkSlice();
|
||||
}
|
||||
|
||||
rpl::producer<JoinedByLinkSlice> InviteLinks::joinedFirstSliceValue(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &link,
|
||||
int fullCount) {
|
||||
const auto key = LinkKey{ peer, link };
|
||||
auto current = lookupJoinedFirstSlice(key);
|
||||
if (current.count == fullCount
|
||||
&& (!fullCount || !current.users.empty())) {
|
||||
return rpl::single(current);
|
||||
}
|
||||
current.count = fullCount;
|
||||
const auto remove = int(current.users.size()) - current.count;
|
||||
if (remove > 0) {
|
||||
current.users.erase(end(current.users) - remove, end(current.users));
|
||||
}
|
||||
requestJoinedFirstSlice(key);
|
||||
using namespace rpl::mappers;
|
||||
return rpl::single(
|
||||
current
|
||||
) | rpl::then(_joinedFirstSliceLoaded.events(
|
||||
) | rpl::filter(
|
||||
_1 == key
|
||||
) | rpl::map([=] {
|
||||
return lookupJoinedFirstSlice(key);
|
||||
}));
|
||||
}
|
||||
|
||||
void InviteLinks::requestJoinedFirstSlice(LinkKey key) {
|
||||
if (_firstJoinedRequests.contains(key)) {
|
||||
return;
|
||||
}
|
||||
const auto requestId = _api->request(MTPmessages_GetChatInviteImporters(
|
||||
key.peer->input,
|
||||
MTP_string(key.link),
|
||||
MTP_int(0), // offset_date
|
||||
MTP_inputUserEmpty(), // offset_user
|
||||
MTP_int(kJoinedFirstPage)
|
||||
)).done([=](const MTPmessages_ChatInviteImporters &result) {
|
||||
_firstJoinedRequests.remove(key);
|
||||
_firstJoined[key] = parseSlice(key.peer, result);
|
||||
_joinedFirstSliceLoaded.fire_copy(key);
|
||||
}).fail([=](const RPCError &error) {
|
||||
_firstJoinedRequests.remove(key);
|
||||
}).send();
|
||||
_firstJoinedRequests.emplace(key, requestId);
|
||||
}
|
||||
|
||||
void InviteLinks::setPermanent(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPExportedChatInvite &invite) {
|
||||
@@ -320,6 +373,27 @@ auto InviteLinks::parseSlice(
|
||||
return result;
|
||||
}
|
||||
|
||||
JoinedByLinkSlice InviteLinks::parseSlice(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_ChatInviteImporters &slice) const {
|
||||
auto result = JoinedByLinkSlice();
|
||||
slice.match([&](const MTPDmessages_chatInviteImporters &data) {
|
||||
auto &owner = peer->session().data();
|
||||
owner.processUsers(data.vusers());
|
||||
result.count = data.vcount().v;
|
||||
result.users.reserve(data.vimporters().v.size());
|
||||
for (const auto importer : data.vimporters().v) {
|
||||
importer.match([&](const MTPDchatInviteImporter &data) {
|
||||
result.users.push_back({
|
||||
.user = owner.user(data.vuser_id().v),
|
||||
.date = data.vdate().v,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
auto InviteLinks::parse(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPExportedChatInvite &invite) const -> Link {
|
||||
|
@@ -28,6 +28,16 @@ struct PeerInviteLinks {
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
struct JoinedByLinkUser {
|
||||
not_null<UserData*> user;
|
||||
TimeId date = 0;
|
||||
};
|
||||
|
||||
struct JoinedByLinkSlice {
|
||||
std::vector<JoinedByLinkUser> users;
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
class InviteLinks final {
|
||||
public:
|
||||
explicit InviteLinks(not_null<ApiWrap*> api);
|
||||
@@ -59,21 +69,29 @@ public:
|
||||
void requestLinks(not_null<PeerData*> peer);
|
||||
[[nodiscard]] const Links &links(not_null<PeerData*> peer) const;
|
||||
|
||||
[[nodiscard]] rpl::producer<JoinedByLinkSlice> joinedFirstSliceValue(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &link,
|
||||
int fullCount);
|
||||
|
||||
void requestMoreLinks(
|
||||
not_null<PeerData*> peer,
|
||||
const QString &last,
|
||||
Fn<void(Links)> done);
|
||||
|
||||
private:
|
||||
struct EditKey {
|
||||
struct LinkKey {
|
||||
not_null<PeerData*> peer;
|
||||
QString link;
|
||||
|
||||
friend inline bool operator<(const EditKey &a, const EditKey &b) {
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] Links parseSlice(
|
||||
@@ -82,6 +100,9 @@ private:
|
||||
[[nodiscard]] Link parse(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPExportedChatInvite &invite) const;
|
||||
[[nodiscard]] JoinedByLinkSlice parseSlice(
|
||||
not_null<PeerData*> peer,
|
||||
const MTPmessages_ChatInviteImporters &slice) const;
|
||||
[[nodiscard]] Link *lookupPermanent(not_null<PeerData*> peer);
|
||||
[[nodiscard]] Link *lookupPermanent(Links &links);
|
||||
[[nodiscard]] const Link *lookupPermanent(const Links &links) const;
|
||||
@@ -108,15 +129,23 @@ private:
|
||||
TimeId expireDate = 0,
|
||||
int usageLimit = 0);
|
||||
|
||||
void requestJoinedFirstSlice(LinkKey key);
|
||||
[[nodiscard]] 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<EditKey, std::vector<Fn<void(Link)>>> _editCallbacks;
|
||||
base::flat_map<LinkKey, std::vector<Fn<void(Link)>>> _editCallbacks;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user