diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 5919b2593..2288910cb 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -5168,6 +5168,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_filters_link" = "Share Folder"; "lng_filters_link_has" = "Invite links"; +"lng_filters_checkbox_remove_bot" = "Remove bot from all folders"; +"lng_filters_checkbox_remove_group" = "Remove group from all folders"; +"lng_filters_checkbox_remove_channel" = "Remove channel from all folders"; + "lng_filters_link_create" = "Create an Invite Link"; "lng_filters_link_cant" = "You can’t share folders which include or exclude specific chat types like 'Groups', 'Contacts', etc."; "lng_filters_link_about" = "Share access to some of this folder's groups and channels with others."; diff --git a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp index 9c68881a1..c7e696e9e 100644 --- a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/ui_integration.h" #include "data/data_channel.h" #include "data/data_chat.h" +#include "data/data_chat_filters.h" #include "data/data_chat_participant_status.h" #include "data/data_histories.h" #include "data/data_peer.h" @@ -512,6 +513,7 @@ void DeleteChatBox(not_null box, not_null peer) { const auto container = box->verticalLayout(); const auto maybeUser = peer->asUser(); + const auto isBot = maybeUser && maybeUser->isBot(); Ui::AddSkip(container); Ui::AddSkip(container); @@ -595,7 +597,7 @@ void DeleteChatBox(not_null box, not_null peer) { }(); const auto maybeBotCheckbox = [&]() -> Ui::Checkbox* { - if (!maybeUser || !maybeUser->isBot()) { + if (!isBot) { return nullptr; } Ui::AddSkip(container); @@ -608,6 +610,40 @@ void DeleteChatBox(not_null box, not_null peer) { st::defaultBoxCheckbox)); }(); + const auto removeFromChatsFilters = [=]( + not_null history) -> std::vector { + auto result = std::vector(); + for (const auto &filter : peer->owner().chatsFilters().list()) { + if (filter.withoutAlways(history) != filter) { + result.push_back(filter.id()); + } + } + return result; + }; + + const auto maybeChatsFiltersCheckbox = [&]() -> Ui::Checkbox* { + const auto history = (isBot || !maybeUser) + ? peer->owner().history(peer).get() + : nullptr; + if (!history || removeFromChatsFilters(history).empty()) { + return nullptr; + } + Ui::AddSkip(container); + Ui::AddSkip(container); + return box->addRow( + object_ptr( + container, + (maybeBotCheckbox + ? tr::lng_filters_checkbox_remove_bot + : (peer->isChannel() && !peer->isMegagroup()) + ? tr::lng_filters_checkbox_remove_channel + : tr::lng_filters_checkbox_remove_group)( + tr::now, + Ui::Text::WithEntities), + false, + st::defaultBoxCheckbox)); + }(); + Ui::AddSkip(container); auto buttonText = maybeUser @@ -622,10 +658,35 @@ void DeleteChatBox(not_null box, not_null peer) { box->addButton(std::move(buttonText), [=] { const auto revoke = maybeCheckbox && maybeCheckbox->checked(); const auto stopBot = maybeBotCheckbox && maybeBotCheckbox->checked(); + const auto removeFromChats = maybeChatsFiltersCheckbox + && maybeChatsFiltersCheckbox->checked(); Core::App().closeChatFromWindows(peer); if (stopBot) { peer->session().api().blockedPeers().block(peer); } + if (removeFromChats) { + const auto history = peer->owner().history(peer).get(); + const auto removeFrom = removeFromChatsFilters(history); + for (const auto &filter : peer->owner().chatsFilters().list()) { + if (!ranges::contains(removeFrom, filter.id())) { + continue; + } + const auto result = filter.withoutAlways(history); + if (result == filter) { + continue; + } + const auto tl = result.tl(); + peer->owner().chatsFilters().apply(MTP_updateDialogFilter( + MTP_flags(MTPDupdateDialogFilter::Flag::f_filter), + MTP_int(filter.id()), + tl)); + peer->session().api().request(MTPmessages_UpdateDialogFilter( + MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter), + MTP_int(filter.id()), + tl + )).send(); + } + } // Don't delete old history by default, // because Android app doesn't. // diff --git a/Telegram/SourceFiles/data/data_chat_filters.cpp b/Telegram/SourceFiles/data/data_chat_filters.cpp index 3dd176d94..354d95bf3 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.cpp +++ b/Telegram/SourceFiles/data/data_chat_filters.cpp @@ -188,6 +188,14 @@ ChatFilter ChatFilter::withChatlist(bool chatlist, bool hasMyLinks) const { return result; } +ChatFilter ChatFilter::withoutAlways(not_null history) const { + auto result = *this; + if (CanRemoveFromChatFilter(result, history)) { + result._always.remove(history); + } + return result; +} + MTPDialogFilter ChatFilter::tl(FilterId replaceId) const { auto always = _always; auto pinned = QVector(); diff --git a/Telegram/SourceFiles/data/data_chat_filters.h b/Telegram/SourceFiles/data/data_chat_filters.h index 2e34cc713..0136919f5 100644 --- a/Telegram/SourceFiles/data/data_chat_filters.h +++ b/Telegram/SourceFiles/data/data_chat_filters.h @@ -64,6 +64,7 @@ public: [[nodiscard]] ChatFilter withChatlist( bool chatlist, bool hasMyLinks) const; + [[nodiscard]] ChatFilter withoutAlways(not_null) const; [[nodiscard]] static ChatFilter FromTL( const MTPDialogFilter &data,