Push recent requests from requests box to the bar.
This commit is contained in:
parent
7543351bc9
commit
8618f6d7eb
|
@ -759,6 +759,15 @@ void InviteLinks::requestMoreLinks(
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InviteLinks::pushRecentRequests(RecentRequests &&requests) {
|
||||||
|
_recentRequestsLocal.fire(std::move(requests));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto InviteLinks::recentRequestsLocal() const
|
||||||
|
-> rpl::producer<RecentRequests> {
|
||||||
|
return _recentRequestsLocal.events();
|
||||||
|
}
|
||||||
|
|
||||||
void InviteLinks::editPermanentLink(
|
void InviteLinks::editPermanentLink(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
const QString &link) {
|
const QString &link) {
|
||||||
|
|
|
@ -132,6 +132,13 @@ public:
|
||||||
bool revoked,
|
bool revoked,
|
||||||
Fn<void(Links)> done);
|
Fn<void(Links)> done);
|
||||||
|
|
||||||
|
struct RecentRequests {
|
||||||
|
not_null<PeerData*> peer;
|
||||||
|
std::vector<not_null<UserData*>> users;
|
||||||
|
};
|
||||||
|
void pushRecentRequests(RecentRequests &&requests);
|
||||||
|
[[nodiscard]] rpl::producer<RecentRequests> recentRequestsLocal() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LinkKey {
|
struct LinkKey {
|
||||||
not_null<PeerData*> peer;
|
not_null<PeerData*> peer;
|
||||||
|
@ -216,6 +223,7 @@ private:
|
||||||
base::flat_map<
|
base::flat_map<
|
||||||
std::pair<not_null<PeerData*>, not_null<UserData*>>,
|
std::pair<not_null<PeerData*>, not_null<UserData*>>,
|
||||||
ProcessRequest> _processRequests;
|
ProcessRequest> _processRequests;
|
||||||
|
rpl::event_stream<RecentRequests> _recentRequestsLocal;
|
||||||
|
|
||||||
rpl::event_stream<Update> _updates;
|
rpl::event_stream<Update> _updates;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/peer_list_controllers.h"
|
#include "boxes/peer_list_controllers.h"
|
||||||
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration
|
#include "boxes/peers/edit_participants_box.h" // SubscribeToMigration
|
||||||
#include "boxes/peers/edit_peer_invite_link.h" // PrepareRequestedRowStatus
|
#include "boxes/peers/edit_peer_invite_link.h" // PrepareRequestedRowStatus
|
||||||
|
#include "history/view/history_view_requests_bar.h" // kRecentRequestsLimit
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_chat.h"
|
#include "data/data_chat.h"
|
||||||
|
@ -382,6 +383,7 @@ void RequestsBoxController::processRequest(
|
||||||
Ui::Text::WithEntities)
|
Ui::Text::WithEntities)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
pushRecentRequests();
|
||||||
});
|
});
|
||||||
const auto fail = [] {};
|
const auto fail = [] {};
|
||||||
session().api().inviteLinks().processRequest(
|
session().api().inviteLinks().processRequest(
|
||||||
|
@ -393,6 +395,24 @@ void RequestsBoxController::processRequest(
|
||||||
fail);
|
fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestsBoxController::pushRecentRequests() {
|
||||||
|
const auto count = std::min(
|
||||||
|
delegate()->peerListFullRowsCount(),
|
||||||
|
HistoryView::kRecentRequestsLimit);
|
||||||
|
if (!count) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto requests = std::vector<not_null<UserData*>>();
|
||||||
|
requests.reserve(count);
|
||||||
|
for (auto i = 0; i != count; ++i) {
|
||||||
|
requests.push_back(delegate()->peerListRowAt(i)->peer()->asUser());
|
||||||
|
}
|
||||||
|
session().api().inviteLinks().pushRecentRequests({
|
||||||
|
.peer = _peer,
|
||||||
|
.users = std::move(requests),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void RequestsBoxController::appendRow(
|
void RequestsBoxController::appendRow(
|
||||||
not_null<UserData*> user,
|
not_null<UserData*> user,
|
||||||
TimeId date) {
|
TimeId date) {
|
||||||
|
|
|
@ -58,6 +58,7 @@ private:
|
||||||
void appendRow(not_null<UserData*> user, TimeId date);
|
void appendRow(not_null<UserData*> user, TimeId date);
|
||||||
void refreshDescription();
|
void refreshDescription();
|
||||||
void processRequest(not_null<UserData*> user, bool approved);
|
void processRequest(not_null<UserData*> user, bool approved);
|
||||||
|
void pushRecentRequests();
|
||||||
|
|
||||||
void subscribeToMigration();
|
void subscribeToMigration();
|
||||||
void migrate(not_null<ChatData*> chat, not_null<ChannelData*> channel);
|
void migrate(not_null<ChatData*> chat, not_null<ChannelData*> channel);
|
||||||
|
|
|
@ -17,12 +17,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/chat/group_call_userpics.h"
|
#include "ui/chat/group_call_userpics.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
#include "api/api_invite_links.h"
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// If less than 10 requests we request userpics each time the count changes.
|
// If less than 10 requests we request userpics each time the count changes.
|
||||||
constexpr auto kRequestAgainThreshold = 10;
|
constexpr auto kRequestExactThreshold = 10;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -31,27 +32,25 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
int userpicSize) {
|
int userpicSize) {
|
||||||
struct State {
|
struct State {
|
||||||
explicit State(not_null<PeerData*> peer)
|
explicit State(not_null<PeerData*> peer)
|
||||||
: api(&peer->session().api()) {
|
: peer(peer) {
|
||||||
current.isGroup = !peer->isBroadcast();
|
current.isGroup = !peer->isBroadcast();
|
||||||
}
|
}
|
||||||
~State() {
|
~State() {
|
||||||
if (requestId) {
|
if (requestId) {
|
||||||
api->request(requestId).cancel();
|
peer->session().api().request(requestId).cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<ApiWrap*> api;
|
not_null<PeerData*> peer;
|
||||||
std::vector<UserpicInRow> userpics;
|
std::vector<UserpicInRow> userpics;
|
||||||
std::vector<not_null<UserData*>> users;
|
std::vector<not_null<UserData*>> users;
|
||||||
Ui::RequestsBarContent current;
|
Ui::RequestsBarContent current;
|
||||||
base::has_weak_ptr guard;
|
base::has_weak_ptr guard;
|
||||||
mtpRequestId requestId = 0;
|
mtpRequestId requestId = 0;
|
||||||
Fn<void()> requestUsers;
|
|
||||||
bool someUserpicsNotLoaded = false;
|
bool someUserpicsNotLoaded = false;
|
||||||
bool pushScheduled = false;
|
bool pushScheduled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr auto kLimit = 3;
|
|
||||||
static const auto FillUserpics = [](
|
static const auto FillUserpics = [](
|
||||||
not_null<State*> state) {
|
not_null<State*> state) {
|
||||||
const auto &users = state->users;
|
const auto &users = state->users;
|
||||||
|
@ -114,6 +113,60 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const auto RequestExact = [](
|
||||||
|
not_null<State*> state,
|
||||||
|
int userpicSize,
|
||||||
|
Fn<void()> push,
|
||||||
|
auto requestExact) {
|
||||||
|
if (state->requestId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
using Flag = MTPmessages_GetChatInviteImporters::Flag;
|
||||||
|
state->requestId = state->peer->session().api().request(
|
||||||
|
MTPmessages_GetChatInviteImporters(
|
||||||
|
MTP_flags(Flag::f_requested),
|
||||||
|
state->peer->input,
|
||||||
|
MTPstring(), // link
|
||||||
|
MTPstring(), // q
|
||||||
|
MTP_int(0), // offset_date
|
||||||
|
MTP_inputUserEmpty(), // offset_user
|
||||||
|
MTP_int(kRecentRequestsLimit))
|
||||||
|
).done([=](const MTPmessages_ChatInviteImporters &result) {
|
||||||
|
state->requestId = 0;
|
||||||
|
|
||||||
|
result.match([&](
|
||||||
|
const MTPDmessages_chatInviteImporters &data) {
|
||||||
|
const auto count = data.vcount().v;
|
||||||
|
const auto changed = (state->current.count != count);
|
||||||
|
const auto &importers = data.vimporters().v;
|
||||||
|
auto &owner = state->peer->owner();
|
||||||
|
state->users = std::vector<not_null<UserData*>>();
|
||||||
|
const auto use = std::min(
|
||||||
|
importers.size(),
|
||||||
|
HistoryView::kRecentRequestsLimit);
|
||||||
|
state->users.reserve(use);
|
||||||
|
for (auto i = 0; i != use; ++i) {
|
||||||
|
importers[i].match([&](
|
||||||
|
const MTPDchatInviteImporter &data) {
|
||||||
|
state->users.push_back(
|
||||||
|
owner.user(data.vuser_id()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
state->current.count = count;
|
||||||
|
}
|
||||||
|
if (RegenerateUserpics(state, userpicSize) || changed) {
|
||||||
|
push();
|
||||||
|
}
|
||||||
|
if (state->userpics.size() > state->current.count) {
|
||||||
|
requestExact(state, userpicSize, push, requestExact);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
state->requestId = 0;
|
||||||
|
}).send();
|
||||||
|
};
|
||||||
|
|
||||||
return [=](auto consumer) {
|
return [=](auto consumer) {
|
||||||
const auto api = &peer->session().api();
|
const auto api = &peer->session().api();
|
||||||
|
|
||||||
|
@ -121,7 +174,9 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
auto state = lifetime.make_state<State>(peer);
|
auto state = lifetime.make_state<State>(peer);
|
||||||
|
|
||||||
const auto pushNext = [=] {
|
const auto pushNext = [=] {
|
||||||
if (state->pushScheduled) {
|
if (state->pushScheduled
|
||||||
|
|| (std::min(state->current.count, kRecentRequestsLimit)
|
||||||
|
!= state->users.size())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
state->pushScheduled = true;
|
state->pushScheduled = true;
|
||||||
|
@ -131,53 +186,6 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
state->requestUsers = [=] {
|
|
||||||
if (state->requestId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
using Flag = MTPmessages_GetChatInviteImporters::Flag;
|
|
||||||
state->requestId = state->api->request(
|
|
||||||
MTPmessages_GetChatInviteImporters(
|
|
||||||
MTP_flags(Flag::f_requested),
|
|
||||||
peer->input,
|
|
||||||
MTPstring(), // link
|
|
||||||
MTPstring(), // q
|
|
||||||
MTP_int(0), // offset_date
|
|
||||||
MTP_inputUserEmpty(), // offset_user
|
|
||||||
MTP_int(kLimit))
|
|
||||||
).done([=](const MTPmessages_ChatInviteImporters &result) {
|
|
||||||
state->requestId = 0;
|
|
||||||
|
|
||||||
result.match([&](
|
|
||||||
const MTPDmessages_chatInviteImporters &data) {
|
|
||||||
const auto count = data.vcount().v;
|
|
||||||
const auto changed = (state->current.count != count);
|
|
||||||
const auto &importers = data.vimporters().v;
|
|
||||||
auto &owner = peer->owner();
|
|
||||||
state->users = std::vector<not_null<UserData*>>();
|
|
||||||
state->users.reserve(importers.size());
|
|
||||||
for (const auto &importer : importers) {
|
|
||||||
importer.match([&](
|
|
||||||
const MTPDchatInviteImporter &data) {
|
|
||||||
state->users.push_back(
|
|
||||||
owner.user(data.vuser_id()));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
state->current.count = count;
|
|
||||||
}
|
|
||||||
if (RegenerateUserpics(state, userpicSize) || changed) {
|
|
||||||
pushNext();
|
|
||||||
}
|
|
||||||
if (state->userpics.size() > state->current.count) {
|
|
||||||
state->requestUsers();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).fail([=](const MTP::Error &error) {
|
|
||||||
state->requestId = 0;
|
|
||||||
}).send();
|
|
||||||
};
|
|
||||||
|
|
||||||
peer->session().downloaderTaskFinished(
|
peer->session().downloaderTaskFinished(
|
||||||
) | rpl::filter([=] {
|
) | rpl::filter([=] {
|
||||||
return state->someUserpicsNotLoaded;
|
return state->someUserpicsNotLoaded;
|
||||||
|
@ -198,15 +206,28 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
return (state->current.count != count);
|
return (state->current.count != count);
|
||||||
}) | rpl::start_with_next([=](int count) {
|
}) | rpl::start_with_next([=](int count) {
|
||||||
const auto was = state->current.count;
|
const auto was = state->current.count;
|
||||||
const auto requestUsersNeeded = (was < kRequestAgainThreshold)
|
const auto requestUsersNeeded = (was < kRequestExactThreshold)
|
||||||
|| (count < kRequestAgainThreshold);
|
|| (count < kRequestExactThreshold);
|
||||||
state->current.count = count;
|
state->current.count = count;
|
||||||
if (requestUsersNeeded) {
|
if (requestUsersNeeded) {
|
||||||
state->requestUsers();
|
RequestExact(state, userpicSize, pushNext, RequestExact);
|
||||||
}
|
}
|
||||||
pushNext();
|
pushNext();
|
||||||
}, lifetime);
|
}, lifetime);
|
||||||
|
|
||||||
|
using RecentRequests = Api::InviteLinks::RecentRequests;
|
||||||
|
api->inviteLinks().recentRequestsLocal(
|
||||||
|
) | rpl::filter([=](const RecentRequests &value) {
|
||||||
|
return (value.peer == peer)
|
||||||
|
&& (state->current.count >= kRequestExactThreshold)
|
||||||
|
&& (value.users.size() == kRecentRequestsLimit);
|
||||||
|
}) | rpl::start_with_next([=](RecentRequests &&value) {
|
||||||
|
state->users = std::move(value.users);
|
||||||
|
if (RegenerateUserpics(state, userpicSize)) {
|
||||||
|
pushNext();
|
||||||
|
}
|
||||||
|
}, lifetime);
|
||||||
|
|
||||||
return lifetime;
|
return lifetime;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ struct RequestsBarContent;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
inline constexpr auto kRecentRequestsLimit = 3;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
[[nodiscard]] rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
int userpicSize);
|
int userpicSize);
|
||||||
|
|
Loading…
Reference in New Issue