mirror of https://github.com/procxx/kepka.git
Fix possible assertion violation.
Allow removing local HistoryItem's after the album was already sent.
This commit is contained in:
parent
54dd05c556
commit
2868899d81
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue