participants handled good in supergroups: auto-load in profiles, outdate when something changes

This commit is contained in:
John Preston 2015-11-19 18:56:29 +03:00
parent 583c0e5904
commit 84a47d3be7
7 changed files with 178 additions and 95 deletions

View File

@ -316,10 +316,11 @@ void ApiWrap::gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mt
channel->about = qs(f.vabout); channel->about = qs(f.vabout);
int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0; int32 newCount = f.has_participants_count() ? f.vparticipants_count.v : 0;
if (newCount != channel->count) { if (newCount != channel->count) {
channel->count = newCount;
if (channel->isMegagroup() && !channel->mgInfo->lastParticipants.isEmpty()) { 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->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(); 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<PeerData*> &peers) {
if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers)); if (!users.isEmpty()) MTP::send(MTPusers_GetUsers(MTP_vector<MTPInputUser>(users)), rpcDone(&ApiWrap::gotUsers));
} }
void ApiWrap::requestLastParticipants(ChannelData *peer) { void ApiWrap::requestLastParticipants(ChannelData *peer, bool fromStart) {
if (!peer || !peer->isMegagroup() || _participantsRequests.contains(peer)) return; if (!peer || !peer->isMegagroup()) 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)); if ((peer->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || peer->lastParticipantsCountOutdated()) {
_participantsRequests.insert(peer, req); fromStart = true;
MTP::send(MTPchannels_GetParticipants(peer->inputChannel, MTP_channelParticipantsBots(), MTP_int(0), MTP_int(cMaxGroupCount())), rpcDone(&ApiWrap::lastParticipantsDone, peer), rpcFail(&ApiWrap::lastParticipantsFail, peer)); }
QMap<PeerData*, mtpRequestId>::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) { 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) { void ApiWrap::lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req) {
bool bots = (_participantsRequests.value(peer) != req); bool bots = (_botsRequests.value(peer) == req), fromStart = false;
if (bots) {
if (!bots) { _botsRequests.remove(peer);
} else {
int32 was = _participantsRequests.value(peer);
if (was == req) {
fromStart = true;
} else if (was != -req) {
return;
}
_participantsRequests.remove(peer); _participantsRequests.remove(peer);
} }
if (!peer->mgInfo) return;
if (result.type() == mtpc_channels_channelParticipants) { if (!peer->mgInfo || result.type() != mtpc_channels_channelParticipants) return;
const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants());
const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v); if (bots) {
App::feedUsers(d.vusers); peer->mgInfo->bots.clear();
int32 botStatus = peer->mgInfo->botStatus; peer->mgInfo->botStatus = -1;
if (bots) { } else if (fromStart) {
peer->mgInfo->bots.clear(); peer->mgInfo->lastAdmins.clear();
botStatus = -1; peer->mgInfo->lastParticipants.clear();
} else { peer->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate;
peer->mgInfo->lastParticipants.clear(); }
peer->mgInfo->lastAdmins.clear();
const MTPDchannels_channelParticipants &d(result.c_channels_channelParticipants());
const QVector<MTPChannelParticipant> &v(d.vparticipants.c_vector().v);
App::feedUsers(d.vusers);
bool added = false;
int32 botStatus = peer->mgInfo->botStatus;
for (QVector<MTPChannelParticipant>::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<MTPChannelParticipant>::const_iterator i = v.cbegin(), e = v.cend(); i != e; ++i) { UserData *u = App::user(userId);
int32 userId = 0; if (bots) {
bool admin = false; if (u->botInfo) {
peer->mgInfo->bots.insert(u, true);
switch (i->type()) { botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
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); } else {
if (bots) { if (peer->mgInfo->lastParticipants.indexOf(u) < 0) {
if (u->botInfo) {
peer->mgInfo->bots.insert(u, true);
botStatus = (botStatus > 0/* || i.key()->botInfo->readsAllHistory*/) ? 2 : 1;
}
} else {
peer->mgInfo->lastParticipants.push_back(u); peer->mgInfo->lastParticipants.push_back(u);
if (admin) peer->mgInfo->lastAdmins.insert(u, true); 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; 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; return true;
} }
@ -603,10 +637,13 @@ void ApiWrap::kickParticipantDone(KickRequest kick, const MTPUpdates &result, mt
if (i >= 0) { if (i >= 0) {
kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i); kick.first->asChannel()->mgInfo->lastParticipants.removeAt(i);
kick.first->asChannel()->mgInfo->lastAdmins.remove(kick.second); 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) { if (kick.first->asChannel()->count > 1) {
kick.first->asChannel()->count--; kick.first->asChannel()->count--;
} else {
kick.first->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated;
kick.first->asChannel()->mgInfo->lastParticipantsCount = 0;
} }
} }
emit fullPeerUpdated(kick.first); emit fullPeerUpdated(kick.first);

View File

@ -36,7 +36,7 @@ public:
void requestFullPeer(PeerData *peer); void requestFullPeer(PeerData *peer);
void requestPeer(PeerData *peer); void requestPeer(PeerData *peer);
void requestPeers(const QList<PeerData*> &peers); void requestPeers(const QList<PeerData*> &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 MTPmessages_ChatFull &result);
void processFullPeer(PeerData *peer, const MTPUserFull &result); void processFullPeer(PeerData *peer, const MTPUserFull &result);
@ -96,8 +96,8 @@ private:
PeerRequests _peerRequests; PeerRequests _peerRequests;
void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req); void lastParticipantsDone(ChannelData *peer, const MTPchannels_ChannelParticipants &result, mtpRequestId req);
bool lastParticipantsFail(ChannelData *peer, const RPCError &error); bool lastParticipantsFail(ChannelData *peer, const RPCError &error, mtpRequestId req);
PeerRequests _participantsRequests; PeerRequests _participantsRequests, _botsRequests;
typedef QPair<PeerData*, UserData*> KickRequest; typedef QPair<PeerData*, UserData*> KickRequest;
typedef QMap<KickRequest, mtpRequestId> KickRequests; typedef QMap<KickRequest, mtpRequestId> KickRequests;

View File

@ -1791,8 +1791,9 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
peer = peerFromMTP(d.c_dialog().vpeer); peer = peerFromMTP(d.c_dialog().vpeer);
break; break;
case mtpc_dialogChannel: case mtpc_dialogChannel:
msgId = d.c_dialogChannel().vtop_important_message.v; //msgId = d.c_dialogChannel().vtop_important_message.v;
if (!msgId) msgId = d.c_dialogChannel().vtop_message.v; //if (!msgId) msgId = d.c_dialogChannel().vtop_message.v;
msgId = d.c_dialogChannel().vtop_message.v;
peer = peerFromMTP(d.c_dialogChannel().vpeer); peer = peerFromMTP(d.c_dialogChannel().vpeer);
break; break;
} }
@ -1802,7 +1803,7 @@ void DialogsWidget::dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpReque
if (!lastMsgId) lastMsgId = msgId; if (!lastMsgId) lastMsgId = msgId;
for (int32 j = m->size(); j > 0;) { for (int32 j = m->size(); j > 0;) {
const MTPMessage &d(m->at(--j)); const MTPMessage &d(m->at(--j));
if (idFromMessage(d) == msgId) { if (idFromMessage(d) == msgId && peerFromMessage(d) == peer) {
int32 date = dateFromMessage(d); int32 date = dateFromMessage(d);
if (date) lastDate = date; if (date) lastDate = date;
break; break;

View File

@ -3006,7 +3006,7 @@ void MentionsDropdown::updateFiltered(bool toDown) {
} }
} else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) { } else if (_filter.at(0) == '@' && _channel && _channel->isMegagroup()) {
QMultiMap<int32, UserData*> ordered; QMultiMap<int32, UserData*> ordered;
if (_channel->mgInfo->lastParticipants.isEmpty()) { if (_channel->mgInfo->lastParticipants.isEmpty() || _channel->lastParticipantsCountOutdated()) {
if (App::api()) App::api()->requestLastParticipants(_channel); if (App::api()) App::api()->requestLastParticipants(_channel);
} else { } else {
rows.reserve(_channel->mgInfo->lastParticipants.size()); rows.reserve(_channel->mgInfo->lastParticipants.size());

View File

@ -1482,12 +1482,26 @@ HistoryItem *History::createItem(HistoryBlock *block, const MTPMessage &msg, boo
switch (d.vaction.type()) { switch (d.vaction.type()) {
case mtpc_messageActionChatAddUser: { case mtpc_messageActionChatAddUser: {
const MTPDmessageActionChatAddUser &d(action.c_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<MTPint> &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; } break;
case mtpc_messageActionChatJoinedByLink: { case mtpc_messageActionChatJoinedByLink: {
const MTPDmessageActionChatJoinedByLink &d(action.c_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; } break;
case mtpc_messageActionChatDeletePhoto: { case mtpc_messageActionChatDeletePhoto: {
@ -1731,8 +1745,9 @@ HistoryItem *History::addNewItem(HistoryBlock *to, bool newBlock, HistoryItem *a
QList<UserData*> *lastAuthors = 0; QList<UserData*> *lastAuthors = 0;
if (peer->isChat()) { if (peer->isChat()) {
lastAuthors = &peer->asChat()->lastAuthors; lastAuthors = &peer->asChat()->lastAuthors;
} else if (peer->isMegagroup() && !peer->asChannel()->mgInfo->lastParticipants.isEmpty()) { } else if (peer->isMegagroup()) {
lastAuthors = &peer->asChannel()->mgInfo->lastParticipants; lastAuthors = &peer->asChannel()->mgInfo->lastParticipants;
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
} }
if (lastAuthors) { if (lastAuthors) {
int prev = lastAuthors->indexOf(adding->from()->asUser()); int prev = lastAuthors->indexOf(adding->from()->asUser());
@ -1948,29 +1963,28 @@ void History::addOlderSlice(const QVector<MTPMessage> &slice, const QVector<MTPM
lastAuthors = &peer->asChat()->lastAuthors; lastAuthors = &peer->asChat()->lastAuthors;
markupSenders = &peer->asChat()->markupSenders; markupSenders = &peer->asChat()->markupSenders;
} else if (peer->isMegagroup()) { } 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; markupSenders = &peer->asChannel()->mgInfo->markupSenders;
peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated;
} }
for (int32 i = block->items.size(); i > 0; --i) { for (int32 i = block->items.size(); i > 0; --i) {
HistoryItem *item = block->items[i - 1]; HistoryItem *item = block->items[i - 1];
if (!item->indexInOverview()) continue; if (item->indexInOverview()) {
HistoryMedia *media = item->getMedia(true);
HistoryMedia *media = item->getMedia(true); if (media) {
if (media) { HistoryMediaType mt = media->type();
HistoryMediaType mt = media->type(); MediaOverviewType t = mediaToOverviewType(mt);
MediaOverviewType t = mediaToOverviewType(mt); if (t != OverviewCount) {
if (t != OverviewCount) { if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) {
if (mt == MediaTypeDocument && static_cast<HistoryDocument*>(media)->document()->song()) { if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments);
if (addToOverviewFront(item, OverviewAudioDocuments)) mask |= (1 << OverviewAudioDocuments); } else {
} else { if (addToOverviewFront(item, t)) mask |= (1 << t);
if (addToOverviewFront(item, t)) mask |= (1 << t); }
} }
} }
} if (item->hasTextLinks()) {
if (item->hasTextLinks()) { if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks);
if (addToOverviewFront(item, OverviewLinks)) mask |= (1 << OverviewLinks); }
} }
if (item->from()->id) { if (item->from()->id) {
if (lastAuthors) { // chats if (lastAuthors) { // chats

View File

@ -130,7 +130,7 @@ ProfileInner::ProfileInner(ProfileWidget *profile, ScrollArea *scroll, PeerData
if (chatPhoto && chatPhoto->date) { if (chatPhoto && chatPhoto->date) {
_photoLink = TextLinkPtr(new PhotoLink(chatPhoto, _peer)); _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); if (App::api()) App::api()->requestLastParticipants(_peerChannel);
} }
_peerChannel->updateFull(); _peerChannel->updateFull();
@ -487,7 +487,7 @@ void ProfileInner::onAdmins() {
void ProfileInner::onCreateInvitationLink() { void ProfileInner::onCreateInvitationLink() {
if (!_peerChat && !_peerChannel) return; 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())); connect(box, SIGNAL(confirmed()), this, SLOT(onCreateInvitationLinkSure()));
App::wnd()->showLayer(box); App::wnd()->showLayer(box);
} }
@ -686,24 +686,31 @@ void ProfileInner::reorderParticipants() {
} }
loadProfilePhotos(_lastPreload); loadProfilePhotos(_lastPreload);
} else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) { } else if (_peerChannel && _peerChannel->isMegagroup() && _peerChannel->amIn() && !_peerChannel->mgInfo->lastParticipants.isEmpty()) {
if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) { if (_peerChannel->mgInfo->lastParticipants.isEmpty() || (_peerChannel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) || _peerChannel->lastParticipantsCountOutdated()) {
_participants.clear(); if (App::api()) App::api()->requestLastParticipants(_peerChannel);
for (ParticipantsData::iterator i = _participantsData.begin(), e = _participantsData.end(); i != e; ++i) { } else if (!_peerChannel->mgInfo->lastParticipants.isEmpty()) {
if (*i) { const MegagroupInfo::LastParticipants &list(_peerChannel->mgInfo->lastParticipants);
delete *i; int32 s = list.size();
*i = 0; 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()); if (_participants.size() > s) {
_participantsData.resize(_peerChannel->mgInfo->lastParticipants.size()); _participants.resize(s);
} } else {
UserData *self = App::self(); _participants.reserve(s);
bool onlyMe = true; for (int32 i = _participants.size(); i < s; ++i) {
for (MegagroupInfo::LastParticipants::const_iterator i = _peerChannel->mgInfo->lastParticipants.cbegin(), e = _peerChannel->mgInfo->lastParticipants.cend(); i != e; ++i) { _participants.push_back(list.at(i));
_participants.push_back(*i); }
} }
if (_peerChannel->mgInfo->lastParticipants.isEmpty()) { _participantsData.resize(s);
if (App::api()) App::api()->requestLastParticipants(_peerChannel);
} }
_onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status); _onlineText = (_peerChannel->count > 0) ? lng_chat_status_members(lt_count, _peerChannel->count) : lang(_peerChannel->isMegagroup() ? lng_group_status : lng_channel_status);
loadProfilePhotos(_lastPreload); loadProfilePhotos(_lastPreload);
@ -1720,6 +1727,11 @@ void ProfileWidget::onScroll() {
if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) { if (!_scroll.isHidden() && _scroll.scrollTop() < _scroll.scrollTopMax()) {
_inner.allowDecreaseHeight(_scroll.scrollTopMax() - _scroll.scrollTop()); _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) { void ProfileWidget::resizeEvent(QResizeEvent *e) {

View File

@ -526,7 +526,7 @@ private:
}; };
struct MegagroupInfo { struct MegagroupInfo {
MegagroupInfo() : botStatus(-1), migrateFromPtr(0) { MegagroupInfo() : botStatus(-1), migrateFromPtr(0), lastParticipantsStatus(LastParticipantsUpToDate), lastParticipantsCount(0) {
} }
typedef QList<UserData*> LastParticipants; typedef QList<UserData*> LastParticipants;
LastParticipants lastParticipants; LastParticipants lastParticipants;
@ -537,6 +537,15 @@ struct MegagroupInfo {
typedef QMap<UserData*, bool> Bots; typedef QMap<UserData*, bool> Bots;
Bots bots; Bots bots;
int32 botStatus; // -1 - no bots, 0 - unknown, 1 - one bot, that sees all history, 2 - other 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; ChatData *migrateFromPtr;
}; };
@ -563,6 +572,16 @@ public:
int32 version; int32 version;
int32 flags, flagsFull; int32 flags, flagsFull;
MegagroupInfo *mgInfo; 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(); void flagsUpdated();
bool isMegagroup() const { bool isMegagroup() const {
return flags & MTPDchannel::flag_megagroup; return flags & MTPDchannel::flag_megagroup;