feat: list of shadow banned users

This commit is contained in:
bleizix
2025-10-06 17:21:17 +05:00
committed by AlexeyZavar
parent 89ae7cfca2
commit 8e895bb78d
7 changed files with 153 additions and 83 deletions
@@ -7,13 +7,17 @@
#include "per_dialog_filter.h"
#include <utility>
#include "lang_auto.h"
#include "settings_filters_list.h"
#include "ayu/ayu_settings.h"
#include "ayu/data/ayu_database.h"
#include "ayu/features/filters/shadow_ban_utils.h"
#include "ayu/utils/telegram_helpers.h"
#include "data/data_peer.h"
#include "data/data_session.h"
#include "main/main_session.h"
#include "styles/style_menu_icons.h"
#include "ui/painter.h"
#include "window/window_session_controller.h"
@@ -50,16 +54,35 @@ PaintRoundImageCallback PerDialogFiltersListRow::generatePaintUserpicCallback(bo
}
PerDialogFiltersListController::PerDialogFiltersListController(not_null<Main::Session*> session,
not_null<Window::SessionController*> controller)
not_null<Window::SessionController*> controller,
bool shadowBan)
: _session(session)
, _controller(controller) {
, _controller(controller)
, shadowBan(shadowBan) {
}
Main::Session &PerDialogFiltersListController::session() const {
return *_session;
}
void PerDialogFiltersListController::prepareShadowBan() {
const auto &settings = AyuSettings::getInstance();
const auto &shadowBanned = settings.shadowBanIds;
for (const auto id : shadowBanned) {
auto peerId = PeerId(PeerIdHelper(abs(id)));
auto row = std::make_unique<PerDialogFiltersListRow>(peerId);
delegate()->peerListAppendRow(reinterpret_cast<std::unique_ptr<PeerListRow>&&>(row));
}
}
void PerDialogFiltersListController::prepare() {
if (shadowBan) {
prepareShadowBan();
return;
}
const auto filters = AyuDatabase::getAllRegexFilters();
const auto exclusions = AyuDatabase::getAllFiltersExclusions();
@@ -106,7 +129,7 @@ void PerDialogFiltersListController::prepare() {
void PerDialogFiltersListController::rowClicked(not_null<PeerListRow*> peer) {
ID did;
if (peer->special()) {
const ID pred = peer->id() & PeerId::kChatTypeMask;
const ID pred = peer->id() & PeerId::kChatTypeMask;
if (countsByDialogIds.contains(pred)) {
did = pred;
} else {
@@ -115,47 +138,28 @@ void PerDialogFiltersListController::rowClicked(not_null<PeerListRow*> peer) {
} else {
did = getDialogIdFromPeer(peer->peer());
}
if (shadowBan) {
auto _contextMenu = new Ui::PopupMenu(nullptr, st::popupMenuWithIcons);
_contextMenu->setAttribute(Qt::WA_DeleteOnClose);
_contextMenu->addAction(
tr::lng_theme_delete(tr::now),
[=]
{
if (ShadowBanUtils::isShadowBanned(did)) {
ShadowBanUtils::removeShadowBan(did);
} else {
ShadowBanUtils::addShadowBan(did);
}
},
&st::menuIconDelete);
_contextMenu->popup(QCursor::pos());
return;
}
_controller->dialogId = did;
_controller->showExclude = true;
_controller->showSettings(AyuFiltersList::Id());
}
SelectChatBoxController::SelectChatBoxController(
not_null<Window::SessionController*> controller,
Fn<void(not_null<PeerData*>)> onSelectedCallback)
: ChatsListBoxController(&controller->session())
, _controller(controller)
, _onSelectedCallback(std::move(onSelectedCallback)) {
}
Main::Session &SelectChatBoxController::session() const {
return _controller->session();
}
void SelectChatBoxController::rowClicked(not_null<PeerListRow*> row) {
if (_onSelectedCallback) {
_onSelectedCallback(row->peer());
}
}
std::unique_ptr<ChatsListBoxController::Row> SelectChatBoxController::createRow(not_null<History*> history) {
const auto peer = history->peer;
const auto skip =
peer->isUser() ||
//peer->forum() ||
peer->monoforum();
if (skip) {
return nullptr;
}
auto result = std::make_unique<Row>(
history,
nullptr);
return result;
}
void SelectChatBoxController::prepareViewHook() {
delegate()->peerListSetTitle(tr::ayu_FiltersMenuSelectChat());
}
}
@@ -35,7 +35,8 @@ class PerDialogFiltersListController final : public PeerListController
{
public:
explicit PerDialogFiltersListController(not_null<Main::Session*> session,
not_null<Window::SessionController*> controller);
not_null<Window::SessionController*> controller,
bool shadowBan = false);
[[nodiscard]] Main::Session &session() const override;
@@ -44,36 +45,19 @@ public:
void rowClicked(not_null<PeerListRow*> row) override;
private:
void prepareShadowBan();
struct FilterCounts
{
int filters = 0;
int exclusions = 0;
};
std::unordered_map<ID, FilterCounts> countsByDialogIds;
const not_null<Main::Session*> _session;
not_null<Window::SessionController*> _controller;
bool shadowBan;
};
class SelectChatBoxController
: public ChatsListBoxController
, public base::has_weak_ptr
{
public:
explicit SelectChatBoxController(
not_null<Window::SessionController*> controller,
Fn<void(not_null<PeerData*>)> onSelectedCallback
);
Main::Session &session() const override;
void rowClicked(not_null<PeerListRow*> row) override;
protected:
std::unique_ptr<Row> createRow(not_null<History*> history) override;
void prepareViewHook() override;
private:
not_null<Window::SessionController*> _controller;
Fn<void(not_null<PeerData*>)> _onSelectedCallback;
};
} // namespace Settings
} // namespace Settings
@@ -6,28 +6,25 @@
// Copyright @Radolyn, 2025
#include "settings_filters_list.h"
#include <styles/style_layers.h>
#include <styles/style_media_view.h>
#include "edit_filter.h"
#include "ayu/ayu_settings.h"
#include "lang_auto.h"
#include "boxes/connection_box.h"
#include "settings/settings_common.h"
#include "storage/localstorage.h"
#include "styles/style_menu_icons.h"
#include "styles/style_settings.h"
#include "styles/style_widgets.h"
#include "../../components/icon_picker.h"
#include "per_dialog_filter.h"
#include "ayu/ayu_settings.h"
#include "ayu/data/ayu_database.h"
#include "ayu/features/filters/filters_cache_controller.h"
#include "ayu/features/filters/filters_utils.h"
#include "ayu/ui/components/icon_picker.h"
#include "ayu/utils/telegram_helpers.h"
#include "boxes/connection_box.h"
#include "data/data_channel.h"
#include "info/info_wrap_widget.h"
#include "settings/settings_common.h"
#include "storage/localstorage.h"
#include "styles/style_boxes.h"
#include "styles/style_media_view.h"
#include "styles/style_menu_icons.h"
#include "styles/style_settings.h"
#include "styles/style_widgets.h"
#include "ui/qt_object_factory.h"
#include "ui/vertical_list.h"
#include "ui/widgets/buttons.h"
@@ -38,6 +35,9 @@
namespace Settings {
rpl::producer<QString> AyuFiltersList::title() {
if (shadowBan) {
return tr::ayu_FiltersShadowBan();
}
if (!dialogId.has_value()) {
return tr::ayu_RegexFiltersShared();
}
@@ -64,7 +64,8 @@ rpl::producer<QString> AyuFiltersList::title() {
AyuFiltersList::AyuFiltersList(
QWidget *parent,
not_null<Window::SessionController*> controller)
: Section(parent), _controller(controller), _content(Ui::CreateChild<Ui::VerticalLayout>(this)) {
: Section(parent), _controller(controller), _content(Ui::CreateChild<Ui::VerticalLayout>(this)),
shadowBan(_controller->shadowBan) {
if (_controller->dialogId.has_value()) {
dialogId = _controller->dialogId.value();
}
@@ -74,6 +75,7 @@ AyuFiltersList::AyuFiltersList(
void AyuFiltersList::checkBeforeClose(Fn<void()> close) {
_controller->showExclude = true;
_controller->shadowBan = false;
close();
}
@@ -260,8 +262,43 @@ void AyuFiltersList::initializeSharedFilters(
}
}
void AyuFiltersList::initializeShadowBan(not_null<Ui::VerticalLayout*> container) {
auto ctrl = container->lifetime().make_state<PerDialogFiltersListController>(
&_controller->session(),
_controller,
true // shadowBan
);
auto list = object_ptr<Ui::PaddingWrap<PeerListContent>>(
container,
object_ptr<PeerListContent>(
container,
ctrl),
QMargins(0, -st::peerListBox.padding.top(), 0, -st::peerListBox.padding.bottom()));
// delegate is not initialized at this moment
if (AyuSettings::getInstance().shadowBanIds.size() > 0) {
AddSkip(container);
filtersTitle = AddSubsectionTitle(container, tr::ayu_RegexFiltersHeader());
const auto content = container->add(std::move(list));
AddSkip(container);
auto delegate = container->lifetime().make_state<PeerListContentDelegateSimple>();
delegate->setContent(content->entity());
ctrl->setDelegate(delegate);
} else {
Ui::AddDividerText(container, tr::ayu_RegexFiltersListEmpty());
}
}
void AyuFiltersList::setupContent(not_null<Window::SessionController*> controller) {
initializeSharedFilters(_content);
if (shadowBan) {
initializeShadowBan(_content);
} else {
initializeSharedFilters(_content);
}
ResizeFitChild(this, _content);
}
@@ -33,6 +33,7 @@ public:
private:
void setupContent(not_null<Window::SessionController*> controller);
void initializeSharedFilters(not_null<Ui::VerticalLayout*> container);
void initializeShadowBan(not_null<Ui::VerticalLayout*> container);
void addNewFilter(const RegexFilter &filter, bool exclusion = false);
@@ -46,6 +47,7 @@ private:
Ui::FlatLabel *excludedTitle = nullptr;
std::optional<long long> dialogId;
bool shadowBan;
};
} // namespace Settings
} // namespace Settings
@@ -212,6 +212,21 @@ void SetupShared(not_null<Window::SessionController*> controller,
});
}
void SetupShadowBan(not_null<Window::SessionController*> controller,
Ui::VerticalLayout *container) {
auto button = container->add(object_ptr<Ui::SettingsButton>(
container,
tr::ayu_FiltersShadowBan()
));
button->addClickHandler([=]
{
controller->dialogId = std::nullopt;
controller->showExclude = false;
controller->shadowBan = true;
controller->showSettings(AyuFiltersList::Id());
});
}
void SetupPerDialog(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container
@@ -268,6 +283,7 @@ void AyuFilters::setupContent(not_null<Window::SessionController*> controller) {
AddDivider(content);
SetupShared(controller, content);
SetupShadowBan(controller, content);
if (AyuDatabase::hasPerDialogFilters()) {
AddSkip(content);
+28 -2
View File
@@ -55,9 +55,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
// AyuGram includes
#include "ayu/ayu_settings.h"
#include "ayu/features/filters/shadow_ban_utils.h"
#include "ayu/ui/settings/filters/edit_filter.h"
#include "ayu/ui/settings/filters/settings_filters_list.h"
#include "ayu/utils/telegram_helpers.h"
#include "inline_bots/bot_attach_web_view.h"
#include "styles/style_ayu_settings.h"
#include "window/window_peer_menu.h"
namespace Info {
namespace {
@@ -431,12 +435,34 @@ void WrapWidget::setupTopBarMenuToggle() {
const auto button = _topBar->addButton(base::make_unique_q<Ui::IconButton>(_topBar, st));
const auto show = controller->uiShow();
if (controller->shadowBan) {
auto types = InlineBots::PeerTypes();
types |= InlineBots::PeerType::Bot;
types |= InlineBots::PeerType::User;
button->addClickHandler(
[=]
button->addClickHandler([=]
{
Window::ShowChooseRecipientBox(
controller,
[=](not_null<Data::Thread*> thread)
{
const auto peer = thread->peer();
const auto realId = getDialogIdFromPeer(peer);
ShadowBanUtils::addShadowBan(realId);
return true;
},
tr::ayu_FiltersMenuSelectChat(),
nullptr,
types
);
});
} else {
button->addClickHandler([=]
{
show->show(::Settings::RegexEditBox(nullptr, nullptr, controller->dialogId));
});
}
if (controller->showExclude.has_value() && controller->showExclude.value()) {
@@ -702,6 +702,7 @@ public:
std::optional<long long> dialogId;
std::vector<char> filterId;
std::optional<bool> showExclude; // whether to show exclude button in the top bar
bool shadowBan = false;
private:
struct CachedThemeKey;
struct CachedTheme;