diff --git a/Telegram/SourceFiles/api/api_chat_participants.cpp b/Telegram/SourceFiles/api/api_chat_participants.cpp index d6d4404c29..ee5c9da64d 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.cpp +++ b/Telegram/SourceFiles/api/api_chat_participants.cpp @@ -23,6 +23,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Api { namespace { +using Members = ChatParticipants::Members; + constexpr auto kSmallDelayMs = crl::time(5); // 1 second wait before reload members in channel after adding. @@ -35,57 +37,32 @@ constexpr auto kMaxUsersPerInvite = 100; // that was added to this chat. constexpr auto kForwardMessagesOnAdd = 100; -[[nodiscard]] PeerId TLToPeerId(const MTPChannelParticipant &p) { - return p.match([](const MTPDchannelParticipantBanned &data) { - return peerFromMTP(data.vpeer()); - }, [](const MTPDchannelParticipantLeft &data) { - return peerFromMTP(data.vpeer()); - }, [](const auto &data) { - return peerFromUser(data.vuser_id()); - }); +std::vector ParseList( + const ChatParticipants::TLMembers &data, + not_null peer) { + return ranges::views::all( + data.vparticipants().v + ) | ranges::views::transform([&](const MTPChannelParticipant &p) { + return ChatParticipant(p, peer); + }) | ranges::to_vector; } -void ApplyMegagroupAdmins( - not_null channel, - const MTPDchannels_channelParticipants &data) { +void ApplyMegagroupAdmins(not_null channel, Members list) { Expects(channel->isMegagroup()); - channel->owner().processUsers(data.vusers()); - - const auto &list = data.vparticipants().v; - const auto i = ranges::find( - list, - mtpc_channelParticipantCreator, - &MTPChannelParticipant::type); + const auto i = ranges::find_if(list, &Api::ChatParticipant::isCreator); if (i != list.end()) { - const auto &data = i->c_channelParticipantCreator(); - const auto userId = data.vuser_id().v; - channel->mgInfo->creator = channel->owner().userLoaded(userId); - channel->mgInfo->creatorRank = qs(data.vrank().value_or_empty()); + i->tryApplyCreatorTo(channel); } else { channel->mgInfo->creator = nullptr; channel->mgInfo->creatorRank = QString(); } auto adding = base::flat_map(); - auto admins = ranges::make_subrange( - list.begin(), list.end() - ) | ranges::views::transform([](const MTPChannelParticipant &p) { - const auto participantId = TLToPeerId(p); - const auto rank = p.match([](const MTPDchannelParticipantAdmin &data) { - return qs(data.vrank().value_or_empty()); - }, [](const MTPDchannelParticipantCreator &data) { - return qs(data.vrank().value_or_empty()); - }, [](const auto &data) { - return QString(); - }); - return std::make_pair(participantId, rank); - }) | ranges::views::filter([](const auto &pair) { - return peerIsUser(pair.first); - }); - for (const auto &[participantId, rank] : admins) { - Assert(peerIsUser(participantId)); - adding.emplace(peerToUser(participantId), rank); + for (const auto &p : list) { + if (p.isUser()) { + adding.emplace(p.userId(), p.rank()); + } } if (channel->mgInfo->creator) { adding.emplace( @@ -113,34 +90,24 @@ void ApplyMegagroupAdmins( void RefreshChannelAdmins( not_null channel, - ChatParticipants::TLMembersList participants) { + Members participants) { Data::ChannelAdminChanges changes(channel); for (const auto &p : participants) { - const auto participantId = TLToPeerId(p); - const auto userId = peerToUser(participantId); - p.match([&](const MTPDchannelParticipantAdmin &data) { - Assert(peerIsUser(participantId)); - changes.add(userId, qs(data.vrank().value_or_empty())); - }, [&](const MTPDchannelParticipantCreator &data) { - Assert(peerIsUser(participantId)); - const auto rank = qs(data.vrank().value_or_empty()); - if (const auto info = channel->mgInfo.get()) { - info->creator = channel->owner().userLoaded(userId); - info->creatorRank = rank; + if (p.isUser()) { + if (p.isCreatorOrAdmin()) { + p.tryApplyCreatorTo(channel); + changes.add(p.userId(), p.rank()); + } else { + changes.remove(p.userId()); } - changes.add(userId, rank); - }, [&](const auto &data) { - if (userId) { - changes.remove(userId); - } - }); + } } } void ApplyLastList( not_null channel, int availableCount, - ChatParticipants::TLMembersList list) { + Members list) { channel->mgInfo->lastAdmins.clear(); channel->mgInfo->lastRestricted.clear(); channel->mgInfo->lastParticipants.clear(); @@ -150,36 +117,15 @@ void ApplyLastList( auto botStatus = channel->mgInfo->botStatus; for (const auto &p : list) { - const auto participantId = TLToPeerId(p); - if (!participantId) { - continue; - } - const auto participant = channel->owner().peer(participantId); + const auto participant = channel->owner().peer(p.id()); const auto user = participant->asUser(); - const auto adminCanEdit = (p.type() == mtpc_channelParticipantAdmin) - ? p.c_channelParticipantAdmin().is_can_edit() - : (p.type() == mtpc_channelParticipantCreator) - ? channel->amCreator() - : false; - const auto adminRights = (p.type() == mtpc_channelParticipantAdmin) - ? ChatAdminRightsInfo(p.c_channelParticipantAdmin().vadmin_rights()) - : (p.type() == mtpc_channelParticipantCreator) - ? ChatAdminRightsInfo(p.c_channelParticipantCreator().vadmin_rights()) - : ChatAdminRightsInfo(); - const auto restrictedRights = (p.type() == mtpc_channelParticipantBanned) - ? ChatRestrictionsInfo( - p.c_channelParticipantBanned().vbanned_rights()) - : ChatRestrictionsInfo(); - if (p.type() == mtpc_channelParticipantCreator) { + const auto adminRights = p.rights(); + const auto restrictedRights = p.restrictions(); + if (p.isCreator()) { Assert(user != nullptr); - const auto &creator = p.c_channelParticipantCreator(); - const auto rank = qs(creator.vrank().value_or_empty()); - channel->mgInfo->creator = user; - channel->mgInfo->creatorRank = rank; + p.tryApplyCreatorTo(channel); if (!channel->mgInfo->admins.empty()) { - Data::ChannelAdminChanges(channel).add( - peerToUser(participantId), - rank); + Data::ChannelAdminChanges(channel).add(p.userId(), p.rank()); } } if (user @@ -188,7 +134,7 @@ void ApplyLastList( if (adminRights.flags) { channel->mgInfo->lastAdmins.emplace( user, - MegagroupInfo::Admin{ adminRights, adminCanEdit }); + MegagroupInfo::Admin{ adminRights, p.canBeEdited() }); } else if (restrictedRights.flags) { channel->mgInfo->lastRestricted.emplace( user, @@ -196,7 +142,8 @@ void ApplyLastList( } if (user->isBot()) { channel->mgInfo->bots.insert(user); - if (channel->mgInfo->botStatus != 0 && channel->mgInfo->botStatus < 2) { + if ((channel->mgInfo->botStatus != 0) + && (channel->mgInfo->botStatus < 2)) { channel->mgInfo->botStatus = 2; } } @@ -227,7 +174,7 @@ void ApplyLastList( void ApplyBotsList( not_null channel, int availableCount, - ChatParticipants::TLMembersList list) { + Members list) { const auto history = channel->owner().historyLoaded(channel); channel->mgInfo->bots.clear(); channel->mgInfo->botStatus = -1; @@ -236,12 +183,7 @@ void ApplyBotsList( auto botStatus = channel->mgInfo->botStatus; auto keyboardBotFound = !history || !history->lastKeyboardFrom; for (const auto &p : list) { - const auto participantId = TLToPeerId(p); - if (!participantId) { - continue; - } - - const auto participant = channel->owner().peer(participantId); + const auto participant = channel->owner().peer(p.id()); const auto user = participant->asUser(); if (user && user->isBot()) { channel->mgInfo->bots.insert(user); @@ -409,8 +351,14 @@ void ChatParticipants::requestForAdd( MTP_int(channel->session().serverConfig().chatSizeMax), MTP_long(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { - base::take(_forAdd).callback(result); - }).fail([=](const MTP::Error &error) { + result.match([&](const MTPDchannels_channelParticipants &data) { + base::take(_forAdd).callback(data); + }, [&](const MTPDchannels_channelParticipantsNotModified &) { + base::take(_forAdd); + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); + }); + }).fail([=] { base::take(_forAdd); }).send(); } @@ -431,11 +379,13 @@ void ChatParticipants::requestLast(not_null channel) { MTP_long(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { _participantsRequests.remove(channel); - parse(channel, result, [&](int availableCount, TLMembersList list) { - ApplyLastList( - channel, - availableCount, - list); + + result.match([&](const MTPDchannels_channelParticipants &data) { + const auto &[availableCount, list] = Parse(channel, data); + ApplyLastList(channel, availableCount, list); + }, [](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); }); }).fail([this, channel](const MTP::Error &error) { _participantsRequests.remove(channel); @@ -459,11 +409,12 @@ void ChatParticipants::requestBots(not_null channel) { MTP_long(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { _botsRequests.remove(channel); - parse(channel, result, [&](int availableCount, TLMembersList list) { - ApplyBotsList( - channel, - availableCount, - list); + result.match([&](const MTPDchannels_channelParticipants &data) { + const auto &[availableCount, list] = Parse(channel, data); + ApplyLastList(channel, availableCount, list); + }, [](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); }); }).fail([=](const MTP::Error &error) { _botsRequests.remove(channel); @@ -488,7 +439,8 @@ void ChatParticipants::requestAdmins(not_null channel) { )).done([=](const MTPchannels_ChannelParticipants &result) { _adminsRequests.remove(channel); result.match([&](const MTPDchannels_channelParticipants &data) { - ApplyMegagroupAdmins(channel, data); + channel->owner().processUsers(data.vusers()); + ApplyMegagroupAdmins(channel, ParseList(data, channel)); }, [](const MTPDchannels_channelParticipantsNotModified &) { LOG(("API Error: " "channels.channelParticipantsNotModified received!")); @@ -562,40 +514,27 @@ void ChatParticipants::add( } } -void ChatParticipants::parseRecent( +ChatParticipants::Parsed ChatParticipants::Parse( not_null channel, - const TLMembers &result, - Fn callbackList) { - parse(channel, result, [&](int availableCount, TLMembersList list) { - const auto applyLast = channel->isMegagroup() - && (channel->mgInfo->lastParticipants.size() <= list.size()); - if (applyLast) { - ApplyLastList( - channel, - availableCount, - list); - } - if (callbackList) { - callbackList(availableCount, list); - } - }); + const TLMembers &data) { + channel->owner().processUsers(data.vusers()); + auto list = ParseList(data, channel); + if (channel->mgInfo) { + RefreshChannelAdmins(channel, list); + } + return { data.vcount().v, std::move(list) }; } -void ChatParticipants::parse( +ChatParticipants::Parsed ChatParticipants::ParseRecent( not_null channel, - const TLMembers &result, - Fn callbackList) { - result.match([&](const MTPDchannels_channelParticipants &data) { - channel->owner().processUsers(data.vusers()); - if (channel->mgInfo) { - RefreshChannelAdmins(channel, data.vparticipants().v); - } - if (callbackList) { - callbackList(data.vcount().v, data.vparticipants().v); - } - }, [&](const MTPDchannels_channelParticipantsNotModified &) { - LOG(("API Error: channels.channelParticipantsNotModified received!")); - }); + const TLMembers &data) { + const auto result = Parse(channel, data); + const auto applyLast = channel->isMegagroup() + && (channel->mgInfo->lastParticipants.size() <= result.list.size()); + if (applyLast) { + ApplyLastList(channel, result.availableCount, result.list); + } + return result; } void ChatParticipants::requestSelf(not_null channel) { diff --git a/Telegram/SourceFiles/api/api_chat_participants.h b/Telegram/SourceFiles/api/api_chat_participants.h index ce4354aa15..70e5eafa59 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.h +++ b/Telegram/SourceFiles/api/api_chat_participants.h @@ -72,8 +72,13 @@ private: class ChatParticipants final { public: - using TLMembers = MTPchannels_ChannelParticipants; - using TLMembersList = const QVector &; + struct Parsed { + const int availableCount; + const std::vector list; + }; + + using TLMembers = MTPDchannels_channelParticipants; + using Members = const std::vector &; explicit ChatParticipants(not_null api); void requestLast(not_null channel); @@ -81,14 +86,12 @@ public: void requestAdmins(not_null channel); void requestCountDelayed(not_null channel); - void parse( + static Parsed Parse( not_null channel, - const TLMembers &result, - Fn callbackList); - void parseRecent( + const TLMembers &data); + static Parsed ParseRecent( not_null channel, - const TLMembers &result, - Fn callbackList = nullptr); + const TLMembers &data); void add( not_null peer, const std::vector> &users, diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index e12ff3d1a5..edaa07d05b 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -466,9 +466,10 @@ void AddSpecialBoxController::loadMoreRows() { )).done([=](const MTPchannels_ChannelParticipants &result) { _loadRequestId = 0; auto &session = channel->session(); - session.api().chatParticipants().parse(channel, result, [&]( - int availableCount, - const QVector &list) { + result.match([&](const MTPDchannels_channelParticipants &data) { + const auto &[availableCount, list] = Api::ChatParticipants::Parse( + channel, + data); for (const auto &data : list) { if (const auto participant = _additional.applyParticipant( data)) { @@ -481,8 +482,9 @@ void AddSpecialBoxController::loadMoreRows() { // To be sure - wait for a whole empty result list. _allLoaded = true; } + }, [&](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: channels.channelParticipantsNotModified received!")); }); - if (delegate()->peerListFullRowsCount() > 0) { setDescriptionText(QString()); } else if (_allLoaded) { @@ -525,7 +527,8 @@ bool AddSpecialBoxController::checkInfoLoaded( )).done([=](const MTPchannels_ChannelParticipant &result) { result.match([&](const MTPDchannels_channelParticipant &data) { channel->owner().processUsers(data.vusers()); - _additional.applyParticipant(data.vparticipant()); + _additional.applyParticipant( + Api::ChatParticipant(data.vparticipant(), channel)); }); callback(); }).fail([=](const MTP::Error &error) { @@ -966,7 +969,7 @@ void AddSpecialBoxSearchController::searchParticipantsDone( const auto channel = _peer->asChannel(); auto query = _query; if (requestId) { - const auto addToCache = [&](auto&&...) { + const auto addToCache = [&] { auto it = _participantsQueries.find(requestId); if (it != _participantsQueries.cend()) { query = it->second.text; @@ -978,10 +981,13 @@ void AddSpecialBoxSearchController::searchParticipantsDone( _participantsQueries.erase(it); } }; - channel->session().api().chatParticipants().parse( - channel, - result, - addToCache); + result.match([&](const MTPDchannels_channelParticipants &data) { + Api::ChatParticipants::Parse(channel, data); + addToCache(); + }, [&](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); + }); } if (_requestId != requestId) { @@ -1001,7 +1007,8 @@ void AddSpecialBoxSearchController::searchParticipantsDone( } } for (const auto &data : list) { - if (const auto user = _additional->applyParticipant(data)) { + if (const auto user = _additional->applyParticipant( + Api::ChatParticipant(data, channel))) { delegate()->peerListSearchAddRow(user); } } diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 92bf2a79af..7658449a59 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -537,34 +537,33 @@ void ParticipantsAdditionalData::applyAdminLocally( const QString &rank) { const auto date = base::unixtime::now(); // Incorrect, but ignored. if (isCreator(user) && user->isSelf()) { - using Flag = MTPDchannelParticipantCreator::Flag; - applyParticipant(MTP_channelParticipantCreator( - MTP_flags(rank.isEmpty() ? Flag(0) : Flag::f_rank), - peerToBareMTPInt(user->id), - MTP_chatAdminRights( - MTP_flags(MTPDchatAdminRights::Flags::from_raw( - uint32(rights.flags)))), - MTP_string(rank))); + applyParticipant(Api::ChatParticipant( + Api::ChatParticipant::Type::Creator, + user->id, + UserId(), + ChatRestrictionsInfo(), + std::move(rights), + true, // As the creator is self. + rank)); } else if (!rights.flags) { - applyParticipant(MTP_channelParticipant( - peerToBareMTPInt(user->id), - MTP_int(date))); + applyParticipant(Api::ChatParticipant( + Api::ChatParticipant::Type::Member, + user->id, + UserId(), + ChatRestrictionsInfo(), + ChatAdminRightsInfo())); } else { - using Flag = MTPDchannelParticipantAdmin::Flag; const auto alreadyPromotedBy = adminPromotedBy(user); - applyParticipant(MTP_channelParticipantAdmin( - MTP_flags(Flag::f_can_edit - | (rank.isEmpty() ? Flag(0) : Flag::f_rank)), - peerToBareMTPInt(user->id), - MTPlong(), // inviter_id - peerToBareMTPInt(alreadyPromotedBy - ? alreadyPromotedBy->id - : user->session().userPeerId()), - MTP_int(date), - MTP_chatAdminRights( - MTP_flags(MTPDchatAdminRights::Flags::from_raw( - uint32(rights.flags)))), - MTP_string(rank))); + applyParticipant(Api::ChatParticipant( + Api::ChatParticipant::Type::Admin, + user->id, + alreadyPromotedBy + ? peerToUser(alreadyPromotedBy->id) + : user->session().userId(), + ChatRestrictionsInfo(), + std::move(rights), + true, + rank)); } } @@ -575,76 +574,73 @@ void ParticipantsAdditionalData::applyBannedLocally( const auto date = base::unixtime::now(); // Incorrect, but ignored. if (!rights.flags) { if (user) { - applyParticipant(MTP_channelParticipant( - peerToBareMTPInt(user->id), - MTP_int(date))); + applyParticipant(Api::ChatParticipant( + Api::ChatParticipant::Type::Member, + user->id, + UserId(), + ChatRestrictionsInfo(), + ChatAdminRightsInfo())); } else { setExternal(participant); } } else { const auto kicked = rights.flags & ChatRestriction::ViewMessages; - const auto alreadyRestrictedBy = restrictedBy( - participant); - applyParticipant(MTP_channelParticipantBanned( - MTP_flags(kicked - ? MTPDchannelParticipantBanned::Flag::f_left - : MTPDchannelParticipantBanned::Flag(0)), - peerToMTP(participant->id), - peerToBareMTPInt(alreadyRestrictedBy - ? alreadyRestrictedBy->id - : participant->session().userPeerId()), - MTP_int(date), - MTP_chatBannedRights( - MTP_flags(MTPDchatBannedRights::Flags::from_raw( - uint32(rights.flags))), - MTP_int(rights.until)))); + const auto alreadyRestrictedBy = restrictedBy(participant); + applyParticipant(Api::ChatParticipant( + kicked + ? Api::ChatParticipant::Type::Banned + : Api::ChatParticipant::Type::Restricted, + participant->id, + alreadyRestrictedBy + ? peerToUser(alreadyRestrictedBy->id) + : participant->session().userId(), + std::move(rights), + ChatAdminRightsInfo())); } } PeerData *ParticipantsAdditionalData::applyParticipant( - const MTPChannelParticipant &data) { + const Api::ChatParticipant &data) { return applyParticipant(data, _role); } PeerData *ParticipantsAdditionalData::applyParticipant( - const MTPChannelParticipant &data, + const Api::ChatParticipant &data, Role overrideRole) { const auto logBad = [&]() -> PeerData* { LOG(("API Error: Bad participant type %1 got " "while requesting for participants, role: %2" - ).arg(data.type() + ).arg(static_cast(data.type()) ).arg(static_cast(overrideRole))); return nullptr; }; - return data.match([&]( - const MTPDchannelParticipantCreator &data) -> PeerData* { + switch (data.type()) { + case Api::ChatParticipant::Type::Creator: { if (overrideRole != Role::Profile && overrideRole != Role::Members && overrideRole != Role::Admins) { return logBad(); } return applyCreator(data); - }, [&](const MTPDchannelParticipantAdmin &data) -> PeerData* { + } + case Api::ChatParticipant::Type::Admin: { if (overrideRole != Role::Profile && overrideRole != Role::Members && overrideRole != Role::Admins) { return logBad(); } return applyAdmin(data); - }, [&](const MTPDchannelParticipantSelf &data) -> PeerData* { + } + case Api::ChatParticipant::Type::Member: { if (overrideRole != Role::Profile && overrideRole != Role::Members) { return logBad(); } - return applyRegular(data.vuser_id()); - }, [&](const MTPDchannelParticipant &data) -> PeerData* { - if (overrideRole != Role::Profile - && overrideRole != Role::Members) { - return logBad(); - } - return applyRegular(data.vuser_id()); - }, [&](const MTPDchannelParticipantBanned &data) { + return applyRegular(data.userId()); + } + case Api::ChatParticipant::Type::Restricted: + case Api::ChatParticipant::Type::Banned: if (overrideRole != Role::Profile && overrideRole != Role::Members && overrideRole != Role::Restricted @@ -652,23 +648,23 @@ PeerData *ParticipantsAdditionalData::applyParticipant( return logBad(); } return applyBanned(data); - }, [&](const MTPDchannelParticipantLeft &data) { + case Api::ChatParticipant::Type::Left: return logBad(); - }); + }; } UserData *ParticipantsAdditionalData::applyCreator( - const MTPDchannelParticipantCreator &data) { - if (const auto user = applyRegular(data.vuser_id())) { + const Api::ChatParticipant &data) { + if (const auto user = applyRegular(data.userId())) { _creator = user; - _adminRights[user] = ChatAdminRightsInfo(data.vadmin_rights()); + _adminRights[user] = data.rights(); if (user->isSelf()) { _adminCanEdit.emplace(user); } else { _adminCanEdit.erase(user); } - if (const auto rank = data.vrank()) { - _adminRanks[user] = qs(*rank); + if (data.rank().isEmpty()) { + _adminRanks[user] = data.rank(); } else { _adminRanks.remove(user); } @@ -678,8 +674,8 @@ UserData *ParticipantsAdditionalData::applyCreator( } UserData *ParticipantsAdditionalData::applyAdmin( - const MTPDchannelParticipantAdmin &data) { - const auto user = _peer->owner().userLoaded(UserId(data.vuser_id().v)); + const Api::ChatParticipant &data) { + const auto user = _peer->owner().userLoaded(data.userId()); if (!user) { return nullptr; } else if (const auto chat = _peer->asChat()) { @@ -692,18 +688,18 @@ UserData *ParticipantsAdditionalData::applyAdmin( _restrictedRights.erase(user); _kicked.erase(user); _restrictedBy.erase(user); - _adminRights[user] = ChatAdminRightsInfo(data.vadmin_rights()); - if (data.is_can_edit()) { + _adminRights[user] = data.rights(); + if (data.canBeEdited()) { _adminCanEdit.emplace(user); } else { _adminCanEdit.erase(user); } - if (const auto rank = data.vrank()) { - _adminRanks[user] = qs(*rank); + if (data.rank().isEmpty()) { + _adminRanks[user] = data.rank(); } else { _adminRanks.remove(user); } - if (const auto by = _peer->owner().userLoaded(data.vpromoted_by())) { + if (const auto by = _peer->owner().userLoaded(data.by())) { const auto i = _adminPromotedBy.find(user); if (i == _adminPromotedBy.end()) { _adminPromotedBy.emplace(user, by); @@ -712,12 +708,12 @@ UserData *ParticipantsAdditionalData::applyAdmin( } } else { LOG(("API Error: No user %1 for admin promoted by." - ).arg(data.vpromoted_by().v)); + ).arg(data.by().bare)); } return user; } -UserData *ParticipantsAdditionalData::applyRegular(MTPlong userId) { +UserData *ParticipantsAdditionalData::applyRegular(UserId userId) { const auto user = _peer->owner().userLoaded(userId); if (!user) { return nullptr; @@ -738,9 +734,8 @@ UserData *ParticipantsAdditionalData::applyRegular(MTPlong userId) { } PeerData *ParticipantsAdditionalData::applyBanned( - const MTPDchannelParticipantBanned &data) { - const auto participant = _peer->owner().peerLoaded( - peerFromMTP(data.vpeer())); + const Api::ChatParticipant &data) { + const auto participant = _peer->owner().peerLoaded(data.id()); if (!participant) { return nullptr; } @@ -751,14 +746,13 @@ PeerData *ParticipantsAdditionalData::applyBanned( _adminCanEdit.erase(user); _adminPromotedBy.erase(user); } - if (data.is_left()) { + if (data.isKicked()) { _kicked.emplace(participant); } else { _kicked.erase(participant); } - _restrictedRights[participant] = ChatRestrictionsInfo( - data.vbanned_rights()); - if (const auto by = _peer->owner().userLoaded(data.vkicked_by())) { + _restrictedRights[participant] = data.restrictions(); + if (const auto by = _peer->owner().userLoaded(data.by())) { const auto i = _restrictedBy.find(participant); if (i == _restrictedBy.end()) { _restrictedBy.emplace(participant, by); @@ -1395,17 +1389,11 @@ void ParticipantsBoxController::loadMoreRows() { auto wasRecentRequest = firstLoad && (_role == Role::Members || _role == Role::Profile); - auto parseParticipants = [&](auto &&result, auto &&callback) { - auto &api = channel->session().api().chatParticipants(); - if (wasRecentRequest) { - api.parseRecent(channel, result, callback); - } else { - api.parse(channel, result, callback); - } - }; - parseParticipants(result, [&]( - int availableCount, - const QVector &list) { + + result.match([&](const MTPDchannels_channelParticipants &data) { + const auto &[availableCount, list] = wasRecentRequest + ? Api::ChatParticipants::ParseRecent(channel, data) + : Api::ChatParticipants::Parse(channel, data); for (const auto &data : list) { if (const auto participant = _additional.applyParticipant( data)) { @@ -1418,6 +1406,9 @@ void ParticipantsBoxController::loadMoreRows() { // To be sure - wait for a whole empty result list. _allLoaded = true; } + }, [](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); }); if (_allLoaded @@ -2011,7 +2002,12 @@ void ParticipantsBoxController::subscribeToCreatorChange( channel->mgInfo->lastAdmins.clear(); channel->mgInfo->lastRestricted.clear(); channel->mgInfo->lastParticipants.clear(); - api->chatParticipants().parseRecent(channel, result); + + result.match([&](const MTPDchannels_channelParticipants &data) { + Api::ChatParticipants::ParseRecent(channel, data); + }, [](const MTPDchannels_channelParticipantsNotModified &) { + }); + if (weak) { fullListRefresh(); } @@ -2176,10 +2172,13 @@ void ParticipantsBoxSearchController::searchDone( _queries.erase(it); } }; - _channel->session().api().chatParticipants().parse( - _channel, - result, - addToCache); + result.match([&](const MTPDchannels_channelParticipants &data) { + Api::ChatParticipants::Parse(_channel, data); + addToCache(); + }, [&](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: " + "channels.channelParticipantsNotModified received!")); + }); } if (_requestId != requestId) { return; @@ -2199,7 +2198,7 @@ void ParticipantsBoxSearchController::searchDone( : _role; for (const auto &data : list) { const auto user = _additional->applyParticipant( - data, + Api::ChatParticipant(data, _channel), overrideRole); if (user) { delegate()->peerListSearchAddRow(user); diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h index 9bafc2b538..cfbb5fbf3c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h @@ -21,6 +21,10 @@ namespace Window { class SessionNavigation; } // namespace Window +namespace Api { +class ChatParticipant; +} // namespace Api + Fn peer, Role role); - PeerData *applyParticipant(const MTPChannelParticipant &data); + PeerData *applyParticipant(const Api::ChatParticipant &data); PeerData *applyParticipant( - const MTPChannelParticipant &data, + const Api::ChatParticipant &data, Role overrideRole); void setExternal(not_null participant); void checkForLoaded(not_null participant); @@ -117,10 +121,10 @@ public: ChatRestrictionsInfo rights); private: - UserData *applyCreator(const MTPDchannelParticipantCreator &data); - UserData *applyAdmin(const MTPDchannelParticipantAdmin &data); - UserData *applyRegular(MTPlong userId); - PeerData *applyBanned(const MTPDchannelParticipantBanned &data); + UserData *applyCreator(const Api::ChatParticipant &data); + UserData *applyAdmin(const Api::ChatParticipant &data); + UserData *applyRegular(UserId userId); + PeerData *applyBanned(const Api::ChatParticipant &data); void fillFromChat(not_null chat); void fillFromChannel(not_null channel); diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 2e932c38a6..3ecd53f4e3 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -445,44 +445,27 @@ void InnerWidget::requestAdmins() { MTP_int(kMaxChannelAdmins), MTP_long(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { - session().api().chatParticipants().parse(_channel, result, [&]( - int availableCount, - const QVector &list) { - auto filtered = ( - list - ) | ranges::views::transform([&](const MTPChannelParticipant &p) { - const auto participantId = p.match([]( - const MTPDchannelParticipantBanned &data) { - return peerFromMTP(data.vpeer()); - }, [](const MTPDchannelParticipantLeft &data) { - return peerFromMTP(data.vpeer()); - }, [](const auto &data) { - return peerFromUser(data.vuser_id()); - }); - const auto canEdit = p.match([]( - const MTPDchannelParticipantAdmin &data) { - return data.is_can_edit(); - }, [](const auto &) { - return false; - }); - return std::make_pair(participantId, canEdit); - }) | ranges::views::transform([&](auto &&pair) { - return std::make_pair( - (peerIsUser(pair.first) - ? session().data().userLoaded( - peerToUser(pair.first)) - : nullptr), - pair.second); - }) | ranges::views::filter([&](auto &&pair) { - return (pair.first != nullptr); - }); - - for (auto [user, canEdit] : filtered) { - _admins.emplace_back(user); - if (canEdit) { - _adminsCanEdit.emplace_back(user); + result.match([&](const MTPDchannels_channelParticipants &data) { + const auto &[availableCount, list] = Api::ChatParticipants::Parse( + _channel, + data); + _admins.clear(); + _adminsCanEdit.clear(); + for (const auto &parsed : list) { + if (parsed.isUser()) { + const auto user = _channel->owner().userLoaded( + parsed.userId()); + if (user) { + _admins.emplace_back(user); + if (parsed.canBeEdited() && !parsed.isCreator()) { + _adminsCanEdit.emplace_back(user); + } + } } } + }, [&](const MTPDchannels_channelParticipantsNotModified &) { + LOG(("API Error: c" + "hannels.channelParticipantsNotModified received!")); }); if (_admins.empty()) { _admins.push_back(session().user()); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index d70773c30d..b329eab3c7 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1092,34 +1092,24 @@ void PeerMenuAddChannelMembers( } const auto api = &channel->session().api(); api->chatParticipants().requestForAdd(channel, crl::guard(navigation, [=]( - const MTPchannels_ChannelParticipants &result) { - api->chatParticipants().parse(channel, result, [&]( - int availableCount, - const QVector &list) { - auto already = ( - list - ) | ranges::views::transform([](const MTPChannelParticipant &p) { - return p.match([](const MTPDchannelParticipantBanned &data) { - return peerFromMTP(data.vpeer()); - }, [](const MTPDchannelParticipantLeft &data) { - return peerFromMTP(data.vpeer()); - }, [](const auto &data) { - return peerFromUser(data.vuser_id()); - }); - }) | ranges::views::transform([&](PeerId participantId) { - return peerIsUser(participantId) - ? channel->owner().userLoaded( - peerToUser(participantId)) - : nullptr; - }) | ranges::views::filter([](UserData *user) { - return (user != nullptr); - }) | ranges::to_vector; + const Api::ChatParticipants::TLMembers &data) { + const auto &[availableCount, list] = Api::ChatParticipants::Parse( + channel, + data); + const auto already = ( + list + ) | ranges::views::transform([&](const Api::ChatParticipant &p) { + return p.isUser() + ? channel->owner().userLoaded(p.userId()) + : nullptr; + }) | ranges::views::filter([](UserData *user) { + return (user != nullptr); + }) | ranges::to_vector; - AddParticipantsBoxController::Start( - navigation, - channel, - { already.begin(), already.end() }); - }); + AddParticipantsBoxController::Start( + navigation, + channel, + { already.begin(), already.end() }); })); }