/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "boxes/peers/edit_peer_permissions_box.h" #include "lang/lang_keys.h" #include "data/data_channel.h" #include "data/data_chat.h" #include "ui/effects/toggle_arrow.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" #include "ui/layers/generic_box.h" #include "ui/painter.h" #include "ui/widgets/labels.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/buttons.h" #include "ui/widgets/continuous_sliders.h" #include "ui/widgets/box_content_divider.h" #include "ui/text/text_utilities.h" #include "ui/toasts/common_toasts.h" #include "info/profile/info_profile_icon.h" #include "info/profile/info_profile_values.h" #include "boxes/peers/edit_participants_box.h" #include "boxes/peers/edit_peer_info_box.h" #include "window/window_session_controller.h" #include "window/window_controller.h" #include "main/main_session.h" #include "apiwrap.h" #include "settings/settings_common.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" #include "styles/style_info.h" #include "styles/style_window.h" namespace { constexpr auto kSlowmodeValues = 7; constexpr auto kSuggestGigagroupThreshold = 199000; int SlowmodeDelayByIndex(int index) { Expects(index >= 0 && index < kSlowmodeValues); switch (index) { case 0: return 0; case 1: return 10; case 2: return 30; case 3: return 60; case 4: return 5 * 60; case 5: return 15 * 60; case 6: return 60 * 60; } Unexpected("Index in SlowmodeDelayByIndex."); } auto Dependencies(ChatRestrictions) -> std::vector> { using Flag = ChatRestriction; return { // stickers <-> gifs { Flag::SendGifs, Flag::SendStickers }, { Flag::SendStickers, Flag::SendGifs }, // stickers <-> games { Flag::SendGames, Flag::SendStickers }, { Flag::SendStickers, Flag::SendGames }, // stickers <-> inline { Flag::SendInline, Flag::SendStickers }, { Flag::SendStickers, Flag::SendInline }, // embed_links -> send_plain { Flag::EmbedLinks, Flag::SendOther }, // send_* -> view_messages { Flag::SendStickers, Flag::ViewMessages }, { Flag::SendGifs, Flag::ViewMessages }, { Flag::SendGames, Flag::ViewMessages }, { Flag::SendInline, Flag::ViewMessages }, { Flag::SendPolls, Flag::ViewMessages }, { Flag::SendPhotos, Flag::ViewMessages }, { Flag::SendVideos, Flag::ViewMessages }, { Flag::SendVideoMessages, Flag::ViewMessages }, { Flag::SendMusic, Flag::ViewMessages }, { Flag::SendVoiceMessages, Flag::ViewMessages }, { Flag::SendFiles, Flag::ViewMessages }, { Flag::SendOther, Flag::ViewMessages }, }; } ChatRestrictions NegateRestrictions(ChatRestrictions value) { using Flag = ChatRestriction; return (~value) & (Flag(0) // view_messages is always allowed, so it is never in restrictions. //| Flag::ViewMessages | Flag::ChangeInfo | Flag::EmbedLinks | Flag::AddParticipants | Flag::CreateTopics | Flag::PinMessages | Flag::SendGames | Flag::SendGifs | Flag::SendInline | Flag::SendPolls | Flag::SendStickers | Flag::SendPhotos | Flag::SendVideos | Flag::SendVideoMessages | Flag::SendMusic | Flag::SendVoiceMessages | Flag::SendFiles | Flag::SendOther); } [[nodiscard]] std::vector MediaRestrictions() { return std::vector{ ChatRestriction::SendPhotos, ChatRestriction::SendVideos, ChatRestriction::SendVideoMessages, ChatRestriction::SendMusic, ChatRestriction::SendVoiceMessages, ChatRestriction::SendFiles, ChatRestriction::SendStickers | ChatRestriction::SendGifs | ChatRestriction::SendGames | ChatRestriction::SendInline, ChatRestriction::EmbedLinks, ChatRestriction::SendPolls, }; } auto Dependencies(ChatAdminRights) -> std::vector> { return {}; } auto ToPositiveNumberString() { return rpl::map([](int count) { return count ? QString::number(count) : QString(); }); } ChatRestrictions DisabledByAdminRights(not_null peer) { using Flag = ChatRestriction; using Admin = ChatAdminRight; using Admins = ChatAdminRights; const auto adminRights = [&] { const auto full = ~Admins(0); if (const auto chat = peer->asChat()) { return chat->amCreator() ? full : chat->adminRights(); } else if (const auto channel = peer->asChannel()) { return channel->amCreator() ? full : channel->adminRights(); } Unexpected("User in DisabledByAdminRights."); }(); return Flag(0) | ((adminRights & Admin::ManageTopics) ? Flag(0) : Flag::CreateTopics) | ((adminRights & Admin::PinMessages) ? Flag(0) : Flag::PinMessages) | ((adminRights & Admin::InviteByLinkOrAdd) ? Flag(0) : Flag::AddParticipants) | ((adminRights & Admin::ChangeInfo) ? Flag(0) : Flag::ChangeInfo); } not_null SendMediaToggle( not_null container, rpl::producer checkedValue, int total, not_null*> wrap, Fn toggleMedia) { class Button final : public Ui::SettingsButton { public: using Ui::SettingsButton::SettingsButton; [[nodiscard]] QRect innerToggleRect() const { return Ui::SettingsButton::maybeToggleRect(); } [[nodiscard]] bool toggleClicked() const { return _togglePressed && _toggleReleased; } protected: void mousePressEvent(QMouseEvent *event) override { _togglePressed = Ui::SettingsButton::maybeToggleRect().contains( event->pos()); Ui::SettingsButton::mousePressEvent(event); } void mouseReleaseEvent(QMouseEvent *event) override { _toggleReleased = Ui::SettingsButton::maybeToggleRect().contains( event->pos()); Ui::SettingsButton::mouseReleaseEvent(event); } private: bool _togglePressed = false; bool _toggleReleased = false; }; const auto button = container->add(object_ptr