mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Replaced use of raw MTP* participant type with new transitional class.
This commit is contained in:
parent
c65468f270
commit
f255573070
7 changed files with 249 additions and 324 deletions
|
@ -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<ChatParticipant> ParseList(
|
||||
const ChatParticipants::TLMembers &data,
|
||||
not_null<PeerData*> 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<ChannelData*> channel,
|
||||
const MTPDchannels_channelParticipants &data) {
|
||||
void ApplyMegagroupAdmins(not_null<ChannelData*> 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<UserId, QString>();
|
||||
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<ChannelData*> 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<ChannelData*> 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<ChannelData*> 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<ChannelData*> 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<ChannelData*> 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<ChannelData*> 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<ChannelData*> channel,
|
||||
const TLMembers &result,
|
||||
Fn<void(int availableCount, TLMembersList list)> 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<ChannelData*> channel,
|
||||
const TLMembers &result,
|
||||
Fn<void(int availableCount, TLMembersList list)> 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<ChannelData*> channel) {
|
||||
|
|
|
@ -72,8 +72,13 @@ private:
|
|||
|
||||
class ChatParticipants final {
|
||||
public:
|
||||
using TLMembers = MTPchannels_ChannelParticipants;
|
||||
using TLMembersList = const QVector<MTPChannelParticipant> &;
|
||||
struct Parsed {
|
||||
const int availableCount;
|
||||
const std::vector<ChatParticipant> list;
|
||||
};
|
||||
|
||||
using TLMembers = MTPDchannels_channelParticipants;
|
||||
using Members = const std::vector<ChatParticipant> &;
|
||||
explicit ChatParticipants(not_null<ApiWrap*> api);
|
||||
|
||||
void requestLast(not_null<ChannelData*> channel);
|
||||
|
@ -81,14 +86,12 @@ public:
|
|||
void requestAdmins(not_null<ChannelData*> channel);
|
||||
void requestCountDelayed(not_null<ChannelData*> channel);
|
||||
|
||||
void parse(
|
||||
static Parsed Parse(
|
||||
not_null<ChannelData*> channel,
|
||||
const TLMembers &result,
|
||||
Fn<void(int availableCount, TLMembersList list)> callbackList);
|
||||
void parseRecent(
|
||||
const TLMembers &data);
|
||||
static Parsed ParseRecent(
|
||||
not_null<ChannelData*> channel,
|
||||
const TLMembers &result,
|
||||
Fn<void(int availableCount, TLMembersList)> callbackList = nullptr);
|
||||
const TLMembers &data);
|
||||
void add(
|
||||
not_null<PeerData*> peer,
|
||||
const std::vector<not_null<UserData*>> &users,
|
||||
|
|
|
@ -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<MTPChannelParticipant> &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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<int>(data.type())
|
||||
).arg(static_cast<int>(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<MTPChannelParticipant> &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);
|
||||
|
|
|
@ -21,6 +21,10 @@ namespace Window {
|
|||
class SessionNavigation;
|
||||
} // namespace Window
|
||||
|
||||
namespace Api {
|
||||
class ChatParticipant;
|
||||
} // namespace Api
|
||||
|
||||
Fn<void(
|
||||
ChatAdminRightsInfo oldRights,
|
||||
ChatAdminRightsInfo newRights,
|
||||
|
@ -80,9 +84,9 @@ public:
|
|||
|
||||
ParticipantsAdditionalData(not_null<PeerData*> 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<PeerData*> participant);
|
||||
void checkForLoaded(not_null<PeerData*> 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<ChatData*> chat);
|
||||
void fillFromChannel(not_null<ChannelData*> channel);
|
||||
|
||||
|
|
|
@ -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<MTPChannelParticipant> &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());
|
||||
|
|
|
@ -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<MTPChannelParticipant> &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() });
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue