From 4bd2091e6e84e4e3436f617d49d00c6f575e056a Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 1 Dec 2022 01:57:36 +0300 Subject: [PATCH] Added initial ability to enable anti-spam mode in megagroups. --- Telegram/CMakeLists.txt | 2 + Telegram/Resources/langs/lang.strings | 5 + .../boxes/peers/edit_participants_box.cpp | 7 ++ .../boxes/peers/edit_peer_info_box.cpp | 3 +- .../menu/menu_antispam_validator.cpp | 111 ++++++++++++++++++ .../menu/menu_antispam_validator.h | 39 ++++++ .../SourceFiles/menu/menu_ttl_validator.h | 1 - 7 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 Telegram/SourceFiles/menu/menu_antispam_validator.cpp create mode 100644 Telegram/SourceFiles/menu/menu_antispam_validator.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index a59a6440fc..da0d43f652 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -980,6 +980,8 @@ PRIVATE media/view/media_view_playback_progress.cpp media/view/media_view_playback_progress.h media/view/media_view_open_common.h + menu/menu_antispam_validator.cpp + menu/menu_antispam_validator.h menu/menu_item_download_files.cpp menu/menu_item_download_files.h menu/menu_mute.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index de010e537a..b573937699 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1269,6 +1269,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_peer_reactions_some_title" = "Only allow these reactions"; "lng_manage_peer_reactions_available" = "Available reactions"; +"lng_manage_peer_antispam" = "Aggressive Anti-Spam"; +"lng_manage_peer_antispam_about" = "Telegram will filter more spam but may occasionally affect ordinary messages. You can report False Positives in Recent Actions."; +"lng_manage_peer_antispam_not_enough#one" = "Aggressive filtering can be enabled only in groups with more than **{count} member**."; +"lng_manage_peer_antispam_not_enough#other" = "Aggressive filtering can be enabled only in groups with more than **{count} members**."; + "lng_manage_peer_group_type" = "Group type"; "lng_manage_peer_channel_type" = "Channel type"; "lng_manage_peer_link_type" = "Link type"; diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 44a12939b8..c238df8632 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/max_invite_box.h" #include "boxes/add_contact_box.h" #include "main/main_session.h" +#include "menu/menu_antispam_validator.h" #include "mtproto/mtproto_config.h" #include "apiwrap.h" #include "lang/lang_keys.h" @@ -1186,6 +1187,12 @@ void ParticipantsBoxController::prepare() { } Unexpected("Role in ParticipantsBoxController::prepare()"); }(); + if ((_role == Role::Admins) && _peer->isMegagroup()) { + const auto validator = AntiSpamMenu::AntiSpamValidator( + _navigation->parentController(), + _peer->asChannel()); + delegate()->peerListSetAboveWidget(validator.createButton()); + } delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled); delegate()->peerListSetTitle(std::move(title)); setDescriptionText(tr::lng_contacts_loading(tr::now)); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index bc541f9ed0..9bf04109bc 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -863,8 +863,7 @@ void Controller::fillForumButton() { ShowForumForDiscussionError(_navigation); } else { Ui::ShowMultilineToast({ - .parentOverride = Window::Show( - _navigation).toastParent(), + .parentOverride = Window::Show(_navigation).toastParent(), .text = tr::lng_forum_topics_not_enough( tr::now, lt_count, diff --git a/Telegram/SourceFiles/menu/menu_antispam_validator.cpp b/Telegram/SourceFiles/menu/menu_antispam_validator.cpp new file mode 100644 index 0000000000..1879b327c8 --- /dev/null +++ b/Telegram/SourceFiles/menu/menu_antispam_validator.cpp @@ -0,0 +1,111 @@ +/* +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 "menu/menu_antispam_validator.h" + +#include "apiwrap.h" +#include "boxes/peers/edit_peer_info_box.h" +#include "data/data_changes.h" +#include "data/data_channel.h" +#include "lang/lang_keys.h" +#include "main/main_account.h" +#include "main/main_app_config.h" +#include "main/main_session.h" +#include "settings/settings_common.h" +#include "ui/text/text_utilities.h" +#include "ui/toasts/common_toasts.h" +#include "ui/widgets/buttons.h" +#include "ui/wrap/slide_wrap.h" +#include "ui/wrap/vertical_layout.h" +#include "window/window_session_controller.h" +#include "styles/style_info.h" +#include "styles/style_settings.h" + +namespace AntiSpamMenu { +namespace { + +[[nodiscard]] int EnableAntiSpamMinMembers(not_null channel) { + return channel->session().account().appConfig().get( + u"telegram_antispam_group_size_min"_q, + 100); +} + +} // namespace + +AntiSpamValidator::AntiSpamValidator( + not_null controller, + not_null channel) +: _channel(channel) +, _controller(controller) { +} + +object_ptr AntiSpamValidator::createButton() const { + const auto channel = _channel; + auto container = object_ptr>( + (QWidget*)nullptr, + object_ptr((QWidget*)nullptr)); + struct State { + rpl::variable locked; + rpl::event_stream toggled; + }; + Settings::AddSkip(container->entity()); + const auto state = container->lifetime().make_state(); + const auto button = container->entity()->add( + EditPeerInfoBox::CreateButton( + container->entity(), + tr::lng_manage_peer_antispam(), + rpl::single(QString()), + [] {}, + st::manageGroupTopicsButton, + { &st::infoRoundedIconAdministrators, Settings::kIconPurple } + ))->toggleOn(rpl::single( + _channel->antiSpamMode() + ) | rpl::then(state->toggled.events())); + container->show(anim::type::instant); + Settings::AddDividerText( + container->entity(), + tr::lng_manage_peer_antispam_about()); + + const auto updateLocked = [=] { + const auto &config = channel->session().account().appConfig(); + const auto min = EnableAntiSpamMinMembers(channel); + const auto locked = (channel->membersCount() <= min); + state->locked = locked; + button->setToggleLocked(locked); + }; + using UpdateFlag = Data::PeerUpdate::Flag; + _channel->session().changes().peerUpdates( + _channel, + UpdateFlag::Members | UpdateFlag::Admins + ) | rpl::start_with_next(updateLocked, button->lifetime()); + updateLocked(); + button->toggledValue( + ) | rpl::start_with_next([=, controller = _controller](bool toggled) { + if (state->locked.current() && toggled) { + state->toggled.fire(false); + Ui::ShowMultilineToast({ + .parentOverride = Window::Show(controller).toastParent(), + .text = tr::lng_manage_peer_antispam_not_enough( + tr::now, + lt_count, + EnableAntiSpamMinMembers(channel), + Ui::Text::RichLangValue), + }); + } else { + channel->session().api().request(MTPchannels_ToggleAntiSpam( + channel->inputChannel, + MTP_bool(toggled) + )).done([=](const MTPUpdates &result) { + channel->session().api().applyUpdates(result); + }).send(); + } + }, button->lifetime()); + + return container; +} + +} // namespace AntiSpamMenu diff --git a/Telegram/SourceFiles/menu/menu_antispam_validator.h b/Telegram/SourceFiles/menu/menu_antispam_validator.h new file mode 100644 index 0000000000..7930b4de9c --- /dev/null +++ b/Telegram/SourceFiles/menu/menu_antispam_validator.h @@ -0,0 +1,39 @@ +/* +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 +*/ +#pragma once + +template +class object_ptr; + +class ChannelData; + +namespace Ui { +class RpWidget; +} // namespace Ui + +namespace Window { +class SessionController; +} // namespace Window + +namespace AntiSpamMenu { + +class AntiSpamValidator final { +public: + AntiSpamValidator( + not_null controller, + not_null channel); + + [[nodiscard]] object_ptr createButton() const; + +private: + const not_null _channel; + const not_null _controller; + +}; + +} // namespace AntiSpamMenu diff --git a/Telegram/SourceFiles/menu/menu_ttl_validator.h b/Telegram/SourceFiles/menu/menu_ttl_validator.h index 4f0862c9a8..fa360b50a9 100644 --- a/Telegram/SourceFiles/menu/menu_ttl_validator.h +++ b/Telegram/SourceFiles/menu/menu_ttl_validator.h @@ -13,7 +13,6 @@ class PeerData; namespace Ui { class Show; -class RpWidget; } // namespace Ui namespace TTLMenu {