Prepare code for dialogFeed handling.

This commit is contained in:
John Preston 2018-01-03 21:00:11 +03:00
parent ac57000437
commit 139ef5411a
6 changed files with 212 additions and 147 deletions

View File

@ -146,6 +146,29 @@ void ApiWrap::applyUpdates(
App::main()->feedUpdates(updates, sentMessageRandomId);
}
void ApiWrap::applyDialogsPinned(const QVector<MTPDialog> &list) {
for (auto i = list.size(); i != 0;) {
const auto &dialog = list[--i];
switch (dialog.type()) {
case mtpc_dialog: {
const auto &dialogData = dialog.c_dialog();
if (const auto peer = peerFromMTP(dialogData.vpeer)) {
const auto history = App::history(peer);
history->setPinnedDialog(dialogData.is_pinned());
}
} break;
case mtpc_dialogFeed: {
const auto &feedData = dialog.c_dialogFeed();
const auto feedId = feedData.vfeed_id.v;
// #TODO feeds
} break;
default: Unexpected("Type in ApiWrap::applyDialogsPinned.");
}
}
}
void ApiWrap::sendMessageFail(const RPCError &error) {
if (error.type() == qstr("PEER_FLOOD")) {
Ui::show(Box<InformBox>(

View File

@ -45,8 +45,13 @@ public:
void applyUpdates(const MTPUpdates &updates, uint64 sentMessageRandomId = 0);
void applyDialogsPinned(const QVector<MTPDialog> &list);
using RequestMessageDataCallback = base::lambda<void(ChannelData*, MsgId)>;
void requestMessageData(ChannelData *channel, MsgId msgId, RequestMessageDataCallback callback);
void requestMessageData(
ChannelData *channel,
MsgId msgId,
RequestMessageDataCallback callback);
void requestContacts();

View File

@ -1494,59 +1494,73 @@ void DialogsInner::itemRemoved(not_null<const HistoryItem*> item) {
void DialogsInner::dialogsReceived(const QVector<MTPDialog> &added) {
for (const auto &dialog : added) {
if (dialog.type() != mtpc_dialog) {
continue;
}
const auto &d = dialog.c_dialog();
const auto peerId = peerFromMTP(d.vpeer);
if (!peerId) {
continue;
}
auto history = App::historyFromDialog(peerId, d.vunread_count.v, d.vread_inbox_max_id.v, d.vread_outbox_max_id.v);
history->setUnreadMentionsCount(d.vunread_mentions_count.v);
auto peer = history->peer;
if (auto channel = peer->asChannel()) {
if (d.has_pts()) {
channel->ptsReceived(d.vpts.v);
}
if (!channel->amCreator()) {
if (auto topMsg = App::histItemById(channel, d.vtop_message.v)) {
if (topMsg->date <= date(channel->date)) {
Auth().api().requestSelfParticipant(channel);
}
}
}
}
App::main()->applyNotifySetting(
MTP_notifyPeer(d.vpeer),
d.vnotify_settings,
history);
if (!history->isPinnedDialog() && !history->lastMsgDate.isNull()) {
addSavedPeersAfter(history->lastMsgDate);
}
_contactsNoDialogs->del(peer);
if (peer->migrateFrom()) {
removeDialog(App::historyLoaded(peer->migrateFrom()->id));
} else if (peer->migrateTo() && peer->migrateTo()->amIn()) {
removeDialog(history);
}
if (d.has_draft() && d.vdraft.type() == mtpc_draftMessage) {
auto &draft = d.vdraft.c_draftMessage();
Data::applyPeerCloudDraft(peerId, draft);
switch (dialog.type()) {
case mtpc_dialog: applyDialog(dialog.c_dialog()); break;
case mtpc_dialogFeed: applyFeedDialog(dialog.c_dialogFeed()); break;
default: Unexpected("Type in DialogsInner::dialogsReceived");
}
}
Notify::unreadCounterUpdated();
refresh();
}
void DialogsInner::applyDialog(const MTPDdialog &dialog) {
const auto peerId = peerFromMTP(dialog.vpeer);
if (!peerId) {
return;
}
const auto history = App::historyFromDialog(
peerId,
dialog.vunread_count.v,
dialog.vread_inbox_max_id.v,
dialog.vread_outbox_max_id.v);
history->setUnreadMentionsCount(dialog.vunread_mentions_count.v);
const auto peer = history->peer;
if (const auto channel = peer->asChannel()) {
if (dialog.has_pts()) {
channel->ptsReceived(dialog.vpts.v);
}
if (!channel->amCreator()) {
const auto topMsgId = FullMsgId(
peerToChannel(channel->id),
dialog.vtop_message.v);
if (const auto topMsg = App::histItemById(topMsgId)) {
if (topMsg->date <= date(channel->date)) {
Auth().api().requestSelfParticipant(channel);
}
}
}
}
App::main()->applyNotifySetting(
MTP_notifyPeer(dialog.vpeer),
dialog.vnotify_settings,
history);
if (!history->isPinnedDialog() && !history->lastMsgDate.isNull()) {
addSavedPeersAfter(history->lastMsgDate);
}
_contactsNoDialogs->del(peer);
if (peer->migrateFrom()) {
removeDialog(App::historyLoaded(peer->migrateFrom()->id));
} else if (peer->migrateTo() && peer->migrateTo()->amIn()) {
removeDialog(history);
}
if (dialog.has_draft() && dialog.vdraft.type() == mtpc_draftMessage) {
const auto &draft = dialog.vdraft.c_draftMessage();
Data::applyPeerCloudDraft(peerId, draft);
}
}
void DialogsInner::applyFeedDialog(const MTPDdialogFeed &dialog) {
// #TODO feeds
}
void DialogsInner::addSavedPeersAfter(const QDateTime &date) {
SavedPeersByTime &saved(cRefSavedPeersByTime());
auto &saved = cRefSavedPeersByTime();
while (!saved.isEmpty() && (date.isNull() || date < saved.lastKey())) {
History *history = App::history(saved.last()->id);
const auto history = App::history(saved.last()->id);
history->setChatsListDate(saved.lastKey());
_contactsNoDialogs->del(history->peer);
saved.remove(saved.lastKey(), saved.last());

View File

@ -152,12 +152,27 @@ private:
void setPeerSearchPressed(int pressed);
void setSearchedPressed(int pressed);
bool isPressed() const {
return _importantSwitchPressed || _pressed || (_hashtagPressed >= 0) || (_filteredPressed >= 0) || (_peerSearchPressed >= 0) || (_searchedPressed >= 0);
return _importantSwitchPressed
|| _pressed
|| (_hashtagPressed >= 0)
|| (_filteredPressed >= 0)
|| (_peerSearchPressed >= 0)
|| (_searchedPressed >= 0);
}
bool isSelected() const {
return _importantSwitchSelected || _selected || (_hashtagSelected >= 0) || (_filteredSelected >= 0) || (_peerSearchSelected >= 0) || (_searchedSelected >= 0);
return _importantSwitchSelected
|| _selected
|| (_hashtagSelected >= 0)
|| (_filteredSelected >= 0)
|| (_peerSearchSelected >= 0)
|| (_searchedSelected >= 0);
}
void handlePeerNameChange(not_null<PeerData*> peer, const PeerData::NameFirstChars &oldChars);
void handlePeerNameChange(
not_null<PeerData*> peer,
const PeerData::NameFirstChars &oldChars);
void applyDialog(const MTPDdialog &dialog);
void applyFeedDialog(const MTPDdialogFeed &dialog);
void itemRemoved(not_null<const HistoryItem*> item);
enum class UpdateRowSection {
@ -170,7 +185,11 @@ private:
using UpdateRowSections = base::flags<UpdateRowSection>;
friend inline constexpr auto is_flag_type(UpdateRowSection) { return true; };
void updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect, UpdateRowSections sections = UpdateRowSection::All);
void updateDialogRow(
PeerData *peer,
MsgId msgId,
QRect updateRect,
UpdateRowSections sections = UpdateRowSection::All);
int dialogsOffset() const;
int filteredOffset() const;

View File

@ -313,127 +313,122 @@ void DialogsWidget::notify_historyMuteUpdated(History *history) {
_inner->notify_historyMuteUpdated(history);
}
void DialogsWidget::unreadCountsReceived(const QVector<MTPDialog> &dialogs) {
}
void DialogsWidget::dialogsReceived(
const MTPmessages_Dialogs &dialogs,
mtpRequestId requestId) {
if (_dialogsRequestId != requestId) return;
const QVector<MTPDialog> *dialogsList = 0;
const QVector<MTPMessage> *messagesList = 0;
switch (dialogs.type()) {
case mtpc_messages_dialogs: {
auto &data = dialogs.c_messages_dialogs();
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
messagesList = &data.vmessages.v;
dialogsList = &data.vdialogs.v;
_dialogsFull = true;
} break;
case mtpc_messages_dialogsSlice: {
auto &data = dialogs.c_messages_dialogsSlice();
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
messagesList = &data.vmessages.v;
dialogsList = &data.vdialogs.v;
} break;
}
Auth().api().requestContacts();
if (dialogsList) {
TimeId lastDate = 0;
PeerId lastPeer = 0;
MsgId lastMsgId = 0;
for (int i = dialogsList->size(); i > 0;) {
auto &dialog = dialogsList->at(--i);
if (dialog.type() != mtpc_dialog) {
continue;
}
const auto &dialogData = dialog.c_dialog();
if (const auto peer = peerFromMTP(dialogData.vpeer)) {
const auto history = App::history(peer);
history->setPinnedDialog(dialogData.is_pinned());
if (!lastDate) {
if (!lastPeer) lastPeer = peer;
if (auto msgId = dialogData.vtop_message.v) {
if (!lastMsgId) lastMsgId = msgId;
for (int j = messagesList->size(); j > 0;) {
auto &message = messagesList->at(--j);
if (idFromMessage(message) == msgId && peerFromMessage(message) == peer) {
if (auto date = dateFromMessage(message)) {
lastDate = date;
}
break;
}
}
}
}
}
}
if (lastDate) {
_dialogsOffsetDate = lastDate;
_dialogsOffsetId = lastMsgId;
_dialogsOffsetPeer = App::peer(lastPeer);
} else {
const auto [dialogsList, messagesList] = [&] {
const auto process = [&](const auto &data) {
App::feedUsers(data.vusers);
App::feedChats(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");
}();
Assert(messagesList != nullptr);
App::feedMsgs(*messagesList, NewMessageLast);
updateDialogsOffset(*dialogsList, *messagesList);
unreadCountsReceived(*dialogsList);
_inner->dialogsReceived(*dialogsList);
onListScroll();
} else {
_dialogsFull = true;
}
applyReceivedDialogs(*dialogsList, *messagesList);
_dialogsRequestId = 0;
loadDialogs();
Auth().data().moreChatsLoaded().notify();
if (_dialogsFull) {
if (_dialogsFull && _pinnedDialogsReceived) {
Auth().data().allChatsLoaded().set(true);
}
Auth().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);
const auto fillFromDialog = [&](const auto &dialog) {
const auto peer = peerFromMTP(dialog.vpeer);
const auto msgId = dialog.vtop_message.v;
if (!peer || !msgId) {
return;
}
if (!lastPeer) {
lastPeer = peer;
}
if (!lastMsgId) {
lastMsgId = msgId;
}
for (auto j = messages.size(); j != 0;) {
const auto &message = messages[--j];
if (idFromMessage(message) == msgId
&& peerFromMessage(message) == peer) {
if (const auto date = dateFromMessage(message)) {
lastDate = date;
}
return;
}
}
};
for (auto i = dialogs.size(); i != 0;) {
const auto &dialog = dialogs[--i];
switch (dialog.type()) {
case mtpc_dialog: fillFromDialog(dialog.c_dialog()); break;
case mtpc_dialogFeed: fillFromDialog(dialog.c_dialogFeed()); break;
default: Unexpected("Type in DialogsWidget::updateDialogsOffset");
}
if (lastDate) {
break;
}
}
if (lastDate) {
_dialogsOffsetDate = lastDate;
_dialogsOffsetId = lastMsgId;
_dialogsOffsetPeer = App::peer(lastPeer);
} else {
_dialogsFull = true;
}
}
void DialogsWidget::pinnedDialogsReceived(const MTPmessages_PeerDialogs &dialogs, mtpRequestId requestId) {
void DialogsWidget::pinnedDialogsReceived(
const MTPmessages_PeerDialogs &result,
mtpRequestId requestId) {
Expects(result.type() == mtpc_messages_peerDialogs);
if (_pinnedDialogsRequestId != requestId) return;
if (dialogs.type() == mtpc_messages_peerDialogs) {
App::histories().clearPinned();
App::histories().clearPinned();
auto &dialogsData = dialogs.c_messages_peerDialogs();
App::feedUsers(dialogsData.vusers);
App::feedChats(dialogsData.vchats);
auto &list = dialogsData.vdialogs.v;
for (auto i = list.size(); i > 0;) {
auto &dialog = list[--i];
if (dialog.type() != mtpc_dialog) {
continue;
}
auto &data = result.c_messages_peerDialogs();
App::feedUsers(data.vusers);
App::feedChats(data.vchats);
const auto &dialogData = dialog.c_dialog();
if (const auto peer = peerFromMTP(dialogData.vpeer)) {
const auto history = App::history(peer);
history->setPinnedDialog(dialogData.is_pinned());
}
}
App::feedMsgs(dialogsData.vmessages, NewMessageLast);
unreadCountsReceived(list);
_inner->dialogsReceived(list);
onListScroll();
}
applyReceivedDialogs(data.vdialogs.v, data.vmessages.v);
_pinnedDialogsRequestId = 0;
_pinnedDialogsReceived = true;
Auth().data().moreChatsLoaded().notify();
if (_dialogsFull && _pinnedDialogsReceived) {
Auth().data().allChatsLoaded().set(true);
}
}
void DialogsWidget::applyReceivedDialogs(
const QVector<MTPDialog> &dialogs,
const QVector<MTPMessage> &messages) {
Auth().api().applyDialogsPinned(dialogs);
App::feedMsgs(messages, NewMessageLast);
_inner->dialogsReceived(dialogs);
onListScroll();
}
bool DialogsWidget::dialogsFailed(const RPCError &error, mtpRequestId requestId) {

View File

@ -131,10 +131,20 @@ protected:
private:
void animationCallback();
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId requestId);
void pinnedDialogsReceived(const MTPmessages_PeerDialogs &dialogs, mtpRequestId requestId);
void dialogsReceived(
const MTPmessages_Dialogs &result,
mtpRequestId requestId);
void pinnedDialogsReceived(
const MTPmessages_PeerDialogs &result,
mtpRequestId requestId);
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId requestId);
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 setSearchInPeer(PeerData *peer, UserData *from = nullptr);
void showSearchFrom();
@ -146,7 +156,6 @@ private:
void updateControlsGeometry();
void updateForwardBar();
void unreadCountsReceived(const QVector<MTPDialog> &dialogs);
bool dialogsFailed(const RPCError &error, mtpRequestId req);
bool searchFailed(DialogsSearchRequestType type, const RPCError &error, mtpRequestId req);
bool peopleFailed(const RPCError &error, mtpRequestId req);