diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 3b86a7dda..18396ecb4 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -615,9 +615,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_security" = "Security"; "lng_settings_passcode_title" = "Local passcode"; "lng_settings_sessions_title" = "Active sessions"; +"lng_settings_archive_title" = "Archive Settings"; "lng_settings_new_unknown" = "New chats from unknown users"; "lng_settings_auto_archive" = "Archive and Mute"; "lng_settings_auto_archive_about" = "Automatically archive and mute new chats, groups and channels from non-contacts."; +"lng_settings_unmuted_chats" = "Unmuted chats"; +"lng_settings_always_in_archive" = "Always keep archived"; +"lng_settings_unmuted_chats_about" = "Keep archived chats in the Archive even if they are unmuted and get a new message."; +"lng_settings_chats_from_folders" = "Chats from folders"; +"lng_settings_chats_from_folders_about" = "Keep archived chats from folders in the Archive even if they are unmuted and get a new message."; "lng_settings_destroy_title" = "Delete my account"; "lng_settings_version_info" = "Version and updates"; "lng_settings_system_integration" = "System integration"; @@ -2278,6 +2284,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_context_archive_to_menu" = "Move to main menu"; "lng_context_archive_to_list" = "Move to chats list"; "lng_context_archive_to_menu_info" = "Archive moved to the main menu!\nYou can return it from the context menu of the archive button."; +"lng_context_archive_settings" = "Archive settings"; "lng_context_mute" = "Mute"; "lng_context_unmute" = "Unmute"; diff --git a/Telegram/SourceFiles/api/api_global_privacy.cpp b/Telegram/SourceFiles/api/api_global_privacy.cpp index 89e1d57da..43a60e9a3 100644 --- a/Telegram/SourceFiles/api/api_global_privacy.cpp +++ b/Telegram/SourceFiles/api/api_global_privacy.cpp @@ -84,19 +84,29 @@ void GlobalPrivacy::dismissArchiveAndMuteSuggestion() { u"AUTOARCHIVE_POPULAR"_q); } -void GlobalPrivacy::update(bool archiveAndMute) { +void GlobalPrivacy::updateArchiveAndMute(bool value) { + update(value, unarchiveOnNewMessageCurrent()); +} + +void GlobalPrivacy::updateUnarchiveOnNewMessage( + UnarchiveOnNewMessage value) { + update(archiveAndMuteCurrent(), value); +} + +void GlobalPrivacy::update( + bool archiveAndMute, + UnarchiveOnNewMessage unarchiveOnNewMessage) { using Flag = MTPDglobalPrivacySettings::Flag; - const auto unarchive = unarchiveOnNewMessageCurrent(); _api.request(_requestId).cancel(); const auto flags = Flag() | (archiveAndMute ? Flag::f_archive_and_mute_new_noncontact_peers : Flag()) - | (unarchive == UnarchiveOnNewMessage::AnyUnmuted + | (unarchiveOnNewMessage == UnarchiveOnNewMessage::AnyUnmuted ? Flag::f_keep_archived_unmuted : Flag()) - | (unarchive != UnarchiveOnNewMessage::None + | (unarchiveOnNewMessage != UnarchiveOnNewMessage::None ? Flag::f_keep_archived_folders : Flag()); _requestId = _api.request(MTPaccount_SetGlobalPrivacySettings( @@ -108,6 +118,7 @@ void GlobalPrivacy::update(bool archiveAndMute) { _requestId = 0; }).send(); _archiveAndMute = archiveAndMute; + _unarchiveOnNewMessage = unarchiveOnNewMessage; } void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &data) { diff --git a/Telegram/SourceFiles/api/api_global_privacy.h b/Telegram/SourceFiles/api/api_global_privacy.h index f569951ca..9e4b8e121 100644 --- a/Telegram/SourceFiles/api/api_global_privacy.h +++ b/Telegram/SourceFiles/api/api_global_privacy.h @@ -28,7 +28,8 @@ public: explicit GlobalPrivacy(not_null api); void reload(Fn callback = nullptr); - void update(bool archiveAndMute); + void updateArchiveAndMute(bool value); + void updateUnarchiveOnNewMessage(UnarchiveOnNewMessage value); [[nodiscard]] bool archiveAndMuteCurrent() const; [[nodiscard]] rpl::producer archiveAndMute() const; @@ -43,6 +44,10 @@ public: private: void apply(const MTPGlobalPrivacySettings &data); + void update( + bool archiveAndMute, + UnarchiveOnNewMessage unarchiveOnNewMessage); + const not_null _session; MTP::Sender _api; mtpRequestId _requestId = 0; diff --git a/Telegram/SourceFiles/settings/settings_advanced.cpp b/Telegram/SourceFiles/settings/settings_advanced.cpp index 1829f92a2..096bcbbdd 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/settings_advanced.cpp @@ -7,16 +7,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "settings/settings_advanced.h" +#include "api/api_global_privacy.h" +#include "apiwrap.h" #include "settings/settings_common.h" #include "settings/settings_chat.h" #include "settings/settings_experimental.h" #include "settings/settings_power_saving.h" +#include "settings/settings_privacy_security.h" #include "ui/wrap/vertical_layout.h" #include "ui/wrap/slide_wrap.h" #include "ui/widgets/labels.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/buttons.h" #include "ui/gl/gl_detection.h" +#include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" // Ui::Text::ToUpper #include "ui/text/format_values.h" #include "ui/boxes/single_choice_box.h" @@ -43,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_session.h" #include "mtproto/facade.h" #include "styles/style_settings.h" +#include "styles/style_layers.h" #ifdef Q_OS_MAC #include "base/platform/mac/base_confirm_quit.h" @@ -710,6 +715,94 @@ void SetupAnimations( }); } +void ArchiveSettingsBox( + not_null box, + not_null controller) { + box->setTitle(tr::lng_settings_archive_title()); + box->setWidth(st::boxWideWidth); + + box->addButton(tr::lng_about_done(), [=] { box->closeBox(); }); + + PreloadArchiveSettings(&controller->session()); + + struct State { + Ui::SlideWrap *foldersWrap = nullptr; + Ui::SettingsButton *folders = nullptr; + }; + const auto state = box->lifetime().make_state(); + const auto privacy = &controller->session().api().globalPrivacy(); + + const auto container = box->verticalLayout(); + AddSkip(container); + AddSubsectionTitle(container, tr::lng_settings_unmuted_chats()); + + using Unarchive = Api::UnarchiveOnNewMessage; + AddButton( + container, + tr::lng_settings_always_in_archive(), + st::settingsButtonNoIcon + )->toggleOn(privacy->unarchiveOnNewMessage( + ) | rpl::map( + rpl::mappers::_1 == Unarchive::None + ))->toggledChanges( + ) | rpl::filter([=](bool toggled) { + const auto current = privacy->unarchiveOnNewMessageCurrent(); + return toggled != (current == Unarchive::None); + }) | rpl::start_with_next([=](bool toggled) { + privacy->updateUnarchiveOnNewMessage(toggled + ? Unarchive::None + : state->folders->toggled() + ? Unarchive::NotInFoldersUnmuted + : Unarchive::AnyUnmuted); + state->foldersWrap->toggle(!toggled, anim::type::normal); + }, container->lifetime()); + + AddSkip(container); + AddDividerText(container, tr::lng_settings_unmuted_chats_about()); + + state->foldersWrap = container->add( + object_ptr>( + container, + object_ptr(container))); + const auto inner = state->foldersWrap->entity(); + AddSkip(inner); + AddSubsectionTitle(inner, tr::lng_settings_chats_from_folders()); + + state->folders = AddButton( + inner, + tr::lng_settings_always_in_archive(), + st::settingsButtonNoIcon + )->toggleOn(privacy->unarchiveOnNewMessage( + ) | rpl::map( + rpl::mappers::_1 != Unarchive::AnyUnmuted + )); + state->folders->toggledChanges( + ) | rpl::filter([=](bool toggled) { + const auto current = privacy->unarchiveOnNewMessageCurrent(); + return toggled != (current != Unarchive::AnyUnmuted); + }) | rpl::start_with_next([=](bool toggled) { + const auto current = privacy->unarchiveOnNewMessageCurrent(); + privacy->updateUnarchiveOnNewMessage(!toggled + ? Unarchive::AnyUnmuted + : (current == Unarchive::AnyUnmuted) + ? Unarchive::NotInFoldersUnmuted + : current); + }, inner->lifetime()); + + AddSkip(inner); + AddDividerText(inner, tr::lng_settings_chats_from_folders_about()); + + state->foldersWrap->toggle( + privacy->unarchiveOnNewMessageCurrent() != Unarchive::None, + anim::type::instant); + + SetupArchiveAndMute(controller, box->verticalLayout()); +} + +void PreloadArchiveSettings(not_null<::Main::Session*> session) { + session->api().globalPrivacy().reload(); +} + void SetupHardwareAcceleration(not_null container) { const auto settings = &Core::App().settings(); AddButton( diff --git a/Telegram/SourceFiles/settings/settings_advanced.h b/Telegram/SourceFiles/settings/settings_advanced.h index 27afff623..21aa2014f 100644 --- a/Telegram/SourceFiles/settings/settings_advanced.h +++ b/Telegram/SourceFiles/settings/settings_advanced.h @@ -11,10 +11,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Main { class Account; +class Session; } // namespace Main +namespace Ui { +class GenericBox; +} // namespace Ui + namespace Window { class Controller; +class SessionController; } // namespace Window namespace Settings { @@ -37,6 +43,11 @@ void SetupAnimations( not_null window, not_null container); +void ArchiveSettingsBox( + not_null box, + not_null controller); +void PreloadArchiveSettings(not_null<::Main::Session*> session); + class Advanced : public Section { public: Advanced( diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index d9a1a97c3..63df59c3d 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -311,53 +311,6 @@ void SetupPrivacy( AddDivider(container); } -void SetupArchiveAndMute( - not_null controller, - not_null container) { - using namespace rpl::mappers; - - const auto wrap = container->add( - object_ptr>( - container, - object_ptr(container))); - const auto inner = wrap->entity(); - - AddSkip(inner); - AddSubsectionTitle(inner, tr::lng_settings_new_unknown()); - - const auto session = &controller->session(); - - const auto privacy = &session->api().globalPrivacy(); - privacy->reload(); - AddButton( - inner, - tr::lng_settings_auto_archive(), - st::settingsButtonNoIcon - )->toggleOn( - privacy->archiveAndMute() - )->toggledChanges( - ) | rpl::filter([=](bool toggled) { - return toggled != privacy->archiveAndMuteCurrent(); - }) | rpl::start_with_next([=](bool toggled) { - privacy->update(toggled); - }, container->lifetime()); - - AddSkip(inner); - AddDividerText(inner, tr::lng_settings_auto_archive_about()); - - auto shown = rpl::single( - false - ) | rpl::then(session->api().globalPrivacy().showArchiveAndMute( - ) | rpl::filter(_1) | rpl::take(1)); - auto premium = Data::AmPremiumValue(&controller->session()); - - using namespace rpl::mappers; - wrap->toggleOn(rpl::combine( - std::move(shown), - std::move(premium), - _1 || _2)); -} - void SetupLocalPasscode( not_null controller, not_null container, @@ -838,6 +791,53 @@ void AddPrivacyButton( }); } +void SetupArchiveAndMute( + not_null controller, + not_null container) { + using namespace rpl::mappers; + + const auto wrap = container->add( + object_ptr>( + container, + object_ptr(container))); + const auto inner = wrap->entity(); + + AddSkip(inner); + AddSubsectionTitle(inner, tr::lng_settings_new_unknown()); + + const auto session = &controller->session(); + + const auto privacy = &session->api().globalPrivacy(); + privacy->reload(); + AddButton( + inner, + tr::lng_settings_auto_archive(), + st::settingsButtonNoIcon + )->toggleOn( + privacy->archiveAndMute() + )->toggledChanges( + ) | rpl::filter([=](bool toggled) { + return toggled != privacy->archiveAndMuteCurrent(); + }) | rpl::start_with_next([=](bool toggled) { + privacy->updateArchiveAndMute(toggled); + }, container->lifetime()); + + AddSkip(inner); + AddDividerText(inner, tr::lng_settings_auto_archive_about()); + + auto shown = rpl::single( + false + ) | rpl::then(session->api().globalPrivacy().showArchiveAndMute( + ) | rpl::filter(_1) | rpl::take(1)); + auto premium = Data::AmPremiumValue(&controller->session()); + + using namespace rpl::mappers; + wrap->toggleOn(rpl::combine( + std::move(shown), + std::move(premium), + _1 || _2)); +} + PrivacySecurity::PrivacySecurity( QWidget *parent, not_null controller) diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.h b/Telegram/SourceFiles/settings/settings_privacy_security.h index 350d6f1b5..83dd827ee 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.h +++ b/Telegram/SourceFiles/settings/settings_privacy_security.h @@ -35,6 +35,10 @@ void AddPrivacyButton( Fn()> controllerFactory, const style::SettingsButton *stOverride = nullptr); +void SetupArchiveAndMute( + not_null controller, + not_null container); + class PrivacySecurity : public Section { public: PrivacySecurity( diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index ba24fba90..52c3e67e3 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/localstorage.h" #include "storage/storage_account.h" #include "support/support_templates.h" +#include "settings/settings_advanced.h" #include "settings/settings_common.h" #include "settings/settings_calls.h" #include "settings/settings_information.h" @@ -63,6 +64,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_changes.h" #include "data/data_stories.h" #include "mainwidget.h" +#include "styles/style_chat.h" // popupMenuExpandedSeparator #include "styles/style_window.h" #include "styles/style_widgets.h" #include "styles/style_dialogs.h" @@ -602,7 +604,7 @@ void MainMenu::setupArchive() { } _contextMenu = base::make_unique_q( this, - st::popupMenuWithIcons); + st::popupMenuExpandedSeparator); const auto addAction = PeerMenuCallback([&]( PeerMenuCallback::Args a) { return _contextMenu->addAction( @@ -626,6 +628,12 @@ void MainMenu::setupArchive() { [f = folder()] { return f->chatsList(); }, addAction); + _contextMenu->addSeparator(); + Settings::PreloadArchiveSettings(&controller->session()); + addAction(tr::lng_context_archive_settings(tr::now), [=] { + controller->show(Box(Settings::ArchiveSettingsBox, controller)); + }, &st::menuIconManage); + _contextMenu->popup(QCursor::pos()); }, button->lifetime()); diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 9098b9112..92025ae40 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -61,6 +61,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_adaptive.h" // Adaptive::isThreeColumn #include "window/window_session_controller.h" #include "window/window_controller.h" +#include "settings/settings_advanced.h" #include "support/support_helper.h" #include "info/info_memento.h" #include "info/info_controller.h" @@ -1276,6 +1277,12 @@ void Filler::fillArchiveActions() { controller, [folder = _folder] { return folder->chatsList(); }, _addAction); + + _addAction({ .isSeparator = true }); + Settings::PreloadArchiveSettings(&controller->session()); + _addAction(tr::lng_context_archive_settings(tr::now), [=] { + controller->show(Box(Settings::ArchiveSettingsBox, controller)); + }, &st::menuIconManage); } } // namespace