From 86398de8bd5712146652f6c8cc81749fc208d955 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 14 Jan 2026 17:24:08 +0400 Subject: [PATCH] Rewrite settings_passkeys to new builder pattern Co-Authored-By: Claude Opus 4.5 --- Telegram/CMakeLists.txt | 4 +- .../core/deep_links/deep_links_settings.cpp | 2 +- .../{ => sections}/settings_passkeys.cpp | 138 ++++++++++-------- .../settings/sections/settings_passkeys.h | 62 ++++++++ .../sections/settings_privacy_security.cpp | 2 +- .../SourceFiles/settings/settings_passkeys.h | 28 ---- 6 files changed, 146 insertions(+), 90 deletions(-) rename Telegram/SourceFiles/settings/{ => sections}/settings_passkeys.cpp (85%) create mode 100644 Telegram/SourceFiles/settings/sections/settings_passkeys.h delete mode 100644 Telegram/SourceFiles/settings/settings_passkeys.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 85b9799f76..8688821442 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1588,8 +1588,8 @@ PRIVATE settings/sections/settings_privacy_security.h settings/sections/settings_notifications_type.cpp settings/sections/settings_notifications_type.h - settings/settings_passkeys.cpp - settings/settings_passkeys.h + settings/sections/settings_passkeys.cpp + settings/sections/settings_passkeys.h settings/settings_power_saving.cpp settings/settings_power_saving.h settings/settings_premium.cpp diff --git a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp index ac573dc69b..8a1a51fdab 100644 --- a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp +++ b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp @@ -44,7 +44,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/sections/settings_business.h" #include "settings/sections/settings_calls.h" #include "settings/sections/settings_chat.h" -#include "settings/settings_passkeys.h" +#include "settings/sections/settings_passkeys.h" #include "data/components/passkeys.h" #include "calls/calls_box_controller.h" #include "settings/sections/settings_credits.h" diff --git a/Telegram/SourceFiles/settings/settings_passkeys.cpp b/Telegram/SourceFiles/settings/sections/settings_passkeys.cpp similarity index 85% rename from Telegram/SourceFiles/settings/settings_passkeys.cpp rename to Telegram/SourceFiles/settings/sections/settings_passkeys.cpp index c62796b81a..2571aa684e 100644 --- a/Telegram/SourceFiles/settings/settings_passkeys.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_passkeys.cpp @@ -5,76 +5,81 @@ 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_passkeys.h" +#include "settings/sections/settings_passkeys.h" +#include "base/unixtime.h" #include "core/application.h" -#include "settings/cloud_password/settings_cloud_password_common.h" -#include "settings/settings_common.h" -#include "settings/settings_common_session.h" #include "data/components/passkeys.h" #include "data/data_session.h" -#include "window/window_controller.h" -#include "window/window_session_controller.h" +#include "data/stickers/data_custom_emoji.h" +#include "lang/lang_keys.h" +#include "lottie/lottie_icon.h" #include "main/main_session.h" #include "platform/platform_webauthn.h" -#include "ui/layers/generic_box.h" +#include "settings/cloud_password/settings_cloud_password_common.h" +#include "settings/sections/settings_privacy_security.h" +#include "settings/settings_builder.h" +#include "settings/settings_common.h" +#include "settings/settings_common_session.h" #include "ui/boxes/confirm_box.h" +#include "ui/layers/generic_box.h" #include "ui/painter.h" #include "ui/rect.h" +#include "ui/text/custom_emoji_instance.h" #include "ui/text/text_utilities.h" #include "ui/vertical_list.h" #include "ui/widgets/buttons.h" #include "ui/widgets/popup_menu.h" #include "ui/widgets/menu/menu_add_action_callback.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" -#include "ui/wrap/vertical_layout.h" #include "ui/wrap/slide_wrap.h" -#include "lang/lang_keys.h" -#include "lottie/lottie_icon.h" -#include "base/unixtime.h" -#include "data/stickers/data_custom_emoji.h" -#include "ui/text/custom_emoji_instance.h" +#include "ui/wrap/vertical_layout.h" +#include "window/window_controller.h" +#include "window/window_session_controller.h" #include "styles/style_boxes.h" #include "styles/style_channel_earn.h" #include "styles/style_chat.h" #include "styles/style_layers.h" +#include "styles/style_menu_icons.h" #include "styles/style_premium.h" #include "styles/style_settings.h" -#include "styles/style_menu_icons.h" namespace Settings { +namespace { -class Passkeys : public Section { -public: - Passkeys( - QWidget *parent, - not_null controller); +using namespace Builder; - [[nodiscard]] rpl::producer title() override; +void BuildPasskeysSection(SectionBuilder &builder) { + builder.add(nullptr, [] { + return SearchEntry{ + .id = u"passkeys/create"_q, + .title = tr::lng_settings_passkeys_button(tr::now), + .keywords = { u"add"_q, u"register"_q, u"create"_q }, + }; + }); + builder.add(nullptr, [] { + return SearchEntry{ + .id = u"passkeys/list"_q, + .title = tr::lng_settings_passkeys_title(tr::now), + .keywords = { u"passkeys"_q, u"biometric"_q, u"authentication"_q }, + }; + }); +} - [[nodiscard]] rpl::producer<> showFinishes() const { - return _showFinished.events(); - } +const auto kMeta = BuildHelper({ + .id = Passkeys::Id(), + .parentId = PrivacySecurity::Id(), + .title = &tr::lng_settings_passkeys_title, + .icon = &st::menuIconPermissions, +}, [](SectionBuilder &builder) { + BuildPasskeysSection(builder); +}); - const Ui::RoundRect *bottomSkipRounding() const override { - return &_bottomSkipRounding; - } - -private: - void showFinished() override; - - void setupContent(); - - QPointer _addButton; - Ui::RoundRect _bottomSkipRounding; - - rpl::event_stream<> _showFinished; - -}; +} // namespace void PasskeysNoneBox( not_null box, - not_null session) { + not_null<::Main::Session*> session) { box->setWidth(st::boxWideWidth); box->setNoContentMargin(true); box->setCloseByEscape(true); @@ -236,11 +241,13 @@ Passkeys::Passkeys( QWidget *parent, not_null controller) : Section(parent, controller) +, _container(Ui::CreateChild(this)) , _bottomSkipRounding(st::boxRadius, st::boxDividerBg) { setupContent(); } void Passkeys::showFinished() { + Section::showFinished(); _showFinished.fire({}); if (_addButton) { controller()->checkHighlightControl( @@ -255,30 +262,29 @@ rpl::producer Passkeys::title() { } void Passkeys::setupContent() { - const auto content = Ui::CreateChild(this); const auto session = &controller()->session(); CloudPassword::SetupHeader( - content, + _container, u"passkeys"_q, - showFinishes(), + _showFinished.events(), rpl::single(QString()), tr::lng_settings_passkeys_about()); - Ui::AddSkip(content); + Ui::AddSkip(_container); - const auto container = content->add( - object_ptr(content)); + const auto passkeysListContainer = _container->add( + object_ptr(_container)); const auto &st = st::peerListBoxItem; const auto nameStyle = &st.nameStyle; const auto rebuild = [=] { - while (container->count()) { - delete container->widgetAt(0); + while (passkeysListContainer->count()) { + delete passkeysListContainer->widgetAt(0); } for (const auto &passkey : session->passkeys().list()) { - const auto button = container->add( - object_ptr(container)); + const auto button = passkeysListContainer->add( + object_ptr(passkeysListContainer)); button->resize(button->width(), st.height); const auto menu = Ui::CreateChild( button, @@ -391,15 +397,15 @@ void Passkeys::setupContent() { }); button->showChildren(); } - container->showChildren(); - container->resizeToWidth(content->width()); + passkeysListContainer->showChildren(); + passkeysListContainer->resizeToWidth(_container->width()); }; - const auto buttonWrap = content->add( + const auto buttonWrap = _container->add( object_ptr>( - content, + _container, CreateButtonWithIcon( - content, + _container, tr::lng_settings_passkeys_button(), st::settingsButtonActive, { &st::settingsIconPasskeys }))); @@ -412,12 +418,12 @@ void Passkeys::setupContent() { buttonWrap->finishAnimating(); session->passkeys().requestList( - ) | rpl::on_next(rebuild, content->lifetime()); + ) | rpl::on_next(rebuild, _container->lifetime()); rebuild(); - Ui::AddSkip(content); + Ui::AddSkip(_container); const auto label = Ui::AddDividerText( - content, + _container, tr::lng_settings_passkeys_button_about( lt_link, tr::lng_channel_earn_about_link( @@ -433,11 +439,27 @@ void Passkeys::setupContent() { controller()->show(Box(PasskeysNoneBox, session)); return false; }); - Ui::ResizeFitChild(this, content); + + widthValue( + ) | rpl::on_next([=](int width) { + _container->resizeToWidth(width); + }, _container->lifetime()); + + _container->heightValue( + ) | rpl::on_next([=](int height) { + resize(width(), height); + }, _container->lifetime()); + + build(_container, Builder::PasskeysSection); } Type PasskeysId() { return Passkeys::Id(); } +namespace Builder { + +SectionBuildMethod PasskeysSection = kMeta.build; + +} // namespace Builder } // namespace Settings diff --git a/Telegram/SourceFiles/settings/sections/settings_passkeys.h b/Telegram/SourceFiles/settings/sections/settings_passkeys.h new file mode 100644 index 0000000000..d9de4f8f6f --- /dev/null +++ b/Telegram/SourceFiles/settings/sections/settings_passkeys.h @@ -0,0 +1,62 @@ +/* +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_session.h" +#include "settings/settings_type.h" + +namespace Ui { +class GenericBox; +class SettingsButton; +class VerticalLayout; +} // namespace Ui + +namespace Main { +class Session; +} // namespace Main + +namespace Settings { + +class Passkeys : public Section { +public: + Passkeys( + QWidget *parent, + not_null controller); + + void showFinished() override; + + [[nodiscard]] rpl::producer title() override; + + const Ui::RoundRect *bottomSkipRounding() const override { + return &_bottomSkipRounding; + } + +private: + void setupContent(); + + const not_null _container; + + QPointer _addButton; + Ui::RoundRect _bottomSkipRounding; + + rpl::event_stream<> _showFinished; + +}; + +void PasskeysNoneBox( + not_null box, + not_null<::Main::Session*> session); + +Type PasskeysId(); + +namespace Builder { + +extern SectionBuildMethod PasskeysSection; + +} // namespace Builder +} // namespace Settings diff --git a/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp index 7d355b2a71..3287460357 100644 --- a/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/sections/settings_privacy_security.cpp @@ -47,7 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/sections/settings_blocked_peers.h" #include "settings/sections/settings_global_ttl.h" #include "settings/sections/settings_local_passcode.h" -#include "settings/settings_passkeys.h" +#include "settings/sections/settings_passkeys.h" #include "settings/settings_premium.h" #include "settings/settings_privacy_controllers.h" #include "settings/settings_websites.h" diff --git a/Telegram/SourceFiles/settings/settings_passkeys.h b/Telegram/SourceFiles/settings/settings_passkeys.h deleted file mode 100644 index 612d507ab0..0000000000 --- a/Telegram/SourceFiles/settings/settings_passkeys.h +++ /dev/null @@ -1,28 +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_type.h" - -namespace Ui { -class GenericBox; -} // namespace Ui - -namespace Main { -class Session; -} // namespace Main - -namespace Settings { - -void PasskeysNoneBox( - not_null box, - not_null<::Main::Session*> session); - -Type PasskeysId(); - -} // namespace Settings