Allow editing ManageTopics rights/restrictions.

This commit is contained in:
John Preston 2022-10-24 11:23:21 +04:00
parent ed895ace66
commit 53beb6f562
9 changed files with 261 additions and 201 deletions

View file

@ -2890,6 +2890,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_rights_group_invite_link" = "Invite users via link"; "lng_rights_group_invite_link" = "Invite users via link";
"lng_rights_group_invite" = "Add users"; "lng_rights_group_invite" = "Add users";
"lng_rights_group_pin" = "Pin messages"; "lng_rights_group_pin" = "Pin messages";
"lng_rights_group_pin_with_topics" = "Pin messages and topics";
"lng_rights_group_topics" = "Manage topics";
"lng_rights_group_add_topics" = "Create topics";
"lng_rights_group_manage_calls" = "Manage voice chats"; "lng_rights_group_manage_calls" = "Manage voice chats";
"lng_rights_group_delete" = "Delete messages"; "lng_rights_group_delete" = "Delete messages";
"lng_rights_group_anonymous" = "Remain Anonymous"; "lng_rights_group_anonymous" = "Remain Anonymous";

View file

@ -1127,9 +1127,9 @@ chatOnlines#f041e250 onlines:int = ChatOnlines;
statsURL#47a971e0 url:string = StatsURL; statsURL#47a971e0 url:string = StatsURL;
chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true = ChatAdminRights; chatAdminRights#5fb224d5 flags:# change_info:flags.0?true post_messages:flags.1?true edit_messages:flags.2?true delete_messages:flags.3?true ban_users:flags.4?true invite_users:flags.5?true pin_messages:flags.7?true add_admins:flags.9?true anonymous:flags.10?true manage_call:flags.11?true other:flags.12?true manage_topics:flags.13?true = ChatAdminRights;
chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true until_date:int = ChatBannedRights; chatBannedRights#9f120418 flags:# view_messages:flags.0?true send_messages:flags.1?true send_media:flags.2?true send_stickers:flags.3?true send_gifs:flags.4?true send_games:flags.5?true send_inline:flags.6?true embed_links:flags.7?true send_polls:flags.8?true change_info:flags.10?true invite_users:flags.15?true pin_messages:flags.17?true manage_topics:flags.18?true until_date:int = ChatBannedRights;
inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper; inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
inputWallPaperSlug#72091c80 slug:string = InputWallPaper; inputWallPaperSlug#72091c80 slug:string = InputWallPaper;

View file

@ -224,6 +224,7 @@ ChatAdminRightsInfo EditAdminBox::defaultRights() const {
| Flag::BanUsers | Flag::BanUsers
| Flag::InviteUsers | Flag::InviteUsers
| Flag::PinMessages | Flag::PinMessages
| Flag::ManageTopics
| Flag::ManageCall) } | Flag::ManageCall) }
: ChatAdminRightsInfo{ (Flag::ChangeInfo : ChatAdminRightsInfo{ (Flag::ChangeInfo
| Flag::PostMessages | Flag::PostMessages
@ -328,13 +329,17 @@ void EditAdminBox::prepare() {
const auto anyoneCanAddMembers = chat const auto anyoneCanAddMembers = chat
? chat->anyoneCanAddMembers() ? chat->anyoneCanAddMembers()
: channel->anyoneCanAddMembers(); : channel->anyoneCanAddMembers();
const auto options = Data::AdminRightsSetOptions{
.isGroup = isGroup,
.isForum = peer()->isForum(),
.anyoneCanAddMembers = anyoneCanAddMembers,
};
auto [checkboxes, getChecked, changes] = CreateEditAdminRights( auto [checkboxes, getChecked, changes] = CreateEditAdminRights(
inner, inner,
tr::lng_rights_edit_admin_header(), tr::lng_rights_edit_admin_header(),
prepareFlags, prepareFlags,
disabledMessages, disabledMessages,
isGroup, options);
anyoneCanAddMembers);
inner->add(std::move(checkboxes), QMargins()); inner->add(std::move(checkboxes), QMargins());
auto selectedFlags = rpl::single( auto selectedFlags = rpl::single(
@ -355,7 +360,7 @@ void EditAdminBox::prepare() {
}, lifetime()); }, lifetime());
if (canTransferOwnership()) { if (canTransferOwnership()) {
const auto allFlags = AdminRightsForOwnershipTransfer(isGroup); const auto allFlags = AdminRightsForOwnershipTransfer(options);
setupTransferButton( setupTransferButton(
inner, inner,
isGroup isGroup
@ -746,7 +751,8 @@ void EditRestrictedBox::prepare() {
this, this,
tr::lng_rights_user_restrictions_header(), tr::lng_rights_user_restrictions_header(),
prepareFlags, prepareFlags,
disabledMessages); disabledMessages,
{ .isForum = peer()->isForum() });
addControl(std::move(checkboxes), QMargins()); addControl(std::move(checkboxes), QMargins());
_until = prepareRights.until; _until = prepareRights.until;

View file

@ -67,14 +67,6 @@ namespace {
}); });
} }
[[nodiscard]] auto ToPositiveNumberStringRestrictions() {
return rpl::map([](int count) {
return QString::number(count)
+ QString("/")
+ QString::number(int(Data::ListOfRestrictions().size()));
});
}
void AddSkip( void AddSkip(
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
int top = st::editPeerTopButtonsLayoutSkip, int top = st::editPeerTopButtonsLayoutSkip,
@ -1086,10 +1078,16 @@ void Controller::fillManageSection() {
tr::lng_manage_peer_permissions(), tr::lng_manage_peer_permissions(),
Info::Profile::MigratedOrMeValue( Info::Profile::MigratedOrMeValue(
_peer _peer
) | rpl::map( ) | rpl::map([=](not_null<PeerData*> peer) {
Info::Profile::RestrictionsCountValue return Info::Profile::RestrictionsCountValue(
) | rpl::flatten_latest( peer
) | ToPositiveNumberStringRestrictions(), ) | rpl::map([=](int count) {
return QString::number(count)
+ QString("/")
+ QString::number(int(Data::ListOfRestrictions(
{ .isForum = peer->isForum() }).size()));
});
}) | rpl::flatten_latest(),
[=] { ShowEditPermissions(_navigation, _peer); }, [=] { ShowEditPermissions(_navigation, _peer); },
{ &st::settingsIconKey, Settings::kIconGreen }); { &st::settingsIconKey, Settings::kIconGreen });
} }

View file

@ -106,58 +106,6 @@ void ApplyDependencies(
}; };
} }
std::vector<std::pair<ChatRestrictions, QString>> RestrictionLabels() {
const auto langKeys = {
tr::lng_rights_chat_send_text,
tr::lng_rights_chat_send_media,
tr::lng_rights_chat_send_stickers,
tr::lng_rights_chat_send_links,
tr::lng_rights_chat_send_polls,
tr::lng_rights_chat_add_members,
tr::lng_rights_group_pin,
tr::lng_rights_group_info,
};
std::vector<std::pair<ChatRestrictions, QString>> vector;
const auto restrictions = Data::ListOfRestrictions();
auto i = 0;
for (const auto &key : langKeys) {
vector.emplace_back(restrictions[i++], key(tr::now));
}
return vector;
}
std::vector<std::pair<ChatAdminRights, QString>> AdminRightLabels(
bool isGroup,
bool anyoneCanAddMembers) {
using Flag = ChatAdminRight;
if (isGroup) {
return {
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) },
{ Flag::BanUsers, tr::lng_rights_group_ban(tr::now) },
{ Flag::InviteUsers, anyoneCanAddMembers
? tr::lng_rights_group_invite_link(tr::now)
: tr::lng_rights_group_invite(tr::now) },
{ Flag::PinMessages, tr::lng_rights_group_pin(tr::now) },
{ Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
};
} else {
return {
{ Flag::ChangeInfo, tr::lng_rights_channel_info(tr::now) },
{ Flag::PostMessages, tr::lng_rights_channel_post(tr::now) },
{ Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) },
{ Flag::InviteUsers, tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) }
};
}
}
auto Dependencies(ChatRestrictions) auto Dependencies(ChatRestrictions)
-> std::vector<std::pair<ChatRestriction, ChatRestriction>> { -> std::vector<std::pair<ChatRestriction, ChatRestriction>> {
using Flag = ChatRestriction; using Flag = ChatRestriction;
@ -248,6 +196,103 @@ ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
: Flag::ChangeInfo); : Flag::ChangeInfo);
} }
template <
typename Flags,
typename DisabledMessagePairs,
typename FlagLabelPairs>
[[nodiscard]] EditFlagsControl<Flags> CreateEditFlags(
QWidget *parent,
rpl::producer<QString> header,
Flags checked,
const DisabledMessagePairs &disabledMessagePairs,
const FlagLabelPairs &flagLabelPairs) {
auto widget = object_ptr<Ui::VerticalLayout>(parent);
const auto container = widget.data();
const auto checkboxes = container->lifetime(
).make_state<std::map<Flags, QPointer<Ui::Checkbox>>>();
const auto value = [=] {
auto result = Flags(0);
for (const auto &[flags, checkbox] : *checkboxes) {
if (checkbox->checked()) {
result |= flags;
} else {
result &= ~flags;
}
}
return result;
};
const auto changes = container->lifetime(
).make_state<rpl::event_stream<>>();
const auto applyDependencies = [=](Ui::Checkbox *control) {
static const auto dependencies = Dependencies(Flags());
ApplyDependencies(*checkboxes, dependencies, control);
};
container->add(
object_ptr<Ui::FlatLabel>(
container,
std::move(header),
st::rightsHeaderLabel),
st::rightsHeaderMargin);
auto addCheckbox = [&](Flags flags, const QString &text) {
const auto lockedIt = ranges::find_if(
disabledMessagePairs,
[&](const auto &pair) { return (pair.first & flags) != 0; });
const auto locked = (lockedIt != end(disabledMessagePairs))
? std::make_optional(lockedIt->second)
: std::nullopt;
const auto toggled = ((checked & flags) != 0);
auto toggle = std::make_unique<Ui::ToggleView>(
st::rightsToggle,
toggled);
toggle->setLocked(locked.has_value());
const auto control = container->add(
object_ptr<Ui::Checkbox>(
container,
text,
st::rightsCheckbox,
std::move(toggle)),
st::rightsToggleMargin);
control->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (locked.has_value()) {
if (checked != toggled) {
Ui::ShowMultilineToast({
.parentOverride = parent,
.text = { *locked },
});
control->setChecked(toggled);
}
} else {
InvokeQueued(control, [=] {
applyDependencies(control);
changes->fire({});
});
}
}, control->lifetime());
checkboxes->emplace(flags, control);
};
for (const auto &[flags, label] : flagLabelPairs) {
addCheckbox(flags, label);
}
applyDependencies(nullptr);
for (const auto &[flags, checkbox] : *checkboxes) {
checkbox->finishAnimating();
}
return {
std::move(widget),
value,
changes->events() | rpl::map(value)
};
}
} // namespace } // namespace
ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer) { ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer) {
@ -306,9 +351,10 @@ ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions) {
return restrictions; return restrictions;
} }
ChatAdminRights AdminRightsForOwnershipTransfer(bool isGroup) { ChatAdminRights AdminRightsForOwnershipTransfer(
Data::AdminRightsSetOptions options) {
auto result = ChatAdminRights(); auto result = ChatAdminRights();
for (const auto &[flag, label] : AdminRightLabels(isGroup, true)) { for (const auto &[flag, label] : AdminRightLabels(options)) {
if (!(flag & ChatAdminRight::Anonymous)) { if (!(flag & ChatAdminRight::Anonymous)) {
result |= flag; result |= flag;
} }
@ -445,7 +491,8 @@ void EditPeerPermissionsBox::prepare() {
this, this,
tr::lng_rights_default_restrictions_header(), tr::lng_rights_default_restrictions_header(),
restrictions, restrictions,
disabledMessages); disabledMessages,
{ .isForum = _peer->isForum() });
inner->add(std::move(checkboxes)); inner->add(std::move(checkboxes));
@ -668,114 +715,88 @@ void EditPeerPermissionsBox::addBannedButtons(
} }
} }
template < std::vector<RestrictionLabel> RestrictionLabels(
typename Flags, Data::RestrictionsSetOptions options) {
typename DisabledMessagePairs, using Flag = ChatRestriction;
typename FlagLabelPairs> auto result = std::vector<RestrictionLabel>{
EditFlagsControl<Flags> CreateEditFlags( { Flag::SendMessages, tr::lng_rights_chat_send_text(tr::now) },
QWidget *parent, { Flag::SendMedia, tr::lng_rights_chat_send_media(tr::now) },
rpl::producer<QString> header, { Flag::SendStickers
Flags checked, | Flag::SendGifs
const DisabledMessagePairs &disabledMessagePairs, | Flag::SendGames
const FlagLabelPairs &flagLabelPairs) { | Flag::SendInline, tr::lng_rights_chat_send_stickers(tr::now) },
auto widget = object_ptr<Ui::VerticalLayout>(parent); { Flag::EmbedLinks, tr::lng_rights_chat_send_links(tr::now) },
const auto container = widget.data(); { Flag::SendPolls, tr::lng_rights_chat_send_polls(tr::now) },
{ Flag::InviteUsers, tr::lng_rights_chat_add_members(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_add_topics(tr::now) },
{ Flag::PinMessages, tr::lng_rights_group_pin(tr::now) },
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
};
if (!options.isForum) {
result.erase(
ranges::remove(
result,
Flag::ManageTopics,
&RestrictionLabel::flags),
end(result));
}
return result;
}
const auto checkboxes = container->lifetime( std::vector<AdminRightLabel> AdminRightLabels(
).make_state<std::map<Flags, QPointer<Ui::Checkbox>>>(); Data::AdminRightsSetOptions options) {
using Flag = ChatAdminRight;
const auto value = [=] { if (options.isGroup) {
auto result = Flags(0); auto result = std::vector<AdminRightLabel>{
for (const auto &[flags, checkbox] : *checkboxes) { { Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
if (checkbox->checked()) { { Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) },
result |= flags; { Flag::BanUsers, tr::lng_rights_group_ban(tr::now) },
} else { { Flag::InviteUsers, options.anyoneCanAddMembers
result &= ~flags; ? tr::lng_rights_group_invite_link(tr::now)
} : tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_topics(tr::now) },
{ Flag::PinMessages, options.isForum
? tr::lng_rights_group_pin_with_topics(tr::now)
: tr::lng_rights_group_pin(tr::now) },
{ Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
};
if (!options.isForum) {
result.erase(
ranges::remove(
result,
Flag::ManageTopics,
&AdminRightLabel::flags),
end(result));
} }
return result; return result;
}; } else {
return {
const auto changes = container->lifetime( { Flag::ChangeInfo, tr::lng_rights_channel_info(tr::now) },
).make_state<rpl::event_stream<>>(); { Flag::PostMessages, tr::lng_rights_channel_post(tr::now) },
{ Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) },
const auto applyDependencies = [=](Ui::Checkbox *control) { { Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) },
static const auto dependencies = Dependencies(Flags()); { Flag::InviteUsers, tr::lng_rights_group_invite(tr::now) },
ApplyDependencies(*checkboxes, dependencies, control); { Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) },
}; { Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) }
};
container->add(
object_ptr<Ui::FlatLabel>(
container,
std::move(header),
st::rightsHeaderLabel),
st::rightsHeaderMargin);
auto addCheckbox = [&](Flags flags, const QString &text) {
const auto lockedIt = ranges::find_if(
disabledMessagePairs,
[&](const auto &pair) { return (pair.first & flags) != 0; });
const auto locked = (lockedIt != end(disabledMessagePairs))
? std::make_optional(lockedIt->second)
: std::nullopt;
const auto toggled = ((checked & flags) != 0);
auto toggle = std::make_unique<Ui::ToggleView>(
st::rightsToggle,
toggled);
toggle->setLocked(locked.has_value());
const auto control = container->add(
object_ptr<Ui::Checkbox>(
container,
text,
st::rightsCheckbox,
std::move(toggle)),
st::rightsToggleMargin);
control->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (locked.has_value()) {
if (checked != toggled) {
Ui::ShowMultilineToast({
.parentOverride = parent,
.text = { *locked },
});
control->setChecked(toggled);
}
} else {
InvokeQueued(control, [=] {
applyDependencies(control);
changes->fire({});
});
}
}, control->lifetime());
checkboxes->emplace(flags, control);
};
for (const auto &[flags, label] : flagLabelPairs) {
addCheckbox(flags, label);
} }
applyDependencies(nullptr);
for (const auto &[flags, checkbox] : *checkboxes) {
checkbox->finishAnimating();
}
return {
std::move(widget),
value,
changes->events() | rpl::map(value)
};
} }
EditFlagsControl<ChatRestrictions> CreateEditRestrictions( EditFlagsControl<ChatRestrictions> CreateEditRestrictions(
QWidget *parent, QWidget *parent,
rpl::producer<QString> header, rpl::producer<QString> header,
ChatRestrictions restrictions, ChatRestrictions restrictions,
std::map<ChatRestrictions, QString> disabledMessages) { std::map<ChatRestrictions, QString> disabledMessages,
Data::RestrictionsSetOptions options) {
auto result = CreateEditFlags( auto result = CreateEditFlags(
parent, parent,
header, header,
NegateRestrictions(restrictions), NegateRestrictions(restrictions),
disabledMessages, disabledMessages,
RestrictionLabels()); RestrictionLabels(options));
result.value = [original = std::move(result.value)]{ result.value = [original = std::move(result.value)]{
return NegateRestrictions(original()); return NegateRestrictions(original());
}; };
@ -791,12 +812,11 @@ EditFlagsControl<ChatAdminRights> CreateEditAdminRights(
rpl::producer<QString> header, rpl::producer<QString> header,
ChatAdminRights rights, ChatAdminRights rights,
std::map<ChatAdminRights, QString> disabledMessages, std::map<ChatAdminRights, QString> disabledMessages,
bool isGroup, Data::AdminRightsSetOptions options) {
bool anyoneCanAddMembers) {
return CreateEditFlags( return CreateEditFlags(
parent, parent,
header, header,
rights, rights,
disabledMessages, disabledMessages,
AdminRightLabels(isGroup, anyoneCanAddMembers)); AdminRightLabels(options));
} }

View file

@ -54,6 +54,20 @@ private:
not_null<ChannelData*> channel, not_null<ChannelData*> channel,
not_null<Window::SessionController*> controller); not_null<Window::SessionController*> controller);
struct RestrictionLabel {
ChatRestrictions flags;
QString label;
};
[[nodiscard]] std::vector<RestrictionLabel> RestrictionLabels(
Data::RestrictionsSetOptions options);
struct AdminRightLabel {
ChatAdminRights flags;
QString label;
};
[[nodiscard]] std::vector<AdminRightLabel> AdminRightLabels(
Data::AdminRightsSetOptions options);
template <typename Flags> template <typename Flags>
struct EditFlagsControl { struct EditFlagsControl {
object_ptr<Ui::RpWidget> widget; object_ptr<Ui::RpWidget> widget;
@ -61,20 +75,23 @@ struct EditFlagsControl {
rpl::producer<Flags> changes; rpl::producer<Flags> changes;
}; };
EditFlagsControl<ChatRestrictions> CreateEditRestrictions( [[nodiscard]] EditFlagsControl<ChatRestrictions> CreateEditRestrictions(
QWidget *parent, QWidget *parent,
rpl::producer<QString> header, rpl::producer<QString> header,
ChatRestrictions restrictions, ChatRestrictions restrictions,
std::map<ChatRestrictions, QString> disabledMessages); std::map<ChatRestrictions, QString> disabledMessages,
Data::RestrictionsSetOptions options);
EditFlagsControl<ChatAdminRights> CreateEditAdminRights( [[nodiscard]] EditFlagsControl<ChatAdminRights> CreateEditAdminRights(
QWidget *parent, QWidget *parent,
rpl::producer<QString> header, rpl::producer<QString> header,
ChatAdminRights rights, ChatAdminRights rights,
std::map<ChatAdminRights, QString> disabledMessages, std::map<ChatAdminRights, QString> disabledMessages,
bool isGroup, Data::AdminRightsSetOptions options);
bool anyoneCanAddMembers);
ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer); [[nodiscard]] ChatAdminRights DisabledByDefaultRestrictions(
ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions); not_null<PeerData*> peer);
ChatAdminRights AdminRightsForOwnershipTransfer(bool isGroup); [[nodiscard]] ChatRestrictions FixDependentRestrictions(
ChatRestrictions restrictions);
[[nodiscard]] ChatAdminRights AdminRightsForOwnershipTransfer(
Data::AdminRightsSetOptions options);

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "data/data_chat_participant_status.h" #include "data/data_chat_participant_status.h"
#include "boxes/peers/edit_peer_permissions_box.h"
namespace { namespace {
[[nodiscard]] ChatAdminRights ChatAdminRightsFlags( [[nodiscard]] ChatAdminRights ChatAdminRightsFlags(
@ -43,22 +45,12 @@ ChatRestrictionsInfo::ChatRestrictionsInfo(const MTPChatBannedRights &rights)
namespace Data { namespace Data {
std::vector<ChatRestrictions> ListOfRestrictions() { std::vector<ChatRestrictions> ListOfRestrictions(
using Flag = ChatRestriction; RestrictionsSetOptions options) {
auto labels = RestrictionLabels(options);
return { return ranges::views::all(labels)
Flag::SendMessages, | ranges::views::transform(&RestrictionLabel::flags)
Flag::SendMedia, | ranges::to_vector;
Flag::SendStickers
| Flag::SendGifs
| Flag::SendGames
| Flag::SendInline,
Flag::EmbedLinks,
Flag::SendPolls,
Flag::InviteUsers,
Flag::PinMessages,
Flag::ChangeInfo,
};
} }
} // namespace Data } // namespace Data

View file

@ -24,6 +24,7 @@ enum class ChatAdminRight {
Anonymous = (1 << 10), Anonymous = (1 << 10),
ManageCall = (1 << 11), ManageCall = (1 << 11),
Other = (1 << 12), Other = (1 << 12),
ManageTopics = (1 << 13),
}; };
inline constexpr bool is_flag_type(ChatAdminRight) { return true; } inline constexpr bool is_flag_type(ChatAdminRight) { return true; }
using ChatAdminRights = base::flags<ChatAdminRight>; using ChatAdminRights = base::flags<ChatAdminRight>;
@ -41,6 +42,7 @@ enum class ChatRestriction {
ChangeInfo = (1 << 10), ChangeInfo = (1 << 10),
InviteUsers = (1 << 15), InviteUsers = (1 << 15),
PinMessages = (1 << 17), PinMessages = (1 << 17),
ManageTopics = (1 << 18),
}; };
inline constexpr bool is_flag_type(ChatRestriction) { return true; } inline constexpr bool is_flag_type(ChatRestriction) { return true; }
using ChatRestrictions = base::flags<ChatRestriction>; using ChatRestrictions = base::flags<ChatRestriction>;
@ -68,6 +70,17 @@ struct ChatRestrictionsInfo {
namespace Data { namespace Data {
std::vector<ChatRestrictions> ListOfRestrictions(); struct AdminRightsSetOptions {
bool isGroup : 1 = false;
bool isForum : 1 = false;
bool anyoneCanAddMembers : 1 = false;
};
struct RestrictionsSetOptions {
bool isForum = false;
};
[[nodiscard]] std::vector<ChatRestrictions> ListOfRestrictions(
RestrictionsSetOptions options);
} // namespace Data } // namespace Data

View file

@ -418,12 +418,15 @@ rpl::producer<int> AdminsCountValue(not_null<PeerData*> peer) {
rpl::producer<int> RestrictionsCountValue(not_null<PeerData*> peer) { rpl::producer<int> RestrictionsCountValue(not_null<PeerData*> peer) {
const auto countOfRestrictions = [](ChatRestrictions restrictions) { const auto countOfRestrictions = [](
Data::RestrictionsSetOptions options,
ChatRestrictions restrictions) {
auto count = 0; auto count = 0;
for (const auto &f : Data::ListOfRestrictions()) { const auto list = Data::ListOfRestrictions(options);
for (const auto &f : list) {
if (restrictions & f) count++; if (restrictions & f) count++;
} }
return int(Data::ListOfRestrictions().size()) - count; return int(list.size()) - count;
}; };
if (const auto chat = peer->asChat()) { if (const auto chat = peer->asChat()) {
@ -431,14 +434,22 @@ rpl::producer<int> RestrictionsCountValue(not_null<PeerData*> peer) {
peer, peer,
UpdateFlag::Rights UpdateFlag::Rights
) | rpl::map([=] { ) | rpl::map([=] {
return countOfRestrictions(chat->defaultRestrictions()); return countOfRestrictions({}, chat->defaultRestrictions());
}); });
} else if (const auto channel = peer->asChannel()) { } else if (const auto channel = peer->asChannel()) {
return peer->session().changes().peerFlagsValue( auto forumValue = channel->flagsValue(
peer, ) | rpl::filter([](const ChannelData::Flags::Change &change) {
UpdateFlag::Rights return (change.diff & ChannelData::Flag::Forum);
});
return rpl::combine(
std::move(forumValue),
channel->session().changes().peerFlagsValue(
channel,
UpdateFlag::Rights)
) | rpl::map([=] { ) | rpl::map([=] {
return countOfRestrictions(channel->defaultRestrictions()); return countOfRestrictions(
{ .isForum = channel->isForum() },
channel->defaultRestrictions());
}); });
} }
Unexpected("User in RestrictionsCountValue()."); Unexpected("User in RestrictionsCountValue().");