mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-29 15:01:03 +00:00
Load dialogs list in ApiWrap and Data::Session.
This commit is contained in:
parent
927735dff2
commit
305a611211
@ -88,6 +88,8 @@ constexpr auto kFileLoaderQueueStopTimeout = crl::time(5000);
|
||||
//constexpr auto kFeedReadTimeout = crl::time(1000); // #feed
|
||||
constexpr auto kStickersByEmojiInvalidateTimeout = crl::time(60 * 60 * 1000);
|
||||
constexpr auto kNotifySettingSaveTimeout = crl::time(1000);
|
||||
constexpr auto kDialogsFirstLoad = 20;
|
||||
constexpr auto kDialogsPerPage = 500;
|
||||
|
||||
using PhotoFileLocationId = Data::PhotoFileLocationId;
|
||||
using DocumentFileLocationId = Data::DocumentFileLocationId;
|
||||
@ -194,13 +196,29 @@ ApiWrap::ApiWrap(not_null<AuthSession*> session)
|
||||
, _proxyPromotionTimer([=] { refreshProxyPromotion(); })
|
||||
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); }) {
|
||||
crl::on_main([=] {
|
||||
// You can't use _session->lifetime() in the constructor,
|
||||
// only queued, because it is not constructed yet.
|
||||
_session->uploader().photoReady(
|
||||
) | rpl::start_with_next([=](const Storage::UploadedPhoto &data) {
|
||||
photoUploadReady(data.fullId, data.file);
|
||||
}, _session->lifetime());
|
||||
|
||||
setupSupportMode();
|
||||
});
|
||||
}
|
||||
|
||||
void ApiWrap::setupSupportMode() {
|
||||
if (!_session->supportMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_session->settings().supportChatsTimeSliceValue(
|
||||
) | rpl::start_with_next([=](int seconds) {
|
||||
_dialogsLoadTill = seconds ? std::max(unixtime() - seconds, 0) : 0;
|
||||
refreshDialogsLoadBlocked();
|
||||
}, _session->lifetime());
|
||||
}
|
||||
|
||||
void ApiWrap::requestChangelog(
|
||||
const QString &sinceVersion,
|
||||
Fn<void(const MTPUpdates &result)> callback) {
|
||||
@ -687,6 +705,162 @@ void ApiWrap::requestContacts() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::requestDialogs() {
|
||||
if (_dialogsRequestId) {
|
||||
return;
|
||||
} else if (_dialogsFull) {
|
||||
_session->data().addAllSavedPeers();
|
||||
return;
|
||||
} else if (_dialogsLoadBlockedByDate.current()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto firstLoad = !_dialogsOffsetDate;
|
||||
const auto loadCount = firstLoad ? kDialogsFirstLoad : kDialogsPerPage;
|
||||
const auto flags = MTPmessages_GetDialogs::Flag::f_exclude_pinned
|
||||
| MTPmessages_GetDialogs::Flag::f_folder_id;
|
||||
const auto folderId = 0;
|
||||
const auto hash = 0;
|
||||
_dialogsRequestId = request(MTPmessages_GetDialogs(
|
||||
MTP_flags(flags),
|
||||
MTP_int(folderId),
|
||||
MTP_int(_dialogsOffsetDate),
|
||||
MTP_int(_dialogsOffsetId),
|
||||
(_dialogsOffsetPeer
|
||||
? _dialogsOffsetPeer->input
|
||||
: MTP_inputPeerEmpty()),
|
||||
MTP_int(loadCount),
|
||||
MTP_int(hash)
|
||||
)).done([=](const MTPmessages_Dialogs &result) {
|
||||
result.match([](const MTPDmessages_dialogsNotModified & data) {
|
||||
LOG(("API Error: not-modified received for requested dialogs."));
|
||||
}, [&](const auto &data) {
|
||||
if constexpr (data.Is<MTPDmessages_dialogs>()) {
|
||||
_dialogsFull = true;
|
||||
}
|
||||
updateDialogsOffset(data.vdialogs.v, data.vmessages.v);
|
||||
_session->data().processUsers(data.vusers);
|
||||
_session->data().processChats(data.vchats);
|
||||
_session->data().applyDialogs(data.vmessages.v, data.vdialogs.v);
|
||||
});
|
||||
|
||||
_dialogsRequestId = 0;
|
||||
requestDialogs();
|
||||
if (!_dialogsRequestId) {
|
||||
refreshDialogsLoadBlocked();
|
||||
}
|
||||
|
||||
_session->data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull && _pinnedDialogsReceived) {
|
||||
_session->data().allChatsLoaded().set(true);
|
||||
}
|
||||
requestContacts();
|
||||
}).fail([=](const RPCError &error) {
|
||||
_dialogsRequestId = 0;
|
||||
}).send();
|
||||
if (!_pinnedDialogsReceived) {
|
||||
requestPinnedDialogs();
|
||||
}
|
||||
refreshDialogsLoadBlocked();
|
||||
}
|
||||
|
||||
void ApiWrap::refreshDialogsLoadBlocked() {
|
||||
_dialogsLoadMayBlockByDate = !_dialogsFull
|
||||
&& (_dialogsLoadTill > 0);
|
||||
_dialogsLoadBlockedByDate = !_dialogsFull
|
||||
&& !_dialogsRequestId
|
||||
&& (_dialogsLoadTill > 0)
|
||||
&& (_dialogsOffsetDate > 0)
|
||||
&& (_dialogsOffsetDate <= _dialogsLoadTill);
|
||||
}
|
||||
|
||||
void ApiWrap::updateDialogsOffset(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages) {
|
||||
auto lastDate = TimeId(0);
|
||||
auto lastPeer = PeerId(0);
|
||||
auto lastMsgId = MsgId(0);
|
||||
for (const auto &dialog : ranges::view::reverse(dialogs)) {
|
||||
dialog.match([&](const auto &dialog) {
|
||||
const auto peer = peerFromMTP(dialog.vpeer);
|
||||
const auto messageId = dialog.vtop_message.v;
|
||||
if (!peer || !messageId) {
|
||||
return;
|
||||
}
|
||||
if (!lastPeer) {
|
||||
lastPeer = peer;
|
||||
}
|
||||
if (!lastMsgId) {
|
||||
lastMsgId = messageId;
|
||||
}
|
||||
for (const auto &message : ranges::view::reverse(messages)) {
|
||||
if (IdFromMessage(message) == messageId
|
||||
&& PeerFromMessage(message) == peer) {
|
||||
if (const auto date = DateFromMessage(message)) {
|
||||
lastDate = date;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (lastDate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastDate) {
|
||||
_dialogsOffsetDate = lastDate;
|
||||
_dialogsOffsetId = lastMsgId;
|
||||
_dialogsOffsetPeer = _session->data().peer(lastPeer);
|
||||
} else {
|
||||
_dialogsFull = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::requestPinnedDialogs() {
|
||||
if (_pinnedDialogsRequestId) {
|
||||
return;
|
||||
}
|
||||
|
||||
_pinnedDialogsReceived = false;
|
||||
const auto folderId = FolderId(0);
|
||||
_pinnedDialogsRequestId = request(MTPmessages_GetPinnedDialogs(
|
||||
MTP_int(folderId)
|
||||
)).done([=](const MTPmessages_PeerDialogs &result) {
|
||||
result.match([&](const MTPDmessages_peerDialogs &data) {
|
||||
_session->data().processUsers(data.vusers);
|
||||
_session->data().processChats(data.vchats);
|
||||
_session->data().applyPinnedDialogs(data.vdialogs.v);
|
||||
_session->data().applyDialogs(data.vmessages.v, data.vdialogs.v);
|
||||
|
||||
_pinnedDialogsRequestId = 0;
|
||||
_pinnedDialogsReceived = true;
|
||||
|
||||
_session->data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull) {
|
||||
_session->data().allChatsLoaded().set(true);
|
||||
}
|
||||
});
|
||||
}).fail([=](const RPCError &error) {
|
||||
_pinnedDialogsRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
void ApiWrap::requestMoreBlockedByDateDialogs() {
|
||||
const auto max = _session->settings().supportChatsTimeSlice();
|
||||
_dialogsLoadTill = _dialogsOffsetDate
|
||||
? (_dialogsOffsetDate - max)
|
||||
: (unixtime() - max);
|
||||
requestDialogs();
|
||||
}
|
||||
|
||||
rpl::producer<bool> ApiWrap::dialogsLoadMayBlockByDate() const {
|
||||
return _dialogsLoadMayBlockByDate.value();
|
||||
}
|
||||
|
||||
rpl::producer<bool> ApiWrap::dialogsLoadBlockedByDate() const {
|
||||
return _dialogsLoadBlockedByDate.value();
|
||||
}
|
||||
|
||||
void ApiWrap::requestDialogEntry(not_null<Data::Folder*> folder) {
|
||||
if (_dialogFolderRequests.contains(folder)) {
|
||||
return;
|
||||
@ -1219,7 +1393,7 @@ void ApiWrap::migrateChat(
|
||||
return MigrateCallbacks{ std::move(done), std::move(fail) };
|
||||
};
|
||||
const auto i = _migrateCallbacks.find(chat);
|
||||
if (i != end(_migrateCallbacks)) {
|
||||
if (i != _migrateCallbacks.end()) {
|
||||
i->second.push_back(callback());
|
||||
return;
|
||||
}
|
||||
|
@ -79,6 +79,12 @@ public:
|
||||
QString exportDirectMessageLink(not_null<HistoryItem*> item);
|
||||
|
||||
void requestContacts();
|
||||
void requestDialogs();
|
||||
void requestPinnedDialogs();
|
||||
void requestMoreBlockedByDateDialogs();
|
||||
rpl::producer<bool> dialogsLoadMayBlockByDate() const;
|
||||
rpl::producer<bool> dialogsLoadBlockedByDate() const;
|
||||
|
||||
void requestDialogEntry(not_null<Data::Folder*> folder);
|
||||
//void requestFeedDialogsEntries(not_null<Data::Feed*> feed); // #feed
|
||||
void requestDialogEntry(
|
||||
@ -448,6 +454,15 @@ private:
|
||||
crl::time received = 0;
|
||||
};
|
||||
|
||||
void setupSupportMode();
|
||||
void refreshDialogsLoadBlocked();
|
||||
void updateDialogsOffset(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
void applyReceivedDialogs(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
@ -734,6 +749,17 @@ private:
|
||||
// SliceType>> _feedMessagesRequestsPending;
|
||||
//mtpRequestId _saveDefaultFeedIdRequest = 0;
|
||||
|
||||
bool _dialogsFull = false;
|
||||
bool _pinnedDialogsReceived = false;
|
||||
TimeId _dialogsLoadTill = 0;
|
||||
TimeId _dialogsOffsetDate = 0;
|
||||
MsgId _dialogsOffsetId = 0;
|
||||
PeerData *_dialogsOffsetPeer = nullptr;
|
||||
mtpRequestId _dialogsRequestId = 0;
|
||||
mtpRequestId _pinnedDialogsRequestId = 0;
|
||||
rpl::variable<bool> _dialogsLoadMayBlockByDate = false;
|
||||
rpl::variable<bool> _dialogsLoadBlockedByDate = false;
|
||||
|
||||
rpl::event_stream<SendOptions> _sendActions;
|
||||
|
||||
struct ReadRequest {
|
||||
|
@ -389,6 +389,7 @@ AuthSession::AuthSession(const MTPUser &user)
|
||||
, _user(_data->processUser(user))
|
||||
, _changelogs(Core::Changelogs::Create(this))
|
||||
, _supportHelper(Support::Helper::Create(this)) {
|
||||
|
||||
_saveDataTimer.setCallback([=] {
|
||||
Local::writeUserSettings();
|
||||
});
|
||||
|
@ -1350,6 +1350,71 @@ void Session::applyPinnedDialogs(const QVector<MTPDialogPeer> &list) {
|
||||
}
|
||||
}
|
||||
|
||||
void Session::applyDialogs(
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs) {
|
||||
App::feedMsgs(messages, NewMessageLast);
|
||||
for (const auto &dialog : dialogs) {
|
||||
dialog.match([&](const auto &data) {
|
||||
applyDialog(data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Session::applyDialog(const MTPDdialog &data) {
|
||||
const auto peerId = peerFromMTP(data.vpeer);
|
||||
if (!peerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto history = session().data().history(peerId);
|
||||
history->applyDialog(data);
|
||||
|
||||
if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
|
||||
const auto date = history->chatListTimeId();
|
||||
if (date != 0) {
|
||||
addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
if (const auto from = history->peer->migrateFrom()) {
|
||||
if (const auto historyFrom = from->owner().historyLoaded(from)) {
|
||||
App::main()->removeDialog(historyFrom);
|
||||
}
|
||||
} else if (const auto to = history->peer->migrateTo()) {
|
||||
if (to->amIn()) {
|
||||
App::main()->removeDialog(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::applyDialog(const MTPDdialogFolder &dialog) {
|
||||
const auto folder = processFolder(dialog.vfolder);
|
||||
folder->applyDialog(dialog);
|
||||
|
||||
if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) {
|
||||
const auto date = folder->chatListTimeId();
|
||||
if (date != 0) {
|
||||
addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Session::addSavedPeersAfter(const QDateTime &date) {
|
||||
auto &saved = cRefSavedPeersByTime();
|
||||
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
|
||||
const auto lastDate = saved.lastKey();
|
||||
const auto lastPeer = saved.last();
|
||||
saved.remove(lastDate, lastPeer);
|
||||
|
||||
const auto history = session().data().history(lastPeer);
|
||||
history->setChatListTimeId(ServerTimeFromParsed(lastDate));
|
||||
}
|
||||
}
|
||||
|
||||
void Session::addAllSavedPeers() {
|
||||
addSavedPeersAfter(QDateTime());
|
||||
}
|
||||
|
||||
int Session::pinnedDialogsCount() const {
|
||||
return _pinnedDialogs.size();
|
||||
}
|
||||
|
@ -293,6 +293,12 @@ public:
|
||||
void applyUpdate(const MTPDupdateChatParticipantAdmin &update);
|
||||
void applyUpdate(const MTPDupdateChatDefaultBannedRights &update);
|
||||
|
||||
void applyDialogs(
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs);
|
||||
void addSavedPeersAfter(const QDateTime &date);
|
||||
void addAllSavedPeers();
|
||||
|
||||
int pinnedDialogsCount() const;
|
||||
const std::deque<Dialogs::Key> &pinnedDialogsOrder() const;
|
||||
void setPinnedDialog(const Dialogs::Key &key, bool pinned);
|
||||
@ -597,6 +603,9 @@ private:
|
||||
int entriesFull,
|
||||
int entriesMuted) const;
|
||||
|
||||
void applyDialog(const MTPDdialog &data);
|
||||
void applyDialog(const MTPDdialogFolder &data);
|
||||
|
||||
void photoApplyFields(
|
||||
not_null<PhotoData*> photo,
|
||||
const MTPPhoto &data);
|
||||
|
@ -1813,7 +1813,7 @@ void DialogsInner::applyDialog(const MTPDdialog &dialog) {
|
||||
if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
|
||||
const auto date = history->chatListTimeId();
|
||||
if (date != 0) {
|
||||
addSavedPeersAfter(ParseDateTime(date));
|
||||
session().data().addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
if (const auto from = history->peer->migrateFrom()) {
|
||||
@ -1834,27 +1834,11 @@ void DialogsInner::applyFolderDialog(const MTPDdialogFolder &dialog) {
|
||||
if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) {
|
||||
const auto date = folder->chatListTimeId();
|
||||
if (date != 0) {
|
||||
addSavedPeersAfter(ParseDateTime(date));
|
||||
session().data().addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
|
||||
auto &saved = cRefSavedPeersByTime();
|
||||
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
|
||||
const auto lastDate = saved.lastKey();
|
||||
const auto lastPeer = saved.last();
|
||||
saved.remove(lastDate, lastPeer);
|
||||
|
||||
const auto history = session().data().history(lastPeer);
|
||||
history->setChatListTimeId(ServerTimeFromParsed(lastDate));
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::addAllSavedPeers() {
|
||||
addSavedPeersAfter(QDateTime());
|
||||
}
|
||||
|
||||
bool DialogsInner::uniqueSearchResults() const {
|
||||
return session().supportMode()
|
||||
&& !session().settings().supportAllSearchResults()
|
||||
|
@ -40,8 +40,6 @@ public:
|
||||
DialogsInner(QWidget *parent, not_null<Window::Controller*> controller);
|
||||
|
||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||
void addSavedPeersAfter(const QDateTime &date);
|
||||
void addAllSavedPeers();
|
||||
bool searchReceived(
|
||||
const QVector<MTPMessage> &result,
|
||||
DialogsSearchRequestType type,
|
||||
|
@ -42,9 +42,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kDialogsFirstLoad = 20;
|
||||
constexpr auto kDialogsPerPage = 500;
|
||||
|
||||
QString SwitchToChooseFromQuery() {
|
||||
return qsl("from:");
|
||||
}
|
||||
@ -164,6 +161,14 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||
, _scroll(this, st::dialogsScroll)
|
||||
, _scrollToTop(_scroll, st::dialogsToUp) {
|
||||
_inner = _scroll->setOwnedWidget(object_ptr<DialogsInner>(this, controller));
|
||||
|
||||
rpl::combine(
|
||||
session().api().dialogsLoadMayBlockByDate(),
|
||||
session().api().dialogsLoadBlockedByDate()
|
||||
) | rpl::start_with_next([=](bool mayBlock, bool isBlocked) {
|
||||
refreshLoadMoreButton(mayBlock, isBlocked);
|
||||
}, lifetime());
|
||||
|
||||
connect(_inner, SIGNAL(draggingScrollDelta(int)), this, SLOT(onDraggingScrollDelta(int)));
|
||||
connect(_inner, SIGNAL(mustScrollTo(int,int)), _scroll, SLOT(scrollToY(int,int)));
|
||||
connect(_inner, SIGNAL(dialogMoved(int,int)), this, SLOT(onDialogMoved(int,int)));
|
||||
@ -178,6 +183,10 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||
});
|
||||
connect(_scroll, SIGNAL(geometryChanged()), _inner, SLOT(onParentGeometryChanged()));
|
||||
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onListScroll()));
|
||||
subscribe(session().data().moreChatsLoaded(), [=] {
|
||||
_inner->refresh();
|
||||
onListScroll();
|
||||
});
|
||||
connect(_filter, &Ui::FlatInput::cancelled, [=] {
|
||||
onCancel();
|
||||
});
|
||||
@ -223,21 +232,22 @@ DialogsWidget::DialogsWidget(QWidget *parent, not_null<Window::Controller*> cont
|
||||
_searchTimer.setSingleShot(true);
|
||||
connect(&_searchTimer, SIGNAL(timeout()), this, SLOT(onSearchMessages()));
|
||||
|
||||
_inner->setLoadMoreCallback([this] {
|
||||
_inner->setLoadMoreCallback([=] {
|
||||
using State = DialogsInner::State;
|
||||
const auto state = _inner->state();
|
||||
if (state == State::Filtered && (!_inner->waitingForSearch()
|
||||
|| (_searchInMigrated
|
||||
&& _searchFull
|
||||
&& !_searchFullMigrated))) {
|
||||
if (state == State::Filtered
|
||||
&& (!_inner->waitingForSearch()
|
||||
|| (_searchInMigrated
|
||||
&& _searchFull
|
||||
&& !_searchFullMigrated))) {
|
||||
onSearchMore();
|
||||
} else {
|
||||
loadDialogs();
|
||||
session().api().requestDialogs();
|
||||
}
|
||||
});
|
||||
_inner->listBottomReached(
|
||||
) | rpl::start_with_next([=] {
|
||||
loadMoreBlockedByDateChats();
|
||||
loadMoreBlockedByDate();
|
||||
}, lifetime());
|
||||
|
||||
_filter->setFocusPolicy(Qt::StrongFocus);
|
||||
@ -316,12 +326,6 @@ void DialogsWidget::setupSupportMode() {
|
||||
return;
|
||||
}
|
||||
|
||||
session().settings().supportChatsTimeSliceValue(
|
||||
) | rpl::start_with_next([=](int seconds) {
|
||||
_dialogsLoadTill = seconds ? std::max(unixtime() - seconds, 0) : 0;
|
||||
refreshLoadMoreButton();
|
||||
}, lifetime());
|
||||
|
||||
session().settings().supportAllSearchResultsValue(
|
||||
) | rpl::filter([=] {
|
||||
return !_searchQuery.isEmpty();
|
||||
@ -525,90 +529,8 @@ void DialogsWidget::notify_historyMuteUpdated(History *history) {
|
||||
_inner->notify_historyMuteUpdated(history);
|
||||
}
|
||||
|
||||
void DialogsWidget::dialogsReceived(
|
||||
const MTPmessages_Dialogs &dialogs,
|
||||
mtpRequestId requestId) {
|
||||
if (_dialogsRequestId != requestId) return;
|
||||
|
||||
const auto [dialogsList, messagesList] = [&] {
|
||||
const auto process = [&](const auto &data) {
|
||||
session().data().processUsers(data.vusers);
|
||||
session().data().processChats(data.vchats);
|
||||
return std::make_tuple(&data.vdialogs.v, &data.vmessages.v);
|
||||
};
|
||||
switch (dialogs.type()) {
|
||||
case mtpc_messages_dialogs:
|
||||
_dialogsFull = true;
|
||||
return process(dialogs.c_messages_dialogs());
|
||||
|
||||
case mtpc_messages_dialogsSlice:
|
||||
return process(dialogs.c_messages_dialogsSlice());
|
||||
}
|
||||
Unexpected("Type in DialogsWidget::dialogsReceived");
|
||||
}();
|
||||
|
||||
updateDialogsOffset(*dialogsList, *messagesList);
|
||||
|
||||
applyReceivedDialogs(*dialogsList, *messagesList);
|
||||
|
||||
_dialogsRequestId = 0;
|
||||
loadDialogs();
|
||||
|
||||
if (!_dialogsRequestId) {
|
||||
refreshLoadMoreButton();
|
||||
}
|
||||
|
||||
session().data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull && _pinnedDialogsReceived) {
|
||||
session().data().allChatsLoaded().set(true);
|
||||
}
|
||||
session().api().requestContacts();
|
||||
}
|
||||
|
||||
void DialogsWidget::updateDialogsOffset(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages) {
|
||||
auto lastDate = TimeId(0);
|
||||
auto lastPeer = PeerId(0);
|
||||
auto lastMsgId = MsgId(0);
|
||||
for (const auto &dialog : ranges::view::reverse(dialogs)) {
|
||||
dialog.match([&](const auto &dialog) {
|
||||
const auto peer = peerFromMTP(dialog.vpeer);
|
||||
const auto messageId = dialog.vtop_message.v;
|
||||
if (!peer || !messageId) {
|
||||
return;
|
||||
}
|
||||
if (!lastPeer) {
|
||||
lastPeer = peer;
|
||||
}
|
||||
if (!lastMsgId) {
|
||||
lastMsgId = messageId;
|
||||
}
|
||||
for (const auto &message : ranges::view::reverse(messages)) {
|
||||
if (IdFromMessage(message) == messageId
|
||||
&& PeerFromMessage(message) == peer) {
|
||||
if (const auto date = DateFromMessage(message)) {
|
||||
lastDate = date;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (lastDate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastDate) {
|
||||
_dialogsOffsetDate = lastDate;
|
||||
_dialogsOffsetId = lastMsgId;
|
||||
_dialogsOffsetPeer = session().data().peer(lastPeer);
|
||||
} else {
|
||||
_dialogsFull = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::refreshLoadMoreButton() {
|
||||
if (_dialogsFull || !_dialogsLoadTill) {
|
||||
void DialogsWidget::refreshLoadMoreButton(bool mayBlock, bool isBlocked) {
|
||||
if (!mayBlock) {
|
||||
_loadMoreChats.destroy();
|
||||
updateControlsGeometry();
|
||||
return;
|
||||
@ -621,69 +543,22 @@ void DialogsWidget::refreshLoadMoreButton() {
|
||||
st::dialogsLoadMore,
|
||||
st::dialogsLoadMore);
|
||||
_loadMoreChats->addClickHandler([=] {
|
||||
loadMoreBlockedByDateChats();
|
||||
loadMoreBlockedByDate();
|
||||
});
|
||||
updateControlsGeometry();
|
||||
}
|
||||
const auto loading = !loadingBlockedByDate();
|
||||
const auto loading = !isBlocked;
|
||||
_loadMoreChats->setDisabled(loading);
|
||||
_loadMoreChats->setText(loading ? "Loading..." : "Load more");
|
||||
}
|
||||
|
||||
void DialogsWidget::loadMoreBlockedByDateChats() {
|
||||
void DialogsWidget::loadMoreBlockedByDate() {
|
||||
if (!_loadMoreChats
|
||||
|| _loadMoreChats->isDisabled()
|
||||
|| _loadMoreChats->isHidden()) {
|
||||
return;
|
||||
}
|
||||
const auto max = session().settings().supportChatsTimeSlice();
|
||||
_dialogsLoadTill = _dialogsOffsetDate
|
||||
? (_dialogsOffsetDate - max)
|
||||
: (unixtime() - max);
|
||||
loadDialogs();
|
||||
}
|
||||
|
||||
void DialogsWidget::pinnedDialogsReceived(
|
||||
const MTPmessages_PeerDialogs &result,
|
||||
mtpRequestId requestId) {
|
||||
Expects(result.type() == mtpc_messages_peerDialogs);
|
||||
|
||||
if (_pinnedDialogsRequestId != requestId) return;
|
||||
|
||||
auto &data = result.c_messages_peerDialogs();
|
||||
session().data().processUsers(data.vusers);
|
||||
session().data().processChats(data.vchats);
|
||||
|
||||
session().data().applyPinnedDialogs(data.vdialogs.v);
|
||||
applyReceivedDialogs(data.vdialogs.v, data.vmessages.v);
|
||||
|
||||
_pinnedDialogsRequestId = 0;
|
||||
_pinnedDialogsReceived = true;
|
||||
|
||||
session().data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull && _pinnedDialogsReceived) {
|
||||
session().data().allChatsLoaded().set(true);
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsWidget::applyReceivedDialogs(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages) {
|
||||
App::feedMsgs(messages, NewMessageLast);
|
||||
_inner->dialogsReceived(dialogs);
|
||||
onListScroll();
|
||||
}
|
||||
|
||||
bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId requestId) {
|
||||
if (MTP::isDefaultHandledError(error)) return false;
|
||||
|
||||
LOG(("RPC Error: %1 %2: %3").arg(error.code()).arg(error.type()).arg(error.description()));
|
||||
if (_dialogsRequestId == requestId) {
|
||||
_dialogsRequestId = 0;
|
||||
} else if (_pinnedDialogsRequestId == requestId) {
|
||||
_pinnedDialogsRequestId = 0;
|
||||
}
|
||||
return true;
|
||||
session().api().requestMoreBlockedByDateDialogs();
|
||||
}
|
||||
|
||||
void DialogsWidget::onDraggingScrollDelta(int delta) {
|
||||
@ -949,55 +824,6 @@ void DialogsWidget::onSearchMore() {
|
||||
}
|
||||
}
|
||||
|
||||
bool DialogsWidget::loadingBlockedByDate() const {
|
||||
return !_dialogsFull
|
||||
&& !_dialogsRequestId
|
||||
&& (_dialogsLoadTill > 0)
|
||||
&& (_dialogsOffsetDate > 0)
|
||||
&& (_dialogsOffsetDate <= _dialogsLoadTill);
|
||||
}
|
||||
|
||||
void DialogsWidget::loadDialogs() {
|
||||
if (_dialogsRequestId) return;
|
||||
if (_dialogsFull) {
|
||||
_inner->addAllSavedPeers();
|
||||
return;
|
||||
} else if (loadingBlockedByDate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto firstLoad = !_dialogsOffsetDate;
|
||||
const auto loadCount = firstLoad ? kDialogsFirstLoad : kDialogsPerPage;
|
||||
const auto flags = MTPmessages_GetDialogs::Flag::f_exclude_pinned
|
||||
| MTPmessages_GetDialogs::Flag::f_folder_id;
|
||||
const auto folderId = 0;
|
||||
const auto hash = 0;
|
||||
_dialogsRequestId = MTP::send(
|
||||
MTPmessages_GetDialogs(
|
||||
MTP_flags(flags),
|
||||
MTP_int(folderId),
|
||||
MTP_int(_dialogsOffsetDate),
|
||||
MTP_int(_dialogsOffsetId),
|
||||
_dialogsOffsetPeer
|
||||
? _dialogsOffsetPeer->input
|
||||
: MTP_inputPeerEmpty(),
|
||||
MTP_int(loadCount),
|
||||
MTP_int(hash)),
|
||||
rpcDone(&DialogsWidget::dialogsReceived),
|
||||
rpcFail(&DialogsWidget::dialogsFailed));
|
||||
if (!_pinnedDialogsReceived) {
|
||||
loadPinnedDialogs();
|
||||
}
|
||||
refreshLoadMoreButton();
|
||||
}
|
||||
|
||||
void DialogsWidget::loadPinnedDialogs() {
|
||||
if (_pinnedDialogsRequestId) return;
|
||||
|
||||
_pinnedDialogsReceived = false;
|
||||
_pinnedDialogsRequestId = MTP::send(MTPmessages_GetPinnedDialogs(MTP_int(0)), rpcDone(&DialogsWidget::pinnedDialogsReceived), rpcFail(&DialogsWidget::dialogsFailed));
|
||||
}
|
||||
|
||||
void DialogsWidget::searchReceived(
|
||||
DialogsSearchRequestType type,
|
||||
const MTPmessages_Messages &result,
|
||||
|
@ -58,8 +58,6 @@ public:
|
||||
|
||||
void searchInChat(Dialogs::Key chat);
|
||||
|
||||
void loadDialogs();
|
||||
void loadPinnedDialogs();
|
||||
void refreshDialog(Dialogs::Key key);
|
||||
void removeDialog(Dialogs::Key key);
|
||||
void repaintDialogRow(Dialogs::Mode list, not_null<Dialogs::Row*> row);
|
||||
@ -137,12 +135,6 @@ private:
|
||||
void peerSearchReceived(
|
||||
const MTPcontacts_Found &result,
|
||||
mtpRequestId requestId);
|
||||
void updateDialogsOffset(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
void applyReceivedDialogs(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
|
||||
void setupSupportMode();
|
||||
void setupConnectingWidget();
|
||||
@ -160,11 +152,9 @@ private:
|
||||
void checkUpdateStatus();
|
||||
|
||||
void applyFilterUpdate(bool force = false);
|
||||
bool loadingBlockedByDate() const;
|
||||
void refreshLoadMoreButton();
|
||||
void loadMoreBlockedByDateChats();
|
||||
void refreshLoadMoreButton(bool mayBlock, bool isBlocked);
|
||||
void loadMoreBlockedByDate();
|
||||
|
||||
bool dialogsFailed(const RPCError &error, mtpRequestId req);
|
||||
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
|
||||
bool peopleFailed(const RPCError &error, mtpRequestId req);
|
||||
|
||||
@ -172,15 +162,6 @@ private:
|
||||
bool _dragForward = false;
|
||||
QTimer _chooseByDragTimer;
|
||||
|
||||
bool _dialogsFull = false;
|
||||
TimeId _dialogsLoadTill = 0;
|
||||
TimeId _dialogsOffsetDate = 0;
|
||||
MsgId _dialogsOffsetId = 0;
|
||||
PeerData *_dialogsOffsetPeer = nullptr;
|
||||
mtpRequestId _dialogsRequestId = 0;
|
||||
mtpRequestId _pinnedDialogsRequestId = 0;
|
||||
bool _pinnedDialogsReceived = false;
|
||||
|
||||
object_ptr<Ui::IconButton> _forwardCancel = { nullptr };
|
||||
object_ptr<Ui::IconButton> _mainMenuToggle;
|
||||
object_ptr<Ui::FlatInput> _filter;
|
||||
|
@ -2931,7 +2931,7 @@ void MainWidget::gotState(const MTPupdates_State &state) {
|
||||
_noUpdatesTimer.callOnce(kNoUpdatesTimeout);
|
||||
_ptsWaiter.setRequesting(false);
|
||||
|
||||
_dialogs->loadDialogs();
|
||||
session().api().requestDialogs();
|
||||
updateOnline();
|
||||
}
|
||||
|
||||
@ -4284,10 +4284,10 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
if (allLoaded) {
|
||||
session().data().applyPinnedDialogs(order);
|
||||
} else {
|
||||
_dialogs->loadPinnedDialogs();
|
||||
session().api().requestPinnedDialogs();
|
||||
}
|
||||
} else {
|
||||
_dialogs->loadPinnedDialogs();
|
||||
session().api().requestPinnedDialogs();
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -4302,7 +4302,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
"pinned chat not loaded for peer %1"
|
||||
).arg(id
|
||||
));
|
||||
_dialogs->loadPinnedDialogs();
|
||||
session().api().requestPinnedDialogs();
|
||||
}
|
||||
}, [&](const MTPDdialogPeerFolder &data) {
|
||||
const auto id = data.vfolder_id.v;
|
||||
@ -4313,7 +4313,7 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||
"pinned folder not loaded for folderId %1"
|
||||
).arg(id
|
||||
));
|
||||
_dialogs->loadPinnedDialogs();
|
||||
session().api().requestPinnedDialogs();
|
||||
}
|
||||
});
|
||||
} break;
|
||||
|
Loading…
Reference in New Issue
Block a user