Allow blocking channels in voice chats.

This commit is contained in:
John Preston 2021-03-19 19:10:44 +04:00
parent a0a13c3b86
commit 3bd6b2268f
14 changed files with 124 additions and 109 deletions

View File

@ -1982,6 +1982,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_group_call_context_remove_hand" = "Cancel request to speak"; "lng_group_call_context_remove_hand" = "Cancel request to speak";
"lng_group_call_context_mute_for_me" = "Mute for me"; "lng_group_call_context_mute_for_me" = "Mute for me";
"lng_group_call_context_unmute_for_me" = "Unmute for me"; "lng_group_call_context_unmute_for_me" = "Unmute for me";
"lng_group_call_context_remove" = "Remove";
"lng_group_call_remove_channel" = "Remove {channel} from the voice chat?";
"lng_group_call_duration_days#one" = "{count} day"; "lng_group_call_duration_days#one" = "{count} day";
"lng_group_call_duration_days#other" = "{count} days"; "lng_group_call_duration_days#other" = "{count} days";
"lng_group_call_duration_hours#one" = "{count} hour"; "lng_group_call_duration_hours#one" = "{count} hour";

View File

@ -1522,9 +1522,6 @@ void ApiWrap::applyLastParticipantsList(
auto botStatus = channel->mgInfo->botStatus; auto botStatus = channel->mgInfo->botStatus;
const auto emptyAdminRights = MTP_chatAdminRights(MTP_flags(0)); const auto emptyAdminRights = MTP_chatAdminRights(MTP_flags(0));
const auto emptyRestrictedRights = MTP_chatBannedRights(
MTP_flags(0),
MTP_int(0));
for (const auto &p : list) { for (const auto &p : list) {
const auto participantId = p.match([]( const auto participantId = p.match([](
const MTPDchannelParticipantBanned &data) { const MTPDchannelParticipantBanned &data) {
@ -1532,6 +1529,11 @@ void ApiWrap::applyLastParticipantsList(
}, [](const auto &data) { }, [](const auto &data) {
return peerFromUser(data.vuser_id()); return peerFromUser(data.vuser_id());
}); });
if (!participantId) {
continue;
}
const auto participant = _session->data().peer(participantId);
const auto user = participant->asUser();
const auto adminCanEdit = (p.type() == mtpc_channelParticipantAdmin) const auto adminCanEdit = (p.type() == mtpc_channelParticipantAdmin)
? p.c_channelParticipantAdmin().is_can_edit() ? p.c_channelParticipantAdmin().is_can_edit()
: (p.type() == mtpc_channelParticipantCreator) : (p.type() == mtpc_channelParticipantCreator)
@ -1544,13 +1546,7 @@ void ApiWrap::applyLastParticipantsList(
: emptyAdminRights; : emptyAdminRights;
const auto restrictedRights = (p.type() == mtpc_channelParticipantBanned) const auto restrictedRights = (p.type() == mtpc_channelParticipantBanned)
? p.c_channelParticipantBanned().vbanned_rights() ? p.c_channelParticipantBanned().vbanned_rights()
: emptyRestrictedRights; : ChannelData::EmptyRestrictedRights(participant);
if (!participantId) {
continue;
}
const auto participant = _session->data().peer(participantId);
const auto user = participant->asUser();
if (p.type() == mtpc_channelParticipantCreator) { if (p.type() == mtpc_channelParticipantCreator) {
Assert(user != nullptr); Assert(user != nullptr);
const auto &creator = p.c_channelParticipantCreator(); const auto &creator = p.c_channelParticipantCreator();
@ -1730,7 +1726,7 @@ void ApiWrap::kickParticipant(
const auto kick = KickRequest(channel, participant); const auto kick = KickRequest(channel, participant);
if (_kickRequests.contains(kick)) return; if (_kickRequests.contains(kick)) return;
const auto rights = ChannelData::KickedRestrictedRights(); const auto rights = ChannelData::KickedRestrictedRights(participant);
const auto requestId = request(MTPchannels_EditBanned( const auto requestId = request(MTPchannels_EditBanned(
channel->inputChannel, channel->inputChannel,
participant->input, participant->input,
@ -1758,7 +1754,7 @@ void ApiWrap::unblockParticipant(
const auto requestId = request(MTPchannels_EditBanned( const auto requestId = request(MTPchannels_EditBanned(
channel->inputChannel, channel->inputChannel,
participant->input, participant->input,
MTP_chatBannedRights(MTP_flags(0), MTP_int(0)) ChannelData::EmptyRestrictedRights(participant)
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result); applyUpdates(result);

View File

@ -900,7 +900,7 @@ void DeleteMessagesBox::deleteAndClear() {
_moderateInChannel->session().api().kickParticipant( _moderateInChannel->session().api().kickParticipant(
_moderateInChannel, _moderateInChannel,
_moderateFrom, _moderateFrom,
MTP_chatBannedRights(MTP_flags(0), MTP_int(0))); ChannelData::EmptyRestrictedRights(_moderateFrom));
} }
if (_reportSpam->checked()) { if (_reportSpam->checked()) {
_moderateInChannel->session().api().request( _moderateInChannel->session().api().request(

View File

@ -421,6 +421,7 @@ void AddSpecialBoxController::rebuildChatRows(not_null<ChatData*> chat) {
auto count = delegate()->peerListFullRowsCount(); auto count = delegate()->peerListFullRowsCount();
for (auto i = 0; i != count;) { for (auto i = 0; i != count;) {
auto row = delegate()->peerListRowAt(i); auto row = delegate()->peerListRowAt(i);
Assert(row->peer()->isUser());
auto user = row->peer()->asUser(); auto user = row->peer()->asUser();
if (participants.contains(user)) { if (participants.contains(user)) {
++i; ++i;
@ -492,11 +493,16 @@ void AddSpecialBoxController::loadMoreRows() {
} }
void AddSpecialBoxController::rowClicked(not_null<PeerListRow*> row) { void AddSpecialBoxController::rowClicked(not_null<PeerListRow*> row) {
auto user = row->peer()->asUser(); const auto participant = row->peer();
const auto user = participant->asUser();
switch (_role) { switch (_role) {
case Role::Admins: return showAdmin(user); case Role::Admins:
case Role::Restricted: return showRestricted(user); Assert(user != nullptr);
case Role::Kicked: return kickUser(user); return showAdmin(user);
case Role::Restricted:
Assert(user != nullptr);
return showRestricted(user);
case Role::Kicked: return kickUser(participant);
} }
Unexpected("Role in AddSpecialBoxController::rowClicked()"); Unexpected("Role in AddSpecialBoxController::rowClicked()");
} }
@ -724,9 +730,7 @@ void AddSpecialBoxController::showRestricted(
// Finally edit the restricted. // Finally edit the restricted.
const auto currentRights = restrictedRights const auto currentRights = restrictedRights
? *restrictedRights ? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights( : ChannelData::EmptyRestrictedRights(user);
MTP_flags(0),
MTP_int(0)));
auto box = Box<EditRestrictedBox>( auto box = Box<EditRestrictedBox>(
_peer, _peer,
user, user,
@ -839,9 +843,7 @@ void AddSpecialBoxController::kickUser(
const auto restrictedRights = _additional.restrictedRights(participant); const auto restrictedRights = _additional.restrictedRights(participant);
const auto currentRights = restrictedRights const auto currentRights = restrictedRights
? *restrictedRights ? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights( : ChannelData::EmptyRestrictedRights(participant);
MTP_flags(0),
MTP_int(0)));
const auto done = crl::guard(this, [=]( const auto done = crl::guard(this, [=](
const MTPChatBannedRights &newRights) { const MTPChatBannedRights &newRights) {
@ -855,7 +857,7 @@ void AddSpecialBoxController::kickUser(
participant, participant,
done, done,
fail); fail);
callback(currentRights, ChannelData::KickedRestrictedRights()); callback(currentRights, ChannelData::KickedRestrictedRights(participant));
} }
bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) { bool AddSpecialBoxController::appendRow(not_null<PeerData*> participant) {

View File

@ -354,7 +354,7 @@ bool ParticipantsAdditionalData::canRestrictParticipant(
} else if (const auto channel = _peer->asChannel()) { } else if (const auto channel = _peer->asChannel()) {
return channel->canBanMembers(); return channel->canBanMembers();
} }
Unexpected("Peer in ParticipantsAdditionalData::canRestrictUser."); Unexpected("Peer in ParticipantsAdditionalData::canRestrictParticipant.");
} }
bool ParticipantsAdditionalData::canRemoveParticipant( bool ParticipantsAdditionalData::canRemoveParticipant(
@ -978,8 +978,10 @@ void ParticipantsBoxController::addNewParticipants() {
auto already = std::vector<not_null<UserData*>>(); auto already = std::vector<not_null<UserData*>>();
already.reserve(count); already.reserve(count);
for (auto i = 0; i != count; ++i) { for (auto i = 0; i != count; ++i) {
already.emplace_back( const auto participant = delegate()->peerListRowAt(i)->peer();
delegate()->peerListRowAt(i)->peer()->asUser()); if (const auto user = participant->asUser()) {
already.emplace_back(user);
}
} }
AddParticipantsBoxController::Start( AddParticipantsBoxController::Start(
_navigation, _navigation,
@ -1188,6 +1190,7 @@ void ParticipantsBoxController::rebuildChatParticipants(
auto count = delegate()->peerListFullRowsCount(); auto count = delegate()->peerListFullRowsCount();
for (auto i = 0; i != count;) { for (auto i = 0; i != count;) {
auto row = delegate()->peerListRowAt(i); auto row = delegate()->peerListRowAt(i);
Assert(row->peer()->isUser());
auto user = row->peer()->asUser(); auto user = row->peer()->asUser();
if (participants.contains(user)) { if (participants.contains(user)) {
++i; ++i;
@ -1439,15 +1442,15 @@ void ParticipantsBoxController::rowClicked(not_null<PeerListRow*> row) {
void ParticipantsBoxController::rowActionClicked( void ParticipantsBoxController::rowActionClicked(
not_null<PeerListRow*> row) { not_null<PeerListRow*> row) {
Expects(row->peer()->isUser()); const auto participant = row->peer();
const auto user = participant->asUser();
const auto user = row->peer()->asUser();
if (_role == Role::Members || _role == Role::Profile) { if (_role == Role::Members || _role == Role::Profile) {
kickMember(user); kickParticipant(participant);
} else if (_role == Role::Admins) { } else if (_role == Role::Admins) {
Assert(user != nullptr);
removeAdmin(user); removeAdmin(user);
} else { } else {
removeKicked(row, user); removeKicked(row, participant);
} }
} }
@ -1473,7 +1476,7 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
if (user && channel->canAddMembers()) { if (user && channel->canAddMembers()) {
result->addAction( result->addAction(
tr::lng_context_add_to_group(tr::now), tr::lng_context_add_to_group(tr::now),
crl::guard(this, [=] { unkickMember(user); })); crl::guard(this, [=] { unkickParticipant(user); }));
} }
result->addAction( result->addAction(
tr::lng_profile_delete_removed(tr::now), tr::lng_profile_delete_removed(tr::now),
@ -1510,7 +1513,7 @@ base::unique_qptr<Ui::PopupMenu> ParticipantsBoxController::rowContextMenu(
(isGroup (isGroup
? tr::lng_context_remove_from_group ? tr::lng_context_remove_from_group
: tr::lng_profile_kick)(tr::now), : tr::lng_profile_kick)(tr::now),
crl::guard(this, [=] { kickMember(user); })); crl::guard(this, [=] { kickParticipant(user); }));
} }
} }
return result; return result;
@ -1596,9 +1599,7 @@ void ParticipantsBoxController::showRestricted(not_null<UserData*> user) {
const auto restrictedRights = _additional.restrictedRights(user); const auto restrictedRights = _additional.restrictedRights(user);
const auto currentRights = restrictedRights const auto currentRights = restrictedRights
? *restrictedRights ? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights( : ChannelData::EmptyRestrictedRights(user);
MTP_flags(0),
MTP_int(0)));
const auto hasAdminRights = _additional.adminRights(user).has_value(); const auto hasAdminRights = _additional.adminRights(user).has_value();
auto box = Box<EditRestrictedBox>( auto box = Box<EditRestrictedBox>(
_peer, _peer,
@ -1660,32 +1661,32 @@ void ParticipantsBoxController::editRestrictedDone(
: MTP_peerChannel(MTP_int(participant->bareId()))), : MTP_peerChannel(MTP_int(participant->bareId()))),
MTP_int(alreadyRestrictedBy MTP_int(alreadyRestrictedBy
? alreadyRestrictedBy->bareId() ? alreadyRestrictedBy->bareId()
: user->session().userId()), : participant->session().userId()),
MTP_int(date), MTP_int(date),
rights)); rights));
if (kicked) { if (kicked) {
if (_role == Role::Kicked) { if (_role == Role::Kicked) {
prependRow(user); prependRow(participant);
} else if (_role == Role::Admins } else if (_role == Role::Admins
|| _role == Role::Restricted || _role == Role::Restricted
|| _role == Role::Members) { || _role == Role::Members) {
removeRow(user); removeRow(participant);
} }
} else { } else {
if (_role == Role::Restricted) { if (_role == Role::Restricted) {
prependRow(user); prependRow(participant);
} else if (_role == Role::Kicked } else if (_role == Role::Kicked
|| _role == Role::Admins || _role == Role::Admins
|| _role == Role::Members) { || _role == Role::Members) {
removeRow(user); removeRow(participant);
} }
} }
} }
recomputeTypeFor(user); recomputeTypeFor(participant);
delegate()->peerListRefreshRows(); delegate()->peerListRefreshRows();
} }
void ParticipantsBoxController::kickMember(not_null<PeerData*> participant) { void ParticipantsBoxController::kickParticipant(not_null<PeerData*> participant) {
const auto user = participant->asUser(); const auto user = participant->asUser();
const auto text = ((_peer->isChat() || _peer->isMegagroup()) const auto text = ((_peer->isChat() || _peer->isMegagroup())
? tr::lng_profile_sure_kick ? tr::lng_profile_sure_kick
@ -1697,11 +1698,11 @@ void ParticipantsBoxController::kickMember(not_null<PeerData*> participant) {
Box<ConfirmBox>( Box<ConfirmBox>(
text, text,
tr::lng_box_remove(tr::now), tr::lng_box_remove(tr::now),
crl::guard(this, [=] { kickMemberSure(participant); })), crl::guard(this, [=] { kickParticipantSure(participant); })),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
void ParticipantsBoxController::unkickMember(not_null<UserData*> user) { void ParticipantsBoxController::unkickParticipant(not_null<UserData*> user) {
_editBox = nullptr; _editBox = nullptr;
if (const auto row = delegate()->peerListFindRow(user->id)) { if (const auto row = delegate()->peerListFindRow(user->id)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
@ -1710,16 +1711,14 @@ void ParticipantsBoxController::unkickMember(not_null<UserData*> user) {
_peer->session().api().addChatParticipants(_peer, { 1, user }); _peer->session().api().addChatParticipants(_peer, { 1, user });
} }
void ParticipantsBoxController::kickMemberSure( void ParticipantsBoxController::kickParticipantSure(
not_null<PeerData*> participant) { not_null<PeerData*> participant) {
_editBox = nullptr; _editBox = nullptr;
const auto restrictedRights = _additional.restrictedRights(participant); const auto restrictedRights = _additional.restrictedRights(participant);
const auto currentRights = restrictedRights const auto currentRights = restrictedRights
? *restrictedRights ? *restrictedRights
: MTPChatBannedRights(MTP_chatBannedRights( : ChannelData::EmptyRestrictedRights(participant);
MTP_flags(0),
MTP_int(0)));
if (const auto row = delegate()->peerListFindRow(participant->id)) { if (const auto row = delegate()->peerListFindRow(participant->id)) {
delegate()->peerListRemoveRow(row); delegate()->peerListRemoveRow(row);
@ -1810,16 +1809,16 @@ bool ParticipantsBoxController::appendRow(not_null<PeerData*> participant) {
return false; return false;
} }
bool ParticipantsBoxController::prependRow(not_null<UserData*> user) { bool ParticipantsBoxController::prependRow(not_null<PeerData*> participant) {
if (const auto row = delegate()->peerListFindRow(user->id)) { if (const auto row = delegate()->peerListFindRow(participant->id)) {
recomputeTypeFor(user); recomputeTypeFor(participant);
refreshCustomStatus(row); refreshCustomStatus(row);
if (_role == Role::Admins) { if (_role == Role::Admins) {
// Perhaps we've added a new admin from search. // Perhaps we've added a new admin from search.
delegate()->peerListPrependRowFromSearchResult(row); delegate()->peerListPrependRowFromSearchResult(row);
} }
return false; return false;
} else if (auto row = createRow(user)) { } else if (auto row = createRow(participant)) {
delegate()->peerListPrependRow(std::move(row)); delegate()->peerListPrependRow(std::move(row));
if (_role != Role::Kicked) { if (_role != Role::Kicked) {
setDescriptionText(QString()); setDescriptionText(QString());

View File

@ -232,13 +232,13 @@ private:
not_null<PeerData*> participant); not_null<PeerData*> participant);
void removeKickedWithRow(not_null<PeerData*> participant); void removeKickedWithRow(not_null<PeerData*> participant);
void removeKicked(not_null<PeerData*> participant); void removeKicked(not_null<PeerData*> participant);
void kickMember(not_null<PeerData*> participant); void kickParticipant(not_null<PeerData*> participant);
void kickMemberSure(not_null<PeerData*> participant); void kickParticipantSure(not_null<PeerData*> participant);
void unkickMember(not_null<UserData*> user); void unkickParticipant(not_null<UserData*> user);
void removeAdmin(not_null<UserData*> user); void removeAdmin(not_null<UserData*> user);
void removeAdminSure(not_null<UserData*> user); void removeAdminSure(not_null<UserData*> user);
bool appendRow(not_null<PeerData*> participant); bool appendRow(not_null<PeerData*> participant);
bool prependRow(not_null<UserData*> user); bool prependRow(not_null<PeerData*> participant);
bool removeRow(not_null<PeerData*> participant); bool removeRow(not_null<PeerData*> participant);
void refreshCustomStatus(not_null<PeerListRow*> row) const; void refreshCustomStatus(not_null<PeerListRow*> row) const;
bool feedMegagroupLastParticipants(); bool feedMegagroupLastParticipants();

View File

@ -1570,7 +1570,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
Window::SectionShow::Way::Forward); Window::SectionShow::Way::Forward);
}); });
}; };
const auto removeFromGroup = crl::guard(this, [=] { const auto removeFromVoiceChat = crl::guard(this, [=] {
_kickParticipantRequests.fire_copy(participantPeer); _kickParticipantRequests.fire_copy(participantPeer);
}); });
@ -1607,9 +1607,7 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
} }
const auto canKick = [&] { const auto canKick = [&] {
const auto user = participantPeer->asUser(); const auto user = participantPeer->asUser();
if (!user) { if (static_cast<Row*>(row.get())->state()
return false;
} else if (static_cast<Row*>(row.get())->state()
== Row::State::Invited) { == Row::State::Invited) {
return false; return false;
} else if (const auto chat = _peer->asChat()) { } else if (const auto chat = _peer->asChat()) {
@ -1617,16 +1615,15 @@ base::unique_qptr<Ui::PopupMenu> MembersController::createRowContextMenu(
|| (user || (user
&& chat->canBanMembers() && chat->canBanMembers()
&& !chat->admins.contains(user)); && !chat->admins.contains(user));
} else if (const auto group = _peer->asMegagroup()) { } else if (const auto channel = _peer->asChannel()) {
return group->amCreator() return channel->canRestrictParticipant(participantPeer);
|| (user && group->canRestrictUser(user));
} }
return false; return false;
}(); }();
if (canKick) { if (canKick) {
result->addAction( result->addAction(
tr::lng_context_remove_from_group(tr::now), tr::lng_group_call_context_remove(tr::now),
removeFromGroup); removeFromVoiceChat);
} }
} }
if (result->empty()) { if (result->empty()) {

View File

@ -530,9 +530,7 @@ void Panel::initWithCall(GroupCall *call) {
_members->kickParticipantRequests( _members->kickParticipantRequests(
) | rpl::start_with_next([=](not_null<PeerData*> participantPeer) { ) | rpl::start_with_next([=](not_null<PeerData*> participantPeer) {
if (const auto user = participantPeer->asUser()) { kickParticipant(participantPeer);
kickMember(user);
}
}, _callLifetime); }, _callLifetime);
const auto showBox = [=](object_ptr<Ui::BoxContent> next) { const auto showBox = [=](object_ptr<Ui::BoxContent> next) {
@ -955,15 +953,22 @@ void Panel::addMembers() {
_layerBg->showBox(Box<PeerListsBox>(std::move(controllers), initBox)); _layerBg->showBox(Box<PeerListsBox>(std::move(controllers), initBox));
} }
void Panel::kickMember(not_null<UserData*> user) { void Panel::kickParticipant(not_null<PeerData*> participantPeer) {
_layerBg->showBox(Box([=](not_null<Ui::GenericBox*> box) { _layerBg->showBox(Box([=](not_null<Ui::GenericBox*> box) {
box->addRow( box->addRow(
object_ptr<Ui::FlatLabel>( object_ptr<Ui::FlatLabel>(
box.get(), box.get(),
tr::lng_profile_sure_kick( (!participantPeer->isUser()
tr::now, ? tr::lng_group_call_remove_channel(
lt_user, tr::now,
user->firstName), lt_channel,
participantPeer->name)
: (_peer->isBroadcast()
? tr::lng_profile_sure_kick_channel
: tr::lng_profile_sure_kick)(
tr::now,
lt_user,
participantPeer->asUser()->firstName)),
st::groupCallBoxLabel), st::groupCallBoxLabel),
style::margins( style::margins(
st::boxRowPadding.left(), st::boxRowPadding.left(),
@ -972,26 +977,29 @@ void Panel::kickMember(not_null<UserData*> user) {
st::boxPadding.bottom())); st::boxPadding.bottom()));
box->addButton(tr::lng_box_remove(), [=] { box->addButton(tr::lng_box_remove(), [=] {
box->closeBox(); box->closeBox();
kickMemberSure(user); kickParticipantSure(participantPeer);
}); });
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
})); }));
} }
void Panel::kickMemberSure(not_null<UserData*> user) { void Panel::kickParticipantSure(not_null<PeerData*> participantPeer) {
if (const auto chat = _peer->asChat()) { if (const auto chat = _peer->asChat()) {
chat->session().api().kickParticipant(chat, user); chat->session().api().kickParticipant(chat, participantPeer);
} else if (const auto channel = _peer->asChannel()) { } else if (const auto channel = _peer->asChannel()) {
const auto currentRestrictedRights = [&]() -> MTPChatBannedRights { const auto currentRestrictedRights = [&] {
const auto it = channel->mgInfo->lastRestricted.find(user); const auto user = participantPeer->asUser();
return (it != channel->mgInfo->lastRestricted.cend()) if (!channel->mgInfo || !user) {
? it->second.rights return ChannelData::EmptyRestrictedRights(participantPeer);
: MTP_chatBannedRights(MTP_flags(0), MTP_int(0)); }
const auto i = channel->mgInfo->lastRestricted.find(user);
return (i != channel->mgInfo->lastRestricted.cend())
? i->second.rights
: ChannelData::EmptyRestrictedRights(participantPeer);
}(); }();
channel->session().api().kickParticipant( channel->session().api().kickParticipant(
channel, channel,
user, participantPeer,
currentRestrictedRights); currentRestrictedRights);
} }
} }

View File

@ -89,8 +89,8 @@ private:
void showMainMenu(); void showMainMenu();
void chooseJoinAs(); void chooseJoinAs();
void addMembers(); void addMembers();
void kickMember(not_null<UserData*> user); void kickParticipant(not_null<PeerData*> participantPeer);
void kickMemberSure(not_null<UserData*> user); void kickParticipantSure(not_null<PeerData*> participantPeer);
[[nodiscard]] QRect computeTitleRect() const; [[nodiscard]] QRect computeTitleRect() const;
void refreshTitle(); void refreshTitle();
void refreshTitleGeometry(); void refreshTitleGeometry();

View File

@ -188,7 +188,13 @@ void ChannelData::setKickedCount(int newKickedCount) {
} }
} }
MTPChatBannedRights ChannelData::KickedRestrictedRights() { MTPChatBannedRights ChannelData::EmptyRestrictedRights(
not_null<PeerData*> participant) {
return MTP_chatBannedRights(MTP_flags(0), MTP_int(0));
}
MTPChatBannedRights ChannelData::KickedRestrictedRights(
not_null<PeerData*> participant) {
using Flag = MTPDchatBannedRights::Flag; using Flag = MTPDchatBannedRights::Flag;
const auto flags = Flag::f_view_messages const auto flags = Flag::f_view_messages
| Flag::f_send_messages | Flag::f_send_messages
@ -199,7 +205,7 @@ MTPChatBannedRights ChannelData::KickedRestrictedRights() {
| Flag::f_send_games | Flag::f_send_games
| Flag::f_send_inline; | Flag::f_send_inline;
return MTP_chatBannedRights( return MTP_chatBannedRights(
MTP_flags(flags), MTP_flags(participant->isUser() ? flags : Flag::f_view_messages),
MTP_int(std::numeric_limits<int32>::max())); MTP_int(std::numeric_limits<int32>::max()));
} }
@ -494,7 +500,7 @@ bool ChannelData::canDelete() const {
} }
bool ChannelData::canEditLastAdmin(not_null<UserData*> user) const { bool ChannelData::canEditLastAdmin(not_null<UserData*> user) const {
// Duplicated in ParticipantsBoxController::canEditAdmin :( // Duplicated in ParticipantsAdditionalData::canEditAdmin :(
if (mgInfo) { if (mgInfo) {
auto i = mgInfo->lastAdmins.find(user); auto i = mgInfo->lastAdmins.find(user);
if (i != mgInfo->lastAdmins.cend()) { if (i != mgInfo->lastAdmins.cend()) {
@ -506,7 +512,7 @@ bool ChannelData::canEditLastAdmin(not_null<UserData*> user) const {
} }
bool ChannelData::canEditAdmin(not_null<UserData*> user) const { bool ChannelData::canEditAdmin(not_null<UserData*> user) const {
// Duplicated in ParticipantsBoxController::canEditAdmin :( // Duplicated in ParticipantsAdditionalData::canEditAdmin :(
if (user->isSelf()) { if (user->isSelf()) {
return false; return false;
} else if (amCreator()) { } else if (amCreator()) {
@ -517,14 +523,17 @@ bool ChannelData::canEditAdmin(not_null<UserData*> user) const {
return adminRights() & AdminRight::f_add_admins; return adminRights() & AdminRight::f_add_admins;
} }
bool ChannelData::canRestrictUser(not_null<UserData*> user) const { bool ChannelData::canRestrictParticipant(
// Duplicated in ParticipantsBoxController::canRestrictUser :( not_null<PeerData*> participant) const {
if (user->isSelf()) { // Duplicated in ParticipantsAdditionalData::canRestrictParticipant :(
if (participant->isSelf()) {
return false; return false;
} else if (amCreator()) { } else if (amCreator()) {
return true; return true;
} else if (!canEditLastAdmin(user)) { } else if (const auto user = participant->asUser()) {
return false; if (!canEditLastAdmin(user)) {
return false;
}
} }
return adminRights() & AdminRight::f_ban_users; return adminRights() & AdminRight::f_ban_users;
} }

View File

@ -209,7 +209,10 @@ public:
return flags() & MTPDchannel::Flag::f_fake; return flags() & MTPDchannel::Flag::f_fake;
} }
static MTPChatBannedRights KickedRestrictedRights(); static MTPChatBannedRights EmptyRestrictedRights(
not_null<PeerData*> participant);
static MTPChatBannedRights KickedRestrictedRights(
not_null<PeerData*> participant);
static constexpr auto kRestrictUntilForever = TimeId(INT_MAX); static constexpr auto kRestrictUntilForever = TimeId(INT_MAX);
[[nodiscard]] static bool IsRestrictedForever(TimeId until) { [[nodiscard]] static bool IsRestrictedForever(TimeId until) {
return !until || (until == kRestrictUntilForever); return !until || (until == kRestrictUntilForever);
@ -310,7 +313,8 @@ public:
[[nodiscard]] bool canEditStickers() const; [[nodiscard]] bool canEditStickers() const;
[[nodiscard]] bool canDelete() const; [[nodiscard]] bool canDelete() const;
[[nodiscard]] bool canEditAdmin(not_null<UserData*> user) const; [[nodiscard]] bool canEditAdmin(not_null<UserData*> user) const;
[[nodiscard]] bool canRestrictUser(not_null<UserData*> user) const; [[nodiscard]] bool canRestrictParticipant(
not_null<PeerData*> participant) const;
void setInviteLink(const QString &newInviteLink); void setInviteLink(const QString &newInviteLink);
[[nodiscard]] QString inviteLink() const { [[nodiscard]] QString inviteLink() const {

View File

@ -1310,7 +1310,7 @@ void InnerWidget::suggestRestrictUser(not_null<UserData*> user) {
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
}; };
if (base::contains(_admins, user)) { if (base::contains(_admins, user)) {
editRestrictions(true, MTP_chatBannedRights(MTP_flags(0), MTP_int(0))); editRestrictions(true, ChannelData::EmptyRestrictedRights(user));
} else { } else {
_api.request(MTPchannels_GetParticipant( _api.request(MTPchannels_GetParticipant(
_channel->inputChannel, _channel->inputChannel,
@ -1327,15 +1327,11 @@ void InnerWidget::suggestRestrictUser(not_null<UserData*> user) {
} else { } else {
auto hasAdminRights = (type == mtpc_channelParticipantAdmin) auto hasAdminRights = (type == mtpc_channelParticipantAdmin)
|| (type == mtpc_channelParticipantCreator); || (type == mtpc_channelParticipantCreator);
auto bannedRights = MTP_chatBannedRights( auto bannedRights = ChannelData::EmptyRestrictedRights(user);
MTP_flags(0),
MTP_int(0));
editRestrictions(hasAdminRights, bannedRights); editRestrictions(hasAdminRights, bannedRights);
} }
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
auto bannedRights = MTP_chatBannedRights( auto bannedRights = ChannelData::EmptyRestrictedRights(user);
MTP_flags(0),
MTP_int(0));
editRestrictions(false, bannedRights); editRestrictions(false, bannedRights);
}).send(); }).send();
} }

View File

@ -701,9 +701,11 @@ bool HistoryItem::suggestReport() const {
} }
bool HistoryItem::suggestBanReport() const { bool HistoryItem::suggestBanReport() const {
auto channel = history()->peer->asChannel(); const auto channel = history()->peer->asChannel();
auto fromUser = from()->asUser(); const auto fromUser = from()->asUser();
if (!channel || !fromUser || !channel->canRestrictUser(fromUser)) { if (!channel
|| !fromUser
|| !channel->canRestrictParticipant(fromUser)) {
return false; return false;
} }
return !isPost() && !out(); return !isPost() && !out();

View File

@ -84,7 +84,7 @@ void GroupMembersWidget::removePeer(PeerData *selectedPeer) {
return it->second.rights; return it->second.rights;
} }
} }
return MTP_chatBannedRights(MTP_flags(0), MTP_int(0)); return ChannelData::EmptyRestrictedRights(user);
}(); }();
const auto peer = this->peer(); const auto peer = this->peer();