Make search in restricted/blocked box paginated.

This commit is contained in:
John Preston 2017-06-14 13:46:06 +03:00
parent 6fe0fe6fd6
commit adcecaa195
7 changed files with 72 additions and 53 deletions

View File

@ -970,7 +970,7 @@ void PeerListBox::Inner::loadProfilePhotos() {
void PeerListBox::Inner::checkScrollForPreload() { void PeerListBox::Inner::checkScrollForPreload() {
if (_visibleBottom + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) { if (_visibleBottom + PreloadHeightsCount * (_visibleBottom - _visibleTop) > height()) {
_controller->preloadRows(); _controller->loadMoreRows();
} }
} }

View File

@ -219,6 +219,7 @@ class PeerListSearchController {
public: public:
virtual void searchQuery(const QString &query) = 0; virtual void searchQuery(const QString &query) = 0;
virtual bool isLoading() = 0; virtual bool isLoading() = 0;
virtual bool loadMoreRows() = 0;
virtual ~PeerListSearchController() = default; virtual ~PeerListSearchController() = default;
void setDelegate(gsl::not_null<PeerListSearchDelegate*> delegate) { void setDelegate(gsl::not_null<PeerListSearchDelegate*> delegate) {
@ -249,7 +250,7 @@ public:
virtual void rowClicked(gsl::not_null<PeerListRow*> row) = 0; virtual void rowClicked(gsl::not_null<PeerListRow*> row) = 0;
virtual void rowActionClicked(gsl::not_null<PeerListRow*> row) { virtual void rowActionClicked(gsl::not_null<PeerListRow*> row) {
} }
virtual void preloadRows() { virtual void loadMoreRows() {
} }
bool isSearchLoading() const { bool isSearchLoading() const {
return _searchController ? _searchController->isLoading() : false; return _searchController ? _searchController->isLoading() : false;
@ -276,6 +277,9 @@ protected:
gsl::not_null<PeerListDelegate*> delegate() const { gsl::not_null<PeerListDelegate*> delegate() const {
return _delegate; return _delegate;
} }
PeerListSearchController *searchController() const {
return _searchController.get();
}
void setDescriptionText(const QString &text); void setDescriptionText(const QString &text);
void setSearchLoadingText(const QString &text); void setSearchLoadingText(const QString &text);
@ -541,6 +545,9 @@ public:
void searchQuery(const QString &query) override; void searchQuery(const QString &query) override;
bool isLoading() override; bool isLoading() override;
bool loadMoreRows() override {
return false;
}
private: private:
bool searchInCache(); bool searchInCache();

View File

@ -205,10 +205,10 @@ void BoxController::prepare() {
setDescriptionText(lang(lng_contacts_loading)); setDescriptionText(lang(lng_contacts_loading));
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
preloadRows(); loadMoreRows();
} }
void BoxController::preloadRows() { void BoxController::loadMoreRows() {
if (_loadRequestId || _allLoaded) { if (_loadRequestId || _allLoaded) {
return; return;
} }

View File

@ -29,7 +29,7 @@ public:
void prepare() override; void prepare() override;
void rowClicked(gsl::not_null<PeerListRow*> row) override; void rowClicked(gsl::not_null<PeerListRow*> row) override;
void rowActionClicked(gsl::not_null<PeerListRow*> row) override; void rowActionClicked(gsl::not_null<PeerListRow*> row) override;
void preloadRows() override; void loadMoreRows() override;
private: private:
void receivedCalls(const QVector<MTPMessage> &result); void receivedCalls(const QVector<MTPMessage> &result);

View File

@ -33,8 +33,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
#include "apiwrap.h" #include "apiwrap.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "mainwindow.h" // tmp
namespace Profile { namespace Profile {
namespace { namespace {
@ -46,6 +44,7 @@ public:
void searchQuery(const QString &query) override; void searchQuery(const QString &query) override;
bool isLoading() override; bool isLoading() override;
bool loadMoreRows() override;
private: private:
bool searchInCache(); bool searchInCache();
@ -62,7 +61,33 @@ private:
int _offset = 0; int _offset = 0;
bool _allLoaded = false; bool _allLoaded = false;
std::map<QString, MTPchannels_ChannelParticipants> _cache; std::map<QString, MTPchannels_ChannelParticipants> _cache;
std::map<mtpRequestId, QString> _queries; std::map<mtpRequestId, std::pair<QString, int>> _queries; // query, offset
};
class BlockedBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this {
public:
BlockedBoxController(gsl::not_null<ChannelData*> channel, bool restricted);
void prepare() override;
void rowClicked(gsl::not_null<PeerListRow*> row) override;
void rowActionClicked(gsl::not_null<PeerListRow*> row) override;
void loadMoreRows() override;
void peerListSearchAddRow(gsl::not_null<PeerData*> peer) override;
private:
bool appendRow(UserData *user);
bool prependRow(UserData *user);
std::unique_ptr<PeerListRow> createRow(UserData *user) const;
gsl::not_null<ChannelData*> _channel;
bool _restricted = false;
int _offset = 0;
mtpRequestId _loadRequestId = 0;
bool _allLoaded = false;
std::map<UserData*, MTPChannelBannedRights> _rights;
QPointer<EditRestrictedBox> _editBox;
}; };
@ -78,6 +103,7 @@ void BlockedBoxSearchController::searchQuery(const QString &query) {
_query = query; _query = query;
_offset = 0; _offset = 0;
_requestId = 0; _requestId = 0;
_allLoaded = false;
if (!_query.isEmpty() && !searchInCache()) { if (!_query.isEmpty() && !searchInCache()) {
_timer.callOnce(AutoSearchTimeout); _timer.callOnce(AutoSearchTimeout);
} else { } else {
@ -98,17 +124,7 @@ bool BlockedBoxSearchController::searchInCache() {
void BlockedBoxSearchController::searchOnServer() { void BlockedBoxSearchController::searchOnServer() {
Expects(!_query.isEmpty()); Expects(!_query.isEmpty());
auto filter = _restricted ? MTP_channelParticipantsBanned(MTP_string(_query)) : MTP_channelParticipantsKicked(MTP_string(_query)); loadMoreRows();
_requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter , MTP_int(_offset), MTP_int(kBlockedPerPage))).done([this](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) {
searchDone(result, requestId);
}).fail([this](const RPCError &error, mtpRequestId requestId) {
if (_requestId == requestId) {
_requestId = 0;
_allLoaded = true;
delegate()->peerListSearchRefreshRows();
}
}).send();
_queries.emplace(_requestId, _query);
} }
void BlockedBoxSearchController::searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { void BlockedBoxSearchController::searchDone(const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) {
@ -120,8 +136,10 @@ void BlockedBoxSearchController::searchDone(const MTPchannels_ChannelParticipant
App::feedUsers(participants.vusers); App::feedUsers(participants.vusers);
auto it = _queries.find(requestId); auto it = _queries.find(requestId);
if (it != _queries.cend()) { if (it != _queries.cend()) {
query = it->second; query = it->second.first; // query
_cache[query] = result; if (it->second.second == 0) { // offset
_cache[query] = result;
}
_queries.erase(it); _queries.erase(it);
} }
} }
@ -155,34 +173,25 @@ bool BlockedBoxSearchController::isLoading() {
return _timer.isActive() || _requestId; return _timer.isActive() || _requestId;
} }
class BlockedBoxController : public PeerListController, private base::Subscriber, private MTP::Sender, public base::enable_weak_from_this { bool BlockedBoxSearchController::loadMoreRows() {
public: if (_query.isEmpty()) {
BlockedBoxController(gsl::not_null<ChannelData*> channel, bool restricted);
void prepare() override;
void rowClicked(gsl::not_null<PeerListRow*> row) override;
void rowActionClicked(gsl::not_null<PeerListRow*> row) override;
void preloadRows() override;
bool searchInLocal() override {
return false; return false;
} }
if (!_allLoaded && !isLoading()) {
void peerListSearchAddRow(gsl::not_null<PeerData*> peer) override; auto filter = _restricted ? MTP_channelParticipantsBanned(MTP_string(_query)) : MTP_channelParticipantsKicked(MTP_string(_query));
_requestId = request(MTPchannels_GetParticipants(_channel->inputChannel, filter, MTP_int(_offset), MTP_int(kBlockedPerPage))).done([this](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) {
private: searchDone(result, requestId);
bool appendRow(UserData *user); }).fail([this](const RPCError &error, mtpRequestId requestId) {
bool prependRow(UserData *user); if (_requestId == requestId) {
std::unique_ptr<PeerListRow> createRow(UserData *user) const; _requestId = 0;
_allLoaded = true;
gsl::not_null<ChannelData*> _channel; delegate()->peerListSearchRefreshRows();
bool _restricted = false; }
int _offset = 0; }).send();
mtpRequestId _loadRequestId = 0; _queries.emplace(_requestId, std::make_pair(_query, _offset));
bool _allLoaded = false; }
std::map<UserData*, MTPChannelBannedRights> _rights; return true;
QPointer<EditRestrictedBox> _editBox; }
};
void BlockedBoxController::peerListSearchAddRow(gsl::not_null<PeerData*> peer) { void BlockedBoxController::peerListSearchAddRow(gsl::not_null<PeerData*> peer) {
PeerListController::peerListSearchAddRow(peer); PeerListController::peerListSearchAddRow(peer);
@ -203,10 +212,13 @@ void BlockedBoxController::prepare() {
setSearchNoResultsText(lang(lng_blocked_list_not_found)); setSearchNoResultsText(lang(lng_blocked_list_not_found));
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
preloadRows(); loadMoreRows();
} }
void BlockedBoxController::preloadRows() { void BlockedBoxController::loadMoreRows() {
if (searchController()->loadMoreRows()) {
return;
}
if (_loadRequestId || _allLoaded) { if (_loadRequestId || _allLoaded) {
return; return;
} }
@ -269,10 +281,10 @@ void BlockedBoxController::rowActionClicked(gsl::not_null<PeerListRow*> row) {
if (rights.c_channelBannedRights().vflags.v == 0 || rights.c_channelBannedRights().is_view_messages()) { if (rights.c_channelBannedRights().vflags.v == 0 || rights.c_channelBannedRights().is_view_messages()) {
if (auto row = weak->delegate()->peerListFindRow(user->id)) { if (auto row = weak->delegate()->peerListFindRow(user->id)) {
weak->delegate()->peerListRemoveRow(row); weak->delegate()->peerListRemoveRow(row);
weak->delegate()->peerListRefreshRows();
if (!weak->delegate()->peerListFullRowsCount()) { if (!weak->delegate()->peerListFullRowsCount()) {
weak->setDescriptionText(lang(lng_blocked_list_not_found)); weak->setDescriptionText(lang(lng_blocked_list_not_found));
} }
weak->delegate()->peerListRefreshRows();
} }
} else { } else {
weak->_rights[user] = rights; weak->_rights[user] = rights;

View File

@ -104,10 +104,10 @@ void BlockedBoxController::prepare() {
} }
})); }));
preloadRows(); loadMoreRows();
} }
void BlockedBoxController::preloadRows() { void BlockedBoxController::loadMoreRows() {
if (_loadRequestId || _allLoaded) { if (_loadRequestId || _allLoaded) {
return; return;
} }

View File

@ -31,7 +31,7 @@ public:
void prepare() override; void prepare() override;
void rowClicked(gsl::not_null<PeerListRow*> row) override; void rowClicked(gsl::not_null<PeerListRow*> row) override;
void rowActionClicked(gsl::not_null<PeerListRow*> row) override; void rowActionClicked(gsl::not_null<PeerListRow*> row) override;
void preloadRows() override; void loadMoreRows() override;
static void BlockNewUser(); static void BlockNewUser();