Use server-side my_results in contacts.search.

This commit is contained in:
John Preston 2018-01-22 13:58:11 +03:00
parent 4527c03c0d
commit 840b42934b
13 changed files with 224 additions and 93 deletions

View file

@ -35,6 +35,7 @@ namespace {
constexpr auto kMaxGroupChannelTitle = 255; constexpr auto kMaxGroupChannelTitle = 255;
constexpr auto kMaxChannelDescription = 255; constexpr auto kMaxChannelDescription = 255;
constexpr auto kMaxBioLength = 70; constexpr auto kMaxBioLength = 70;
constexpr auto kMinUsernameLength = 5;
style::InputField CreateBioFieldStyle() { style::InputField CreateBioFieldStyle() {
auto result = st::newGroupDescription; auto result = st::newGroupDescription;
@ -767,7 +768,7 @@ void SetupChannelBox::onChange() {
return; return;
} }
} }
if (name.size() < MinUsernameLength) { if (name.size() < kMinUsernameLength) {
if (_errorText != lang(lng_create_channel_link_too_short)) { if (_errorText != lang(lng_create_channel_link_too_short)) {
_errorText = lang(lng_create_channel_link_too_short); _errorText = lang(lng_create_channel_link_too_short);
update(); update();
@ -788,9 +789,14 @@ void SetupChannelBox::onCheck() {
MTP::cancel(_checkRequestId); MTP::cancel(_checkRequestId);
} }
QString link = _link->text().trimmed(); QString link = _link->text().trimmed();
if (link.size() >= MinUsernameLength) { if (link.size() >= kMinUsernameLength) {
_checkUsername = link; _checkUsername = link;
_checkRequestId = MTP::send(MTPchannels_CheckUsername(_channel->inputChannel, MTP_string(link)), rpcDone(&SetupChannelBox::onCheckDone), rpcFail(&SetupChannelBox::onCheckFail)); _checkRequestId = MTP::send(
MTPchannels_CheckUsername(
_channel->inputChannel,
MTP_string(link)),
rpcDone(&SetupChannelBox::onCheckDone),
rpcFail(&SetupChannelBox::onCheckFail));
} }
} }

View file

@ -149,7 +149,7 @@ void PeerListGlobalSearchController::searchQuery(const QString &query) {
if (_query != query) { if (_query != query) {
_query = query; _query = query;
_requestId = 0; _requestId = 0;
if (_query.size() >= MinUsernameLength && !searchInCache()) { if (!_query.isEmpty() && !searchInCache()) {
_timer.callOnce(AutoSearchTimeout); _timer.callOnce(AutoSearchTimeout);
} else { } else {
_timer.cancel(); _timer.cancel();
@ -168,9 +168,12 @@ bool PeerListGlobalSearchController::searchInCache() {
} }
void PeerListGlobalSearchController::searchOnServer() { void PeerListGlobalSearchController::searchOnServer() {
_requestId = request(MTPcontacts_Search(MTP_string(_query), MTP_int(SearchPeopleLimit))).done([this](const MTPcontacts_Found &result, mtpRequestId requestId) { _requestId = request(MTPcontacts_Search(
MTP_string(_query),
MTP_int(SearchPeopleLimit)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
searchDone(result, requestId); searchDone(result, requestId);
}).fail([this](const RPCError &error, mtpRequestId requestId) { }).fail([=](const RPCError &error, mtpRequestId requestId) {
if (_requestId == requestId) { if (_requestId == requestId) {
_requestId = 0; _requestId = 0;
delegate()->peerListSearchRefreshRows(); delegate()->peerListSearchRefreshRows();
@ -179,7 +182,9 @@ void PeerListGlobalSearchController::searchOnServer() {
_queries.emplace(_requestId, _query); _queries.emplace(_requestId, _query);
} }
void PeerListGlobalSearchController::searchDone(const MTPcontacts_Found &result, mtpRequestId requestId) { void PeerListGlobalSearchController::searchDone(
const MTPcontacts_Found &result,
mtpRequestId requestId) {
Expects(result.type() == mtpc_contacts_found); Expects(result.type() == mtpc_contacts_found);
auto &contacts = result.c_contacts_found(); auto &contacts = result.c_contacts_found();
@ -194,13 +199,17 @@ void PeerListGlobalSearchController::searchDone(const MTPcontacts_Found &result,
_queries.erase(it); _queries.erase(it);
} }
} }
if (_requestId == requestId) { const auto feedList = [&](const MTPVector<MTPPeer> &list) {
_requestId = 0; for (const auto &mtpPeer : list.v) {
for_const (auto &mtpPeer, contacts.vresults.v) { if (const auto peer = App::peerLoaded(peerFromMTP(mtpPeer))) {
if (auto peer = App::peerLoaded(peerFromMTP(mtpPeer))) {
delegate()->peerListSearchAddRow(peer); delegate()->peerListSearchAddRow(peer);
} }
} }
};
if (_requestId == requestId) {
_requestId = 0;
feedList(contacts.vmy_results);
feedList(contacts.vresults);
delegate()->peerListSearchRefreshRows(); delegate()->peerListSearchRefreshRows();
} }
} }

View file

@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace { namespace {
constexpr auto kUsernameCheckTimeout = TimeMs(200); constexpr auto kUsernameCheckTimeout = TimeMs(200);
constexpr auto kMinUsernameLength = 5;
class Controller class Controller
: private MTP::Sender : private MTP::Sender
@ -503,7 +504,7 @@ void Controller::checkUsernameAvailability() {
auto checking = initial auto checking = initial
? qsl(".bad.") ? qsl(".bad.")
: _controls.username->getLastText().trimmed(); : _controls.username->getLastText().trimmed();
if (checking.size() < MinUsernameLength) { if (checking.size() < kMinUsernameLength) {
return; return;
} }
if (_checkUsernameRequestId) { if (_checkUsernameRequestId) {
@ -580,7 +581,7 @@ void Controller::usernameChanged() {
if (bad) { if (bad) {
showUsernameError( showUsernameError(
Lang::Viewer(lng_create_channel_link_bad_symbols)); Lang::Viewer(lng_create_channel_link_bad_symbols));
} else if (username.size() < MinUsernameLength) { } else if (username.size() < kMinUsernameLength) {
showUsernameError( showUsernameError(
Lang::Viewer(lng_create_channel_link_too_short)); Lang::Viewer(lng_create_channel_link_too_short));
} else { } else {

View file

@ -93,7 +93,7 @@ bool ShareBox::onSearchByUsername(bool searchCache) {
} }
return true; return true;
} }
if (query.size() >= MinUsernameLength) { if (!query.isEmpty()) {
if (searchCache) { if (searchCache) {
auto i = _peopleCache.constFind(query); auto i = _peopleCache.constFind(query);
if (i != _peopleCache.cend()) { if (i != _peopleCache.cend()) {
@ -105,7 +105,12 @@ bool ShareBox::onSearchByUsername(bool searchCache) {
} else if (_peopleQuery != query) { } else if (_peopleQuery != query) {
_peopleQuery = query; _peopleQuery = query;
_peopleFull = false; _peopleFull = false;
_peopleRequest = MTP::send(MTPcontacts_Search(MTP_string(_peopleQuery), MTP_int(SearchPeopleLimit)), rpcDone(&ShareBox::peopleReceived), rpcFail(&ShareBox::peopleFailed)); _peopleRequest = MTP::send(
MTPcontacts_Search(
MTP_string(_peopleQuery),
MTP_int(SearchPeopleLimit)),
rpcDone(&ShareBox::peopleReceived),
rpcFail(&ShareBox::peopleFailed));
_peopleQueries.insert(_peopleRequest, _peopleQuery); _peopleQueries.insert(_peopleRequest, _peopleQuery);
} }
} }
@ -118,7 +123,11 @@ void ShareBox::onNeedSearchByUsername() {
} }
} }
void ShareBox::peopleReceived(const MTPcontacts_Found &result, mtpRequestId requestId) { void ShareBox::peopleReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId) {
Expects(result.type() == mtpc_contacts_found);
auto query = _peopleQuery; auto query = _peopleQuery;
auto i = _peopleQueries.find(requestId); auto i = _peopleQueries.find(requestId);
@ -134,7 +143,10 @@ void ShareBox::peopleReceived(const MTPcontacts_Found &result, mtpRequestId requ
auto &found = result.c_contacts_found(); auto &found = result.c_contacts_found();
App::feedUsers(found.vusers); App::feedUsers(found.vusers);
App::feedChats(found.vchats); App::feedChats(found.vchats);
_inner->peopleReceived(query, found.vresults.v); _inner->peopleReceived(
query,
found.vmy_results.v,
found.vresults.v);
} break; } break;
} }
@ -764,33 +776,36 @@ void ShareBox::Inner::updateFilter(QString filter) {
} }
} }
void ShareBox::Inner::peopleReceived(const QString &query, const QVector<MTPPeer> &people) { void ShareBox::Inner::peopleReceived(
const QString &query,
const QVector<MTPPeer> &my,
const QVector<MTPPeer> &people) {
_lastQuery = query.toLower().trimmed(); _lastQuery = query.toLower().trimmed();
if (_lastQuery.at(0) == '@') _lastQuery = _lastQuery.mid(1); if (_lastQuery.at(0) == '@') _lastQuery = _lastQuery.mid(1);
int32 already = _byUsernameFiltered.size(); int32 already = _byUsernameFiltered.size();
_byUsernameFiltered.reserve(already + people.size()); _byUsernameFiltered.reserve(already + my.size() + people.size());
d_byUsernameFiltered.reserve(already + people.size()); d_byUsernameFiltered.reserve(already + my.size() + people.size());
for_const (auto &mtpPeer, people) { const auto feedList = [&](const QVector<MTPPeer> &list) {
auto peerId = peerFromMTP(mtpPeer); for (const auto &mtpPeer : list) {
int j = 0; if (const auto peer = App::peerLoaded(peerFromMTP(mtpPeer))) {
for (; j < already; ++j) {
if (_byUsernameFiltered[j]->id == peerId) break;
}
if (j == already) {
const auto peer = App::peer(peerId);
const auto history = App::historyLoaded(peer); const auto history = App::historyLoaded(peer);
if (!peer || !_filterCallback(peer)) { if (!_filterCallback(peer)) {
continue; continue;
} else if (history && _chatsIndexed->getRow(history)) { } else if (history && _chatsIndexed->getRow(history)) {
continue; continue;
} else if (base::contains(_byUsernameFiltered, peer)) {
continue;
} }
auto chat = new Chat(peer, [=] { repaintChat(peer); });
auto chat = new Chat(peer, [this, peer] { repaintChat(peer); });
updateChatName(chat, peer); updateChatName(chat, peer);
_byUsernameFiltered.push_back(peer); _byUsernameFiltered.push_back(peer);
d_byUsernameFiltered.push_back(chat); d_byUsernameFiltered.push_back(chat);
} }
} }
};
feedList(my);
feedList(people);
_searching = false; _searching = false;
refresh(); refresh();
} }

View file

@ -65,7 +65,9 @@ private:
void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false); void addPeerToMultiSelect(PeerData *peer, bool skipAnimation = false);
void onPeerSelectedChanged(PeerData *peer, bool checked); void onPeerSelectedChanged(PeerData *peer, bool checked);
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId requestId); void peopleReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId);
bool peopleFailed(const RPCError &error, mtpRequestId requestId); bool peopleFailed(const RPCError &error, mtpRequestId requestId);
CopyCallback _copyCallback; CopyCallback _copyCallback;
@ -107,7 +109,10 @@ public:
QVector<PeerData*> selected() const; QVector<PeerData*> selected() const;
bool hasSelected() const; bool hasSelected() const;
void peopleReceived(const QString &query, const QVector<MTPPeer> &people); void peopleReceived(
const QString &query,
const QVector<MTPPeer> &my,
const QVector<MTPPeer> &people);
void activateSkipRow(int direction); void activateSkipRow(int direction);
void activateSkipColumn(int direction); void activateSkipColumn(int direction);

View file

@ -17,6 +17,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
#include "messenger.h" #include "messenger.h"
namespace {
constexpr auto kMinUsernameLength = 5;
} // namespace
UsernameBox::UsernameBox(QWidget*) UsernameBox::UsernameBox(QWidget*)
: _username(this, st::defaultInputField, [] { return qsl("@username"); }, App::self()->username, false) : _username(this, st::defaultInputField, [] { return qsl("@username"); }, App::self()->username, false)
, _link(this, QString(), st::boxLinkButton) , _link(this, QString(), st::boxLinkButton)
@ -102,9 +108,13 @@ void UsernameBox::onCheck() {
MTP::cancel(_checkRequestId); MTP::cancel(_checkRequestId);
} }
QString name = getName(); QString name = getName();
if (name.size() >= MinUsernameLength) { if (name.size() >= kMinUsernameLength) {
_checkUsername = name; _checkUsername = name;
_checkRequestId = MTP::send(MTPaccount_CheckUsername(MTP_string(name)), rpcDone(&UsernameBox::onCheckDone), rpcFail(&UsernameBox::onCheckFail)); _checkRequestId = MTP::send(
MTPaccount_CheckUsername(
MTP_string(name)),
rpcDone(&UsernameBox::onCheckDone),
rpcFail(&UsernameBox::onCheckFail));
} }
} }
@ -130,7 +140,7 @@ void UsernameBox::onChanged() {
return; return;
} }
} }
if (name.size() < MinUsernameLength) { if (name.size() < kMinUsernameLength) {
if (_errorText != lang(lng_username_too_short)) { if (_errorText != lang(lng_username_too_short)) {
_errorText = lang(lng_username_too_short); _errorText = lang(lng_username_too_short);
update(); update();

View file

@ -90,8 +90,6 @@ enum {
PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request PreloadHeightsCount = 3, // when 3 screens to scroll left make a preload request
SearchPeopleLimit = 5, SearchPeopleLimit = 5,
MinUsernameLength = 5,
MaxUsernameLength = 32,
UsernameCheckTimeout = 200, UsernameCheckTimeout = 200,
MaxPhotoCaption = 200, MaxPhotoCaption = 200,

View file

@ -318,6 +318,7 @@ void DialogsInner::paintRegion(Painter &p, const QRegion &region, bool paintingO
auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size()); auto to = ceilclamp(r.y() + r.height() - skip, st::dialogsRowHeight, 0, _filterResults.size());
p.translate(0, from * st::dialogsRowHeight); p.translate(0, from * st::dialogsRowHeight);
if (from < _filterResults.size()) { if (from < _filterResults.size()) {
// #TODO feeds show
const auto activePeer = App::main()->activePeer(); const auto activePeer = App::main()->activePeer();
const auto activeMsgId = App::main()->activeMsgId(); const auto activeMsgId = App::main()->activeMsgId();
for (; from < to; ++from) { for (; from < to; ++from) {
@ -1083,7 +1084,9 @@ void DialogsInner::resizeEvent(QResizeEvent *e) {
_cancelSearchFromUser->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width(), st::searchedBarHeight + st::dialogsSearchInHeight + st::lineWidth + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2); _cancelSearchFromUser->moveToLeft(widthForCancelButton - st::dialogsSearchInSkip - _cancelSearchFromUser->width(), st::searchedBarHeight + st::dialogsSearchInHeight + st::lineWidth + (st::dialogsSearchInHeight - st::dialogsCancelSearchInPeer.height) / 2);
} }
void DialogsInner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow) { void DialogsInner::onDialogRowReplaced(
Dialogs::Row *oldRow,
Dialogs::Row *newRow) {
if (_state == State::Filtered) { if (_state == State::Filtered) {
for (auto i = _filterResults.begin(); i != _filterResults.end();) { for (auto i = _filterResults.begin(); i != _filterResults.end();) {
if (*i == oldRow) { // this row is shown in filtered and maybe is in contacts! if (*i == oldRow) { // this row is shown in filtered and maybe is in contacts!
@ -1488,6 +1491,7 @@ void DialogsInner::onFilterUpdate(QString newFilter, bool force) {
_state = State::Filtered; _state = State::Filtered;
_waitingForSearch = true; _waitingForSearch = true;
_filterResults.clear(); _filterResults.clear();
_filterResultsGlobal.clear();
if (!_searchInPeer && !words.isEmpty()) { if (!_searchInPeer && !words.isEmpty()) {
const Dialogs::List *toFilter = nullptr; const Dialogs::List *toFilter = nullptr;
if (!_dialogs->isEmpty()) { if (!_dialogs->isEmpty()) {
@ -1771,7 +1775,7 @@ void DialogsInner::addAllSavedPeers() {
bool DialogsInner::searchReceived( bool DialogsInner::searchReceived(
const QVector<MTPMessage> &messages, const QVector<MTPMessage> &messages,
DialogsSearchRequestType type, DialogsSearchRequestType type,
int32 fullCount) { int fullCount) {
if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) { if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) {
clearSearchResults(false); clearSearchResults(false);
} }
@ -1820,21 +1824,54 @@ bool DialogsInner::searchReceived(
return lastDateFound != 0; return lastDateFound != 0;
} }
void DialogsInner::peerSearchReceived(const QString &query, const QVector<MTPPeer> &result) { void DialogsInner::peerSearchReceived(
const QString &query,
const QVector<MTPPeer> &my,
const QVector<MTPPeer> &result) {
if (_state != State::Filtered) {
return;
}
_peerSearchQuery = query.toLower().trimmed(); _peerSearchQuery = query.toLower().trimmed();
_peerSearchResults.clear(); _peerSearchResults.clear();
_peerSearchResults.reserve(result.size()); _peerSearchResults.reserve(result.size());
for (auto i = result.cbegin(), e = result.cend(); i != e; ++i) { for (const auto &mtpPeer : my) {
auto peerId = peerFromMTP(*i); if (const auto peer = App::peerLoaded(peerFromMTP(mtpPeer))) {
if (auto history = App::historyLoaded(peerId)) { if (const auto history = App::historyLoaded(peer)) {
if (history->inChatList(Dialogs::Mode::All)) { if (history->inChatList(Dialogs::Mode::All)) {
continue; // skip existing chats continue; // skip existing chats
} }
} }
if (auto peer = App::peerLoaded(peerId)) { const auto prev = nullptr, next = nullptr;
_peerSearchResults.push_back(std::make_unique<PeerSearchResult>(App::peer(peerId))); const auto position = 0;
auto row = std::make_unique<Dialogs::Row>(
App::history(peer),
prev,
next,
position);
const auto [i, ok] = _filterResultsGlobal.emplace(
peer,
std::move(row));
_filterResults.push_back(i->second.get());
} else { } else {
LOG(("API Error: user %1 was not loaded in DialogsInner::peopleReceived()").arg(peerId)); LOG(("API Error: "
"user %1 was not loaded in DialogsInner::peopleReceived()"
).arg(peer->id));
}
}
for (const auto &mtpPeer : result) {
if (const auto peer = App::peerLoaded(peerFromMTP(mtpPeer))) {
if (const auto history = App::historyLoaded(peer)) {
if (history->inChatList(Dialogs::Mode::All)) {
continue; // skip existing chats
}
}
_peerSearchResults.push_back(std::make_unique<PeerSearchResult>(
peer));
} else {
LOG(("API Error: "
"user %1 was not loaded in DialogsInner::peopleReceived()"
).arg(peer->id));
} }
} }
refresh(); refresh();
@ -2007,6 +2044,7 @@ void DialogsInner::clearFilter() {
} }
_hashtagResults.clear(); _hashtagResults.clear();
_filterResults.clear(); _filterResults.clear();
_filterResultsGlobal.clear();
_peerSearchResults.clear(); _peerSearchResults.clear();
_searchResults.clear(); _searchResults.clear();
_lastSearchDate = 0; _lastSearchDate = 0;
@ -2370,6 +2408,7 @@ void DialogsInner::destroyData() {
_hashtagResults.clear(); _hashtagResults.clear();
_filteredSelected = -1; _filteredSelected = -1;
_filterResults.clear(); _filterResults.clear();
_filterResultsGlobal.clear();
_filter.clear(); _filter.clear();
_searchedSelected = _peerSearchSelected = -1; _searchedSelected = _peerSearchSelected = -1;
clearSearchResults(); clearSearchResults();

View file

@ -36,8 +36,14 @@ public:
void dialogsReceived(const QVector<MTPDialog> &dialogs); void dialogsReceived(const QVector<MTPDialog> &dialogs);
void addSavedPeersAfter(const QDateTime &date); void addSavedPeersAfter(const QDateTime &date);
void addAllSavedPeers(); void addAllSavedPeers();
bool searchReceived(const QVector<MTPMessage> &result, DialogsSearchRequestType type, int32 fullCount); bool searchReceived(
void peerSearchReceived(const QString &query, const QVector<MTPPeer> &result); const QVector<MTPMessage> &result,
DialogsSearchRequestType type,
int fullCount);
void peerSearchReceived(
const QString &query,
const QVector<MTPPeer> &my,
const QVector<MTPPeer> &result);
void showMore(int32 pixels); void showMore(int32 pixels);
void activate(); void activate();
@ -300,6 +306,9 @@ private:
bool _hashtagDeletePressed = false; bool _hashtagDeletePressed = false;
FilteredDialogs _filterResults; FilteredDialogs _filterResults;
base::flat_map<
not_null<PeerData*>,
std::unique_ptr<Dialogs::Row>> _filterResultsGlobal;
int _filteredSelected = -1; int _filteredSelected = -1;
int _filteredPressed = -1; int _filteredPressed = -1;

View file

@ -472,13 +472,18 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
return true; return true;
} }
if (searchCache) { if (searchCache) {
SearchCache::const_iterator i = _searchCache.constFind(q); const auto i = _searchCache.constFind(q);
if (i != _searchCache.cend()) { if (i != _searchCache.cend()) {
_searchQuery = q; _searchQuery = q;
_searchQueryFrom = _searchFromUser; _searchQueryFrom = _searchFromUser;
_searchFull = _searchFullMigrated = false; _searchFull = _searchFullMigrated = false;
MTP::cancel(base::take(_searchRequest)); MTP::cancel(base::take(_searchRequest));
searchReceived(_searchInPeer ? DialogsSearchPeerFromStart : DialogsSearchFromStart, i.value(), 0); searchReceived(
_searchInPeer
? DialogsSearchPeerFromStart
: DialogsSearchFromStart,
i.value(),
0);
return true; return true;
} }
} else if (_searchQuery != q || _searchQueryFrom != _searchFromUser) { } else if (_searchQuery != q || _searchQueryFrom != _searchFromUser) {
@ -487,7 +492,9 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
_searchFull = _searchFullMigrated = false; _searchFull = _searchFullMigrated = false;
MTP::cancel(base::take(_searchRequest)); MTP::cancel(base::take(_searchRequest));
if (_searchInPeer) { if (_searchInPeer) {
auto flags = _searchQueryFrom ? MTP_flags(MTPmessages_Search::Flag::f_from_id) : MTP_flags(0); const auto flags = _searchQueryFrom
? MTP_flags(MTPmessages_Search::Flag::f_from_id)
: MTP_flags(0);
_searchRequest = MTP::send( _searchRequest = MTP::send(
MTPmessages_Search( MTPmessages_Search(
flags, flags,
@ -520,7 +527,7 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
} }
_searchQueries.insert(_searchRequest, _searchQuery); _searchQueries.insert(_searchRequest, _searchQuery);
} }
if (!_searchInPeer && q.size() >= MinUsernameLength) { if (!_searchInPeer && !q.isEmpty()) {
if (searchCache) { if (searchCache) {
auto i = _peerSearchCache.constFind(q); auto i = _peerSearchCache.constFind(q);
if (i != _peerSearchCache.cend()) { if (i != _peerSearchCache.cend()) {
@ -532,7 +539,12 @@ bool DialogsWidget::onSearchMessages(bool searchCache) {
} else if (_peerSearchQuery != q) { } else if (_peerSearchQuery != q) {
_peerSearchQuery = q; _peerSearchQuery = q;
_peerSearchFull = false; _peerSearchFull = false;
_peerSearchRequest = MTP::send(MTPcontacts_Search(MTP_string(_peerSearchQuery), MTP_int(SearchPeopleLimit)), rpcDone(&DialogsWidget::peerSearchReceived), rpcFail(&DialogsWidget::peopleFailed)); _peerSearchRequest = MTP::send(
MTPcontacts_Search(
MTP_string(_peerSearchQuery),
MTP_int(SearchPeopleLimit)),
rpcDone(&DialogsWidget::peerSearchReceived),
rpcFail(&DialogsWidget::peopleFailed));
_peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery); _peerSearchQueries.insert(_peerSearchRequest, _peerSearchQuery);
} }
} }
@ -673,12 +685,15 @@ void DialogsWidget::loadPinnedDialogs() {
_pinnedDialogsRequestId = MTP::send(MTPmessages_GetPinnedDialogs(), rpcDone(&DialogsWidget::pinnedDialogsReceived), rpcFail(&DialogsWidget::dialogsFailed)); _pinnedDialogsRequestId = MTP::send(MTPmessages_GetPinnedDialogs(), rpcDone(&DialogsWidget::pinnedDialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
} }
void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req) { void DialogsWidget::searchReceived(
DialogsSearchRequestType type,
const MTPmessages_Messages &result,
mtpRequestId requestId) {
using State = DialogsInner::State; using State = DialogsInner::State;
const auto state = _inner->state(); const auto state = _inner->state();
if (state == State::Filtered) { if (state == State::Filtered) {
if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) { if (type == DialogsSearchFromStart || type == DialogsSearchPeerFromStart) {
auto i = _searchQueries.find(req); auto i = _searchQueries.find(requestId);
if (i != _searchQueries.cend()) { if (i != _searchQueries.cend()) {
_searchCache[i.value()] = result; _searchCache[i.value()] = result;
_searchQueries.erase(i); _searchQueries.erase(i);
@ -686,7 +701,7 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa
} }
} }
if (_searchRequest == req) { if (_searchRequest == requestId) {
switch (result.type()) { switch (result.type()) {
case mtpc_messages_messages: { case mtpc_messages_messages: {
auto &d = result.c_messages_messages(); auto &d = result.c_messages_messages();
@ -751,25 +766,27 @@ void DialogsWidget::searchReceived(DialogsSearchRequestType type, const MTPmessa
} }
} }
void DialogsWidget::peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId req) { void DialogsWidget::peerSearchReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId) {
using State = DialogsInner::State; using State = DialogsInner::State;
const auto state = _inner->state(); const auto state = _inner->state();
auto q = _peerSearchQuery; auto q = _peerSearchQuery;
if (state == State::Filtered) { if (state == State::Filtered) {
auto i = _peerSearchQueries.find(req); auto i = _peerSearchQueries.find(requestId);
if (i != _peerSearchQueries.cend()) { if (i != _peerSearchQueries.cend()) {
q = i.value(); q = i.value();
_peerSearchCache[q] = result; _peerSearchCache[q] = result;
_peerSearchQueries.erase(i); _peerSearchQueries.erase(i);
} }
} }
if (_peerSearchRequest == req) { if (_peerSearchRequest == requestId) {
switch (result.type()) { switch (result.type()) {
case mtpc_contacts_found: { case mtpc_contacts_found: {
auto &d = result.c_contacts_found(); auto &d = result.c_contacts_found();
App::feedUsers(d.vusers); App::feedUsers(d.vusers);
App::feedChats(d.vchats); App::feedChats(d.vchats);
_inner->peerSearchReceived(q, d.vresults.v); _inner->peerSearchReceived(q, d.vmy_results.v, d.vresults.v);
} break; } break;
} }
@ -778,10 +795,13 @@ void DialogsWidget::peerSearchReceived(const MTPcontacts_Found &result, mtpReque
} }
} }
bool DialogsWidget::searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req) { bool DialogsWidget::searchFailed(
DialogsSearchRequestType type,
const RPCError &error,
mtpRequestId requestId) {
if (MTP::isDefaultHandledError(error)) return false; if (MTP::isDefaultHandledError(error)) return false;
if (_searchRequest == req) { if (_searchRequest == requestId) {
_searchRequest = 0; _searchRequest = 0;
if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) { if (type == DialogsSearchMigratedFromStart || type == DialogsSearchMigratedFromOffset) {
_searchFullMigrated = true; _searchFullMigrated = true;
@ -891,7 +911,7 @@ void DialogsWidget::onFilterUpdate(bool force) {
_cancelSearch->toggle(!filterText.isEmpty(), anim::type::normal); _cancelSearch->toggle(!filterText.isEmpty(), anim::type::normal);
updateJumpToDateVisibility(); updateJumpToDateVisibility();
if (filterText.size() < MinUsernameLength) { if (filterText.isEmpty()) {
_peerSearchCache.clear(); _peerSearchCache.clear();
_peerSearchQueries.clear(); _peerSearchQueries.clear();
_peerSearchQuery = QString(); _peerSearchQuery = QString();

View file

@ -140,8 +140,13 @@ private:
void pinnedDialogsReceived( void pinnedDialogsReceived(
const MTPmessages_PeerDialogs &result, const MTPmessages_PeerDialogs &result,
mtpRequestId requestId); mtpRequestId requestId);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId requestId); void searchReceived(
void peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId requestId); DialogsSearchRequestType type,
const MTPmessages_Messages &result,
mtpRequestId requestId);
void peerSearchReceived(
const MTPcontacts_Found &result,
mtpRequestId requestId);
void updateDialogsOffset( void updateDialogsOffset(
const QVector<MTPDialog> &dialogs, const QVector<MTPDialog> &dialogs,
const QVector<MTPMessage> &messages); const QVector<MTPMessage> &messages);

View file

@ -1829,15 +1829,18 @@ void AddParticipantBoxSearchController::searchParticipantsDone(mtpRequestId requ
} }
void AddParticipantBoxSearchController::requestGlobal() { void AddParticipantBoxSearchController::requestGlobal() {
if (_query.size() < MinUsernameLength) { if (_query.isEmpty()) {
_globalLoaded = true; _globalLoaded = true;
return; return;
} }
auto perPage = SearchPeopleLimit; auto perPage = SearchPeopleLimit;
_requestId = request(MTPcontacts_Search(MTP_string(_query), MTP_int(perPage))).done([this](const MTPcontacts_Found &result, mtpRequestId requestId) { _requestId = request(MTPcontacts_Search(
MTP_string(_query),
MTP_int(perPage)
)).done([=](const MTPcontacts_Found &result, mtpRequestId requestId) {
searchGlobalDone(requestId, result); searchGlobalDone(requestId, result);
}).fail([this](const RPCError &error, mtpRequestId requestId) { }).fail([=](const RPCError &error, mtpRequestId requestId) {
if (_requestId == requestId) { if (_requestId == requestId) {
_requestId = 0; _requestId = 0;
_globalLoaded = true; _globalLoaded = true;
@ -1863,24 +1866,31 @@ void AddParticipantBoxSearchController::searchGlobalDone(mtpRequestId requestId,
} }
} }
if (_requestId == requestId) { const auto feedList = [&](const MTPVector<MTPPeer> &list) {
_requestId = 0; const auto contains = [](const auto &map, const auto &value) {
_globalLoaded = true; return map.find(value) != map.end();
for_const (auto &mtpPeer, found.vresults.v) { };
auto peerId = peerFromMTP(mtpPeer); for (const auto &mtpPeer : list.v) {
if (auto peer = App::peerLoaded(peerId)) { const auto peerId = peerFromMTP(mtpPeer);
if (auto user = peer->asUser()) { if (const auto peer = App::peerLoaded(peerId)) {
if (_additional->adminRights.find(user) == _additional->adminRights.cend() if (const auto user = peer->asUser()) {
&& _additional->restrictedRights.find(user) == _additional->restrictedRights.cend() if (_additional->creator != user
&& _additional->external.find(user) == _additional->external.cend() && !contains(_additional->adminRights, user)
&& _additional->kicked.find(user) == _additional->kicked.cend() && !contains(_additional->restrictedRights, user)
&& _additional->creator != user) { && !contains(_additional->external, user)
&& !contains(_additional->kicked, user)) {
_additional->infoNotLoaded.emplace(user); _additional->infoNotLoaded.emplace(user);
} }
delegate()->peerListSearchAddRow(user); delegate()->peerListSearchAddRow(user);
} }
} }
} }
};
if (_requestId == requestId) {
_requestId = 0;
_globalLoaded = true;
feedList(found.vmy_results);
feedList(found.vresults);
delegate()->peerListSearchRefreshRows(); delegate()->peerListSearchRefreshRows();
} }
} }

View file

@ -18,6 +18,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui { namespace Ui {
namespace { namespace {
constexpr auto kMaxUsernameLength = 32;
template <typename InputClass> template <typename InputClass>
class InputStyle : public QCommonStyle { class InputStyle : public QCommonStyle {
public: public:
@ -3976,7 +3978,9 @@ void UsernameInput::correctValue(
if (newPos > 0) --newPos; if (newPos > 0) --newPos;
} }
len -= from; len -= from;
if (len > MaxUsernameLength) len = MaxUsernameLength + (now.at(from) == '@' ? 1 : 0); if (len > kMaxUsernameLength) {
len = kMaxUsernameLength + (now.at(from) == '@' ? 1 : 0);
}
for (int32 to = from + len; to > from;) { for (int32 to = from + len; to > from;) {
--to; --to;
if (!now.at(to).isSpace()) { if (!now.at(to).isSpace()) {