From 84a47d3be711b368160c0ca65f70c3114bcf47b4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 19 Nov 2015 18:56:29 +0300 Subject: [PATCH] participants handled good in supergroups: auto-load in profiles, outdate when something changes --- Telegram/SourceFiles/apiwrap.cpp | 135 ++++++++++++++++--------- Telegram/SourceFiles/apiwrap.h | 6 +- Telegram/SourceFiles/dialogswidget.cpp | 7 +- Telegram/SourceFiles/dropdown.cpp | 2 +- Telegram/SourceFiles/history.cpp | 54 ++++++---- Telegram/SourceFiles/profilewidget.cpp | 48 +++++---- Telegram/SourceFiles/structs.h | 21 +++- 7 files changed, 178 insertions(+), 95 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 02c32ab51..d0f9d7460 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -316,10 +316,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt channel->about = qs(f.vabout); int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0; if (newCount != channel->count) { - channel->count = newCount; if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) { - requestLastParticipants(channel); + channel->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated; + channel->mgInfo->lastParticipantsCount = channel->count; } + channel->count = newCount; } channel->adminsCount = f.has_admins_count() ? f.vadmins_count.v : 0; channel->invitationUrl = (f.vexported_invite.type() == mtpc_chatInviteExported) ? qs(f.vexported_invite.c_chatInviteExported().vlink) : QString(); @@ -421,11 +422,24 @@ void ApiWrap::requestPeers(const QList &peers) { if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector(users)), rpcDone(&ApiWrap::gotUsers)); } -void ApiWrap::requestLastParticipants(ChannelData *peer) { - if (!peer || !peer->isMegagroup() || _participantsRequests.contains(peer)) return; - mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); - _participantsRequests.insert(peer, req); - MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); +void ApiWrap::requestLastParticipants(ChannelData *peer, bool fromStart) { + if (!peer || !peer->isMegagroup()) return; + if ((peer->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || peer->lastParticipantsCountOutdated()) { + fromStart = true; + } + QMap::iterator i = _participantsRequests.find(peer); + if (i != _participantsRequests.cend()) { + if (fromStart && i.value() < 0) { // was not loading from start + _participantsRequests.erase(i); + } else { + return; + } + } + mtpRequestId req = MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsRecent(), MTP_int(fromStart ? 0 : peer->mgInfo->lastParticipants.size()), MTP_int(1)), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); + _participantsRequests.insert(peer, fromStart ? req : -req); + if (fromStart) { + _botsRequests.insert(peer, MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer))); + } } void ApiWrap::gotChat(PeerData *peer, const MTPmessages_Chats &result) { @@ -477,60 +491,80 @@ bool ApiWrap::gotPeerFailed(PeerData *peer, const RPCError &error) { } void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req) { - bool bots = (_participantsRequests.value(peer) != req); - - if (!bots) { + bool bots = (_botsRequests.value(peer) == req), fromStart = false; + if (bots) { + _botsRequests.remove(peer); + } else { + int32 was = _participantsRequests.value(peer); + if (was == req) { + fromStart = true; + } else if (was != -req) { + return; + } _participantsRequests.remove(peer); } - if (!peer->mgInfo) return; - if (result.type() == mtpc_channels_channelParticipants) { - const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants()); - const QVector &v(d.vparticipants.c_vector().v); - App::feedUsers(d.vusers); - int32 botStatus = peer->mgInfo->botStatus; - if (bots) { - peer->mgInfo->bots.clear(); - botStatus = -1; - } else { - peer->mgInfo->lastParticipants.clear(); - peer->mgInfo->lastAdmins.clear(); + if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return; + + if (bots) { + peer->mgInfo->bots.clear(); + peer->mgInfo->botStatus = -1; + } else if (fromStart) { + peer->mgInfo->lastAdmins.clear(); + peer->mgInfo->lastParticipants.clear(); + peer->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate; + } + + const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants()); + const QVector &v(d.vparticipants.c_vector().v); + App::feedUsers(d.vusers); + bool added = false; + int32 botStatus = peer->mgInfo->botStatus; + for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { + int32 userId = 0; + bool admin = false; + + switch (i->type()) { + case mtpc_channelParticipant: userId = i->c_channelParticipant().vuser_id.v; break; + case mtpc_channelParticipantSelf: userId = i->c_channelParticipantSelf().vuser_id.v; break; + case mtpc_channelParticipantModerator: userId = i->c_channelParticipantModerator().vuser_id.v; break; + case mtpc_channelParticipantEditor: userId = i->c_channelParticipantEditor().vuser_id.v; admin = true; break; + case mtpc_channelParticipantKicked: userId = i->c_channelParticipantKicked().vuser_id.v; break; + case mtpc_channelParticipantCreator: userId = i->c_channelParticipantCreator().vuser_id.v; admin = true; break; } - for (QVector::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { - int32 userId = 0; - bool admin = false; - - switch (i->type()) { - case mtpc_channelParticipant: userId = i->c_channelParticipant().vuser_id.v; break; - case mtpc_channelParticipantSelf: userId = i->c_channelParticipantSelf().vuser_id.v; break; - case mtpc_channelParticipantModerator: userId = i->c_channelParticipantModerator().vuser_id.v; break; - case mtpc_channelParticipantEditor: userId = i->c_channelParticipantEditor().vuser_id.v; admin = true; break; - case mtpc_channelParticipantKicked: userId = i->c_channelParticipantKicked().vuser_id.v; break; - case mtpc_channelParticipantCreator: userId = i->c_channelParticipantCreator().vuser_id.v; admin = true; break; + UserData *u = App::user(userId); + if (bots) { + if (u->botInfo) { + peer->mgInfo->bots.insert(u, true); + botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1; } - UserData *u = App::user(userId); - if (bots) { - if (u->botInfo) { - peer->mgInfo->bots.insert(u, true); - botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1; - } - } else { + } else { + if (peer->mgInfo->lastParticipants.indexOf(u) < 0) { peer->mgInfo->lastParticipants.push_back(u); if (admin) peer->mgInfo->lastAdmins.insert(u, true); + added = true; } } - if (d.vcount.v > peer->count) { - peer->count = d.vcount.v; - } else if (v.count() > peer->count) { - peer->count = v.count(); - } - if (App::main()) emit fullPeerUpdated(peer); } + if (d.vcount.v > peer->count) { + peer->count = d.vcount.v; + } else if (v.count() > peer->count) { + peer->count = v.count(); + } + if (!bots && v.isEmpty()) { + peer->count = peer->mgInfo->lastParticipants.size(); + } + peer->mgInfo->botStatus = botStatus; + if (App::main()) emit fullPeerUpdated(peer); } -bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error) { +bool ApiWrap::lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req) { if (mtpIsFlood(error)) return false; - _participantsRequests.remove(peer); + if (_participantsRequests.value(peer) == req || _participantsRequests.value(peer) == -req) { + _participantsRequests.remove(peer); + } else if (_botsRequests.value(peer) == req) { + _botsRequests.remove(peer); + } return true; } @@ -603,10 +637,13 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt if (i >= 0) { kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i); kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second); - kick.first->asChannel()->mgInfo->bots.remove(kick.second); } + kick.first->asChannel()->mgInfo->bots.remove(kick.second); if (kick.first->asChannel()->count > 1) { kick.first->asChannel()->count--; + } else { + kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated; + kick.first->asChannel()->mgInfo->lastParticipantsCount = 0; } } emit fullPeerUpdated(kick.first); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 2e3a0d6ad..1e2fd040e 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -36,7 +36,7 @@ public: void requestFullPeer(PeerData *peer); void requestPeer(PeerData *peer); void requestPeers(const QList &peers); - void requestLastParticipants(ChannelData *peer); + void requestLastParticipants(ChannelData *peer, bool fromStart = true); void processFullPeer(PeerData *peer, const MTPmessages_ChatFull &result); void processFullPeer(PeerData *peer, const MTPUserFull &result); @@ -96,8 +96,8 @@ private: PeerRequests _peerRequests; void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req); - bool lastParticipantsFail(ChannelData *peer, const RPCError &error); - PeerRequests _participantsRequests; + bool lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req); + PeerRequests _participantsRequests, _botsRequests; typedef QPair KickRequest; typedef QMap KickRequests; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 861a66b5a..931554bd9 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -1791,8 +1791,9 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque peer = peerFromMTP(d.c_dialog().vpeer); break; case mtpc_dialogChannel: - msgId = d.c_dialogChannel().vtop_important_message.v; - if (!msgId) msgId = d.c_dialogChannel().vtop_message.v; + //msgId = d.c_dialogChannel().vtop_important_message.v; + //if (!msgId) msgId = d.c_dialogChannel().vtop_message.v; + msgId = d.c_dialogChannel().vtop_message.v; peer = peerFromMTP(d.c_dialogChannel().vpeer); break; } @@ -1802,7 +1803,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque if (!lastMsgId) lastMsgId = msgId; for (int32 j = m->size(); j > 0;) { const MTPMessage &d(m->at(--j)); - if (idFromMessage(d) == msgId) { + if (idFromMessage(d) == msgId && peerFromMessage(d) == peer) { int32 date = dateFromMessage(d); if (date) lastDate = date; break; diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 9b5640828..a52541d73 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -3006,7 +3006,7 @@ void MentionsDropdown::updateFiltered(bool toDown) { } } else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) { QMultiMap ordered; - if (_channel->mgInfo->lastParticipants.isEmpty()) { + if (_channel->mgInfo->lastParticipants.isEmpty() || _channel->lastParticipantsCountOutdated()) { if (App::api()) App::api()->requestLastParticipants(_channel); } else { rows.reserve(_channel->mgInfo->lastParticipants.size()); diff --git a/Telegram/SourceFiles/history.cpp b/Telegram/SourceFiles/history.cpp index 00e2f93a9..613fa1729 100644 --- a/Telegram/SourceFiles/history.cpp +++ b/Telegram/SourceFiles/history.cpp @@ -1482,12 +1482,26 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo switch (d.vaction.type()) { case mtpc_messageActionChatAddUser: { const MTPDmessageActionChatAddUser &d(action.c_messageActionChatAddUser()); - // App::user(App::peerFromUser(d.vuser_id)); added + if (peer->isMegagroup()) { + peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; + const QVector &v(d.vusers.c_vector().v); + for (int32 i = 0, l = v.size(); i < l; ++i) { + if (UserData *user = App::userLoaded(peerFromUser(v.at(i)))) { + if (peer->asChannel()->mgInfo->lastParticipants.indexOf(user) < 0) { + peer->asChannel()->mgInfo->lastParticipants.push_front(user); + } + } + } + } } break; case mtpc_messageActionChatJoinedByLink: { const MTPDmessageActionChatJoinedByLink &d(action.c_messageActionChatJoinedByLink()); - // App::user(App::peerFromUser(d.vuser_id)); added + if (peer->isMegagroup()) { + if (result->from()->isUser() && peer->asChannel()->mgInfo->lastParticipants.indexOf(result->from()->asUser()) < 0) { + peer->asChannel()->mgInfo->lastParticipants.push_front(result->from()->asUser()); + } + } } break; case mtpc_messageActionChatDeletePhoto: { @@ -1731,8 +1745,9 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a QList *lastAuthors = 0; if (peer->isChat()) { lastAuthors = &peer->asChat()->lastAuthors; - } else if (peer->isMegagroup() && !peer->asChannel()->mgInfo->lastParticipants.isEmpty()) { + } else if (peer->isMegagroup()) { lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; + peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; } if (lastAuthors) { int prev = lastAuthors->indexOf(adding->from()->asUser()); @@ -1948,29 +1963,28 @@ void History::addOlderSlice(const QVector &slice, const QVectorasChat()->lastAuthors; markupSenders = &peer->asChat()->markupSenders; } else if (peer->isMegagroup()) { - if (!peer->asChannel()->mgInfo->lastParticipants.isEmpty()) { - lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; - } + lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; markupSenders = &peer->asChannel()->mgInfo->markupSenders; + peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; } for (int32 i = block->items.size(); i > 0; --i) { HistoryItem *item = block->items[i - 1]; - if (!item->indexInOverview()) continue; - - HistoryMedia *media = item->getMedia(true); - if (media) { - HistoryMediaType mt = media->type(); - MediaOverviewType t = mediaToOverviewType(mt); - if (t != OverviewCount) { - if (mt == MediaTypeDocument && static_cast(media)->document()->song()) { - if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments); - } else { - if (addToOverviewFront(item, t)) mask |= (1 << t); + if (item->indexInOverview()) { + HistoryMedia *media = item->getMedia(true); + if (media) { + HistoryMediaType mt = media->type(); + MediaOverviewType t = mediaToOverviewType(mt); + if (t != OverviewCount) { + if (mt == MediaTypeDocument && static_cast(media)->document()->song()) { + if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments); + } else { + if (addToOverviewFront(item, t)) mask |= (1 << t); + } } } - } - if (item->hasTextLinks()) { - if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks); + if (item->hasTextLinks()) { + if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks); + } } if (item->from()->id) { if (lastAuthors) { // chats diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 677f9ec92..a56264980 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -130,7 +130,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData if (chatPhoto && chatPhoto->date) { _photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); } - if (_peerChannel->isMegagroup() && _peerChannel->mgInfo->lastParticipants.isEmpty()) { + if (_peerChannel->isMegagroup() && (_peerChannel->mgInfo->lastParticipants.isEmpty() || (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || _peerChannel->lastParticipantsCountOutdated())) { if (App::api()) App::api()->requestLastParticipants(_peerChannel); } _peerChannel->updateFull(); @@ -487,7 +487,7 @@ void ProfileInner::onAdmins() { void ProfileInner::onCreateInvitationLink() { if (!_peerChat && !_peerChannel) return; - ConfirmBox *box = new ConfirmBox(lang((_peerChat && _peerChat->invitationUrl.isEmpty()) ? lng_group_invite_about : lng_group_invite_about_new)); + ConfirmBox *box = new ConfirmBox(lang(((_peerChat && _peerChat->invitationUrl.isEmpty()) || (_peerChannel && _peerChannel->invitationUrl.isEmpty())) ? lng_group_invite_about : lng_group_invite_about_new)); connect(box, SIGNAL(confirmed()), this, SLOT(onCreateInvitationLinkSure())); App::wnd()->showLayer(box); } @@ -686,24 +686,31 @@ void ProfileInner::reorderParticipants() { } loadProfilePhotos(_lastPreload); } else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) { - if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) { - _participants.clear(); - for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) { - if (*i) { - delete *i; - *i = 0; + if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) { + if (App::api()) App::api()->requestLastParticipants(_peerChannel); + } else if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) { + const MegagroupInfo::LastParticipants &list(_peerChannel->mgInfo->lastParticipants); + int32 s = list.size(); + for (int32 i = 0, l = _participants.size(); i < l; ++i) { + if (i >= s || _participants.at(i) != list.at(i)) { + if (_participantsData.at(i)) { + delete _participantsData.at(i); + _participantsData[i] = 0; + } + if (i < s) { + _participants[i] = list.at(i); + } } } - _participants.reserve(_peerChannel->mgInfo->lastParticipants.size()); - _participantsData.resize(_peerChannel->mgInfo->lastParticipants.size()); - } - UserData *self = App::self(); - bool onlyMe = true; - for (MegagroupInfo::LastParticipants::const_iterator i = _peerChannel->mgInfo->lastParticipants.cbegin(), e = _peerChannel->mgInfo->lastParticipants.cend(); i != e; ++i) { - _participants.push_back(*i); - } - if (_peerChannel->mgInfo->lastParticipants.isEmpty()) { - if (App::api()) App::api()->requestLastParticipants(_peerChannel); + if (_participants.size() > s) { + _participants.resize(s); + } else { + _participants.reserve(s); + for (int32 i = _participants.size(); i < s; ++i) { + _participants.push_back(list.at(i)); + } + } + _participantsData.resize(s); } _onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status); loadProfilePhotos(_lastPreload); @@ -1720,6 +1727,11 @@ void ProfileWidget::onScroll() { if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) { _inner.allowDecreaseHeight(_scroll.scrollTopMax() - _scroll.scrollTop()); } + if (peer()->isMegagroup() && !peer()->asChannel()->mgInfo->lastParticipants.isEmpty() && peer()->asChannel()->mgInfo->lastParticipants.size() < peer()->asChannel()->count) { + if (_scroll.scrollTop() + PreloadHeightsCount * _scroll.height() > _scroll.scrollTopMax()) { + App::api()->requestLastParticipants(peer()->asChannel(), false); + } + } } void ProfileWidget::resizeEvent(QResizeEvent *e) { diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index 7eb374098..1435211a7 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -526,7 +526,7 @@ private: }; struct MegagroupInfo { - MegagroupInfo() : botStatus(-1), migrateFromPtr(0) { + MegagroupInfo() : botStatus(-1), migrateFromPtr(0), lastParticipantsStatus(LastParticipantsUpToDate), lastParticipantsCount(0) { } typedef QList LastParticipants; LastParticipants lastParticipants; @@ -537,6 +537,15 @@ struct MegagroupInfo { typedef QMap Bots; Bots bots; int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other + + enum LastParticipantsStatus { + LastParticipantsUpToDate = 0x00, + LastParticipantsAdminsOutdated = 0x01, + LastParticipantsCountOutdated = 0x02, + }; + mutable int32 lastParticipantsStatus; + int32 lastParticipantsCount; + ChatData *migrateFromPtr; }; @@ -563,6 +572,16 @@ public: int32 version; int32 flags, flagsFull; MegagroupInfo *mgInfo; + bool lastParticipantsCountOutdated() const { + if (!mgInfo || !(mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsCountOutdated)) { + return false; + } + if (mgInfo->lastParticipantsCount == count) { + mgInfo->lastParticipantsStatus &= ~MegagroupInfo::LastParticipantsCountOutdated; + return false; + } + return true; + } void flagsUpdated(); bool isMegagroup() const { return flags & MTPDchannel::flag_megagroup;