Fix possible assertion violation.

Allow removing local HistoryItem's after the album was already sent.
This commit is contained in:
John Preston 2018-01-03 12:06:02 +03:00
parent 54dd05c556
commit 2868899d81
3 changed files with 44 additions and 25 deletions

View File

@ -2960,7 +2960,15 @@ void ApiWrap::sendAlbumWithCancelled(
const MessageGroupId &groupId) { const MessageGroupId &groupId) {
const auto localId = item->fullId(); const auto localId = item->fullId();
const auto albumIt = _sendingAlbums.find(groupId.raw()); const auto albumIt = _sendingAlbums.find(groupId.raw());
Assert(albumIt != _sendingAlbums.end()); if (albumIt != _sendingAlbums.end()) {
// Sometimes we destroy item being sent already after the album
// was sent successfully. For example the message could be loaded
// from server (by messages.getHistory or updateNewMessage) and
// added to history and after that updateMessageID was received with
// the same message id, in this case we destroy a detached local
// item and sendAlbumWithCancelled is called for already sent album.
return;
}
const auto &album = albumIt->second; const auto &album = albumIt->second;
const auto proj = [](const SendingAlbum::Item &item) { const auto proj = [](const SendingAlbum::Item &item) {

View File

@ -1061,29 +1061,35 @@ namespace {
} }
void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds) { void feedWereDeleted(ChannelId channelId, const QVector<MTPint> &msgsIds) {
MsgsData *data = fetchMsgsData(channelId, false); const auto data = fetchMsgsData(channelId, false);
if (!data) return; if (!data) return;
ChannelHistory *channelHistory = (channelId == NoChannel) ? 0 : App::historyLoaded(peerFromChannel(channelId))->asChannelHistory(); const auto channelHistory = (channelId != NoChannel)
? App::history(peerFromChannel(channelId))->asChannelHistory()
: nullptr;
QMap<History*, bool> historiesToCheck; base::flat_set<not_null<History*>> historiesToCheck;
for (QVector<MTPint>::const_iterator i = msgsIds.cbegin(), e = msgsIds.cend(); i != e; ++i) { for (const auto msgId : msgsIds) {
MsgsData::const_iterator j = data->constFind(i->v); auto j = data->constFind(msgId.v);
if (j != data->cend()) { if (j != data->cend()) {
History *h = (*j)->history(); const auto h = (*j)->history();
(*j)->destroy(); (*j)->destroy();
if (!h->lastMsg) historiesToCheck.insert(h, true); if (!h->lastMsg) {
historiesToCheck.emplace(h);
}
} else { } else {
if (channelHistory) { if (channelHistory) {
if (channelHistory->unreadCount() > 0 && i->v >= channelHistory->inboxReadBefore) { if (channelHistory->unreadCount() > 0
channelHistory->setUnreadCount(channelHistory->unreadCount() - 1); && msgId.v >= channelHistory->inboxReadBefore) {
channelHistory->setUnreadCount(
channelHistory->unreadCount() - 1);
} }
} }
} }
} }
if (main()) { if (main()) {
for (QMap<History*, bool>::const_iterator i = historiesToCheck.cbegin(), e = historiesToCheck.cend(); i != e; ++i) { for (const auto history : historiesToCheck) {
main()->checkPeerHistory(i.key()->peer); main()->checkPeerHistory(history->peer);
} }
} }
} }

View File

@ -4925,24 +4925,29 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
} break; } break;
case mtpc_updateMessageID: { case mtpc_updateMessageID: {
auto &d = update.c_updateMessageID(); const auto &d = update.c_updateMessageID();
auto msg = App::histItemByRandom(d.vrandom_id.v); if (const auto fullId = App::histItemByRandom(d.vrandom_id.v)) {
if (msg.msg) { const auto channel = fullId.channel;
if (auto msgRow = App::histItemById(msg)) { const auto newId = d.vid.v;
if (App::histItemById(msg.channel, d.vid.v)) { if (const auto local = App::histItemById(fullId)) {
auto history = msgRow->history(); const auto existing = App::histItemById(channel, newId);
auto wasLast = (history->lastMsg == msgRow); if (existing && local->detached()) {
msgRow->destroy(); const auto history = local->history();
const auto wasLast = (history->lastMsg == local);
local->destroy();
if (wasLast && !history->lastMsg) { if (wasLast && !history->lastMsg) {
checkPeerHistory(history->peer); checkPeerHistory(history->peer);
} }
_history->peerMessagesUpdated(); _history->peerMessagesUpdated();
} else { } else {
App::historyUnregItem(msgRow); if (existing) {
Auth().messageIdChanging.notify({ msgRow, d.vid.v }, true); existing->destroy();
msgRow->setId(d.vid.v); }
App::historyRegItem(msgRow); App::historyUnregItem(local);
Auth().data().requestItemRepaint(msgRow); Auth().messageIdChanging.notify({ local, newId }, true);
local->setId(d.vid.v);
App::historyRegItem(local);
Auth().data().requestItemRepaint(local);
} }
} }
App::historyUnregRandom(d.vrandom_id.v); App::historyUnregRandom(d.vrandom_id.v);