Correctly handle complex pin_messages/manage_topics.

This commit is contained in:
John Preston 2022-10-24 13:13:21 +04:00
parent 53beb6f562
commit 70e5f752ba
16 changed files with 135 additions and 53 deletions

View file

@ -2891,6 +2891,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"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_pin_with_topics" = "Pin messages and topics";
"lng_rights_group_pin_topics" = "Pin topics";
"lng_rights_group_topics" = "Manage topics"; "lng_rights_group_topics" = "Manage topics";
"lng_rights_group_add_topics" = "Create topics"; "lng_rights_group_add_topics" = "Create topics";
"lng_rights_group_manage_calls" = "Manage voice chats"; "lng_rights_group_manage_calls" = "Manage voice chats";
@ -3109,6 +3110,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_admin_log_admin_invite_users" = "Add members"; "lng_admin_log_admin_invite_users" = "Add members";
"lng_admin_log_admin_invite_link" = "Invite users via link"; "lng_admin_log_admin_invite_link" = "Invite users via link";
"lng_admin_log_admin_pin_messages" = "Pin messages"; "lng_admin_log_admin_pin_messages" = "Pin messages";
"lng_admin_log_admin_pin_messages_topics" = "Pin messages and topics";
"lng_admin_log_admin_pin_topics" = "Pin topics";
"lng_admin_log_admin_manage_topics" = "Manage topics";
"lng_admin_log_admin_create_topics" = "Create topics";
"lng_admin_log_admin_manage_calls" = "Manage voice chats"; "lng_admin_log_admin_manage_calls" = "Manage voice chats";
"lng_admin_log_admin_manage_calls_channel" = "Manage live streams"; "lng_admin_log_admin_manage_calls_channel" = "Manage live streams";
"lng_admin_log_admin_add_admins" = "Add new admins"; "lng_admin_log_admin_add_admins" = "Add new admins";

View file

@ -647,7 +647,7 @@ rightsHeaderLabel: FlatLabel(boxLabel) {
textFg: windowActiveTextFg; textFg: windowActiveTextFg;
} }
rightsUntilMargin: margins(0px, 8px, 0px, 20px); rightsUntilMargin: margins(0px, 8px, 0px, 20px);
rightsRankMargin: margins(0px, 16px, 0px, 20px); rightsRankMargin: margins(0px, 7px, 0px, 20px);
mutePhotoButton: UserpicButton(defaultUserpicButton) { mutePhotoButton: UserpicButton(defaultUserpicButton) {
size: size(40px, 40px); size: size(40px, 40px);

View file

@ -222,15 +222,15 @@ ChatAdminRightsInfo EditAdminBox::defaultRights() const {
? ChatAdminRightsInfo{ (Flag::ChangeInfo ? ChatAdminRightsInfo{ (Flag::ChangeInfo
| Flag::DeleteMessages | Flag::DeleteMessages
| Flag::BanUsers | Flag::BanUsers
| Flag::InviteUsers | Flag::InviteByLinkOrAdd
| Flag::PinMessages
| Flag::ManageTopics | Flag::ManageTopics
| Flag::PinMessagesOrTopics
| Flag::ManageCall) } | Flag::ManageCall) }
: ChatAdminRightsInfo{ (Flag::ChangeInfo : ChatAdminRightsInfo{ (Flag::ChangeInfo
| Flag::PostMessages | Flag::PostMessages
| Flag::EditMessages | Flag::EditMessages
| Flag::DeleteMessages | Flag::DeleteMessages
| Flag::InviteUsers | Flag::InviteByLinkOrAdd
| Flag::ManageCall) }; | Flag::ManageCall) };
} }
@ -329,10 +329,14 @@ void EditAdminBox::prepare() {
const auto anyoneCanAddMembers = chat const auto anyoneCanAddMembers = chat
? chat->anyoneCanAddMembers() ? chat->anyoneCanAddMembers()
: channel->anyoneCanAddMembers(); : channel->anyoneCanAddMembers();
const auto anyoneCanPinMessages = chat
? chat->anyoneCanPinMessages()
: channel->anyoneCanPinMessages();
const auto options = Data::AdminRightsSetOptions{ const auto options = Data::AdminRightsSetOptions{
.isGroup = isGroup, .isGroup = isGroup,
.isForum = peer()->isForum(), .isForum = peer()->isForum(),
.anyoneCanAddMembers = anyoneCanAddMembers, .anyoneCanAddMembers = anyoneCanAddMembers,
.anyoneCanPinMessages = anyoneCanPinMessages,
}; };
auto [checkboxes, getChecked, changes] = CreateEditAdminRights( auto [checkboxes, getChecked, changes] = CreateEditAdminRights(
inner, inner,

View file

@ -148,7 +148,8 @@ ChatRestrictions NegateRestrictions(ChatRestrictions value) {
//| Flag::ViewMessages //| Flag::ViewMessages
| Flag::ChangeInfo | Flag::ChangeInfo
| Flag::EmbedLinks | Flag::EmbedLinks
| Flag::InviteUsers | Flag::AddParticipants
| Flag::CreateTopics
| Flag::PinMessages | Flag::PinMessages
| Flag::SendGames | Flag::SendGames
| Flag::SendGifs | Flag::SendGifs
@ -185,12 +186,15 @@ ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
Unexpected("User in DisabledByAdminRights."); Unexpected("User in DisabledByAdminRights.");
}(); }();
return Flag(0) return Flag(0)
| ((adminRights & Admin::PinMessages) | ((adminRights & Admin::ManageTopics)
? Flag(0)
: Flag::CreateTopics)
| ((adminRights & Admin::PinMessagesOrTopics)
? Flag(0) ? Flag(0)
: Flag::PinMessages) : Flag::PinMessages)
| ((adminRights & Admin::InviteUsers) | ((adminRights & Admin::InviteByLinkOrAdd)
? Flag(0) ? Flag(0)
: Flag::InviteUsers) : Flag::AddParticipants)
| ((adminRights & Admin::ChangeInfo) | ((adminRights & Admin::ChangeInfo)
? Flag(0) ? Flag(0)
: Flag::ChangeInfo); : Flag::ChangeInfo);
@ -307,18 +311,23 @@ ChatAdminRights DisabledByDefaultRestrictions(not_null<PeerData*> peer) {
} }
Unexpected("User in DisabledByDefaultRestrictions."); Unexpected("User in DisabledByDefaultRestrictions.");
}()); }());
const auto forum = peer->isForum();
return Flag(0) return Flag(0)
| ((restrictions & Restriction::PinMessages) //
// We allow to edit 'pin_messages' admin right in forums
// even if it is allowed in default permissions, because
// if everyone can 'pin_messages' admin can also pin topics.
| ((forum || (restrictions & Restriction::PinMessages))
? Flag(0) ? Flag(0)
: Flag::PinMessages) : Flag::PinMessagesOrTopics)
// //
// We allow to edit 'invite_users' admin right no matter what // We allow to edit 'invite_users' admin right no matter what
// is chosen in default permissions for 'invite_users', because // is chosen in default permissions for 'invite_users', because
// if everyone can 'invite_users' it handles invite link for admins. // if everyone can 'invite_users' it handles invite link for admins.
// //
//| ((restrictions & Restriction::InviteUsers) //| ((restrictions & Restriction::AddParticipants)
// ? Flag(0) // ? Flag(0)
// : Flag::InviteUsers) // : Flag::InviteByLinkOrAdd)
// //
| ((restrictions & Restriction::ChangeInfo) | ((restrictions & Restriction::ChangeInfo)
? Flag(0) ? Flag(0)
@ -727,8 +736,8 @@ std::vector<RestrictionLabel> RestrictionLabels(
| Flag::SendInline, tr::lng_rights_chat_send_stickers(tr::now) }, | Flag::SendInline, tr::lng_rights_chat_send_stickers(tr::now) },
{ Flag::EmbedLinks, tr::lng_rights_chat_send_links(tr::now) }, { Flag::EmbedLinks, tr::lng_rights_chat_send_links(tr::now) },
{ Flag::SendPolls, tr::lng_rights_chat_send_polls(tr::now) }, { Flag::SendPolls, tr::lng_rights_chat_send_polls(tr::now) },
{ Flag::InviteUsers, tr::lng_rights_chat_add_members(tr::now) }, { Flag::AddParticipants, tr::lng_rights_chat_add_members(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_add_topics(tr::now) }, { Flag::CreateTopics, tr::lng_rights_group_add_topics(tr::now) },
{ Flag::PinMessages, tr::lng_rights_group_pin(tr::now) }, { Flag::PinMessages, tr::lng_rights_group_pin(tr::now) },
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) }, { Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
}; };
@ -736,7 +745,7 @@ std::vector<RestrictionLabel> RestrictionLabels(
result.erase( result.erase(
ranges::remove( ranges::remove(
result, result,
Flag::ManageTopics, Flag::CreateTopics,
&RestrictionLabel::flags), &RestrictionLabel::flags),
end(result)); end(result));
} }
@ -752,13 +761,15 @@ std::vector<AdminRightLabel> AdminRightLabels(
{ Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) }, { Flag::ChangeInfo, tr::lng_rights_group_info(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) }, { Flag::DeleteMessages, tr::lng_rights_group_delete(tr::now) },
{ Flag::BanUsers, tr::lng_rights_group_ban(tr::now) }, { Flag::BanUsers, tr::lng_rights_group_ban(tr::now) },
{ Flag::InviteUsers, options.anyoneCanAddMembers { Flag::InviteByLinkOrAdd, options.anyoneCanAddMembers
? tr::lng_rights_group_invite_link(tr::now) ? tr::lng_rights_group_invite_link(tr::now)
: tr::lng_rights_group_invite(tr::now) }, : tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageTopics, tr::lng_rights_group_topics(tr::now) }, { Flag::ManageTopics, tr::lng_rights_group_topics(tr::now) },
{ Flag::PinMessages, options.isForum { Flag::PinMessagesOrTopics, !options.isForum
? tr::lng_rights_group_pin_with_topics(tr::now) ? tr::lng_rights_group_pin(tr::now)
: tr::lng_rights_group_pin(tr::now) }, : options.anyoneCanPinMessages
? tr::lng_rights_group_pin_topics(tr::now)
: tr::lng_rights_group_pin_with_topics(tr::now) },
{ Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) }, { Flag::ManageCall, tr::lng_rights_group_manage_calls(tr::now) },
{ Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) }, { Flag::Anonymous, tr::lng_rights_group_anonymous(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) }, { Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) },
@ -778,7 +789,7 @@ std::vector<AdminRightLabel> AdminRightLabels(
{ Flag::PostMessages, tr::lng_rights_channel_post(tr::now) }, { Flag::PostMessages, tr::lng_rights_channel_post(tr::now) },
{ Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) }, { Flag::EditMessages, tr::lng_rights_channel_edit(tr::now) },
{ Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) }, { Flag::DeleteMessages, tr::lng_rights_channel_delete(tr::now) },
{ Flag::InviteUsers, tr::lng_rights_group_invite(tr::now) }, { Flag::InviteByLinkOrAdd, tr::lng_rights_group_invite(tr::now) },
{ Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) }, { Flag::ManageCall, tr::lng_rights_channel_manage_calls(tr::now) },
{ Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) } { Flag::AddAdmins, tr::lng_rights_add_admins(tr::now) }
}; };

View file

@ -295,9 +295,11 @@ bool ShowWallPaper(
} else if (element == u"restrict_members"_q) { } else if (element == u"restrict_members"_q) {
result |= ChatAdminRight::BanUsers; result |= ChatAdminRight::BanUsers;
} else if (element == u"invite_users"_q) { } else if (element == u"invite_users"_q) {
result |= ChatAdminRight::InviteUsers; result |= ChatAdminRight::InviteByLinkOrAdd;
} else if (element == u"manage_topics"_q) {
result |= ChatAdminRight::ManageTopics;
} else if (element == u"pin_messages"_q) { } else if (element == u"pin_messages"_q) {
result |= ChatAdminRight::PinMessages; result |= ChatAdminRight::PinMessagesOrTopics;
} else if (element == u"promote_members"_q) { } else if (element == u"promote_members"_q) {
result |= ChatAdminRight::AddAdmins; result |= ChatAdminRight::AddAdmins;
} else if (element == u"manage_video_chats"_q) { } else if (element == u"manage_video_chats"_q) {

View file

@ -201,7 +201,7 @@ void ChannelData::setInviteLink(const QString &newInviteLink) {
bool ChannelData::canHaveInviteLink() const { bool ChannelData::canHaveInviteLink() const {
return amCreator() return amCreator()
|| (adminRights() & AdminRight::InviteUsers); || (adminRights() & AdminRight::InviteByLinkOrAdd);
} }
void ChannelData::setLocation(const MTPChannelLocation &data) { void ChannelData::setLocation(const MTPChannelLocation &data) {
@ -525,7 +525,11 @@ bool ChannelData::canDeleteMessages() const {
} }
bool ChannelData::anyoneCanAddMembers() const { bool ChannelData::anyoneCanAddMembers() const {
return !(defaultRestrictions() & Restriction::InviteUsers); return !(defaultRestrictions() & Restriction::AddParticipants);
}
bool ChannelData::anyoneCanPinMessages() const {
return !(defaultRestrictions() & Restriction::PinMessages);
} }
bool ChannelData::hiddenPreHistory() const { bool ChannelData::hiddenPreHistory() const {
@ -534,8 +538,8 @@ bool ChannelData::hiddenPreHistory() const {
bool ChannelData::canAddMembers() const { bool ChannelData::canAddMembers() const {
return isMegagroup() return isMegagroup()
? !amRestricted(ChatRestriction::InviteUsers) ? !amRestricted(ChatRestriction::AddParticipants)
: ((adminRights() & AdminRight::InviteUsers) || amCreator()); : ((adminRights() & AdminRight::InviteByLinkOrAdd) || amCreator());
} }
bool ChannelData::canSendPolls() const { bool ChannelData::canSendPolls() const {

View file

@ -324,6 +324,7 @@ public:
[[nodiscard]] bool canBanMembers() const; [[nodiscard]] bool canBanMembers() const;
[[nodiscard]] bool canSendPolls() const; [[nodiscard]] bool canSendPolls() const;
[[nodiscard]] bool anyoneCanAddMembers() const; [[nodiscard]] bool anyoneCanAddMembers() const;
[[nodiscard]] bool anyoneCanPinMessages() const;
[[nodiscard]] bool canEditMessages() const; [[nodiscard]] bool canEditMessages() const;
[[nodiscard]] bool canDeleteMessages() const; [[nodiscard]] bool canDeleteMessages() const;

View file

@ -57,8 +57,8 @@ ChatAdminRightsInfo ChatData::defaultAdminRights(not_null<UserData*> user) {
| Flag::ChangeInfo | Flag::ChangeInfo
| Flag::DeleteMessages | Flag::DeleteMessages
| Flag::BanUsers | Flag::BanUsers
| Flag::InviteUsers | Flag::InviteByLinkOrAdd
| Flag::PinMessages | Flag::PinMessagesOrTopics
| Flag::ManageCall | Flag::ManageCall
| (isCreator ? Flag::AddAdmins : Flag(0))); | (isCreator ? Flag::AddAdmins : Flag(0)));
} }
@ -96,7 +96,7 @@ bool ChatData::canDeleteMessages() const {
} }
bool ChatData::canAddMembers() const { bool ChatData::canAddMembers() const {
return amIn() && !amRestricted(ChatRestriction::InviteUsers); return amIn() && !amRestricted(ChatRestriction::AddParticipants);
} }
bool ChatData::canSendPolls() const { bool ChatData::canSendPolls() const {
@ -113,7 +113,11 @@ bool ChatData::canBanMembers() const {
} }
bool ChatData::anyoneCanAddMembers() const { bool ChatData::anyoneCanAddMembers() const {
return !(defaultRestrictions() & ChatRestriction::InviteUsers); return !(defaultRestrictions() & ChatRestriction::AddParticipants);
}
bool ChatData::anyoneCanPinMessages() const {
return !(defaultRestrictions() & ChatRestriction::PinMessages);
} }
void ChatData::setName(const QString &newName) { void ChatData::setName(const QString &newName) {
@ -147,7 +151,7 @@ void ChatData::setInviteLink(const QString &newInviteLink) {
bool ChatData::canHaveInviteLink() const { bool ChatData::canHaveInviteLink() const {
return amCreator() return amCreator()
|| (adminRights() & ChatAdminRight::InviteUsers); || (adminRights() & ChatAdminRight::InviteByLinkOrAdd);
} }
void ChatData::setAdminRights(ChatAdminRights rights) { void ChatData::setAdminRights(ChatAdminRights rights) {

View file

@ -112,6 +112,7 @@ public:
[[nodiscard]] bool canBanMembers() const; [[nodiscard]] bool canBanMembers() const;
[[nodiscard]] bool canSendPolls() const; [[nodiscard]] bool canSendPolls() const;
[[nodiscard]] bool anyoneCanAddMembers() const; [[nodiscard]] bool anyoneCanAddMembers() const;
[[nodiscard]] bool anyoneCanPinMessages() const;
void applyEditAdmin(not_null<UserData*> user, bool isAdmin); void applyEditAdmin(not_null<UserData*> user, bool isAdmin);

View file

@ -18,8 +18,8 @@ enum class ChatAdminRight {
EditMessages = (1 << 2), EditMessages = (1 << 2),
DeleteMessages = (1 << 3), DeleteMessages = (1 << 3),
BanUsers = (1 << 4), BanUsers = (1 << 4),
InviteUsers = (1 << 5), InviteByLinkOrAdd = (1 << 5),
PinMessages = (1 << 7), PinMessagesOrTopics = (1 << 7),
AddAdmins = (1 << 9), AddAdmins = (1 << 9),
Anonymous = (1 << 10), Anonymous = (1 << 10),
ManageCall = (1 << 11), ManageCall = (1 << 11),
@ -40,9 +40,9 @@ enum class ChatRestriction {
EmbedLinks = (1 << 7), EmbedLinks = (1 << 7),
SendPolls = (1 << 8), SendPolls = (1 << 8),
ChangeInfo = (1 << 10), ChangeInfo = (1 << 10),
InviteUsers = (1 << 15), AddParticipants = (1 << 15),
PinMessages = (1 << 17), PinMessages = (1 << 17),
ManageTopics = (1 << 18), CreateTopics = (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>;
@ -74,6 +74,7 @@ struct AdminRightsSetOptions {
bool isGroup : 1 = false; bool isGroup : 1 = false;
bool isForum : 1 = false; bool isForum : 1 = false;
bool anyoneCanAddMembers : 1 = false; bool anyoneCanAddMembers : 1 = false;
bool anyoneCanPinMessages : 1 = false;
}; };
struct RestrictionsSetOptions { struct RestrictionsSetOptions {

View file

@ -210,10 +210,12 @@ bool ForumTopic::canEdit() const {
} }
bool ForumTopic::canDelete() const { bool ForumTopic::canDelete() const {
return !creating() if (creating()) {
&& (channel()->canEditTopics() return false;
// We don't know if we can delete or not. } else if (channel()->canDeleteMessages()) {
/*|| (my() && onlyOneMyMessage)*/); return true;
}
return my() && replies()->canDeleteMyTopic();
} }
bool ForumTopic::canToggleClosed() const { bool ForumTopic::canToggleClosed() const {
@ -221,7 +223,12 @@ bool ForumTopic::canToggleClosed() const {
} }
bool ForumTopic::canTogglePinned() const { bool ForumTopic::canTogglePinned() const {
return !creating() && channel()->canEditTopics(); if (creating()) {
return false;
}
const auto channel = this->channel();
return channel->amCreator()
|| (channel->adminRights() & ChatAdminRight::PinMessagesOrTopics);
} }
bool ForumTopic::creating() const { bool ForumTopic::creating() const {

View file

@ -524,21 +524,25 @@ bool PeerData::canPinMessages() const {
} else if (const auto channel = asChannel()) { } else if (const auto channel = asChannel()) {
return channel->isMegagroup() return channel->isMegagroup()
? !channel->amRestricted(ChatRestriction::PinMessages) ? !channel->amRestricted(ChatRestriction::PinMessages)
: ((channel->adminRights() & ChatAdminRight::EditMessages) : ((channel->amCreator()
|| channel->amCreator()); || channel->adminRights() & ChatAdminRight::EditMessages));
} }
Unexpected("Peer type in PeerData::canPinMessages."); Unexpected("Peer type in PeerData::canPinMessages.");
} }
bool PeerData::canCreateTopics() const { bool PeerData::canCreateTopics() const {
return isForum() && canPinMessages(); if (const auto channel = asChannel()) {
return channel->isForum()
&& !channel->amRestricted(ChatRestriction::CreateTopics);
}
return false;
} }
bool PeerData::canEditTopics() const { bool PeerData::canEditTopics() const {
if (const auto channel = asChannel()) { if (const auto channel = asChannel()) {
return channel->isForum() return channel->isForum()
&& (channel->amCreator() && (channel->amCreator()
|| (channel->adminRights() & ChatAdminRight::PinMessages)); || (channel->adminRights() & ChatAdminRight::ManageTopics));
} }
return false; return false;
} }
@ -959,12 +963,14 @@ Data::RestrictionCheckResult PeerData::amRestricted(
ChatRestriction right) const { ChatRestriction right) const {
using Result = Data::RestrictionCheckResult; using Result = Data::RestrictionCheckResult;
const auto allowByAdminRights = [](auto right, auto chat) -> bool { const auto allowByAdminRights = [](auto right, auto chat) -> bool {
if (right == ChatRestriction::InviteUsers) { if (right == ChatRestriction::AddParticipants) {
return chat->adminRights() & ChatAdminRight::InviteUsers; return chat->adminRights() & ChatAdminRight::InviteByLinkOrAdd;
} else if (right == ChatRestriction::ChangeInfo) { } else if (right == ChatRestriction::ChangeInfo) {
return chat->adminRights() & ChatAdminRight::ChangeInfo; return chat->adminRights() & ChatAdminRight::ChangeInfo;
} else if (right == ChatRestriction::CreateTopics) {
return chat->adminRights() & ChatAdminRight::ManageTopics;
} else if (right == ChatRestriction::PinMessages) { } else if (right == ChatRestriction::PinMessages) {
return chat->adminRights() & ChatAdminRight::PinMessages; return chat->adminRights() & ChatAdminRight::PinMessagesOrTopics;
} else { } else {
return chat->hasAdminRights(); return chat->hasAdminRights();
} }

View file

@ -264,7 +264,7 @@ rpl::producer<bool> CanPinMessagesValue(not_null<PeerData*> peer) {
| ChatDataFlag::Creator; | ChatDataFlag::Creator;
return rpl::combine( return rpl::combine(
PeerFlagsValue(chat, mask), PeerFlagsValue(chat, mask),
AdminRightValue(chat, ChatAdminRight::PinMessages), AdminRightValue(chat, ChatAdminRight::PinMessagesOrTopics),
DefaultRestrictionValue(chat, ChatRestriction::PinMessages), DefaultRestrictionValue(chat, ChatRestriction::PinMessages),
[]( [](
ChatDataFlags flags, ChatDataFlags flags,
@ -284,7 +284,7 @@ rpl::producer<bool> CanPinMessagesValue(not_null<PeerData*> peer) {
return rpl::single(true); return rpl::single(true);
} }
return rpl::combine( return rpl::combine(
AdminRightValue(megagroup, ChatAdminRight::PinMessages), AdminRightValue(megagroup, ChatAdminRight::PinMessagesOrTopics),
DefaultRestrictionValue(megagroup, ChatRestriction::PinMessages), DefaultRestrictionValue(megagroup, ChatRestriction::PinMessages),
PeerFlagsValue( PeerFlagsValue(
megagroup, megagroup,

View file

@ -28,6 +28,7 @@ namespace {
constexpr auto kMessagesPerPage = 50; constexpr auto kMessagesPerPage = 50;
constexpr auto kReadRequestTimeout = 3 * crl::time(1000); constexpr auto kReadRequestTimeout = 3 * crl::time(1000);
constexpr auto kMaxMessagesToDeleteMyTopic = 10;
[[nodiscard]] HistoryService *GenerateDivider( [[nodiscard]] HistoryService *GenerateDivider(
not_null<History*> history, not_null<History*> history,
@ -947,4 +948,25 @@ void RepliesList::reloadUnreadCountIfNeeded() {
} }
} }
bool RepliesList::canDeleteMyTopic() const {
if (_skippedBefore != 0 || _skippedAfter != 0) {
return false;
}
auto counter = 0;
const auto owner = &_history->owner();
const auto peerId = _history->peer->id;
for (const auto &id : _list) {
if (id == _rootId) {
continue;
} else if (const auto item = owner->message(peerId, id)) {
if (!item->out() || ++counter > kMaxMessagesToDeleteMyTopic) {
return false;
}
} else {
return false;
}
}
return true;
}
} // namespace Data } // namespace Data

View file

@ -54,6 +54,8 @@ public:
void readTill(not_null<HistoryItem*> item); void readTill(not_null<HistoryItem*> item);
void readTill(MsgId tillId); void readTill(MsgId tillId);
[[nodiscard]] bool canDeleteMyTopic() const;
[[nodiscard]] rpl::lifetime &lifetime() { [[nodiscard]] rpl::lifetime &lifetime() {
return _lifetime; return _lifetime;
} }

View file

@ -199,9 +199,18 @@ TextWithEntities GenerateAdminChangeText(
const auto useInviteLinkPhrase = channel->isMegagroup() const auto useInviteLinkPhrase = channel->isMegagroup()
&& channel->anyoneCanAddMembers(); && channel->anyoneCanAddMembers();
const auto pinMessagesAndTopics = channel->isForum()
&& !channel->anyoneCanPinMessages();
const auto pinOnlyTopics = channel->isForum()
&& channel->anyoneCanPinMessages();
const auto invitePhrase = useInviteLinkPhrase const auto invitePhrase = useInviteLinkPhrase
? tr::lng_admin_log_admin_invite_link ? tr::lng_admin_log_admin_invite_link
: tr::lng_admin_log_admin_invite_users; : tr::lng_admin_log_admin_invite_users;
const auto pinPhrase = pinOnlyTopics
? tr::lng_admin_log_admin_pin_topics
: pinMessagesAndTopics
? tr::lng_admin_log_admin_pin_messages_topics
: tr::lng_admin_log_admin_pin_messages;
const auto callPhrase = channel->isBroadcast() const auto callPhrase = channel->isBroadcast()
? tr::lng_admin_log_admin_manage_calls_channel ? tr::lng_admin_log_admin_manage_calls_channel
: tr::lng_admin_log_admin_manage_calls; : tr::lng_admin_log_admin_manage_calls;
@ -211,12 +220,14 @@ TextWithEntities GenerateAdminChangeText(
{ Flag::EditMessages, tr::lng_admin_log_admin_edit_messages }, { Flag::EditMessages, tr::lng_admin_log_admin_edit_messages },
{ Flag::DeleteMessages, tr::lng_admin_log_admin_delete_messages }, { Flag::DeleteMessages, tr::lng_admin_log_admin_delete_messages },
{ Flag::BanUsers, tr::lng_admin_log_admin_ban_users }, { Flag::BanUsers, tr::lng_admin_log_admin_ban_users },
{ Flag::InviteUsers, invitePhrase }, { Flag::InviteByLinkOrAdd, invitePhrase },
{ Flag::PinMessages, tr::lng_admin_log_admin_pin_messages }, { Flag::ManageTopics, tr::lng_admin_log_admin_manage_topics },
{ Flag::PinMessagesOrTopics, pinPhrase },
{ Flag::ManageCall, tr::lng_admin_log_admin_manage_calls }, { Flag::ManageCall, tr::lng_admin_log_admin_manage_calls },
{ Flag::AddAdmins, tr::lng_admin_log_admin_add_admins }, { Flag::AddAdmins, tr::lng_admin_log_admin_add_admins },
}; };
phraseMap[Flag::InviteUsers] = invitePhrase; phraseMap[Flag::InviteByLinkOrAdd] = invitePhrase;
phraseMap[Flag::PinMessagesOrTopics] = pinPhrase;
phraseMap[Flag::ManageCall] = callPhrase; phraseMap[Flag::ManageCall] = callPhrase;
if (!channel->isMegagroup()) { if (!channel->isMegagroup()) {
@ -253,7 +264,8 @@ QString GeneratePermissionsChangeText(
{ Flag::EmbedLinks, tr::lng_admin_log_banned_embed_links }, { Flag::EmbedLinks, tr::lng_admin_log_banned_embed_links },
{ Flag::SendPolls, tr::lng_admin_log_banned_send_polls }, { Flag::SendPolls, tr::lng_admin_log_banned_send_polls },
{ Flag::ChangeInfo, tr::lng_admin_log_admin_change_info }, { Flag::ChangeInfo, tr::lng_admin_log_admin_change_info },
{ Flag::InviteUsers, tr::lng_admin_log_admin_invite_users }, { Flag::AddParticipants, tr::lng_admin_log_admin_invite_users },
{ Flag::CreateTopics, tr::lng_admin_log_admin_create_topics },
{ Flag::PinMessages, tr::lng_admin_log_admin_pin_messages }, { Flag::PinMessages, tr::lng_admin_log_admin_pin_messages },
}; };
return CollectChanges(phraseMap, prevRights.flags, newRights.flags); return CollectChanges(phraseMap, prevRights.flags, newRights.flags);