Load folder dialogs list.
This commit is contained in:
parent
be0cf8d379
commit
0367319934
|
@ -191,6 +191,7 @@ ApiWrap::ApiWrap(not_null<AuthSession*> session)
|
|||
, _webPagesTimer([=] { resolveWebPages(); })
|
||||
, _draftsSaveTimer([=] { saveDraftsToCloud(); })
|
||||
, _featuredSetsReadTimer([=] { readFeaturedSets(); })
|
||||
, _dialogsLoadState(std::make_unique<DialogsLoadState>())
|
||||
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
|
||||
//, _feedReadTimer([=] { readFeeds(); }) // #feed
|
||||
, _proxyPromotionTimer([=] { refreshProxyPromotion(); })
|
||||
|
@ -706,28 +707,41 @@ void ApiWrap::requestContacts() {
|
|||
}
|
||||
|
||||
void ApiWrap::requestDialogs() {
|
||||
if (_dialogsRequestId) {
|
||||
requestMoreDialogs(FolderId(0));
|
||||
}
|
||||
|
||||
void ApiWrap::requestFolderDialogs(FolderId folderId) {
|
||||
if (!_foldersLoadState.contains(folderId)) {
|
||||
_foldersLoadState.emplace(folderId, DialogsLoadState());
|
||||
}
|
||||
requestMoreDialogs(folderId);
|
||||
}
|
||||
|
||||
void ApiWrap::requestMoreDialogs(FolderId folderId) {
|
||||
const auto state = dialogsLoadState(folderId);
|
||||
if (!state) {
|
||||
if (!folderId) {
|
||||
_session->data().addAllSavedPeers();
|
||||
}
|
||||
return;
|
||||
} else if (_dialogsFull) {
|
||||
_session->data().addAllSavedPeers();
|
||||
} else if (state->requestId) {
|
||||
return;
|
||||
} else if (_dialogsLoadBlockedByDate.current()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto firstLoad = !_dialogsOffsetDate;
|
||||
const auto firstLoad = !state->offsetDate;
|
||||
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(
|
||||
state->requestId = request(MTPmessages_GetDialogs(
|
||||
MTP_flags(flags),
|
||||
MTP_int(folderId),
|
||||
MTP_int(_dialogsOffsetDate),
|
||||
MTP_int(_dialogsOffsetId),
|
||||
(_dialogsOffsetPeer
|
||||
? _dialogsOffsetPeer->input
|
||||
MTP_int(state->offsetDate),
|
||||
MTP_int(state->offsetId),
|
||||
(state->offsetPeer
|
||||
? state->offsetPeer->input
|
||||
: MTP_inputPeerEmpty()),
|
||||
MTP_int(loadCount),
|
||||
MTP_int(hash)
|
||||
|
@ -736,27 +750,36 @@ void ApiWrap::requestDialogs() {
|
|||
LOG(("API Error: not-modified received for requested dialogs."));
|
||||
}, [&](const auto &data) {
|
||||
if constexpr (data.Is<MTPDmessages_dialogs>()) {
|
||||
_dialogsFull = true;
|
||||
dialogsLoadFinish(folderId);
|
||||
} else {
|
||||
updateDialogsOffset(
|
||||
folderId,
|
||||
data.vdialogs.v,
|
||||
data.vmessages.v);
|
||||
}
|
||||
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);
|
||||
_session->data().applyDialogs(
|
||||
folderId,
|
||||
data.vmessages.v,
|
||||
data.vdialogs.v);
|
||||
});
|
||||
|
||||
_dialogsRequestId = 0;
|
||||
requestDialogs();
|
||||
if (!_dialogsRequestId) {
|
||||
refreshDialogsLoadBlocked();
|
||||
if (!folderId) {
|
||||
requestDialogs();
|
||||
if (!_dialogsLoadState || !_dialogsLoadState->requestId) {
|
||||
refreshDialogsLoadBlocked();
|
||||
}
|
||||
}
|
||||
|
||||
_session->data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull && _pinnedDialogsReceived) {
|
||||
_session->data().allChatsLoaded().set(true);
|
||||
if (!folderId) {
|
||||
if (!_dialogsLoadState && _pinnedDialogsReceived) {
|
||||
_session->data().allChatsLoaded().set(true);
|
||||
}
|
||||
requestContacts();
|
||||
}
|
||||
requestContacts();
|
||||
}).fail([=](const RPCError &error) {
|
||||
_dialogsRequestId = 0;
|
||||
dialogsLoadState(folderId)->requestId = 0;
|
||||
}).send();
|
||||
if (!_pinnedDialogsReceived) {
|
||||
requestPinnedDialogs();
|
||||
|
@ -765,16 +788,17 @@ void ApiWrap::requestDialogs() {
|
|||
}
|
||||
|
||||
void ApiWrap::refreshDialogsLoadBlocked() {
|
||||
_dialogsLoadMayBlockByDate = !_dialogsFull
|
||||
_dialogsLoadMayBlockByDate = _dialogsLoadState
|
||||
&& (_dialogsLoadTill > 0);
|
||||
_dialogsLoadBlockedByDate = !_dialogsFull
|
||||
&& !_dialogsRequestId
|
||||
_dialogsLoadBlockedByDate = _dialogsLoadState
|
||||
&& !_dialogsLoadState->requestId
|
||||
&& (_dialogsLoadTill > 0)
|
||||
&& (_dialogsOffsetDate > 0)
|
||||
&& (_dialogsOffsetDate <= _dialogsLoadTill);
|
||||
&& (_dialogsLoadState->offsetDate > 0)
|
||||
&& (_dialogsLoadState->offsetDate <= _dialogsLoadTill);
|
||||
}
|
||||
|
||||
void ApiWrap::updateDialogsOffset(
|
||||
FolderId folderId,
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages) {
|
||||
auto lastDate = TimeId(0);
|
||||
|
@ -808,11 +832,30 @@ void ApiWrap::updateDialogsOffset(
|
|||
}
|
||||
}
|
||||
if (lastDate) {
|
||||
_dialogsOffsetDate = lastDate;
|
||||
_dialogsOffsetId = lastMsgId;
|
||||
_dialogsOffsetPeer = _session->data().peer(lastPeer);
|
||||
if (const auto state = dialogsLoadState(folderId)) {
|
||||
state->offsetDate = lastDate;
|
||||
state->offsetId = lastMsgId;
|
||||
state->offsetPeer = _session->data().peer(lastPeer);
|
||||
state->requestId = 0;
|
||||
}
|
||||
} else {
|
||||
_dialogsFull = true;
|
||||
dialogsLoadFinish(folderId);
|
||||
}
|
||||
}
|
||||
|
||||
auto ApiWrap::dialogsLoadState(FolderId folderId) -> DialogsLoadState* {
|
||||
if (!folderId) {
|
||||
return _dialogsLoadState.get();
|
||||
}
|
||||
const auto i = _foldersLoadState.find(folderId);
|
||||
return (i != end(_foldersLoadState)) ? &i->second : nullptr;
|
||||
}
|
||||
|
||||
void ApiWrap::dialogsLoadFinish(FolderId folderId) {
|
||||
if (folderId) {
|
||||
_foldersLoadState.remove(folderId);
|
||||
} else {
|
||||
_dialogsLoadState = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -827,16 +870,21 @@ void ApiWrap::requestPinnedDialogs() {
|
|||
MTP_int(folderId)
|
||||
)).done([=](const MTPmessages_PeerDialogs &result) {
|
||||
result.match([&](const MTPDmessages_peerDialogs &data) {
|
||||
const auto folderId = FolderId(0);
|
||||
|
||||
_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);
|
||||
_session->data().applyDialogs(
|
||||
folderId,
|
||||
data.vmessages.v,
|
||||
data.vdialogs.v);
|
||||
|
||||
_pinnedDialogsRequestId = 0;
|
||||
_pinnedDialogsReceived = true;
|
||||
|
||||
_session->data().moreChatsLoaded().notify();
|
||||
if (_dialogsFull) {
|
||||
if (!_dialogsLoadState) {
|
||||
_session->data().allChatsLoaded().set(true);
|
||||
}
|
||||
});
|
||||
|
@ -846,9 +894,12 @@ void ApiWrap::requestPinnedDialogs() {
|
|||
}
|
||||
|
||||
void ApiWrap::requestMoreBlockedByDateDialogs() {
|
||||
if (!_dialogsLoadState) {
|
||||
return;
|
||||
}
|
||||
const auto max = _session->settings().supportChatsTimeSlice();
|
||||
_dialogsLoadTill = _dialogsOffsetDate
|
||||
? (_dialogsOffsetDate - max)
|
||||
_dialogsLoadTill = _dialogsLoadState->offsetDate
|
||||
? (_dialogsLoadState->offsetDate - max)
|
||||
: (unixtime() - max);
|
||||
requestDialogs();
|
||||
}
|
||||
|
@ -990,11 +1041,14 @@ void ApiWrap::applyPeerDialogs(const MTPmessages_PeerDialogs &dialogs) {
|
|||
for (const auto &dialog : data.vdialogs.v) {
|
||||
dialog.match([&](const MTPDdialog &data) {
|
||||
if (const auto peerId = peerFromMTP(data.vpeer)) {
|
||||
_session->data().history(peerId)->applyDialog(data);
|
||||
const auto requestFolderId = FolderId(0);
|
||||
_session->data().history(peerId)->applyDialog(
|
||||
requestFolderId,
|
||||
data);
|
||||
}
|
||||
}, [&](const MTPDdialogFolder &data) { // #TODO archive
|
||||
//const auto folder = _session->data().processFolder(data.vfolder);
|
||||
//folder->applyDialog(data);
|
||||
}, [&](const MTPDdialogFolder &data) {
|
||||
const auto folder = _session->data().processFolder(data.vfolder);
|
||||
folder->applyDialog(data);
|
||||
});
|
||||
}
|
||||
_session->data().sendHistoryChangeNotifications();
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
|
||||
void requestContacts();
|
||||
void requestDialogs();
|
||||
void requestFolderDialogs(FolderId folderId);
|
||||
void requestPinnedDialogs();
|
||||
void requestMoreBlockedByDateDialogs();
|
||||
rpl::producer<bool> dialogsLoadMayBlockByDate() const;
|
||||
|
@ -454,16 +455,23 @@ private:
|
|||
crl::time received = 0;
|
||||
};
|
||||
|
||||
struct DialogsLoadState {
|
||||
TimeId offsetDate = 0;
|
||||
MsgId offsetId = 0;
|
||||
PeerData *offsetPeer = nullptr;
|
||||
mtpRequestId requestId = 0;
|
||||
};
|
||||
|
||||
void setupSupportMode();
|
||||
void refreshDialogsLoadBlocked();
|
||||
void updateDialogsOffset(
|
||||
FolderId folderId,
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
void applyReceivedDialogs(
|
||||
const QVector<MTPDialog> &dialogs,
|
||||
const QVector<MTPMessage> &messages);
|
||||
void requestMoreDialogs(FolderId folderId);
|
||||
DialogsLoadState *dialogsLoadState(FolderId folderId);
|
||||
void dialogsLoadFinish(FolderId folderId);
|
||||
|
||||
void updatesReceived(const MTPUpdates &updates);
|
||||
void checkQuitPreventFinished();
|
||||
|
||||
void saveDraftsToCloud();
|
||||
|
@ -749,17 +757,16 @@ private:
|
|||
// SliceType>> _feedMessagesRequestsPending;
|
||||
//mtpRequestId _saveDefaultFeedIdRequest = 0;
|
||||
|
||||
bool _dialogsFull = false;
|
||||
bool _pinnedDialogsReceived = false;
|
||||
std::unique_ptr<DialogsLoadState> _dialogsLoadState;
|
||||
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;
|
||||
|
||||
bool _pinnedDialogsReceived = false;
|
||||
mtpRequestId _pinnedDialogsRequestId = 0;
|
||||
|
||||
base::flat_map<FolderId, DialogsLoadState> _foldersLoadState;
|
||||
|
||||
rpl::event_stream<SendOptions> _sendActions;
|
||||
|
||||
struct ReadRequest {
|
||||
|
|
|
@ -21,6 +21,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_dialogs.h" // st::dialogsArchiveUserpic
|
||||
|
||||
namespace Data {
|
||||
namespace {
|
||||
|
||||
constexpr auto kLoadedChatsMinCount = 20;
|
||||
|
||||
} // namespace
|
||||
|
||||
// #feed
|
||||
//MessagePosition FeedPositionFromMTP(const MTPFeedPosition &position) {
|
||||
|
@ -367,6 +372,10 @@ void Folder::applyDialog(const MTPDdialogFolder &data) {
|
|||
//if (data.has_read_max_position()) { // #feed
|
||||
// setUnreadPosition(FeedPositionFromMTP(data.vread_max_position));
|
||||
//}
|
||||
|
||||
if (_chatsList.size() < kLoadedChatsMinCount) {
|
||||
session().api().requestFolderDialogs(_id);
|
||||
}
|
||||
}
|
||||
|
||||
void Folder::changedInChatListHook(Dialogs::Mode list, bool added) {
|
||||
|
|
|
@ -1351,24 +1351,25 @@ void Session::applyPinnedDialogs(const QVector<MTPDialogPeer> &list) {
|
|||
}
|
||||
|
||||
void Session::applyDialogs(
|
||||
FolderId requestFolderId,
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs) {
|
||||
App::feedMsgs(messages, NewMessageLast);
|
||||
for (const auto &dialog : dialogs) {
|
||||
dialog.match([&](const auto &data) {
|
||||
applyDialog(data);
|
||||
applyDialog(requestFolderId, data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void Session::applyDialog(const MTPDdialog &data) {
|
||||
void Session::applyDialog(FolderId requestFolderId, const MTPDdialog &data) {
|
||||
const auto peerId = peerFromMTP(data.vpeer);
|
||||
if (!peerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto history = session().data().history(peerId);
|
||||
history->applyDialog(data);
|
||||
history->applyDialog(requestFolderId, data);
|
||||
|
||||
if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
|
||||
const auto date = history->chatListTimeId();
|
||||
|
@ -1387,7 +1388,12 @@ void Session::applyDialog(const MTPDdialog &data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Session::applyDialog(const MTPDdialogFolder &dialog) {
|
||||
void Session::applyDialog(
|
||||
FolderId requestFolderId,
|
||||
const MTPDdialogFolder &dialog) {
|
||||
if (requestFolderId != 0) {
|
||||
LOG(("API Error: requestFolderId != 0 for dialogFolder."));
|
||||
}
|
||||
const auto folder = processFolder(dialog.vfolder);
|
||||
folder->applyDialog(dialog);
|
||||
|
||||
|
|
|
@ -294,6 +294,7 @@ public:
|
|||
void applyUpdate(const MTPDupdateChatDefaultBannedRights &update);
|
||||
|
||||
void applyDialogs(
|
||||
FolderId requestFolderId,
|
||||
const QVector<MTPMessage> &messages,
|
||||
const QVector<MTPDialog> &dialogs);
|
||||
void addSavedPeersAfter(const QDateTime &date);
|
||||
|
@ -603,8 +604,8 @@ private:
|
|||
int entriesFull,
|
||||
int entriesMuted) const;
|
||||
|
||||
void applyDialog(const MTPDdialog &data);
|
||||
void applyDialog(const MTPDdialogFolder &data);
|
||||
void applyDialog(FolderId requestFolderId, const MTPDdialog &data);
|
||||
void applyDialog(FolderId requestFolderId, const MTPDdialogFolder &data);
|
||||
|
||||
void photoApplyFields(
|
||||
not_null<PhotoData*> photo,
|
||||
|
|
|
@ -1790,55 +1790,6 @@ void DialogsInner::itemRemoved(not_null<const HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
|
||||
void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
|
||||
for (const auto &dialog : added) {
|
||||
dialog.match([&](const MTPDdialog &data) {
|
||||
applyDialog(data);
|
||||
}, [&](const MTPDdialogFolder &data) {
|
||||
applyFolderDialog(data);
|
||||
});
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
void DialogsInner::applyDialog(const MTPDdialog &dialog) {
|
||||
const auto peerId = peerFromMTP(dialog.vpeer);
|
||||
if (!peerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto history = session().data().history(peerId);
|
||||
history->applyDialog(dialog);
|
||||
|
||||
if (!history->useProxyPromotion() && !history->isPinnedDialog()) {
|
||||
const auto date = history->chatListTimeId();
|
||||
if (date != 0) {
|
||||
session().data().addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
if (const auto from = history->peer->migrateFrom()) {
|
||||
if (const auto historyFrom = from->owner().historyLoaded(from)) {
|
||||
removeDialog(historyFrom);
|
||||
}
|
||||
} else if (const auto to = history->peer->migrateTo()) {
|
||||
if (to->amIn()) {
|
||||
removeDialog(history);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsInner::applyFolderDialog(const MTPDdialogFolder &dialog) {
|
||||
const auto folder = session().data().processFolder(dialog.vfolder);
|
||||
folder->applyDialog(dialog);
|
||||
|
||||
if (!folder->useProxyPromotion() && !folder->isPinnedDialog()) {
|
||||
const auto date = folder->chatListTimeId();
|
||||
if (date != 0) {
|
||||
session().data().addSavedPeersAfter(ParseDateTime(date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DialogsInner::uniqueSearchResults() const {
|
||||
return session().supportMode()
|
||||
&& !session().settings().supportAllSearchResults()
|
||||
|
|
|
@ -39,7 +39,6 @@ class DialogsInner
|
|||
public:
|
||||
DialogsInner(QWidget *parent, not_null<Window::Controller*> controller);
|
||||
|
||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||
bool searchReceived(
|
||||
const QVector<MTPMessage> &result,
|
||||
DialogsSearchRequestType type,
|
||||
|
@ -48,7 +47,6 @@ public:
|
|||
const QString &query,
|
||||
const QVector<MTPPeer> &my,
|
||||
const QVector<MTPPeer> &result);
|
||||
void showMore(int32 pixels);
|
||||
|
||||
void activate();
|
||||
|
||||
|
@ -199,9 +197,6 @@ private:
|
|||
Dialogs::RowDescriptor chatListEntryFirst() const;
|
||||
Dialogs::RowDescriptor chatListEntryLast() const;
|
||||
|
||||
void applyDialog(const MTPDdialog &dialog);
|
||||
void applyFolderDialog(const MTPDdialogFolder &dialog);
|
||||
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
enum class UpdateRowSection {
|
||||
Default = (1 << 0),
|
||||
|
|
|
@ -122,12 +122,6 @@ protected:
|
|||
|
||||
private:
|
||||
void animationCallback();
|
||||
void dialogsReceived(
|
||||
const MTPmessages_Dialogs &result,
|
||||
mtpRequestId requestId);
|
||||
void pinnedDialogsReceived(
|
||||
const MTPmessages_PeerDialogs &result,
|
||||
mtpRequestId requestId);
|
||||
void searchReceived(
|
||||
DialogsSearchRequestType type,
|
||||
const MTPmessages_Messages &result,
|
||||
|
|
|
@ -2431,7 +2431,7 @@ bool History::isServerSideUnread(not_null<const HistoryItem*> item) const {
|
|||
: (!_inboxReadBefore || (item->id >= *_inboxReadBefore));
|
||||
}
|
||||
|
||||
void History::applyDialog(const MTPDdialog &data) {
|
||||
void History::applyDialog(FolderId requestFolderId, const MTPDdialog &data) {
|
||||
applyDialogFields(
|
||||
data.vunread_count.v,
|
||||
data.vread_inbox_max_id.v,
|
||||
|
@ -2461,6 +2461,15 @@ void History::applyDialog(const MTPDdialog &data) {
|
|||
if (data.has_draft() && data.vdraft.type() == mtpc_draftMessage) {
|
||||
Data::applyPeerCloudDraft(peer->id, data.vdraft.c_draftMessage());
|
||||
}
|
||||
|
||||
const auto folderId = data.has_folder_id()
|
||||
? data.vfolder_id.v
|
||||
: requestFolderId;
|
||||
if (folderId) {
|
||||
setFolder(owner().folder(folderId));
|
||||
} else {
|
||||
clearFolder();
|
||||
}
|
||||
session().api().dialogEntryApplied(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ public:
|
|||
bool lastMessageKnown() const;
|
||||
void unknownMessageDeleted(MsgId messageId);
|
||||
void applyDialogTopMessage(MsgId topMessageId);
|
||||
void applyDialog(const MTPDdialog &data);
|
||||
void applyDialog(FolderId requestFolderId, const MTPDdialog &data);
|
||||
void applyDialogFields(
|
||||
int unreadCount,
|
||||
MsgId maxInboxRead,
|
||||
|
|
Loading…
Reference in New Issue