diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 13b82fb8f8..104f7a5763 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1582,10 +1582,10 @@ PRIVATE settings/settings_search.h settings/builder/settings_builder.cpp settings/builder/settings_builder.h - settings/builder/settings_privacy_security_builder.cpp - settings/builder/settings_privacy_security_builder.h settings/sections/settings_notifications.cpp settings/sections/settings_notifications.h + settings/sections/settings_privacy_security.cpp + settings/sections/settings_privacy_security.h settings/settings_notifications_type.cpp settings/settings_notifications_type.h settings/settings_passkeys.cpp @@ -1596,8 +1596,6 @@ PRIVATE settings/settings_premium.h settings/settings_privacy_controllers.cpp settings/settings_privacy_controllers.h - settings/settings_privacy_security.cpp - settings/settings_privacy_security.h settings/settings_scale_preview.cpp settings/settings_scale_preview.h settings/settings_shortcuts.cpp diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp index 7541cdbc42..3675004127 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp @@ -22,7 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_common.h" #include "settings/settings_premium.h" #include "settings/settings_privacy_controllers.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "ui/boxes/peer_qr_box.h" #include "ui/controls/invite_link_buttons.h" #include "ui/controls/invite_link_label.h" diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 20bbb9f565..6e514a14b3 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -29,7 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rect.h" #include "passport/passport_encryption.h" #include "passport/passport_panel_edit_contact.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "styles/style_layers.h" #include "styles/style_passport.h" #include "styles/style_boxes.h" diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp index 5f6a43e957..f78275e45c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp @@ -24,7 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_options.h" #include "ui/painter.h" #include "chat_helpers/emoji_suggestions_widget.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "ui/boxes/choose_date_time.h" #include "ui/boxes/confirm_box.h" #include "boxes/passcode_box.h" diff --git a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp index 14cbfc0e6c..809a5a5ce7 100644 --- a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp +++ b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp @@ -63,7 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_power_saving.h" #include "settings/settings_premium.h" #include "ui/power_saving.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "settings/settings_websites.h" #include "boxes/connection_box.h" #include "boxes/local_storage_box.h" diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 4f1fb87fd1..fee4857594 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -63,7 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_folders.h" #include "settings/sections/settings_main.h" #include "settings/settings_privacy_controllers.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "settings/sections/settings_chat.h" #include "settings/settings_premium.h" #include "storage/storage_account.h" diff --git a/Telegram/SourceFiles/settings/builder/settings_builder.cpp b/Telegram/SourceFiles/settings/builder/settings_builder.cpp index c75e16e7bf..5c4b32518d 100644 --- a/Telegram/SourceFiles/settings/builder/settings_builder.cpp +++ b/Telegram/SourceFiles/settings/builder/settings_builder.cpp @@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/edit_privacy_box.h" #include "main/main_session.h" #include "settings/settings_common.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "ui/vertical_list.h" #include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" diff --git a/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.cpp b/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.cpp deleted file mode 100644 index 173409956d..0000000000 --- a/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.cpp +++ /dev/null @@ -1,684 +0,0 @@ -/* -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 "settings/builder/settings_privacy_security_builder.h" - -#include "api/api_authorizations.h" -#include "api/api_blocked_peers.h" -#include "api/api_cloud_password.h" -#include "api/api_global_privacy.h" -#include "api/api_self_destruct.h" -#include "api/api_sensitive_content.h" -#include "api/api_user_privacy.h" -#include "api/api_websites.h" -#include "apiwrap.h" -#include "main/main_app_config.h" -#include "ui/chat/chat_style.h" -#include "base/timer_rpl.h" -#include "boxes/edit_privacy_box.h" -#include "boxes/self_destruction_box.h" -#include "core/application.h" -#include "core/core_cloud_password.h" -#include "core/core_settings.h" -#include "data/components/passkeys.h" -#include "data/components/top_peers.h" -#include "data/data_peer_values.h" -#include "lang/lang_keys.h" -#include "main/main_domain.h" -#include "main/main_session.h" -#include "platform/platform_webauthn.h" -#include "settings/builder/settings_builder.h" -#include "settings/cloud_password/settings_cloud_password_email_confirm.h" -#include "settings/cloud_password/settings_cloud_password_input.h" -#include "settings/cloud_password/settings_cloud_password_start.h" -#include "settings/settings_active_sessions.h" -#include "settings/settings_blocked_peers.h" -#include "settings/settings_global_ttl.h" -#include "settings/settings_local_passcode.h" -#include "settings/sections/settings_main.h" -#include "settings/settings_passkeys.h" -#include "settings/settings_privacy_controllers.h" -#include "settings/settings_privacy_security.h" -#include "settings/settings_websites.h" -#include "storage/storage_domain.h" -#include "ui/layers/generic_box.h" -#include "ui/text/format_values.h" -#include "ui/vertical_list.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_menu_icons.h" -#include "styles/style_settings.h" - -namespace Settings::Builder { -namespace { - -constexpr auto kUpdateTimeout = 60 * crl::time(1000); - -using Privacy = Api::UserPrivacy; - -void BuildSecuritySection( - SectionBuilder &builder, - rpl::producer<> updateTrigger) { - const auto controller = builder.controller(); - const auto showOther = builder.showOther(); - const auto session = builder.session(); - - builder.addSkip(st::settingsPrivacySkip); - builder.addSubsectionTitle({ - .id = u"security/section"_q, - .title = tr::lng_settings_security(), - .keywords = { u"security"_q, u"password"_q, u"passcode"_q }, - }); - - using State = Core::CloudPasswordState; - enum class PasswordState { - Loading, - On, - Off, - Unconfirmed, - }; - auto passwordState = rpl::single( - PasswordState::Loading - ) | rpl::then(session->api().cloudPassword().state( - ) | rpl::map([](const State &state) { - return (!state.unconfirmedPattern.isEmpty()) - ? PasswordState::Unconfirmed - : state.hasPassword - ? PasswordState::On - : PasswordState::Off; - })) | rpl::distinct_until_changed(); - - auto cloudPasswordLabel = rpl::duplicate( - passwordState - ) | rpl::map([=](PasswordState state) { - return (state == PasswordState::Loading) - ? tr::lng_profile_loading(tr::now) - : (state == PasswordState::On) - ? tr::lng_settings_cloud_password_on(tr::now) - : tr::lng_settings_cloud_password_off(tr::now); - }); - - builder.addButton({ - .id = u"security/cloud_password"_q, - .title = tr::lng_settings_cloud_password_start_title(), - .icon = { &st::menuIcon2SV }, - .label = std::move(cloudPasswordLabel), - .onClick = [=, passwordState = base::duplicate(passwordState)] { - const auto state = rpl::variable( - base::duplicate(passwordState)).current(); - if (state == PasswordState::Loading) { - return; - } else if (state == PasswordState::On) { - showOther(CloudPasswordInputId()); - } else if (state == PasswordState::Off) { - showOther(CloudPasswordStartId()); - } else if (state == PasswordState::Unconfirmed) { - showOther(CloudPasswordEmailConfirmId()); - } - }, - .keywords = { u"password"_q, u"2fa"_q, u"two-factor"_q }, - }); - - session->api().cloudPassword().reload(); - - auto ttlLabel = rpl::combine( - session->api().selfDestruct().periodDefaultHistoryTTL(), - tr::lng_settings_ttl_after_off() - ) | rpl::map([](int ttl, const QString &none) { - return ttl ? Ui::FormatTTL(ttl) : none; - }); - - builder.addButton({ - .id = u"security/ttl"_q, - .title = tr::lng_settings_ttl_title(), - .icon = { &st::menuIconTTL }, - .label = std::move(ttlLabel), - .onClick = [showOther] { - showOther(GlobalTTLId()); - }, - .keywords = { u"ttl"_q, u"auto-delete"_q, u"timer"_q }, - }); - - builder.add([session, updateTrigger = rpl::duplicate(updateTrigger)](const WidgetContext &ctx) mutable { - std::move(updateTrigger) | rpl::on_next([=] { - session->api().selfDestruct().reload(); - }, ctx.container->lifetime()); - return SectionBuilder::WidgetToAdd{}; - }); - - auto passcodeHas = rpl::single(rpl::empty) | rpl::then( - session->domain().local().localPasscodeChanged() - ) | rpl::map([=] { - return session->domain().local().hasLocalPasscode(); - }); - auto passcodeLabel = rpl::combine( - tr::lng_settings_cloud_password_on(), - tr::lng_settings_cloud_password_off(), - rpl::duplicate(passcodeHas) - ) | rpl::map([](const QString &on, const QString &off, bool has) { - return has ? on : off; - }); - - builder.addButton({ - .id = u"security/passcode"_q, - .title = tr::lng_settings_passcode_title(), - .icon = { &st::menuIconLock }, - .label = std::move(passcodeLabel), - .onClick = [=, passcodeHas = std::move(passcodeHas)]() mutable { - if (rpl::variable(std::move(passcodeHas)).current()) { - showOther(LocalPasscodeCheckId()); - } else { - showOther(LocalPasscodeCreateId()); - } - }, - .keywords = { u"passcode"_q, u"lock"_q, u"pin"_q }, - }); - - if (session->passkeys().possible()) { - auto passkeysLabel = rpl::combine( - tr::lng_profile_loading(), - (rpl::single(rpl::empty_value()) - | rpl::then(session->passkeys().requestList())) | rpl::map([=] { - return session->passkeys().list().size(); - }) - ) | rpl::map([=](const QString &loading, int count) { - return !session->passkeys().listKnown() - ? loading - : count == 1 - ? session->passkeys().list().front().name - : count - ? QString::number(count) - : tr::lng_settings_cloud_password_off(tr::now); - }); - - auto passkeysShown = (rpl::single(rpl::empty_value()) - | rpl::then(session->passkeys().requestList())) | rpl::map([=] { - return Platform::WebAuthn::IsSupported() - || !session->passkeys().list().empty(); - }); - - builder.addButton({ - .id = u"security/passkeys"_q, - .title = tr::lng_settings_passkeys_title(), - .icon = { &st::menuIconPermissions }, - .label = std::move(passkeysLabel), - .onClick = [=] { - if (!session->passkeys().listKnown()) { - return; - } - const auto count = session->passkeys().list().size(); - if (count == 0) { - controller->show(Box([=](not_null box) { - PasskeysNoneBox(box, session); - box->boxClosing() | rpl::on_next([=] { - if (session->passkeys().list().size()) { - controller->showSettings(PasskeysId()); - } - }, box->lifetime()); - })); - } else { - controller->showSettings(PasskeysId()); - } - }, - .keywords = { u"passkeys"_q, u"biometric"_q }, - .shown = std::move(passkeysShown), - }); - } - - auto blockedCount = rpl::combine( - session->api().blockedPeers().slice( - ) | rpl::map([](const Api::BlockedPeers::Slice &data) { - return data.total; - }), - tr::lng_settings_no_blocked_users() - ) | rpl::map([](int count, const QString &none) { - return count ? QString::number(count) : none; - }); - - builder.addButton({ - .id = u"security/blocked"_q, - .title = tr::lng_settings_blocked_users(), - .icon = { &st::menuIconBlock }, - .label = std::move(blockedCount), - .onClick = [=] { - showOther(Blocked::Id()); - }, - .keywords = { u"blocked"_q, u"ban"_q }, - }); - - builder.add([session, updateTrigger = rpl::duplicate(updateTrigger)](const WidgetContext &ctx) mutable { - std::move(updateTrigger) | rpl::on_next([=] { - session->api().blockedPeers().reload(); - }, ctx.container->lifetime()); - return SectionBuilder::WidgetToAdd{}; - }); - - auto websitesCount = session->api().websites().totalValue(); - auto websitesShown = rpl::duplicate(websitesCount) | rpl::map( - rpl::mappers::_1 > 0); - auto websitesLabel = rpl::duplicate( - websitesCount - ) | rpl::filter(rpl::mappers::_1 > 0) | rpl::map([](int count) { - return QString::number(count); - }); - - builder.addButton({ - .id = u"security/websites"_q, - .title = tr::lng_settings_logged_in(), - .icon = { &st::menuIconIpAddress }, - .label = std::move(websitesLabel), - .onClick = [=] { - showOther(Websites::Id()); - }, - .keywords = { u"websites"_q, u"bots"_q, u"logged"_q }, - .shown = std::move(websitesShown), - }); - - builder.add([session, updateTrigger = rpl::duplicate(updateTrigger)](const WidgetContext &ctx) mutable { - std::move(updateTrigger) | rpl::on_next([=] { - session->api().websites().reload(); - }, ctx.container->lifetime()); - return SectionBuilder::WidgetToAdd{}; - }); - - auto sessionsCount = session->api().authorizations().totalValue( - ) | rpl::map([](int count) { - return count ? QString::number(count) : QString(); - }); - - builder.addButton({ - .id = u"security/sessions"_q, - .title = tr::lng_settings_show_sessions(), - .icon = { &st::menuIconDevices }, - .label = std::move(sessionsCount), - .onClick = [=] { - showOther(Sessions::Id()); - }, - .keywords = { u"sessions"_q, u"devices"_q, u"active"_q }, - }); - - builder.add([session, updateTrigger = std::move(updateTrigger)](const WidgetContext &ctx) mutable { - std::move(updateTrigger) | rpl::on_next([=] { - session->api().authorizations().reload(); - }, ctx.container->lifetime()); - return SectionBuilder::WidgetToAdd{}; - }); - - builder.addSkip(); - builder.addDividerText(tr::lng_settings_sessions_about()); -} - -void BuildPrivacySection(SectionBuilder &builder) { - const auto controller = builder.controller(); - const auto session = builder.session(); - - builder.addSkip(st::settingsPrivacySkip); - builder.addSubsectionTitle({ - .id = u"privacy/section"_q, - .title = tr::lng_settings_privacy_title(), - .keywords = { u"privacy"_q, u"visibility"_q }, - }); - - using Key = Privacy::Key; - - builder.addPrivacyButton({ - .id = u"privacy/phone_number"_q, - .title = tr::lng_settings_phone_number_privacy(), - .key = Key::PhoneNumber, - .controllerFactory = [=] { - return std::make_unique(controller); - }, - .keywords = { u"phone"_q, u"number"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/last_seen"_q, - .title = tr::lng_settings_last_seen(), - .key = Key::LastSeen, - .controllerFactory = [=] { - return std::make_unique(session); - }, - .keywords = { u"last seen"_q, u"online"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/profile_photo"_q, - .title = tr::lng_settings_profile_photo_privacy(), - .key = Key::ProfilePhoto, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"photo"_q, u"avatar"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/forwards"_q, - .title = tr::lng_settings_forwards_privacy(), - .key = Key::Forwards, - .controllerFactory = [=] { - return std::make_unique(controller); - }, - .keywords = { u"forwards"_q, u"link"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/calls"_q, - .title = tr::lng_settings_calls(), - .key = Key::Calls, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"calls"_q, u"voice"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/voices"_q, - .title = tr::lng_settings_voices_privacy(), - .key = Key::Voices, - .controllerFactory = [=] { - return std::make_unique(session); - }, - .premium = true, - .keywords = { u"voice"_q, u"messages"_q }, - }); - - const auto privacy = &session->api().globalPrivacy(); - auto messagesLabel = rpl::combine( - privacy->newRequirePremium(), - privacy->newChargeStars() - ) | rpl::map([=](bool requirePremium, int chargeStars) { - return chargeStars - ? tr::lng_edit_privacy_paid() - : requirePremium - ? tr::lng_edit_privacy_contacts_and_premium() - : tr::lng_edit_privacy_everyone(); - }) | rpl::flatten_latest(); - - const auto messagesPremium = !session->appConfig().newRequirePremiumFree(); - const auto messagesButton = builder.addButton({ - .id = u"privacy/messages"_q, - .title = tr::lng_settings_messages_privacy(), - .st = &st::settingsButtonNoIcon, - .label = rpl::duplicate(messagesLabel), - .onClick = [=] { - controller->show(Box(EditMessagesPrivacyBox, controller, QString())); - }, - .keywords = { u"messages"_q, u"new"_q, u"unknown"_q }, - }); - if (messagesPremium && messagesButton) { - AddPrivacyPremiumStar( - messagesButton, - session, - std::move(messagesLabel), - st::settingsButtonNoIcon.padding); - } - - builder.addPrivacyButton({ - .id = u"privacy/birthday"_q, - .title = tr::lng_settings_birthday_privacy(), - .key = Key::Birthday, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"birthday"_q, u"age"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/gifts"_q, - .title = tr::lng_settings_gifts_privacy(), - .key = Key::GiftsAutoSave, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"gifts"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/bio"_q, - .title = tr::lng_settings_bio_privacy(), - .key = Key::About, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"bio"_q, u"about"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/saved_music"_q, - .title = tr::lng_settings_saved_music_privacy(), - .key = Key::SavedMusic, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"music"_q, u"saved"_q }, - }); - - builder.addPrivacyButton({ - .id = u"privacy/groups"_q, - .title = tr::lng_settings_groups_invite(), - .key = Key::Invites, - .controllerFactory = [] { - return std::make_unique(); - }, - .keywords = { u"groups"_q, u"invite"_q }, - }); - - session->api().userPrivacy().reload(Privacy::Key::AddedByPhone); - - builder.addSkip(st::settingsPrivacySecurityPadding); - builder.addDivider(); -} - -void BuildArchiveAndMuteSection(SectionBuilder &builder) { - const auto session = builder.session(); - const auto privacy = &session->api().globalPrivacy(); - - privacy->reload(); - - auto shown = rpl::single( - false - ) | rpl::then(privacy->showArchiveAndMute( - ) | rpl::filter(rpl::mappers::_1) | rpl::take(1)); - auto premium = Data::AmPremiumValue(session); - - builder.scope([&] { - builder.addSkip(); - builder.addSubsectionTitle({ - .id = u"privacy/new_unknown"_q, - .title = tr::lng_settings_new_unknown(), - .keywords = { u"unknown"_q, u"archive"_q, u"mute"_q }, - }); - - const auto toggle = builder.addButton({ - .id = u"privacy/archive_and_mute"_q, - .title = tr::lng_settings_auto_archive(), - .st = &st::settingsButtonNoIcon, - .toggled = privacy->archiveAndMute(), - .keywords = { u"archive"_q, u"mute"_q, u"unknown"_q }, - }); - - if (toggle) { - toggle->toggledChanges( - ) | rpl::filter([=](bool toggled) { - return toggled != privacy->archiveAndMuteCurrent(); - }) | rpl::on_next([=](bool toggled) { - privacy->updateArchiveAndMute(toggled); - }, toggle->lifetime()); - } - - builder.addSkip(); - builder.addDividerText(tr::lng_settings_auto_archive_about()); - }, rpl::combine( - std::move(shown), - std::move(premium), - rpl::mappers::_1 || rpl::mappers::_2)); -} - -void BuildBotsAndWebsitesSection(SectionBuilder &builder) { - const auto controller = builder.controller(); - const auto session = builder.session(); - - builder.addSkip(); - builder.addSubsectionTitle({ - .id = u"privacy/bots"_q, - .title = tr::lng_settings_security_bots(), - .keywords = { u"bots"_q, u"payment"_q, u"websites"_q }, - }); - - builder.addButton({ - .id = u"privacy/bots_payment"_q, - .title = tr::lng_settings_clear_payment_info(), - .st = &st::settingsButtonNoIcon, - .onClick = [=] { - controller->show(ClearPaymentInfoBox(session)); - }, - .keywords = { u"payment"_q, u"bots"_q, u"clear"_q }, - }); - - builder.addSkip(); - builder.addDivider(); -} - -void BuildTopPeersSection(SectionBuilder &builder) { - const auto session = builder.session(); - - builder.addSkip(); - builder.addSubsectionTitle({ - .id = u"privacy/top_peers"_q, - .title = tr::lng_settings_top_peers_title(), - .keywords = { u"suggest"_q, u"contacts"_q, u"frequent"_q }, - }); - - const auto toggle = builder.addButton({ - .id = u"privacy/top_peers_toggle"_q, - .title = tr::lng_settings_top_peers_suggest(), - .st = &st::settingsButtonNoIcon, - .toggled = rpl::single( - rpl::empty - ) | rpl::then( - session->topPeers().updates() - ) | rpl::map([=] { - return !session->topPeers().disabled(); - }), - .keywords = { u"suggest"_q, u"contacts"_q }, - }); - - if (toggle) { - toggle->toggledChanges( - ) | rpl::filter([=](bool enabled) { - return enabled == session->topPeers().disabled(); - }) | rpl::on_next([=](bool enabled) { - session->topPeers().toggleDisabled(!enabled); - }, toggle->lifetime()); - } - - builder.addSkip(); - builder.addDividerText(tr::lng_settings_top_peers_about()); -} - -void BuildSelfDestructionSection( - SectionBuilder &builder, - rpl::producer<> updateTrigger) { - const auto controller = builder.controller(); - const auto session = builder.session(); - - builder.addSkip(); - builder.addSubsectionTitle({ - .id = u"privacy/self_destruct"_q, - .title = tr::lng_settings_destroy_title(), - .keywords = { u"delete"_q, u"destroy"_q, u"inactive"_q, u"account"_q }, - }); - - builder.add([session, updateTrigger = std::move(updateTrigger)](const WidgetContext &ctx) mutable { - std::move(updateTrigger) | rpl::on_next([=] { - session->api().selfDestruct().reload(); - }, ctx.container->lifetime()); - return SectionBuilder::WidgetToAdd{}; - }); - - auto label = session->api().selfDestruct().daysAccountTTL( - ) | rpl::map(SelfDestructionBox::DaysLabel); - - builder.addButton({ - .id = u"privacy/self_destruct_button"_q, - .title = tr::lng_settings_destroy_if(), - .st = &st::settingsButtonNoIcon, - .label = std::move(label), - .onClick = [=] { - controller->show(Box( - session, - SelfDestructionBox::Type::Account, - session->api().selfDestruct().daysAccountTTL())); - }, - .keywords = { u"delete"_q, u"destroy"_q, u"inactive"_q }, - }); - - builder.addSkip(); -} - -void BuildConfirmationExtensions(SectionBuilder &builder) { - const auto controller = builder.controller(); - const auto hasExtensions = !Core::App().settings().noWarningExtensions().empty() - || !Core::App().settings().ipRevealWarning(); - - if (!hasExtensions) { - return; - } - - builder.addSkip(); - builder.addSubsectionTitle({ - .id = u"privacy/file_confirmations"_q, - .title = tr::lng_settings_file_confirmations(), - .keywords = { u"extensions"_q, u"files"_q, u"confirmations"_q }, - }); - - builder.addButton({ - .id = u"privacy/file_confirmations_button"_q, - .title = tr::lng_settings_edit_extensions(), - .st = &st::settingsButtonNoIcon, - .onClick = [=] { - controller->show(Box(OpenFileConfirmationsBox)); - }, - .keywords = { u"extensions"_q, u"files"_q, u"confirmations"_q }, - }); - - builder.addSkip(); - builder.addDividerText(tr::lng_settings_edit_extensions_about()); -} - -void BuildPrivacySecuritySectionContent(SectionBuilder &builder) { - auto updateOnTick = rpl::single( - ) | rpl::then(base::timer_each(kUpdateTimeout)); - const auto trigger = [&] { - return rpl::duplicate(updateOnTick); - }; - - BuildSecuritySection(builder, trigger()); - BuildPrivacySection(builder); - BuildArchiveAndMuteSection(builder); - BuildBotsAndWebsitesSection(builder); - BuildConfirmationExtensions(builder); - BuildTopPeersSection(builder); - BuildSelfDestructionSection(builder, trigger()); -} - -const auto kMeta = BuildHelper({ - .id = PrivacySecurity::Id(), - .parentId = Main::Id(), - .title = &tr::lng_settings_section_privacy, - .icon = &st::menuIconLock, -}, [](SectionBuilder &builder) { - BuildPrivacySecuritySectionContent(builder); -}); - -} // namespace - -SectionBuildMethod PrivacySecuritySection = kMeta.build; - -} // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.h b/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.h deleted file mode 100644 index 671ff7e6fa..0000000000 --- a/Telegram/SourceFiles/settings/builder/settings_privacy_security_builder.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -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 - -#include "settings/settings_common.h" - -namespace Ui { -class VerticalLayout; -} // namespace Ui - -namespace Window { -class SessionController; -} // namespace Window - -namespace Settings::Builder { - -extern SectionBuildMethod PrivacySecuritySection; - -} // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/sections/settings_advanced.cpp b/Telegram/SourceFiles/settings/sections/settings_advanced.cpp index 20d4e7cc8e..38a6f13761 100644 --- a/Telegram/SourceFiles/settings/sections/settings_advanced.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_advanced.cpp @@ -38,7 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/sections/settings_chat.h" #include "settings/settings_experimental.h" #include "settings/settings_power_saving.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "storage/localstorage.h" #include "storage/storage_domain.h" #include "tray.h" diff --git a/Telegram/SourceFiles/settings/sections/settings_chat.cpp b/Telegram/SourceFiles/settings/sections/settings_chat.cpp index a36a6a08a9..a091c4d82a 100644 --- a/Telegram/SourceFiles/settings/sections/settings_chat.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_chat.cpp @@ -11,7 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/builder/settings_builder.h" #include "settings/sections/settings_advanced.h" #include "settings/sections/settings_main.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "settings/settings_experimental.h" #include "settings/settings_shortcuts.h" #include "boxes/abstract_box.h" diff --git a/Telegram/SourceFiles/settings/sections/settings_main.cpp b/Telegram/SourceFiles/settings/sections/settings_main.cpp index 8c61eeeda9..c0618bb4de 100644 --- a/Telegram/SourceFiles/settings/sections/settings_main.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_main.cpp @@ -52,7 +52,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/sections/settings_notifications.h" #include "settings/settings_power_saving.h" #include "settings/settings_premium.h" -#include "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" #include "settings/settings_scale_preview.h" #include "storage/localstorage.h" #include "ui/basic_click_handlers.h" diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp similarity index 64% rename from Telegram/SourceFiles/settings/settings_privacy_security.cpp rename to Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp index 9a958049fa..56b3dd9116 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp @@ -5,69 +5,70 @@ 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 "settings/settings_privacy_security.h" +#include "settings/sections/settings_privacy_security.h" -#include "settings/builder/settings_privacy_security_builder.h" #include "api/api_authorizations.h" +#include "api/api_blocked_peers.h" #include "api/api_cloud_password.h" +#include "api/api_global_privacy.h" #include "api/api_self_destruct.h" #include "api/api_sensitive_content.h" -#include "api/api_global_privacy.h" #include "api/api_websites.h" +#include "apiwrap.h" +#include "base/system_unlock.h" +#include "base/timer_rpl.h" +#include "boxes/edit_privacy_box.h" +#include "boxes/passcode_box.h" +#include "boxes/self_destruction_box.h" +#include "core/application.h" +#include "core/click_handler_types.h" +#include "core/core_cloud_password.h" +#include "core/core_settings.h" +#include "core/update_checker.h" #include "data/components/passkeys.h" +#include "data/components/top_peers.h" +#include "data/data_channel.h" +#include "data/data_chat.h" +#include "data/data_peer_values.h" +#include "data/data_session.h" +#include "history/view/media/history_view_media_common.h" +#include "ui/chat/chat_style.h" +#include "lang/lang_keys.h" +#include "main/main_app_config.h" +#include "main/main_domain.h" +#include "main/main_session.h" #include "platform/platform_webauthn.h" +#include "settings/builder/settings_builder.h" #include "settings/cloud_password/settings_cloud_password_email_confirm.h" #include "settings/cloud_password/settings_cloud_password_input.h" -#include "settings/cloud_password/settings_cloud_password_login_email.h" #include "settings/cloud_password/settings_cloud_password_start.h" +#include "settings/sections/settings_main.h" #include "settings/settings_active_sessions.h" #include "settings/settings_blocked_peers.h" #include "settings/settings_global_ttl.h" #include "settings/settings_local_passcode.h" #include "settings/settings_passkeys.h" -#include "settings/settings_premium.h" // Settings::ShowPremium. +#include "settings/settings_premium.h" #include "settings/settings_privacy_controllers.h" #include "settings/settings_websites.h" -#include "base/system_unlock.h" -#include "base/timer_rpl.h" -#include "boxes/passcode_box.h" +#include "storage/storage_domain.h" #include "ui/boxes/confirm_box.h" -#include "ui/layers/generic_box.h" -#include "boxes/self_destruction_box.h" -#include "core/application.h" -#include "core/core_settings.h" -#include "history/view/media/history_view_media_common.h" -#include "ui/basic_click_handlers.h" -#include "ui/chat/chat_style.h" #include "ui/effects/premium_graphics.h" -#include "ui/effects/premium_top_bar.h" +#include "ui/layers/generic_box.h" +#include "ui/rect.h" #include "ui/text/format_values.h" #include "ui/text/text_utilities.h" #include "ui/toast/toast.h" -#include "ui/wrap/slide_wrap.h" -#include "ui/wrap/fade_wrap.h" -#include "ui/widgets/fields/input_field.h" -#include "ui/widgets/shadow.h" -#include "ui/widgets/checkbox.h" #include "ui/vertical_list.h" -#include "ui/rect.h" -#include "calls/calls_instance.h" -#include "core/update_checker.h" -#include "lang/lang_keys.h" -#include "data/components/top_peers.h" -#include "data/data_session.h" -#include "data/data_chat.h" -#include "data/data_channel.h" -#include "data/data_peer_values.h" -#include "main/main_app_config.h" -#include "main/main_domain.h" -#include "main/main_session.h" -#include "storage/storage_domain.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/checkbox.h" +#include "ui/widgets/fields/input_field.h" +#include "ui/wrap/slide_wrap.h" +#include "ui/wrap/vertical_layout.h" #include "window/window_session_controller.h" -#include "apiwrap.h" -#include "styles/style_settings.h" -#include "styles/style_menu_icons.h" #include "styles/style_layers.h" +#include "styles/style_menu_icons.h" +#include "styles/style_settings.h" #include #include @@ -98,7 +99,7 @@ using Privacy = Api::UserPrivacy; void AddPremiumStar( not_null button, - not_null session, + not_null<::Main::Session*> session, rpl::producer label, const QMargins &padding) { const auto badge = Ui::CreateChild(button.get()); @@ -226,139 +227,59 @@ rpl::producer BlockedPeersCount(not_null<::Main::Session*> session) { }); } -} // namespace +void ClearPaymentInfoBoxBuilder( + not_null box, + not_null<::Main::Session*> session) { + box->setTitle(tr::lng_clear_payment_info_title()); -rpl::producer PrivacyButtonLabel( - not_null<::Main::Session*> session, - Privacy::Key key) { - return PrivacyString(session, key); -} + const auto checkboxPadding = style::margins( + st::boxRowPadding.left(), + st::boxRowPadding.left(), + st::boxRowPadding.right(), + st::boxRowPadding.bottom()); + const auto label = box->addRow(object_ptr( + box, + tr::lng_clear_payment_info_sure(), + st::boxLabel)); + const auto shipping = box->addRow( + object_ptr( + box, + tr::lng_clear_payment_info_shipping(tr::now), + true, + st::defaultBoxCheckbox), + checkboxPadding); + const auto payment = box->addRow( + object_ptr( + box, + tr::lng_clear_payment_info_payment(tr::now), + true, + st::defaultBoxCheckbox), + checkboxPadding); -void AddPrivacyPremiumStar( - not_null button, - not_null session, - rpl::producer label, - const QMargins &padding) { - const auto badge = Ui::CreateChild(button.get()); - badge->showOn(Data::AmPremiumValue(session)); - const auto sampleLeft = st::settingsColorSamplePadding.left(); - const auto badgeLeft = padding.left() + sampleLeft; + using Flags = MTPpayments_ClearSavedInfo::Flags; + const auto flags = box->lifetime().make_state(); - const auto factor = style::DevicePixelRatio(); - const auto size = Size(st::settingsButtonNoIcon.style.font->ascent); - auto starImage = QImage( - size * factor, - QImage::Format_ARGB32_Premultiplied); - starImage.setDevicePixelRatio(factor); - starImage.fill(Qt::transparent); - { - auto p = QPainter(&starImage); - auto star = QSvgRenderer( - Ui::Premium::ColorizedSvg(Ui::Premium::ButtonGradientStops())); - star.render(&p, Rect(size)); - } - - badge->resize(starImage.size() / style::DevicePixelRatio()); - badge->paintRequest( - ) | rpl::on_next([=, star = std::move(starImage)] { - auto p = QPainter(badge); - p.drawImage(0, 0, star); - }, badge->lifetime()); - - rpl::combine( - button->sizeValue(), - std::move(label) - ) | rpl::on_next([=](const QSize &s, const QString &) { - if (s.isNull()) { - return; - } - badge->moveToLeft( - button->fullTextWidth() + badgeLeft, - (s.height() - badge->height()) / 2); - }, badge->lifetime()); -} - -void SetupPrivacy( - not_null controller, - not_null container, - rpl::producer<> updateTrigger) { - Ui::AddSkip(container, st::settingsPrivacySkip); - Ui::AddSubsectionTitle(container, tr::lng_settings_privacy_title()); - - const auto session = &controller->session(); - - using Key = Privacy::Key; - const auto add = [&]( - rpl::producer label, - Key key, - auto controllerFactory) { - return AddPrivacyButton( - controller, - container, - std::move(label), - {}, - key, - controllerFactory); - }; - add( - tr::lng_settings_phone_number_privacy(), - Key::PhoneNumber, - [=] { return std::make_unique( - controller); }); - add( - tr::lng_settings_last_seen(), - Key::LastSeen, - [=] { return std::make_unique( - session); }); - add( - tr::lng_settings_profile_photo_privacy(), - Key::ProfilePhoto, - [] { return std::make_unique(); }); - add( - tr::lng_settings_forwards_privacy(), - Key::Forwards, - [=] { return std::make_unique( - controller); }); - add( - tr::lng_settings_calls(), - Key::Calls, - [] { return std::make_unique(); }); - { - const auto &phrase = tr::lng_settings_voices_privacy; - const auto &st = st::settingsButtonNoIcon; - auto callback = [=] { - return std::make_unique(session); - }; - const auto voices = add(phrase(), Key::Voices, std::move(callback)); - AddPremiumStar(voices, session, phrase(), st.padding); - } - AddMessagesPrivacyButton(controller, container); - add( - tr::lng_settings_birthday_privacy(), - Key::Birthday, - [] { return std::make_unique(); }); - add( - tr::lng_settings_gifts_privacy(), - Key::GiftsAutoSave, - [=] { return std::make_unique(); }); - add( - tr::lng_settings_bio_privacy(), - Key::About, - [] { return std::make_unique(); }); - add( - tr::lng_settings_saved_music_privacy(), - Key::SavedMusic, - [] { return std::make_unique(); }); - add( - tr::lng_settings_groups_invite(), - Key::Invites, - [] { return std::make_unique(); }); - - session->api().userPrivacy().reload( - Api::UserPrivacy::Key::AddedByPhone); - - Ui::AddSkip(container, st::settingsPrivacySecurityPadding); - Ui::AddDivider(container); + box->addButton(tr::lng_clear_payment_info_clear(), [=] { + using Flag = Flags::Enum; + *flags = (shipping->checked() ? Flag::f_info : Flag(0)) + | (payment->checked() ? Flag::f_credentials : Flag(0)); + delete label; + delete shipping; + delete payment; + box->addRow(object_ptr( + box, + tr::lng_clear_payment_info_confirm(), + st::boxLabel)); + box->clearButtons(); + box->addButton(tr::lng_clear_payment_info_clear(), [=] { + session->api().request(MTPpayments_ClearSavedInfo( + MTP_flags(*flags) + )).send(); + box->closeBox(); + }, st::attentionBoxButton); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + }, st::attentionBoxButton); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); } void SetupLocalPasscode( @@ -543,7 +464,7 @@ void SetupLoginEmail( auto email = session->api().cloudPassword().state( ) | rpl::map([](const State &state) { return state.loginEmailPattern; }); auto text = tr::lng_settings_cloud_login_email_section_title(); - auto label = rpl::duplicate(email) | rpl::map([](QString email) { + auto labelText = rpl::duplicate(email) | rpl::map([](QString email) { if (email.contains(' ')) { return tr::lng_settings_cloud_password_off(tr::now, tr::rich); } @@ -556,7 +477,7 @@ void SetupLoginEmail( rpl::duplicate(text), st, { &st::menuIconRecoveryEmail }); - CreateRightLabel(button, std::move(label), st, std::move(text)); + CreateRightLabel(button, std::move(labelText), st, std::move(text)); button->addClickHandler([=] { UrlClickHandler::Open(u"tg://settings/login_email"_q); @@ -576,176 +497,6 @@ void SetupLoginEmail( session->api().cloudPassword().reload(); } -void SetupTopPeers( - not_null controller, - not_null container) { - Ui::AddSkip(container); - Ui::AddSubsectionTitle(container, tr::lng_settings_top_peers_title()); - - const auto session = &controller->session(); - - container->add(object_ptr