Load folders exceptions after 100 chats.

This commit is contained in:
John Preston 2020-03-25 22:25:50 +04:00
parent b054c3e7e6
commit c3b807d483
4 changed files with 78 additions and 6 deletions

View file

@ -895,7 +895,11 @@ void ApiWrap::refreshDialogsLoadBlocked() {
}
void ApiWrap::requestMoreDialogsIfNeeded() {
if (_dialogsLoadState && !_dialogsLoadState->listReceived) {
const auto dialogsReady = !_dialogsLoadState
|| _dialogsLoadState->listReceived;
if (_session->data().chatsFilters().loadNextExceptions(dialogsReady)) {
return;
} else if (_dialogsLoadState && !_dialogsLoadState->listReceived) {
if (_dialogsLoadState->requestId) {
return;
}

View file

@ -14,7 +14,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_session.h"
#include "data/data_folder.h"
#include "data/data_histories.h"
#include "dialogs/dialogs_main_list.h"
#include "ui/ui_utility.h"
#include "main/main_session.h"
#include "apiwrap.h"
@ -22,6 +24,8 @@ namespace Data {
namespace {
constexpr auto kRefreshSuggestedTimeout = 7200 * crl::time(1000);
constexpr auto kLoadExceptionsAfter = 100;
constexpr auto kLoadExceptionsPerRequest = 100;
} // namespace
@ -344,8 +348,12 @@ void ChatFilters::applyRemove(int position) {
}
bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) {
const auto rulesChanged = (filter.flags() != updated.flags())
|| (filter.always() != updated.always())
Expects(filter.id() == updated.id());
const auto id = filter.id();
const auto exceptionsChanged = filter.always() != updated.always();
const auto rulesChanged = exceptionsChanged
|| (filter.flags() != updated.flags())
|| (filter.never() != updated.never());
const auto pinnedChanged = (filter.pinned() != updated.pinned());
if (!rulesChanged
@ -355,7 +363,6 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) {
return false;
}
if (rulesChanged) {
const auto id = filter.id();
const auto filterList = _owner->chatsFilters().chatsList(id);
const auto feedHistory = [&](not_null<History*> history) {
const auto now = updated.contains(history);
@ -379,9 +386,14 @@ bool ChatFilters::applyChange(ChatFilter &filter, ChatFilter &&updated) {
if (const auto folder = _owner->folderLoaded(Data::Folder::kId)) {
feedList(folder->chatsList());
}
if (exceptionsChanged && !updated.always().empty()) {
_exceptionsToLoad.push_back(id);
Ui::PostponeCall(&_owner->session(), [=] {
_owner->session().api().requestMoreDialogsIfNeeded();
});
}
}
if (pinnedChanged) {
const auto id = filter.id();
const auto filterList = _owner->chatsFilters().chatsList(id);
filterList->pinned()->applyList(updated.pinned());
}
@ -496,6 +508,56 @@ rpl::producer<> ChatFilters::changed() const {
return _listChanged.events();
}
bool ChatFilters::loadNextExceptions(bool chatsListLoaded) {
if (_exceptionsLoadRequestId) {
return true;
} else if (!chatsListLoaded
&& (_owner->chatsList()->fullSize().current()
< kLoadExceptionsAfter)) {
return false;
}
auto inputs = QVector<MTPInputDialogPeer>();
const auto collectExceptions = [&](FilterId id) {
auto result = QVector<MTPInputDialogPeer>();
const auto i = ranges::find(_list, id, &ChatFilter::id);
if (i != end(_list)) {
result.reserve(i->always().size());
for (const auto history : i->always()) {
if (!history->folderKnown()) {
inputs.push_back(
MTP_inputDialogPeer(history->peer->input));
}
}
}
return result;
};
while (!_exceptionsToLoad.empty()) {
const auto id = _exceptionsToLoad.front();
const auto exceptions = collectExceptions(id);
if (inputs.size() + exceptions.size() > kLoadExceptionsPerRequest) {
Assert(!inputs.isEmpty());
break;
}
_exceptionsToLoad.pop_front();
inputs.append(exceptions);
}
if (inputs.isEmpty()) {
return false;
}
const auto api = &_owner->session().api();
_exceptionsLoadRequestId = api->request(MTPmessages_GetPeerDialogs(
MTP_vector(inputs)
)).done([=](const MTPmessages_PeerDialogs &result) {
_exceptionsLoadRequestId = 0;
_owner->session().data().histories().applyPeerDialogs(result);
_owner->session().api().requestMoreDialogsIfNeeded();
}).fail([=](const RPCError &error) {
_exceptionsLoadRequestId = 0;
_owner->session().api().requestMoreDialogsIfNeeded();
}).send();
return true;
}
void ChatFilters::refreshHistory(not_null<History*> history) {
_refreshHistoryRequests.fire_copy(history);
}

View file

@ -102,6 +102,8 @@ public:
[[nodiscard]] const std::vector<ChatFilter> &list() const;
[[nodiscard]] rpl::producer<> changed() const;
bool loadNextExceptions(bool chatsListLoaded);
void refreshHistory(not_null<History*> history);
[[nodiscard]] auto refreshHistoryRequests() const
-> rpl::producer<not_null<History*>>;
@ -146,6 +148,9 @@ private:
rpl::event_stream<> _suggestedUpdated;
crl::time _suggestedLastReceived = 0;
std::deque<FilterId> _exceptionsToLoad;
mtpRequestId _exceptionsLoadRequestId = 0;
};
} // namespace Data

View file

@ -39,6 +39,8 @@ public:
[[nodiscard]] History *find(PeerId peerId);
[[nodiscard]] not_null<History*> findOrCreate(PeerId peerId);
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
void unloadAll();
void clearAll();
@ -108,7 +110,6 @@ private:
void postponeRequestDialogEntries();
void sendDialogRequests();
void applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs);
const not_null<Session*> _owner;