From f3c8da481920e7d9218c7576ad323377b38092f4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 3 Dec 2017 20:43:42 +0400 Subject: [PATCH] Request all admins when first opening a supergroup. --- Telegram/SourceFiles/apiwrap.cpp | 341 ++++++++++-------- Telegram/SourceFiles/apiwrap.h | 26 +- Telegram/SourceFiles/data/data_peer.h | 1 - Telegram/SourceFiles/history/history.cpp | 7 +- .../SourceFiles/history/history_widget.cpp | 9 +- Telegram/SourceFiles/mainwidget.cpp | 45 ++- Telegram/SourceFiles/mainwidget.h | 12 +- 7 files changed, 263 insertions(+), 178 deletions(-) diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 7df6244c3..0bee33c5b 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -565,15 +565,8 @@ void ApiWrap::requestPeers(const QList &peers) { } } -void ApiWrap::requestLastParticipants(ChannelData *channel) { - if (!channel || !channel->isMegagroup()) { - return; - } - - auto needAdmins = channel->canViewAdmins(); - auto adminsOutdated = (channel->mgInfo->lastParticipantsStatus & MegagroupInfo::LastParticipantsAdminsOutdated) != 0; - auto i = _participantsRequests.find(channel); - if (i != _participantsRequests.cend()) { +void ApiWrap::requestLastParticipants(not_null channel) { + if (!channel->isMegagroup() || _participantsRequests.contains(channel)) { return; } @@ -585,20 +578,25 @@ void ApiWrap::requestLastParticipants(ChannelData *channel) { MTP_int(offset), MTP_int(Global::ChatSizeMax()), MTP_int(participantsHash) - )).done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - lastParticipantsDone(channel, result, requestId); - }).fail([this, channel](const RPCError &error, mtpRequestId requestId) { - if (_participantsRequests.value(channel) == requestId - || _participantsRequests.value(channel) == -requestId) { - _participantsRequests.remove(channel); - } + )).done([this, channel](const MTPchannels_ChannelParticipants &result) { + _participantsRequests.remove(channel); + parseChannelParticipants(channel, result, [&]( + int availableCount, + const QVector &list) { + applyLastParticipantsList( + channel, + availableCount, + list); + }); + }).fail([this, channel](const RPCError &error) { + _participantsRequests.remove(channel); }).send(); _participantsRequests.insert(channel, requestId); } -void ApiWrap::requestBots(ChannelData *channel) { - if (!channel || !channel->isMegagroup() || _botsRequests.contains(channel)) { +void ApiWrap::requestBots(not_null channel) { + if (!channel->isMegagroup() || _botsRequests.contains(channel)) { return; } @@ -610,154 +608,203 @@ void ApiWrap::requestBots(ChannelData *channel) { MTP_int(offset), MTP_int(Global::ChatSizeMax()), MTP_int(participantsHash) - )).done([this, channel](const MTPchannels_ChannelParticipants &result, mtpRequestId requestId) { - lastParticipantsDone(channel, result, requestId); - }).fail([this, channel](const RPCError &error, mtpRequestId requestId) { - if (_botsRequests.value(channel) == requestId) { - _botsRequests.remove(channel); - } + )).done([this, channel](const MTPchannels_ChannelParticipants &result) { + _botsRequests.remove(channel); + parseChannelParticipants(channel, result, [&]( + int availableCount, + const QVector &list) { + applyBotsList( + channel, + availableCount, + list); + }); + }).fail([this, channel](const RPCError &error) { + _botsRequests.remove(channel); }).send(); _botsRequests.insert(channel, requestId); } -void ApiWrap::lastParticipantsDone( - ChannelData *peer, - const MTPchannels_ChannelParticipants &result, - mtpRequestId requestId) { - auto bots = (_botsRequests.value(peer) == requestId); - auto fromStart = false; - if (bots) { - _botsRequests.remove(peer); - } else { - auto was = _participantsRequests.value(peer); - if (was == requestId) { - fromStart = true; - } else if (was != -requestId) { - return; - } - _participantsRequests.remove(peer); +void ApiWrap::requestAdmins(not_null channel) { + if (!channel->isMegagroup() || _adminsRequests.contains(channel)) { + return; } - if (!peer->mgInfo) return; + auto offset = 0; + auto participantsHash = 0; + auto requestId = request(MTPchannels_GetParticipants( + channel->inputChannel, + MTP_channelParticipantsAdmins(), + MTP_int(offset), + MTP_int(Global::ChatSizeMax()), + MTP_int(participantsHash) + )).done([this, channel](const MTPchannels_ChannelParticipants &result) { + _adminsRequests.remove(channel); + TLHelp::VisitChannelParticipants(result, base::overload([&]( + const MTPDchannels_channelParticipants &data) { + App::feedUsers(data.vusers); + applyAdminsList( + channel, + data.vcount.v, + data.vparticipants.v); + }, [&](mtpTypeId) { + LOG(("API Error: channels.channelParticipantsNotModified received!")); + })); + }).fail([this, channel](const RPCError &error) { + _adminsRequests.remove(channel); + }).send(); - parseChannelParticipants(peer, result, [&]( - int availableCount, - const QVector &list) { - applyLastParticipantsList( - peer, - availableCount, - list, - bots, - fromStart); - }); + _adminsRequests.insert(channel, requestId); } void ApiWrap::applyLastParticipantsList( - ChannelData *peer, + not_null channel, int availableCount, - const QVector &list, - bool bots, - bool fromStart) { - auto h = bots ? App::historyLoaded(peer->id) : nullptr; - 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 QVector &list) { + channel->mgInfo->lastAdmins.clear(); + channel->mgInfo->lastRestricted.clear(); + channel->mgInfo->lastParticipants.clear(); + channel->mgInfo->lastParticipantsStatus = MegagroupInfo::LastParticipantsUpToDate; - auto added = false; - auto needBotsInfos = false; - auto botStatus = peer->mgInfo->botStatus; - auto keyboardBotFound = !h || !h->lastKeyboardFrom; - auto emptyAdminRights = MTP_channelAdminRights(MTP_flags(0)); - auto emptyRestrictedRights = MTP_channelBannedRights(MTP_flags(0), MTP_int(0)); - for (auto &participant : list) { - auto userId = UserId(0); - auto adminCanEdit = false; - auto adminRights = emptyAdminRights; - auto restrictedRights = emptyRestrictedRights; - - switch (participant.type()) { - case mtpc_channelParticipant: userId = participant.c_channelParticipant().vuser_id.v; break; - case mtpc_channelParticipantSelf: userId = participant.c_channelParticipantSelf().vuser_id.v; break; - case mtpc_channelParticipantAdmin: - userId = participant.c_channelParticipantAdmin().vuser_id.v; - adminCanEdit = participant.c_channelParticipantAdmin().is_can_edit(); - adminRights = participant.c_channelParticipantAdmin().vadmin_rights; - break; - case mtpc_channelParticipantBanned: - userId = participant.c_channelParticipantBanned().vuser_id.v; - restrictedRights = participant.c_channelParticipantBanned().vbanned_rights; - break; - case mtpc_channelParticipantCreator: userId = participant.c_channelParticipantCreator().vuser_id.v; break; - } + auto botStatus = channel->mgInfo->botStatus; + const auto emptyAdminRights = MTP_channelAdminRights(MTP_flags(0)); + const auto emptyRestrictedRights = MTP_channelBannedRights( + MTP_flags(0), + MTP_int(0)); + for (const auto &p : list) { + const auto userId = TLHelp::ReadChannelParticipantUserId(p); + const auto adminCanEdit = (p.type() == mtpc_channelParticipantAdmin) + ? p.c_channelParticipantAdmin().is_can_edit() + : false; + const auto adminRights = (p.type() == mtpc_channelParticipantAdmin) + ? p.c_channelParticipantAdmin().vadmin_rights + : emptyAdminRights; + const auto restrictedRights = (p.type() == mtpc_channelParticipantBanned) + ? p.c_channelParticipantBanned().vbanned_rights + : emptyRestrictedRights; if (!userId) { continue; } - auto u = App::user(userId); - if (participant.type() == mtpc_channelParticipantCreator) { - peer->mgInfo->creator = u; + auto user = App::user(userId); + if (p.type() == mtpc_channelParticipantCreator) { + channel->mgInfo->creator = user; + if (!channel->mgInfo->admins.empty() + && !channel->mgInfo->admins.contains(userId)) { + Data::ChannelAdminChanges changes(channel); + changes.feed(userId, true); + } } - if (bots) { - if (u->botInfo) { - peer->mgInfo->bots.insert(u); - botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; - if (!u->botInfo->inited) { - needBotsInfos = true; + if (!base::contains(channel->mgInfo->lastParticipants, user)) { + channel->mgInfo->lastParticipants.push_back(user); + if (adminRights.c_channelAdminRights().vflags.v) { + channel->mgInfo->lastAdmins.emplace( + user, + MegagroupInfo::Admin{ adminRights, adminCanEdit }); + } else if (restrictedRights.c_channelBannedRights().vflags.v != 0) { + channel->mgInfo->lastRestricted.emplace( + user, + MegagroupInfo::Restricted{ restrictedRights }); + } + if (user->botInfo) { + channel->mgInfo->bots.insert(user); + if (channel->mgInfo->botStatus != 0 && channel->mgInfo->botStatus < 2) { + channel->mgInfo->botStatus = 2; } } - if (!keyboardBotFound && u->id == h->lastKeyboardFrom) { - keyboardBotFound = true; - } - } else { - if (!base::contains(peer->mgInfo->lastParticipants, u)) { - peer->mgInfo->lastParticipants.push_back(u); - if (adminRights.c_channelAdminRights().vflags.v) { - peer->mgInfo->lastAdmins.emplace(u, MegagroupInfo::Admin { adminRights, adminCanEdit }); - } else if (restrictedRights.c_channelBannedRights().vflags.v != 0) { - peer->mgInfo->lastRestricted.emplace(u, MegagroupInfo::Restricted { restrictedRights }); - } - if (u->botInfo) { - peer->mgInfo->bots.insert(u); - if (peer->mgInfo->botStatus != 0 && peer->mgInfo->botStatus < 2) { - peer->mgInfo->botStatus = 2; - } - } - added = true; + } + } + // + // getParticipants(Recent) sometimes can't return all members, + // only some last subset, size of this subset is availableCount. + // + // So both list size and availableCount have nothing to do with + // the full supergroup members count. + // + //if (list.isEmpty()) { + // channel->setMembersCount(channel->mgInfo->lastParticipants.size()); + //} else { + // channel->setMembersCount(availableCount); + //} + Notify::PeerUpdate update(channel); + update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; + Notify::peerUpdatedDelayed(update); + + channel->mgInfo->botStatus = botStatus; + if (App::main()) fullPeerUpdated().notify(channel); +} + +void ApiWrap::applyBotsList( + not_null channel, + int availableCount, + const QVector &list) { + const auto history = App::historyLoaded(channel->id); + channel->mgInfo->bots.clear(); + channel->mgInfo->botStatus = -1; + + auto needBotsInfos = false; + auto botStatus = channel->mgInfo->botStatus; + auto keyboardBotFound = !history || !history->lastKeyboardFrom; + for (const auto &p : list) { + const auto userId = TLHelp::ReadChannelParticipantUserId(p); + if (!userId) { + continue; + } + + auto user = App::user(userId); + if (user->botInfo) { + channel->mgInfo->bots.insert(user); + botStatus = 2;// (botStatus > 0/* || !i.key()->botInfo->readsAllHistory*/) ? 2 : 1; + if (!user->botInfo->inited) { + needBotsInfos = true; } } + if (!keyboardBotFound && user->id == history->lastKeyboardFrom) { + keyboardBotFound = true; + } } if (needBotsInfos) { - requestFullPeer(peer); + requestFullPeer(channel); } if (!keyboardBotFound) { - h->clearLastKeyboard(); - } - if (!bots) { - // - // getParticipants(Recent) sometimes can't return all members, - // only some last subset, size of this subset is availableCount. - // - // So both list size and availableCount have nothing to do with - // the full supergroup members count. - // - //if (list.isEmpty()) { - // peer->setMembersCount(peer->mgInfo->lastParticipants.size()); - //} else { - // peer->setMembersCount(availableCount); - //} - Notify::PeerUpdate update(peer); - update.flags |= Notify::PeerUpdate::Flag::MembersChanged | Notify::PeerUpdate::Flag::AdminsChanged; - Notify::peerUpdatedDelayed(update); + history->clearLastKeyboard(); } - peer->mgInfo->botStatus = botStatus; - if (App::main()) fullPeerUpdated().notify(peer); + channel->mgInfo->botStatus = botStatus; + if (App::main()) fullPeerUpdated().notify(channel); +} + +void ApiWrap::applyAdminsList( + not_null channel, + int availableCount, + const QVector &list) { + auto admins = ranges::make_iterator_range( + list.begin(), list.end() + ) | ranges::view::transform([](const MTPChannelParticipant &p) { + return TLHelp::ReadChannelParticipantUserId(p); + }); + auto adding = base::flat_set{ admins.begin(), admins.end() }; + if (channel->mgInfo->creator) { + adding.insert(peerToUser(channel->mgInfo->creator->id)); + } + auto removing = channel->mgInfo->admins; + + if (removing.empty() && adding.empty()) { + // Add some admin-placeholder so we don't DDOS + // server with admins list requests. + LOG(("API Error: Got empty admins list from server.")); + adding.insert(0); + } + + Data::ChannelAdminChanges changes(channel); + for (const auto addingId : adding) { + if (!removing.remove(addingId)) { + changes.feed(addingId, true); + } + } + for (const auto removingId : removing) { + changes.feed(removingId, false); + } } void ApiWrap::requestSelfParticipant(ChannelData *channel) { @@ -765,7 +812,10 @@ void ApiWrap::requestSelfParticipant(ChannelData *channel) { return; } - auto requestId = request(MTPchannels_GetParticipant(channel->inputChannel, MTP_inputUserSelf())).done([this, channel](const MTPchannels_ChannelParticipant &result) { + auto requestId = request(MTPchannels_GetParticipant( + channel->inputChannel, + MTP_inputUserSelf() + )).done([this, channel](const MTPchannels_ChannelParticipant &result) { _selfParticipantRequests.remove(channel); if (result.type() != mtpc_channels_channelParticipant) { LOG(("API Error: unknown type in gotSelfParticipant (%1)").arg(result.type())); @@ -1500,10 +1550,11 @@ void ApiWrap::resolveWebPages() { } } -void ApiWrap::requestParticipantsCountDelayed(ChannelData *channel) { - _participantsCountRequestTimer.call(kReloadChannelMembersTimeout, [this, channel] { - channel->updateFullForced(); - }); +void ApiWrap::requestParticipantsCountDelayed( + not_null channel) { + _participantsCountRequestTimer.call( + kReloadChannelMembersTimeout, + [this, channel] { channel->updateFullForced(); }); } void ApiWrap::gotWebPages(ChannelData *channel, const MTPmessages_Messages &msgs, mtpRequestId req) { @@ -1819,9 +1870,7 @@ void ApiWrap::parseRecentChannelParticipants( applyLastParticipantsList( channel, availableCount, - list, - false, - true); + list); } callbackList(availableCount, list); }, std::move(callbackNotModified)); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index f359bd385..da58dc28a 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -61,9 +61,10 @@ public: void requestFullPeer(PeerData *peer); void requestPeer(PeerData *peer); void requestPeers(const QList &peers); - void requestLastParticipants(ChannelData *channel); - void requestBots(ChannelData *channel); - void requestParticipantsCountDelayed(ChannelData *channel); + void requestLastParticipants(not_null channel); + void requestBots(not_null channel); + void requestAdmins(not_null channel); + void requestParticipantsCountDelayed(not_null channel); void requestChannelMembersForAdd( not_null channel, @@ -187,16 +188,18 @@ private: void gotChatFull(PeerData *peer, const MTPmessages_ChatFull &result, mtpRequestId req); void gotUserFull(UserData *user, const MTPUserFull &result, mtpRequestId req); - void lastParticipantsDone( - ChannelData *peer, - const MTPchannels_ChannelParticipants &result, - mtpRequestId req); void applyLastParticipantsList( - ChannelData *peer, + not_null channel, int availableCount, - const QVector &list, - bool bots, - bool fromStart); + const QVector &list); + void applyBotsList( + not_null channel, + int availableCount, + const QVector &list); + void applyAdminsList( + not_null channel, + int availableCount, + const QVector &list); void resolveWebPages(); void gotWebPages(ChannelData *channel, const MTPmessages_Messages &result, mtpRequestId req); void gotStickerSet(uint64 setId, const MTPmessages_StickerSet &result); @@ -255,6 +258,7 @@ private: PeerRequests _participantsRequests; PeerRequests _botsRequests; + PeerRequests _adminsRequests; base::DelayedCallTimer _participantsCountRequestTimer; ChannelData *_channelMembersForAdd = nullptr; diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 60ed0e64a..c145027aa 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -755,7 +755,6 @@ struct MegagroupInfo { enum LastParticipantsStatus { LastParticipantsUpToDate = 0x00, - LastParticipantsAdminsOutdated = 0x01, LastParticipantsCountOutdated = 0x02, }; mutable int lastParticipantsStatus = LastParticipantsUpToDate; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 89750ac29..f432588a8 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -948,7 +948,6 @@ HistoryItem *History::createItem(const MTPMessage &msg, bool applyServiceAction, if (auto user = App::userLoaded(peerFromUser(v[i]))) { if (!base::contains(mgInfo->lastParticipants, user)) { mgInfo->lastParticipants.push_front(user); - mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); Auth().data().addNewMegagroupParticipant(megagroup, user); } @@ -1339,7 +1338,7 @@ HistoryItem *History::addNewItem(HistoryItem *adding, bool newMsg) { if (index > 0) { lastAuthors->erase(prev); } else if (index < 0 && peer->isMegagroup()) { // nothing is outdated if just reordering - peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; + // admins information outdated } if (index) { lastAuthors->push_front(user); @@ -1610,10 +1609,6 @@ void History::addOlderSlice(const QVector &slice) { if (auto user = item->from()->asUser()) { if (!base::contains(*lastAuthors, user)) { lastAuthors->push_back(user); - if (peer->isMegagroup()) { - peer->asChannel()->mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsAdminsOutdated; - Notify::peerUpdatedDelayed(peer, Notify::PeerUpdate::Flag::MembersChanged); - } } } } diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 4e265b223..191c21767 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -5989,8 +5989,13 @@ void HistoryWidget::handlePeerUpdate() { Auth().api().requestFullPeer(_peer); } else if (_peer->isUser() && (_peer->asUser()->blockStatus() == UserData::BlockStatus::Unknown || _peer->asUser()->callsStatus() == UserData::CallsStatus::Unknown)) { Auth().api().requestFullPeer(_peer); - } else if (_peer->isMegagroup() && !_peer->asChannel()->mgInfo->botStatus) { - Auth().api().requestBots(_peer->asChannel()); + } else if (auto channel = _peer->asMegagroup()) { + if (!channel->mgInfo->botStatus) { + Auth().api().requestBots(channel); + } + if (channel->mgInfo->admins.empty()) { + Auth().api().requestAdmins(channel); + } } if (!_a_show.animating()) { if (_unblock->isHidden() == isBlocked() || (!isBlocked() && _joinChannel->isHidden() == isJoinChannel())) { diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 21f88e2a3..e1c338eec 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1233,24 +1233,47 @@ void MainWidget::deleteAllFromUserPart(DeleteAllFromUserParams params, const MTP } } -void MainWidget::addParticipants(PeerData *chatOrChannel, const std::vector> &users) { - if (chatOrChannel->isChat()) { - auto chat = chatOrChannel->asChat(); +void MainWidget::addParticipants( + not_null chatOrChannel, + const std::vector> &users) { + if (auto chat = chatOrChannel->asChat()) { for_const (auto user, users) { - MTP::send(MTPmessages_AddChatUser(chat->inputChat, user->inputUser, MTP_int(ForwardOnAdd)), rpcDone(&MainWidget::sentUpdatesReceived), rpcFail(&MainWidget::addParticipantFail, { user, chat }), 0, 5); + MTP::send( + MTPmessages_AddChatUser( + chat->inputChat, + user->inputUser, + MTP_int(ForwardOnAdd)), + rpcDone(&MainWidget::sentUpdatesReceived), + rpcFail(&MainWidget::addParticipantFail, { user, chat }), + 0, + 5); } - } else if (chatOrChannel->isChannel()) { + } else if (auto channel = chatOrChannel->asChannel()) { QVector inputUsers; inputUsers.reserve(qMin(int(users.size()), int(MaxUsersPerInvite))); for (auto i = users.cbegin(), e = users.cend(); i != e; ++i) { inputUsers.push_back((*i)->inputUser); if (inputUsers.size() == MaxUsersPerInvite) { - MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5); + MTP::send( + MTPchannels_InviteToChannel( + channel->inputChannel, + MTP_vector(inputUsers)), + rpcDone(&MainWidget::inviteToChannelDone, { channel }), + rpcFail(&MainWidget::addParticipantsFail, { channel }), + 0, + 5); inputUsers.clear(); } } if (!inputUsers.isEmpty()) { - MTP::send(MTPchannels_InviteToChannel(chatOrChannel->asChannel()->inputChannel, MTP_vector(inputUsers)), rpcDone(&MainWidget::inviteToChannelDone, chatOrChannel->asChannel()), rpcFail(&MainWidget::addParticipantsFail, chatOrChannel->asChannel()), 0, 5); + MTP::send( + MTPchannels_InviteToChannel( + channel->inputChannel, + MTP_vector(inputUsers)), + rpcDone(&MainWidget::inviteToChannelDone, { channel }), + rpcFail(&MainWidget::addParticipantsFail, { channel }), + 0, + 5); } } } @@ -1275,7 +1298,9 @@ bool MainWidget::addParticipantFail(UserAndPeer data, const RPCError &error) { return false; } -bool MainWidget::addParticipantsFail(ChannelData *channel, const RPCError &error) { +bool MainWidget::addParticipantsFail( + not_null channel, + const RPCError &error) { if (MTP::isDefaultHandledError(error)) return false; QString text = lang(lng_failed_add_participant); @@ -3070,7 +3095,9 @@ bool MainWidget::deleteChannelFailed(const RPCError &error) { return true; } -void MainWidget::inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates) { +void MainWidget::inviteToChannelDone( + not_null channel, + const MTPUpdates &updates) { sentUpdatesReceived(updates); Auth().api().requestParticipantsCountDelayed(channel); } diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 090a0a306..4f2938d14 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -135,7 +135,9 @@ public: return sentUpdatesReceived(0, updates); } bool deleteChannelFailed(const RPCError &error); - void inviteToChannelDone(ChannelData *channel, const MTPUpdates &updates); + void inviteToChannelDone( + not_null channel, + const MTPUpdates &updates); void historyToDown(History *hist); void dialogsToUp(); void newUnreadMsg(History *history, HistoryItem *item); @@ -215,13 +217,17 @@ public: void deleteAndExit(ChatData *chat); void deleteAllFromUser(ChannelData *channel, UserData *from); - void addParticipants(PeerData *chatOrChannel, const std::vector> &users); + void addParticipants( + not_null chatOrChannel, + const std::vector> &users); struct UserAndPeer { UserData *user; PeerData *peer; }; bool addParticipantFail(UserAndPeer data, const RPCError &e); - bool addParticipantsFail(ChannelData *channel, const RPCError &e); // for multi invite in channels + bool addParticipantsFail( + not_null channel, + const RPCError &e); // for multi invite in channels void kickParticipant(ChatData *chat, UserData *user); bool kickParticipantFail(ChatData *chat, const RPCError &e);