diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index ea3f726ad2..c3f6d40560 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -358,6 +358,16 @@ const style::MultiSelect &PeerListController::computeSelectSt() const { return _selectSt ? *_selectSt : st::defaultMultiSelect; } +void PeerListController::showFinished() { + if (const auto onstack = _showFinished) { + onstack(); + } +} + +void PeerListController::setShowFinishedCallback(Fn callback) { + _showFinished = std::move(callback); +} + bool PeerListController::hasComplexSearch() const { return (_searchController != nullptr); } diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 34fe0b13cf..9cc91cafea 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -486,8 +486,8 @@ public: virtual void prepare() = 0; - virtual void showFinished() { - } + virtual void showFinished(); + void setShowFinishedCallback(Fn callback); virtual void rowClicked(not_null row) = 0; virtual void rowMiddleClicked(not_null row) { @@ -621,6 +621,8 @@ private: const style::PeerList *_listSt = nullptr; const style::MultiSelect *_selectSt = nullptr; + Fn _showFinished; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index b32ce30ba3..31a75a1405 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_premium.h" // MessageMoneyRestriction. #include "base/random.h" #include "boxes/filters/edit_filter_chats_list.h" +#include "settings/settings_common.h" #include "settings/settings_premium.h" #include "ui/boxes/confirm_box.h" #include "ui/effects/round_checkbox.h" @@ -62,7 +63,7 @@ constexpr auto kSearchPerPage = 50; } // namespace object_ptr PrepareContactsBox( - not_null sessionController) { + not_null window) { using Mode = ContactsBoxController::SortMode; class Controller final : public ContactsBoxController { public: @@ -90,7 +91,7 @@ object_ptr PrepareContactsBox( }; auto controller = std::make_unique( - &sessionController->session()); + &window->session()); controller->setStyleOverrides(&st::contactsWithStories); controller->setStoriesShown(true); const auto raw = controller.get(); @@ -105,7 +106,7 @@ object_ptr PrepareContactsBox( box->addButton(tr::lng_close(), [=] { box->closeBox(); }); box->addLeftButton( tr::lng_profile_add_contact(), - [=] { sessionController->showAddContact(); }); + [=] { window->showAddContact(); }); state->toggleSort = box->addTopButton(st::contactsSortButton, [=] { const auto online = (state->mode.current() == Mode::Online); const auto mode = online ? Mode::Alphabet : Mode::Online; @@ -118,8 +119,15 @@ object_ptr PrepareContactsBox( raw->setSortMode(Mode::Online); raw->wheelClicks() | rpl::on_next([=](not_null p) { - sessionController->showInNewWindow(p); + window->showInNewWindow(p); }, box->lifetime()); + + raw->setShowFinishedCallback([=] { + window->checkHighlightControl( + u"contacts/sort"_q, + state->toggleSort, + { .rippleShape = true }); + }); }; return Box(std::move(controller), std::move(init)); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp index c950c1f19f..054c00f4ab 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp @@ -2716,7 +2716,7 @@ void SetupPeerColorSample( emojiStatusWidget->setAttribute(Qt::WA_TransparentForMouseEvents); } -void AddPeerColorButton( +not_null AddPeerColorButton( not_null container, std::shared_ptr show, not_null peer, @@ -2769,6 +2769,7 @@ void AddPeerColorButton( button->setClickedCallback([=] { show->show(Box(EditPeerColorBox, show, peer, style, theme)); }); + return button; } void CheckBoostLevel( diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.h index 394a13aa88..991919e228 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.h @@ -45,7 +45,7 @@ void EditPeerColorBox( std::shared_ptr style = nullptr, std::shared_ptr theme = nullptr); -void AddPeerColorButton( +not_null AddPeerColorButton( not_null container, std::shared_ptr show, not_null peer, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 99b3d15de0..c59370f190 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1203,7 +1203,6 @@ void Controller::refreshForumToggleLocked() { void Controller::fillColorIndexButton() { Expects(_controls.buttonsLayout != nullptr); - const auto show = _navigation->uiShow(); AddPeerColorButton( _controls.buttonsLayout, _navigation->uiShow(), diff --git a/Telegram/SourceFiles/core/deep_links/deep_links_contacts.cpp b/Telegram/SourceFiles/core/deep_links/deep_links_contacts.cpp index 8ebd718d26..d7158a2969 100644 --- a/Telegram/SourceFiles/core/deep_links/deep_links_contacts.cpp +++ b/Telegram/SourceFiles/core/deep_links/deep_links_contacts.cpp @@ -7,11 +7,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "core/deep_links/deep_links_router.h" +#include "boxes/peer_list_controllers.h" #include "window/window_session_controller.h" namespace Core::DeepLinks { namespace { +Result ShowContacts(const Context &ctx) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + ctx.controller->show(PrepareContactsBox(ctx.controller)); + return Result::Handled; +} + Result ShowAddContact(const Context &ctx) { if (!ctx.controller) { return Result::NeedsAuth; @@ -23,6 +32,32 @@ Result ShowAddContact(const Context &ctx) { } // namespace void RegisterContactsHandlers(Router &router) { + router.add(u"contacts"_q, { + .path = QString(), + .action = CodeBlock{ [](const Context &ctx) { + return ShowContacts(ctx); + }}, + }); + + router.add(u"contacts"_q, { + .path = u"search"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowContacts(ctx); + }}, + }); + + router.add(u"contacts"_q, { + .path = u"sort"_q, + .action = CodeBlock{ [](const Context &ctx) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + ctx.controller->setHighlightControlId(u"contacts/sort"_q); + ctx.controller->show(PrepareContactsBox(ctx.controller)); + return Result::Handled; + }}, + }); + router.add(u"contacts"_q, { .path = u"new"_q, .action = CodeBlock{ ShowAddContact }, diff --git a/Telegram/SourceFiles/core/deep_links/deep_links_router.cpp b/Telegram/SourceFiles/core/deep_links/deep_links_router.cpp index 386f93091a..805e4d5d95 100644 --- a/Telegram/SourceFiles/core/deep_links/deep_links_router.cpp +++ b/Telegram/SourceFiles/core/deep_links/deep_links_router.cpp @@ -156,6 +156,9 @@ Result Router::executeAction(const Action &action, const Context &ctx) { if (!ctx.controller) { return Result::NeedsAuth; } + if (!s.controlId.isEmpty()) { + ctx.controller->setHighlightControlId(s.controlId); + } ctx.controller->showSettings(s.sectionId); return Result::Handled; }, [&](const CodeBlock &c) { diff --git a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp index 9f001aff41..6d6a4acfcd 100644 --- a/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp +++ b/Telegram/SourceFiles/core/deep_links/deep_links_settings.cpp @@ -8,9 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/deep_links/deep_links_router.h" #include "base/binary_guard.h" +#include "boxes/add_contact_box.h" #include "boxes/language_box.h" +#include "boxes/star_gift_box.h" #include "boxes/username_box.h" +#include "core/application.h" +#include "core/click_handler_types.h" #include "data/data_user.h" +#include "data/notify/data_notify_settings.h" #include "ui/boxes/peer_qr_box.h" #include "ui/layers/generic_box.h" #include "main/main_session.h" @@ -27,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_local_passcode.h" #include "settings/settings_main.h" #include "settings/settings_notifications.h" +#include "settings/settings_notifications_type.h" #include "settings/settings_premium.h" #include "settings/settings_privacy_security.h" #include "settings/settings_websites.h" @@ -86,6 +92,54 @@ Result HandleQrCode(const Context &ctx, bool highlightCopy) { return Result::Handled; } +Result ShowEditName(const Context &ctx) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + if (ctx.controller->showFrozenError()) { + return Result::Handled; + } + ctx.controller->show(Box(ctx.controller->session().user())); + return Result::Handled; +} + +Result ShowEditUsername(const Context &ctx) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + if (ctx.controller->showFrozenError()) { + return Result::Handled; + } + ctx.controller->show(Box(UsernamesBox, ctx.controller->session().user())); + return Result::Handled; +} + +Result OpenInternalUrl(const Context &ctx, const QString &url) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + Core::App().openInternalUrl( + url, + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(ctx.controller), + })); + return Result::Handled; +} + +Result ShowNotificationType( + const Context &ctx, + Data::DefaultNotify type, + const QString &highlightId = QString()) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + if (!highlightId.isEmpty()) { + ctx.controller->setHighlightControlId(highlightId); + } + ctx.controller->showSettings(::Settings::NotificationsType::Id(type)); + return Result::Handled; +} + } // namespace void RegisterSettingsHandlers(Router &router) { @@ -104,6 +158,81 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::Information::Id() }, }); + router.add(u"settings"_q, { + .path = u"my-profile/edit"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"my-profile/posts"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"my-profile/posts/add-album"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"my-profile/gifts"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"my-profile/archived-posts"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"emoji-status"_q, + .action = SettingsSection{ ::Settings::Main::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/profile"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/profile/add-icons"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/profile/use-gift"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/name"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/name/add-icons"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-color/name/use-gift"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-photo"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"profile-photo/use-emoji"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + router.add(u"settings"_q, { .path = u"devices"_q, .action = SettingsSection{ ::Settings::Sessions::Id() }, @@ -129,11 +258,24 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::Blocked::Id() }, }); + router.add(u"settings"_q, { + .path = u"privacy/blocked/block-user"_q, + .action = SettingsControl{ + ::Settings::Blocked::Id(), + u"privacy/blocked/block-user"_q, + }, + }); + router.add(u"settings"_q, { .path = u"privacy/active-websites"_q, .action = SettingsSection{ ::Settings::Websites::Id() }, }); + router.add(u"settings"_q, { + .path = u"privacy/active-websites/disconnect-all"_q, + .action = SettingsSection{ ::Settings::Websites::Id() }, + }); + router.add(u"settings"_q, { .path = u"privacy/passcode"_q, .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, @@ -144,6 +286,316 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::GlobalTTLId() }, }); + router.add(u"settings"_q, { + .path = u"privacy/2sv"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passkey"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passkey/create"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passcode/disable"_q, + .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passcode/change"_q, + .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passcode/auto-lock"_q, + .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passcode/face-id"_q, + .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/passcode/fingerprint"_q, + .action = SettingsSection{ ::Settings::LocalPasscodeManageId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/2sv/change"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/2sv/disable"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/2sv/change-email"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/auto-delete/set-custom"_q, + .action = SettingsSection{ ::Settings::GlobalTTLId() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/phone-number"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/phone-number/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/phone-number/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/last-seen"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/last-seen/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/last-seen/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/last-seen/hide-read-time"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos/set-public"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos/update-public"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/profile-photos/remove-public"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/bio"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/bio/never-share"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/bio/always-share"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/gifts"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/gifts/show-icon"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/gifts/never-share"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/gifts/always-share"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/gifts/accepted-types"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/birthday"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/birthday/add"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/birthday/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/birthday/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/saved-music"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/saved-music/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/saved-music/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/forwards"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/forwards/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/forwards/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls/p2p"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls/p2p/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/calls/p2p/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/voice"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/voice/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/voice/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/messages"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/messages/set-price"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/messages/remove-fee"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/invites"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/invites/never"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/invites/always"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/self-destruct"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/data-settings/suggest-contacts"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/data-settings/clear-payment-info"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"privacy/archive-and-mute"_q, + .action = SettingsSection{ ::Settings::PrivacySecurity::Id() }, + }); + router.add(u"settings"_q, { .path = u"data/storage"_q, .action = SettingsSection{ ::Settings::Advanced::Id() }, @@ -154,6 +606,31 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::Advanced::Id() }, }); + router.add(u"settings"_q, { + .path = u"data/storage/clear-cache"_q, + .action = SettingsSection{ ::Settings::Advanced::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"data/max-cache"_q, + .action = SettingsSection{ ::Settings::Advanced::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"data/show-18-content"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"data/proxy/add-proxy"_q, + .action = SettingsSection{ ::Settings::Advanced::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"data/proxy/share-list"_q, + .action = SettingsSection{ ::Settings::Advanced::Id() }, + }); + router.add(u"settings"_q, { .path = u"appearance"_q, .action = SettingsSection{ ::Settings::Chat::Id() }, @@ -164,12 +641,180 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::Chat::Id() }, }); + router.add(u"settings"_q, { + .path = u"power-saving/stickers"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"power-saving/emoji"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"power-saving/effects"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/themes"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/themes/edit"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/themes/create"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/wallpapers"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/wallpapers/set"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/wallpapers/choose-photo"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/profile"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/profile/add-icons"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/profile/use-gift"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/profile/reset"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/name"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/name/add-icons"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/your-color/name/use-gift"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/night-mode"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/auto-night-mode"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/text-size"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/animations"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/edit"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/trending"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/archived"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/emoji"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/emoji/suggest"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/emoji/quick-reaction"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/emoji/quick-reaction/choose"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/suggest-by-emoji"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + + router.add(u"settings"_q, { + .path = u"appearance/stickers-and-emoji/emoji/large"_q, + .action = SettingsSection{ ::Settings::Chat::Id() }, + }); + router.add(u"settings"_q, { .path = u"language"_q, .action = CodeBlock{ ShowLanguageBox }, .requiresAuth = false, }); + router.add(u"settings"_q, { + .path = u"language/show-button"_q, + .action = CodeBlock{ ShowLanguageBox }, + .requiresAuth = false, + }); + + router.add(u"settings"_q, { + .path = u"language/translate-chats"_q, + .action = CodeBlock{ ShowLanguageBox }, + .requiresAuth = false, + }); + + router.add(u"settings"_q, { + .path = u"language/do-not-translate"_q, + .action = CodeBlock{ ShowLanguageBox }, + .requiresAuth = false, + }); + router.add(u"settings"_q, { .path = u"premium"_q, .action = SettingsSection{ ::Settings::PremiumId() }, @@ -180,6 +825,35 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::CreditsId() }, }); + router.add(u"settings"_q, { + .path = u"stars/top-up"_q, + .action = SettingsSection{ ::Settings::CreditsId() }, + }); + + router.add(u"settings"_q, { + .path = u"stars/stats"_q, + .action = SettingsControl{ + ::Settings::CreditsId(), + u"stars/stats"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"stars/gift"_q, + .action = SettingsControl{ + ::Settings::CreditsId(), + u"stars/gift"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"stars/earn"_q, + .action = SettingsControl{ + ::Settings::CreditsId(), + u"stars/earn"_q, + }, + }); + router.add(u"settings"_q, { .path = u"ton"_q, .action = SettingsSection{ ::Settings::CurrencyId() }, @@ -190,6 +864,33 @@ void RegisterSettingsHandlers(Router &router) { .action = SettingsSection{ ::Settings::BusinessId() }, }); + router.add(u"settings"_q, { + .path = u"business/do-not-hide-ads"_q, + .action = SettingsControl{ + ::Settings::BusinessId(), + u"business/sponsored"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"send-gift"_q, + .action = SettingsControl{ + ::Settings::Main::Id(), + u"main/send-gift"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"send-gift/self"_q, + .action = CodeBlock{ [](const Context &ctx) { + if (!ctx.controller) { + return Result::NeedsAuth; + } + Ui::ShowStarGiftBox(ctx.controller, ctx.controller->session().user()); + return Result::Handled; + }}, + }); + router.add(u"settings"_q, { .path = u"saved-messages"_q, .action = CodeBlock{ ShowSavedMessages }, @@ -211,6 +912,27 @@ void RegisterSettingsHandlers(Router &router) { .requiresAuth = false, }); + router.add(u"settings"_q, { + .path = u"ask-question"_q, + .action = SettingsControl{ + ::Settings::Main::Id(), + u"main/ask-question"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"features"_q, + .action = SettingsControl{ + ::Settings::Main::Id(), + u"main/features"_q, + }, + }); + + router.add(u"settings"_q, { + .path = u"search"_q, + .action = SettingsSection{ ::Settings::Main::Id() }, + }); + router.add(u"settings"_q, { .path = u"qr-code"_q, .action = CodeBlock{ [](const Context &ctx) { @@ -224,6 +946,299 @@ void RegisterSettingsHandlers(Router &router) { return HandleQrCode(ctx, true); }}, }); + + // Edit profile deep links. + router.add(u"settings"_q, { + .path = u"edit/first-name"_q, + .action = CodeBlock{ ShowEditName }, + }); + router.add(u"settings"_q, { + .path = u"edit/last-name"_q, + .action = CodeBlock{ ShowEditName }, + }); + router.add(u"settings"_q, { + .path = u"edit/bio"_q, + .action = SettingsControl{ + ::Settings::Information::Id(), + u"edit/bio"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"edit/birthday"_q, + .action = CodeBlock{ [](const Context &ctx) { + return OpenInternalUrl(ctx, u"internal:edit_birthday"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"edit/change-number"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + router.add(u"settings"_q, { + .path = u"edit/username"_q, + .action = CodeBlock{ ShowEditUsername }, + }); + router.add(u"settings"_q, { + .path = u"edit/your-color"_q, + .action = SettingsControl{ + ::Settings::Information::Id(), + u"edit/your-color"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"edit/channel"_q, + .action = CodeBlock{ [](const Context &ctx) { + return OpenInternalUrl(ctx, u"internal:edit_personal_channel"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"edit/add-account"_q, + .action = SettingsControl{ + ::Settings::Information::Id(), + u"edit/add-account"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"edit/log-out"_q, + .action = SettingsSection{ ::Settings::Information::Id() }, + }); + + // Calls deep links. + router.add(u"settings"_q, { + .path = u"calls/start-call"_q, + .action = SettingsSection{ ::Settings::Calls::Id() }, + }); + + // Devices (sessions) deep links. + router.add(u"settings"_q, { + .path = u"devices/terminate-sessions"_q, + .action = SettingsControl{ + ::Settings::Sessions::Id(), + u"devices/terminate-sessions"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"devices/auto-terminate"_q, + .action = SettingsControl{ + ::Settings::Sessions::Id(), + u"devices/auto-terminate"_q, + }, + }); + + // Folders deep links. + router.add(u"settings"_q, { + .path = u"folders/create"_q, + .action = SettingsControl{ + ::Settings::Folders::Id(), + u"folders/create"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"folders/add-recommended"_q, + .action = SettingsSection{ ::Settings::Folders::Id() }, + }); + router.add(u"settings"_q, { + .path = u"folders/show-tags"_q, + .action = SettingsControl{ + ::Settings::Folders::Id(), + u"folders/show-tags"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"folders/tab-view"_q, + .action = SettingsControl{ + ::Settings::Folders::Id(), + u"folders/tab-view"_q, + }, + }); + + // Notifications deep links. + router.add(u"settings"_q, { + .path = u"notifications/accounts"_q, + .action = SettingsControl{ + ::Settings::Notifications::Id(), + u"notifications/accounts"_q, + }, + }); + + // Notification type deep links - Private Chats. + router.add(u"settings"_q, { + .path = u"notifications/private-chats"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::User); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/private-chats/edit"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::User); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/private-chats/show"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::User, + u"notifications/type/show"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/private-chats/sound"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::User, + u"notifications/type/sound"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/private-chats/add-exception"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::User, + u"notifications/type/add-exception"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/private-chats/delete-exceptions"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::User, + u"notifications/type/delete-exceptions"_q); + }}, + }); + + // Notification type deep links - Groups. + router.add(u"settings"_q, { + .path = u"notifications/groups"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::Group); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/groups/edit"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::Group); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/groups/show"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Group, + u"notifications/type/show"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/groups/sound"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Group, + u"notifications/type/sound"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/groups/add-exception"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Group, + u"notifications/type/add-exception"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/groups/delete-exceptions"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Group, + u"notifications/type/delete-exceptions"_q); + }}, + }); + + // Notification type deep links - Channels. + router.add(u"settings"_q, { + .path = u"notifications/channels"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::Broadcast); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/channels/edit"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType(ctx, Data::DefaultNotify::Broadcast); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/channels/show"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Broadcast, + u"notifications/type/show"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/channels/sound"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Broadcast, + u"notifications/type/sound"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/channels/add-exception"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Broadcast, + u"notifications/type/add-exception"_q); + }}, + }); + router.add(u"settings"_q, { + .path = u"notifications/channels/delete-exceptions"_q, + .action = CodeBlock{ [](const Context &ctx) { + return ShowNotificationType( + ctx, + Data::DefaultNotify::Broadcast, + u"notifications/type/delete-exceptions"_q); + }}, + }); + + // Other notification deep links. + router.add(u"settings"_q, { + .path = u"notifications/include-muted-chats"_q, + .action = SettingsControl{ + ::Settings::Notifications::Id(), + u"notifications/include-muted-chats"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"notifications/count-unread-messages"_q, + .action = SettingsControl{ + ::Settings::Notifications::Id(), + u"notifications/count-unread-messages"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"notifications/new-contacts"_q, + .action = SettingsControl{ + ::Settings::Notifications::Id(), + u"notifications/events/joined"_q, + }, + }); + router.add(u"settings"_q, { + .path = u"notifications/pinned-messages"_q, + .action = SettingsControl{ + ::Settings::Notifications::Id(), + u"notifications/events/pinned"_q, + }, + }); } } // namespace Core::DeepLinks diff --git a/Telegram/SourceFiles/settings/builder/settings_builder.cpp b/Telegram/SourceFiles/settings/builder/settings_builder.cpp index 108f2ea49d..eacd0ee03c 100644 --- a/Telegram/SourceFiles/settings/builder/settings_builder.cpp +++ b/Telegram/SourceFiles/settings/builder/settings_builder.cpp @@ -58,6 +58,8 @@ Ui::RpWidget *SectionBuilder::addControl(ControlArgs &&args) { Ui::SettingsButton *SectionBuilder::addSettingsButton(ButtonArgs &&args) { const auto &st = args.st ? *args.st : st::settingsButton; + auto highlight = std::move(args.highlight); + const auto id = args.id; const auto button = v::match(_context, [&](const WidgetContext &ctx) -> Ui::SettingsButton* { if (args.label) { return AddButtonWithLabel( @@ -86,6 +88,10 @@ Ui::SettingsButton *SectionBuilder::addSettingsButton(ButtonArgs &&args) { if (button && args.onClick) { button->addClickHandler(std::move(args.onClick)); } + if (button && !id.isEmpty()) { + const auto highlightId = highlight.id.isEmpty() ? id : highlight.id; + registerHighlight(highlightId, button, std::move(highlight.args)); + } return button; } @@ -251,7 +257,9 @@ Ui::SettingsButton *SectionBuilder::addPremiumButton(PremiumButtonArgs &&args) { } Ui::SettingsButton *SectionBuilder::addToggle(ToggleArgs &&args) { - return v::match(_context, [&](const WidgetContext &ctx) + auto highlight = std::move(args.highlight); + const auto id = args.id; + const auto button = v::match(_context, [&](const WidgetContext &ctx) -> Ui::SettingsButton* { const auto &st = args.st ? *args.st : st::settingsButton; const auto button = ctx.container->add(CreateButtonWithIcon( @@ -271,6 +279,11 @@ Ui::SettingsButton *SectionBuilder::addToggle(ToggleArgs &&args) { } return nullptr; }); + if (button && !id.isEmpty()) { + const auto highlightId = highlight.id.isEmpty() ? id : highlight.id; + registerHighlight(highlightId, button, std::move(highlight.args)); + } + return button; } Ui::SlideWrap *SectionBuilder::addSlideToggle( @@ -335,4 +348,19 @@ Fn SectionBuilder::showOther() const { }); } +void SectionBuilder::registerHighlight( + QString id, + QWidget *widget, + HighlightArgs &&args) { + v::match(_context, [&](const WidgetContext &ctx) { + if (ctx.highlights && widget) { + ctx.highlights->push_back({ + std::move(id), + { widget, std::move(args) }, + }); + } + }, [](const SearchContext &) { + }); +} + } // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/builder/settings_builder.h b/Telegram/SourceFiles/settings/builder/settings_builder.h index 2e2b7071a1..8651cd2187 100644 --- a/Telegram/SourceFiles/settings/builder/settings_builder.h +++ b/Telegram/SourceFiles/settings/builder/settings_builder.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_type.h" #include +#include namespace Ui { class RpWidget; @@ -40,11 +41,19 @@ struct SearchEntry { QStringList keywords; }; +struct HighlightEntry { + QPointer widget; + HighlightArgs args; +}; + +using HighlightRegistry = std::vector>; + struct WidgetContext { not_null container; not_null controller; Fn showOther; Fn isPaused; + HighlightRegistry *highlights = nullptr; }; struct SearchContext { @@ -74,6 +83,7 @@ public: rpl::producer label; Fn onClick; QStringList keywords; + HighlightDescriptor highlight; }; Ui::SettingsButton *addSettingsButton(ButtonArgs &&args); Ui::SettingsButton *addLabeledButton(ButtonArgs &&args); @@ -128,6 +138,7 @@ public: IconDescriptor icon; rpl::producer toggled; QStringList keywords; + HighlightDescriptor highlight; }; Ui::SettingsButton *addToggle(ToggleArgs &&args); @@ -153,7 +164,13 @@ public: [[nodiscard]] Fn showOther() const; private: + void registerHighlight( + QString id, + QWidget *widget, + HighlightArgs &&args); + BuildContext _context; + }; } // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/builder/settings_main_builder.cpp b/Telegram/SourceFiles/settings/builder/settings_main_builder.cpp index efec26f190..bdac3f5e10 100644 --- a/Telegram/SourceFiles/settings/builder/settings_main_builder.cpp +++ b/Telegram/SourceFiles/settings/builder/settings_main_builder.cpp @@ -279,7 +279,7 @@ void BuildPremiumSection( if (!controller || controller->session().premiumCanBuy()) { builder.addSettingsButton({ - .id = u"main/gift"_q, + .id = u"main/send-gift"_q, .title = tr::lng_settings_gift_premium(), .icon = { .icon = &st::menuIconGiftPremium, .newBadge = true }, .onClick = controller @@ -299,14 +299,14 @@ void BuildHelpSection( builder.addSkip(); const auto faqClick = controller - ? Fn([=] { + ? [=] { UrlClickHandler::Open( tr::lng_settings_faq_link(tr::now), QVariant::fromValue(ClickHandlerContext{ .sessionWindow = base::make_weak(controller), })); - }) - : Fn(nullptr); + } + : Fn(); builder.addSettingsButton({ .id = u"main/faq"_q, .title = tr::lng_settings_faq(), @@ -326,9 +326,12 @@ void BuildHelpSection( }); builder.addSettingsButton({ - .id = u"main/ask"_q, + .id = u"main/ask-question"_q, .title = tr::lng_settings_ask_question(), .icon = { &st::menuIconDiscussion }, + .onClick = [] { + UrlClickHandler::Open(tr::lng_telegram_features_url(tr::now)); + }, .keywords = { u"contact"_q, u"feedback"_q }, }); @@ -380,10 +383,13 @@ void BuildMainSectionContent( } // namespace -void BuildMainSection( +void MainSection( not_null container, not_null controller, - Fn showOther) { + Fn showOther, + rpl::producer<> showFinished) { + auto &lifetime = container->lifetime(); + const auto highlights = lifetime.make_state(); const auto isPaused = Window::PausedIn( controller, Window::GifPauseReason::Layer); @@ -392,11 +398,23 @@ void BuildMainSection( .controller = controller, .showOther = std::move(showOther), .isPaused = isPaused, + .highlights = highlights, }); BuildMainSectionContent(builder, controller); + + std::move(showFinished) | rpl::on_next([=] { + for (const auto &[id, entry] : *highlights) { + if (const auto widget = entry.widget.data()) { + controller->checkHighlightControl( + id, + widget, + base::duplicate(entry.args)); + } + } + }, lifetime); } -std::vector BuildMainSectionForSearch() { +std::vector MainSectionForSearch() { auto entries = std::vector(); auto builder = SectionBuilder(SearchContext{ .entries = &entries, diff --git a/Telegram/SourceFiles/settings/builder/settings_main_builder.h b/Telegram/SourceFiles/settings/builder/settings_main_builder.h index 9c5273cf5f..7bab7efc5f 100644 --- a/Telegram/SourceFiles/settings/builder/settings_main_builder.h +++ b/Telegram/SourceFiles/settings/builder/settings_main_builder.h @@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include namespace Ui { +class RpWidget; +class SettingsButton; class VerticalLayout; } // namespace Ui @@ -23,11 +25,12 @@ namespace Settings::Builder { struct SearchEntry; -void BuildMainSection( +void MainSection( not_null container, not_null controller, - Fn showOther); + Fn showOther, + rpl::producer<> showFinished); -[[nodiscard]] std::vector BuildMainSectionForSearch(); +[[nodiscard]] std::vector MainSectionForSearch(); } // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/builder/settings_notifications_builder.cpp b/Telegram/SourceFiles/settings/builder/settings_notifications_builder.cpp index 9eba3937bf..22100a8922 100644 --- a/Telegram/SourceFiles/settings/builder/settings_notifications_builder.cpp +++ b/Telegram/SourceFiles/settings/builder/settings_notifications_builder.cpp @@ -74,7 +74,7 @@ void BuildMultiAccountSection( } const auto fromAll = builder.addToggle({ - .id = u"notifications/multi_account"_q, + .id = u"notifications/accounts"_q, .title = tr::lng_settings_notify_all(), .st = &st::settingsButtonNoIcon, .toggled = rpl::single(Core::App().settings().notifyFromAll()), @@ -468,7 +468,7 @@ void BuildBadgeCounterSection( const auto &settings = Core::App().settings(); const auto muted = builder.addToggle({ - .id = u"notifications/badge/muted"_q, + .id = u"notifications/include-muted-chats"_q, .title = tr::lng_settings_include_muted(), .st = &st::settingsButtonNoIcon, .toggled = rpl::single(settings.includeMutedCounter()), @@ -486,7 +486,7 @@ void BuildBadgeCounterSection( }) : nullptr; const auto count = builder.addToggle({ - .id = u"notifications/badge/count"_q, + .id = u"notifications/count-unread-messages"_q, .title = tr::lng_settings_count_unread(), .st = &st::settingsButtonNoIcon, .toggled = rpl::single(settings.countUnreadMessages()), @@ -742,10 +742,13 @@ void BuildNotificationsSectionContent( } // namespace -void BuildNotificationsSection( +void NotificationsSection( not_null container, not_null controller, - Fn showOther) { + Fn showOther, + rpl::producer<> showFinished) { + auto &lifetime = container->lifetime(); + const auto highlights = lifetime.make_state(); const auto isPaused = Window::PausedIn( controller, Window::GifPauseReason::Layer); @@ -754,11 +757,21 @@ void BuildNotificationsSection( .controller = controller, .showOther = std::move(showOther), .isPaused = isPaused, + .highlights = highlights, }); BuildNotificationsSectionContent(builder, controller); + + std::move(showFinished) | rpl::on_next([=] { + for (const auto &[id, entry] : *highlights) { + if (entry.widget) { + auto args = entry.args; + controller->checkHighlightControl(id, entry.widget, std::move(args)); + } + } + }, lifetime); } -std::vector BuildNotificationsSectionForSearch() { +std::vector NotificationsSectionForSearch() { auto entries = std::vector(); auto builder = SectionBuilder(SearchContext{ .entries = &entries, diff --git a/Telegram/SourceFiles/settings/builder/settings_notifications_builder.h b/Telegram/SourceFiles/settings/builder/settings_notifications_builder.h index a6238a1441..c146140ba8 100644 --- a/Telegram/SourceFiles/settings/builder/settings_notifications_builder.h +++ b/Telegram/SourceFiles/settings/builder/settings_notifications_builder.h @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "settings/settings_type.h" #include "settings/builder/settings_builder.h" namespace Ui { @@ -19,11 +20,12 @@ class SessionController; namespace Settings::Builder { -void BuildNotificationsSection( +void NotificationsSection( not_null container, not_null controller, - Fn showOther); + Fn showOther, + rpl::producer<> showFinished); -[[nodiscard]] std::vector BuildNotificationsSectionForSearch(); +[[nodiscard]] std::vector NotificationsSectionForSearch(); } // namespace Settings::Builder diff --git a/Telegram/SourceFiles/settings/settings_active_sessions.cpp b/Telegram/SourceFiles/settings/settings_active_sessions.cpp index ceb16ee804..1dc50cde38 100644 --- a/Telegram/SourceFiles/settings/settings_active_sessions.cpp +++ b/Telegram/SourceFiles/settings/settings_active_sessions.cpp @@ -607,6 +607,8 @@ public: not_null controller); void setupContent(); + [[nodiscard]] Ui::RpWidget *terminateAllButton() const; + [[nodiscard]] Ui::RpWidget *autoTerminateButton() const; protected: void resizeEvent(QResizeEvent *e) override; @@ -685,6 +687,8 @@ public: [[nodiscard]] rpl::producer showRequests() const; [[nodiscard]] rpl::producer terminateOne() const; [[nodiscard]] rpl::producer<> terminateAll() const; + [[nodiscard]] Ui::RpWidget *terminateAllButton() const; + [[nodiscard]] Ui::RpWidget *autoTerminateButton() const; private: void setupContent(); @@ -692,6 +696,7 @@ private: const not_null _controller; std::unique_ptr _current; QPointer _terminateAll; + QPointer _autoTerminate; std::unique_ptr _incomplete; std::unique_ptr _list; rpl::variable _ttlDays; @@ -874,6 +879,14 @@ void SessionsContent::terminateAll() { terminate(std::move(callback), tr::lng_settings_reset_sure(tr::now)); } +Ui::RpWidget *SessionsContent::terminateAllButton() const { + return _inner ? _inner->terminateAllButton() : nullptr; +} + +Ui::RpWidget *SessionsContent::autoTerminateButton() const { + return _inner ? _inner->autoTerminateButton() : nullptr; +} + SessionsContent::Inner::Inner( QWidget *parent, not_null controller, @@ -961,12 +974,12 @@ void SessionsContent::Inner::setupContent() { AddSkip(ttlInner, st::sessionSubtitleSkip); AddSubsectionTitle(ttlInner, tr::lng_settings_terminate_title()); - AddButtonWithLabel( + _autoTerminate = AddButtonWithLabel( ttlInner, tr::lng_settings_terminate_if(), _ttlDays.value() | rpl::map(SelfDestructionBox::DaysLabel), - st::settingsButtonNoIcon - )->addClickHandler([=] { + st::settingsButtonNoIcon); + _autoTerminate->addClickHandler([=] { _controller->show(Box( &_controller->session(), SelfDestructionBox::Type::Sessions, @@ -1007,6 +1020,14 @@ rpl::producer<> SessionsContent::Inner::terminateAll() const { return _terminateAll->clicks() | rpl::to_empty; } +Ui::RpWidget *SessionsContent::Inner::terminateAllButton() const { + return _terminateAll.data(); +} + +Ui::RpWidget *SessionsContent::Inner::autoTerminateButton() const { + return _autoTerminate.data(); +} + rpl::producer SessionsContent::Inner::terminateOne() const { return rpl::merge( _incomplete->terminateRequests(), @@ -1124,7 +1145,8 @@ namespace Settings { Sessions::Sessions( QWidget *parent, not_null controller) -: Section(parent) { +: Section(parent) +, _controller(controller) { setupContent(controller); } @@ -1132,6 +1154,11 @@ rpl::producer Sessions::title() { return tr::lng_settings_sessions_title(); } +void Sessions::showFinished() { + _controller->checkHighlightControl(u"devices/terminate-sessions"_q, _terminateAll); + _controller->checkHighlightControl(u"devices/auto-terminate"_q, _autoTerminate); +} + void Sessions::setupContent(not_null controller) { const auto container = Ui::CreateChild(this); AddSkip(container, st::settingsPrivacySkip); @@ -1139,6 +1166,9 @@ void Sessions::setupContent(not_null controller) { object_ptr(container, controller)); content->setupContent(); + _terminateAll = content->terminateAllButton(); + _autoTerminate = content->autoTerminateButton(); + Ui::ResizeFitChild(this, container); } diff --git a/Telegram/SourceFiles/settings/settings_active_sessions.h b/Telegram/SourceFiles/settings/settings_active_sessions.h index bc45147f7b..6244116405 100644 --- a/Telegram/SourceFiles/settings/settings_active_sessions.h +++ b/Telegram/SourceFiles/settings/settings_active_sessions.h @@ -22,10 +22,15 @@ public: not_null controller); [[nodiscard]] rpl::producer title() override; + void showFinished() override; private: void setupContent(not_null controller); + const not_null _controller; + QPointer _terminateAll; + QPointer _autoTerminate; + }; void AddSessionInfoRow( diff --git a/Telegram/SourceFiles/settings/settings_blocked_peers.cpp b/Telegram/SourceFiles/settings/settings_blocked_peers.cpp index df7737dc8f..9978541f2d 100644 --- a/Telegram/SourceFiles/settings/settings_blocked_peers.cpp +++ b/Telegram/SourceFiles/settings/settings_blocked_peers.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "lottie/lottie_icon.h" #include "main/main_session.h" +#include "settings/settings_common.h" #include "settings/settings_privacy_controllers.h" #include "ui/widgets/buttons.h" #include "ui/wrap/padding_wrap.h" @@ -76,12 +77,13 @@ base::weak_qptr Blocked::createPinnedToTop(not_null pare Ui::AddSkip(content); - AddButtonWithIcon( + const auto blockButton = AddButtonWithIcon( content, tr::lng_blocked_list_add(), st::settingsButtonActive, - { &st::menuIconBlockSettings } - )->addClickHandler([=] { + { &st::menuIconBlockSettings }); + _blockUserButton = blockButton; + blockButton->addClickHandler([=] { BlockedBoxController::BlockNewPeer(_controller); }); @@ -236,6 +238,7 @@ void Blocked::visibleTopBottomUpdated(int visibleTop, int visibleBottom) { void Blocked::showFinished() { _showFinished.fire({}); + _controller->checkHighlightControl(u"privacy/blocked/block-user"_q, _blockUserButton); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_blocked_peers.h b/Telegram/SourceFiles/settings/settings_blocked_peers.h index e8a8e7c2da..ac7e61c4bc 100644 --- a/Telegram/SourceFiles/settings/settings_blocked_peers.h +++ b/Telegram/SourceFiles/settings/settings_blocked_peers.h @@ -48,6 +48,8 @@ private: rpl::event_stream<> _showFinished; rpl::event_stream _emptinessChanges; + QPointer _blockUserButton; + }; } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_business.cpp b/Telegram/SourceFiles/settings/settings_business.cpp index 9311914048..fc092f8aea 100644 --- a/Telegram/SourceFiles/settings/settings_business.cpp +++ b/Telegram/SourceFiles/settings/settings_business.cpp @@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/business/settings_location.h" #include "settings/business/settings_quick_replies.h" #include "settings/business/settings_working_hours.h" +#include "settings/settings_common.h" #include "settings/settings_common_session.h" #include "settings/settings_premium.h" #include "ui/effects/gradient.h" @@ -366,6 +367,8 @@ private: PremiumFeature _waitingToShow = PremiumFeature::Business; + QPointer _sponsoredButton; + }; Business::Business( @@ -563,6 +566,7 @@ void Business::setupContent() { const auto button = inner->add(object_ptr( inner, tr::lng_business_button_sponsored())); + _sponsoredButton = button; Ui::AddSkip(inner); const auto session = &_controller->session(); @@ -716,6 +720,7 @@ base::weak_qptr Business::createPinnedToTop( void Business::showFinished() { _showFinished.fire({}); + _controller->checkHighlightControl(u"business/sponsored"_q, _sponsoredButton); } base::weak_qptr Business::createPinnedToBottom( diff --git a/Telegram/SourceFiles/settings/settings_common.cpp b/Telegram/SourceFiles/settings/settings_common.cpp index 5efd25d187..c091044ee6 100644 --- a/Telegram/SourceFiles/settings/settings_common.cpp +++ b/Telegram/SourceFiles/settings/settings_common.cpp @@ -226,7 +226,13 @@ void HighlightOverlay::finish() { } // namespace -void HighlightWidget(not_null target, HighlightArgs &&args) { +void HighlightWidget(QWidget *target, HighlightArgs &&args) { + if (!target) { + return; + } + if (args.scroll) { + ScrollToWidget(target); + } new HighlightOverlay(target, std::move(args)); } @@ -257,13 +263,6 @@ void ScrollToWidget(not_null target) { } } -void ScrollAndHighlightWidget( - not_null target, - HighlightArgs &&args) { - ScrollToWidget(target); - HighlightWidget(target, std::move(args)); -} - Icon::Icon(IconDescriptor descriptor) : _icon(descriptor.icon) { const auto background = [&]() -> const style::color* { if (descriptor.type == IconType::Simple) { diff --git a/Telegram/SourceFiles/settings/settings_common.h b/Telegram/SourceFiles/settings/settings_common.h index 5afdf415f0..f45f659e18 100644 --- a/Telegram/SourceFiles/settings/settings_common.h +++ b/Telegram/SourceFiles/settings/settings_common.h @@ -69,17 +69,23 @@ struct HighlightArgs { float64 opacity = 0.15; bool below = false; bool rippleShape = false; + bool scroll = true; crl::time showDuration = 600; crl::time shownDuration = 800; crl::time hideDuration = 600; }; -void HighlightWidget(not_null target, HighlightArgs &&args = {}); -void ScrollToWidget(not_null target); +struct HighlightDescriptor { + QString id; + HighlightArgs args; -void ScrollAndHighlightWidget( - not_null target, - HighlightArgs &&args = {}); + explicit operator bool() const { + return !id.isEmpty(); + } +}; + +void HighlightWidget(QWidget *target, HighlightArgs &&args = {}); +void ScrollToWidget(not_null target); class AbstractSection : public Ui::RpWidget { public: diff --git a/Telegram/SourceFiles/settings/settings_common_session.h b/Telegram/SourceFiles/settings/settings_common_session.h index 8bea347a02..48abfff2cf 100644 --- a/Telegram/SourceFiles/settings/settings_common_session.h +++ b/Telegram/SourceFiles/settings/settings_common_session.h @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class ScrollArea; +class VerticalLayout; } // namespace Ui namespace Ui::Menu { @@ -64,6 +65,12 @@ struct SectionFactory : AbstractSectionFactory { }; +using SectionBuilder = void(*)( + not_null container, + not_null controller, + Fn showOther, + rpl::producer<> showFinished); + template class Section : public AbstractSection { public: @@ -88,8 +95,32 @@ public: }); } + void showFinished() override { + _showFinished.fire({}); + } + +protected: + void setController(not_null controller) { + _controller = controller; + } + [[nodiscard]] Window::SessionController *controller() const { + return _controller; + } + + void build( + not_null container, + SectionBuilder builder) { + builder( + container, + _controller, + showOtherMethod(), + _showFinished.events()); + } + private: rpl::event_stream _showOtherRequests; + rpl::event_stream<> _showFinished; + Window::SessionController *_controller = nullptr; }; diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index a7c49c2cd4..a454da2800 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/statistics/info_statistics_list_controllers.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "settings/settings_common.h" #include "settings/settings_common_session.h" #include "settings/settings_credits_graphics.h" #include "statistics/widgets/chart_header_widget.h" @@ -115,6 +116,10 @@ private: rpl::event_stream<> _showFinished; rpl::variable _buttonText; + QPointer _statsButton; + QPointer _giftButton; + QPointer _earnButton; + }; Credits::Credits( @@ -611,6 +616,7 @@ void Credits::setupContent() { tr::lng_credits_stats_button(), st::settingsCreditsButton, { &st::menuIconStats }))); + _statsButton = static_cast(wrap->entity()); wrap->entity()->setClickedCallback([=] { controller->showSection(Info::BotEarn::Make(self)); }); @@ -620,21 +626,23 @@ void Credits::setupContent() { })); } if (!isCurrency) { - AddButtonWithIcon( + _giftButton = AddButtonWithIcon( content, tr::lng_credits_gift_button(), st::settingsCreditsButton, - { &st::settingsButtonIconGift })->setClickedCallback([=] { + { &st::settingsButtonIconGift }); + _giftButton->setClickedCallback([=] { Ui::ShowGiftCreditsBox(controller, paid); }); } if (!isCurrency && Info::BotStarRef::Join::Allowed(self)) { - AddButtonWithIcon( + _earnButton = AddButtonWithIcon( content, tr::lng_credits_earn_button(), st::settingsCreditsButton, - { &st::settingsButtonIconEarn })->setClickedCallback([=] { + { &st::settingsButtonIconEarn }); + _earnButton->setClickedCallback([=] { controller->showSection(Info::BotStarRef::Join::Make(self)); }); } @@ -904,6 +912,9 @@ base::weak_qptr Credits::createPinnedToTop( void Credits::showFinished() { _showFinished.fire({}); + _controller->checkHighlightControl(u"stars/stats"_q, _statsButton); + _controller->checkHighlightControl(u"stars/gift"_q, _giftButton); + _controller->checkHighlightControl(u"stars/earn"_q, _earnButton); } class Currency { diff --git a/Telegram/SourceFiles/settings/settings_folders.cpp b/Telegram/SourceFiles/settings/settings_folders.cpp index b453f9cd6b..26c95d165b 100644 --- a/Telegram/SourceFiles/settings/settings_folders.cpp +++ b/Telegram/SourceFiles/settings/settings_folders.cpp @@ -48,6 +48,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_chat_helpers.h" namespace Settings { + +struct FoldersHighlightTargets { + QPointer createButton; + QPointer tagsButton; + QPointer viewSection; +}; namespace { using Flag = Data::ChatFilter::Flag; @@ -350,7 +356,8 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { [[nodiscard]] Fn SetupFoldersContent( not_null controller, not_null container, - not_null*> tagsButtonEnabled) { + not_null*> tagsButtonEnabled, + FoldersHighlightTargets *targets) { auto &lifetime = container->lifetime(); const auto weak = base::make_weak(container); @@ -557,12 +564,15 @@ void FilterRowButton::paintEvent(QPaintEvent *e) { j->button->updateCount(j->filter); }, container->lifetime()); - AddButtonWithIcon( + const auto createButton = AddButtonWithIcon( container, tr::lng_filters_create(), st::settingsButtonActive, - { &st::settingsIconAdd, IconType::Round, &st::windowBgActive } - )->setClickedCallback([=] { + { &st::settingsIconAdd, IconType::Round, &st::windowBgActive }); + if (targets) { + targets->createButton = createButton; + } + createButton->setClickedCallback([=] { if (showLimitReached()) { return; } @@ -879,7 +889,8 @@ void SetupTopContent( void SetupTagContent( not_null controller, not_null content, - not_null*> tagsButtonEnabled) { + not_null*> tagsButtonEnabled, + FoldersHighlightTargets *targets) { Ui::AddDivider(content); Ui::AddSkip(content); @@ -897,6 +908,9 @@ void SetupTagContent( content, tr::lng_filters_enable_tags(), st::settingsButtonNoIconLocked)); + if (targets) { + targets->tagsButton = tagsButton; + } const auto state = tagsButton->lifetime().make_state(); tagsButton->toggleOn(rpl::merge( rpl::combine( @@ -970,12 +984,16 @@ void SetupTagContent( void SetupView( not_null controller, not_null content, - bool dividerNeeded) { + bool dividerNeeded, + FoldersHighlightTargets *targets) { const auto wrap = content->add( object_ptr>( content, object_ptr(content))); wrap->toggleOn(controller->enoughSpaceForFiltersValue()); + if (targets) { + targets->viewSection = wrap->entity(); + } content = wrap->entity(); if (dividerNeeded) { @@ -1012,7 +1030,8 @@ void SetupView( Folders::Folders( QWidget *parent, not_null controller) -: Section(parent) { +: Section(parent) +, _controller(controller) { setupContent(controller); } @@ -1035,21 +1054,29 @@ void Folders::setupContent(not_null controller) { SetupTopContent(content, _showFinished.events()); - _save = SetupFoldersContent(controller, content, tagsButtonEnabled); + auto targets = FoldersHighlightTargets(); + _save = SetupFoldersContent(controller, content, tagsButtonEnabled, &targets); + _createButton = targets.createButton; auto dividerNeeded = true; if (controller->session().premiumPossible()) { - SetupTagContent(controller, content, tagsButtonEnabled); + SetupTagContent(controller, content, tagsButtonEnabled, &targets); + _tagsButton = targets.tagsButton; dividerNeeded = false; } - SetupView(controller, content, dividerNeeded); + SetupView(controller, content, dividerNeeded, &targets); + _viewSection = targets.viewSection; Ui::ResizeFitChild(this, content); } void Folders::showFinished() { _showFinished.fire({}); + + _controller->checkHighlightControl(u"folders/create"_q, _createButton); + _controller->checkHighlightControl(u"folders/show-tags"_q, _tagsButton); + _controller->checkHighlightControl(u"folders/tab-view"_q, _viewSection); } } // namespace Settings diff --git a/Telegram/SourceFiles/settings/settings_folders.h b/Telegram/SourceFiles/settings/settings_folders.h index 4598d22ae0..c1cf93fe3a 100644 --- a/Telegram/SourceFiles/settings/settings_folders.h +++ b/Telegram/SourceFiles/settings/settings_folders.h @@ -25,9 +25,13 @@ public: private: void setupContent(not_null controller); + const not_null _controller; Fn _save; rpl::event_stream<> _showFinished; + QPointer _createButton; + QPointer _tagsButton; + QPointer _viewSection; }; diff --git a/Telegram/SourceFiles/settings/settings_information.cpp b/Telegram/SourceFiles/settings/settings_information.cpp index 08f8067b10..aa0398366b 100644 --- a/Telegram/SourceFiles/settings/settings_information.cpp +++ b/Telegram/SourceFiles/settings/settings_information.cpp @@ -68,6 +68,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include namespace Settings { + +struct InformationHighlightTargets { + QPointer bio; + QPointer colorButton; + QPointer addAccount; +}; + namespace { constexpr auto kSaveBioTimeout = 1000; @@ -191,6 +198,7 @@ public: not_null controller); [[nodiscard]] rpl::producer<> closeRequests() const; + [[nodiscard]] Ui::RpWidget *addAccountButton() const; private: void setup(); @@ -418,7 +426,8 @@ void SetupBirthday( void SetupPersonalChannel( not_null container, not_null controller, - not_null self) { + not_null self, + InformationHighlightTargets *targets) { Ui::AddSkip(container); auto value = rpl::combine( @@ -442,11 +451,14 @@ void SetupPersonalChannel( edit, { &st::menuIconChannel }); - AddPeerColorButton( + const auto colorButton = AddPeerColorButton( container, controller->uiShow(), self, st::settingsColorButton); + if (targets) { + targets->colorButton = colorButton; + } Ui::AddSkip(container); Ui::AddDivider(container); @@ -539,7 +551,8 @@ void SetupRows( void SetupBio( not_null container, - not_null self) { + not_null self, + InformationHighlightTargets *targets) { const auto limits = Data::PremiumLimits(&self->session()); const auto defaultLimit = limits.aboutLengthDefault(); const auto premiumLimit = limits.aboutLengthPremium(); @@ -561,6 +574,9 @@ void SetupBio( tr::lng_bio_placeholder(), *current), st::settingsBioMargins); + if (targets) { + targets->bio = bio; + } const auto countdown = Ui::CreateChild( container.get(), @@ -659,10 +675,14 @@ void SetupBio( void SetupAccountsWrap( not_null container, - not_null controller) { + not_null controller, + InformationHighlightTargets *targets) { Ui::AddSkip(container); - SetupAccounts(container, controller); + auto events = SetupAccounts(container, controller); + if (targets) { + targets->addAccount = events.addAccountButton; + } } [[nodiscard]] bool IsAltShift(Qt::KeyboardModifiers modifiers) { @@ -839,6 +859,10 @@ rpl::producer<> AccountsList::closeRequests() const { return _closeRequests.events(); } +Ui::RpWidget *AccountsList::addAccountButton() const { + return _addAccount ? _addAccount->entity() : nullptr; +} + void AccountsList::setup() { _addAccount = setupAdd(); @@ -1052,7 +1076,8 @@ void AccountsList::rebuild() { Information::Information( QWidget *parent, not_null controller) -: Section(parent) { +: Section(parent) +, _controller(controller) { setupContent(controller); } @@ -1060,17 +1085,29 @@ rpl::producer Information::title() { return tr::lng_settings_section_info(); } +void Information::showFinished() { + _controller->checkHighlightControl(u"edit/bio"_q, _bio); + _controller->checkHighlightControl(u"edit/your-color"_q, _colorButton); + _controller->checkHighlightControl(u"edit/add-account"_q, _addAccount); +} + void Information::setupContent( not_null controller) { const auto content = Ui::CreateChild(this); const auto self = controller->session().user(); + auto targets = InformationHighlightTargets(); + SetupPhoto(content, controller, self); - SetupBio(content, self); + SetupBio(content, self, &targets); SetupRows(content, controller, self); - SetupPersonalChannel(content, controller, self); + SetupPersonalChannel(content, controller, self, &targets); SetupBirthday(content, controller, self); - SetupAccountsWrap(content, controller); + SetupAccountsWrap(content, controller, &targets); + + _bio = targets.bio; + _colorButton = targets.colorButton; + _addAccount = targets.addAccount; Ui::ResizeFitChild(this, content); } @@ -1083,6 +1120,7 @@ AccountsEvents SetupAccounts( controller); return { .closeRequests = list->closeRequests(), + .addAccountButton = list->addAccountButton(), }; } diff --git a/Telegram/SourceFiles/settings/settings_information.h b/Telegram/SourceFiles/settings/settings_information.h index d83b571de9..7cbff69e42 100644 --- a/Telegram/SourceFiles/settings/settings_information.h +++ b/Telegram/SourceFiles/settings/settings_information.h @@ -29,13 +29,21 @@ public: [[nodiscard]] rpl::producer title() override; + void showFinished() override; + private: void setupContent(not_null controller); + const not_null _controller; + QPointer _bio; + QPointer _colorButton; + QPointer _addAccount; + }; struct AccountsEvents { rpl::producer<> closeRequests; + QPointer addAccountButton; }; AccountsEvents SetupAccounts( not_null container, diff --git a/Telegram/SourceFiles/settings/settings_main.cpp b/Telegram/SourceFiles/settings/settings_main.cpp index a4076d487b..84b24eea3d 100644 --- a/Telegram/SourceFiles/settings/settings_main.cpp +++ b/Telegram/SourceFiles/settings/settings_main.cpp @@ -671,10 +671,10 @@ void SetupInterfaceScale( Main::Main( QWidget *parent, not_null controller) -: Section(parent) -, _controller(controller) { - setupContentWithBuilder(controller); - _controller->session().api().premium().reload(); +: Section(parent) { + setController(controller); + setupContent(); + controller->session().api().premium().reload(); } rpl::producer Main::title() { @@ -688,13 +688,13 @@ void Main::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) { Core::App().domain().addActivated(MTP::Environment{}); }, &st::menuIconAddAccount); } - if (!_controller->session().supportMode()) { + if (!controller()->session().supportMode()) { addAction( tr::lng_settings_information(tr::now), [=] { showOther(Information::Id()); }, &st::menuIconEdit); } - const auto window = &_controller->window(); + const auto window = &controller()->window(); addAction({ .text = tr::lng_settings_logout(tr::now), .handler = [=] { window->showLogoutConfirmation(); }, @@ -705,29 +705,28 @@ void Main::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) { void Main::keyPressEvent(QKeyEvent *e) { crl::on_main(this, [=, text = e->text()]{ - CodesFeedString(_controller, text); + CodesFeedString(controller(), text); }); return Section::keyPressEvent(e); } -void Main::setupContentWithBuilder( - not_null controller) { +void Main::setupContent() { const auto content = Ui::CreateChild(this); content->add(object_ptr( content, - controller, - controller->session().user())); + controller(), + controller()->session().user())); - Builder::BuildMainSection(content, controller, showOtherMethod()); + build(content, Builder::MainSection); Ui::ResizeFitChild(this, content); - controller->session().api().cloudPassword().reload(); - controller->session().api().reloadContactSignupSilent(); - controller->session().api().sensitiveContent().reload(); - controller->session().api().globalPrivacy().reload(); - controller->session().data().cloudThemes().refresh(); + controller()->session().api().cloudPassword().reload(); + controller()->session().api().reloadContactSignupSilent(); + controller()->session().api().sensitiveContent().reload(); + controller()->session().api().globalPrivacy().reload(); + controller()->session().data().cloudThemes().refresh(); } void OpenFaq(base::weak_ptr weak) { diff --git a/Telegram/SourceFiles/settings/settings_main.h b/Telegram/SourceFiles/settings/settings_main.h index 4037af4cb7..d6cab9677a 100644 --- a/Telegram/SourceFiles/settings/settings_main.h +++ b/Telegram/SourceFiles/settings/settings_main.h @@ -15,6 +15,7 @@ class SessionController; } // namespace Window namespace Ui { +class SettingsButton; class VerticalLayout; } // namespace Ui @@ -53,9 +54,7 @@ protected: void keyPressEvent(QKeyEvent *e) override; private: - void setupContentWithBuilder(not_null controller); - - const not_null _controller; + void setupContent(); }; diff --git a/Telegram/SourceFiles/settings/settings_notifications.cpp b/Telegram/SourceFiles/settings/settings_notifications.cpp index cd595b235c..eb816ef4af 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications.cpp @@ -797,22 +797,17 @@ Notifications::Notifications( QWidget *parent, not_null controller) : Section(parent) { - setupContent(controller); + setController(controller); + setupContent(); } rpl::producer Notifications::title() { return tr::lng_settings_section_notify(); } -void Notifications::setupContent( - not_null controller) { +void Notifications::setupContent() { const auto content = Ui::CreateChild(this); - - Builder::BuildNotificationsSection( - content, - controller, - showOtherMethod()); - + build(content, Builder::NotificationsSection); Ui::ResizeFitChild(this, content); } diff --git a/Telegram/SourceFiles/settings/settings_notifications.h b/Telegram/SourceFiles/settings/settings_notifications.h index 89142d747b..3d043fc5c8 100644 --- a/Telegram/SourceFiles/settings/settings_notifications.h +++ b/Telegram/SourceFiles/settings/settings_notifications.h @@ -24,7 +24,7 @@ public: [[nodiscard]] rpl::producer title() override; private: - void setupContent(not_null controller); + void setupContent(); }; diff --git a/Telegram/SourceFiles/settings/settings_notifications_type.cpp b/Telegram/SourceFiles/settings/settings_notifications_type.cpp index 098973cbb6..a11b980c55 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_type.cpp +++ b/Telegram/SourceFiles/settings/settings_notifications_type.cpp @@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/vertical_layout.h" #include "ui/vertical_list.h" #include "window/window_session_controller.h" +#include "settings/settings_common.h" #include "styles/style_layers.h" #include "styles/style_menu_icons.h" #include "styles/style_settings.h" @@ -40,6 +41,13 @@ namespace { using Notify = Data::DefaultNotify; +struct NotificationsTypeHighlightTargets { + QPointer showToggle; + QPointer soundToggle; + QPointer addException; + QPointer deleteExceptions; +}; + struct Factory : AbstractSectionFactory { explicit Factory(Notify type) : type(type) { } @@ -394,7 +402,8 @@ void ExceptionsController::sort() { void SetupChecks( not_null container, not_null controller, - Notify type) { + Notify type, + NotificationsTypeHighlightTargets *targets) { Ui::AddSubsectionTitle(container, Title(type)); const auto session = &controller->session(); @@ -409,6 +418,9 @@ void SetupChecks( enabled->toggleOn( NotificationsEnabledForTypeValue(session, type), true); + if (targets) { + targets->showToggle = enabled; + } enabled->setAcceptBoth(); MuteMenu::SetupMuteMenu( @@ -450,6 +462,9 @@ void SetupChecks( ) | rpl::then(settings->defaultUpdates( type ) | rpl::map([=] { return soundValue(); }))); + if (targets) { + targets->soundToggle = sound; + } const auto toneWrap = soundInner->add( object_ptr>( @@ -538,12 +553,16 @@ void SetupChecks( void SetupExceptions( not_null container, not_null window, - Notify type) { + Notify type, + NotificationsTypeHighlightTargets *targets) { const auto add = AddButtonWithIcon( container, tr::lng_notification_exceptions_add(), st::settingsButtonActive, { &st::menuIconInviteSettings }); + if (targets) { + targets->addException = add; + } auto controller = std::make_unique(window, type); controller->setStyleOverrides(&st::settingsBlockedList); @@ -588,6 +607,9 @@ void SetupExceptions( tr::lng_notification_exceptions_clear(), st::settingsAttentionButtonWithIcon, { &st::menuIconDeleteAttention }))); + if (targets) { + targets->deleteExceptions = wrap->entity(); + } wrap->entity()->setClickedCallback([=] { const auto clear = [=](Fn close) { window->session().data().notifySettings().clearExceptions(type); @@ -613,6 +635,7 @@ NotificationsType::NotificationsType( not_null controller, Notify type) : AbstractSection(parent) +, _controller(controller) , _type(type) { setupContent(controller); } @@ -626,6 +649,13 @@ rpl::producer NotificationsType::title() { Unexpected("Type in NotificationsType."); } +void NotificationsType::showFinished() { + _controller->checkHighlightControl(u"notifications/type/show"_q, _showToggle); + _controller->checkHighlightControl(u"notifications/type/sound"_q, _soundToggle); + _controller->checkHighlightControl(u"notifications/type/add-exception"_q, _addException); + _controller->checkHighlightControl(u"notifications/type/delete-exceptions"_q, _deleteExceptions); +} + Type NotificationsType::Id(Notify type) { return std::make_shared(type); } @@ -634,14 +664,21 @@ void NotificationsType::setupContent( not_null controller) { const auto container = Ui::CreateChild(this); + auto targets = NotificationsTypeHighlightTargets(); + Ui::AddSkip(container, st::settingsPrivacySkip); - SetupChecks(container, controller, _type); + SetupChecks(container, controller, _type, &targets); Ui::AddSkip(container); Ui::AddDivider(container); Ui::AddSkip(container); - SetupExceptions(container, controller, _type); + SetupExceptions(container, controller, _type, &targets); + + _showToggle = targets.showToggle; + _soundToggle = targets.soundToggle; + _addException = targets.addException; + _deleteExceptions = targets.deleteExceptions; Ui::ResizeFitChild(this, container); } diff --git a/Telegram/SourceFiles/settings/settings_notifications_type.h b/Telegram/SourceFiles/settings/settings_notifications_type.h index 0416c929bc..c1fc4fc16c 100644 --- a/Telegram/SourceFiles/settings/settings_notifications_type.h +++ b/Telegram/SourceFiles/settings/settings_notifications_type.h @@ -27,11 +27,19 @@ public: return Id(_type); } + void showFinished() override; + private: void setupContent(not_null controller); + const not_null _controller; const Data::DefaultNotify _type; + QPointer _showToggle; + QPointer _soundToggle; + QPointer _addException; + QPointer _deleteExceptions; + }; [[nodiscard]] bool NotificationsEnabledForType( diff --git a/Telegram/SourceFiles/ui/boxes/peer_qr_box.cpp b/Telegram/SourceFiles/ui/boxes/peer_qr_box.cpp index beed73e617..fbd35f74f7 100644 --- a/Telegram/SourceFiles/ui/boxes/peer_qr_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/peer_qr_box.cpp @@ -986,13 +986,15 @@ void FillPeerQrBox( box->showFinishes( ) | rpl::take(1) | rpl::on_next([=] { if (const auto window = Core::App().findWindow(box)) { - if (window->takeHighlightControlId(u"self-qr-code/copy"_q)) { - Settings::HighlightWidget(saveButton, { - .radius = st::boxRadius, + window->checkHighlightControl( + u"self-qr-code/copy"_q, + saveButton, + { + .radius = st::buttonRadius, .color = &st::activeButtonFg, .opacity = 0.6, + .scroll = false, }); - } } }, box->lifetime()); } diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index 29f406bef6..47f88da2fc 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/boxes/confirm_box.h" #include "data/components/promo_suggestions.h" #include "data/data_thread.h" +#include "settings/settings_common.h" #include "apiwrap.h" // ApiWrap::acceptTerms. #include "styles/style_layers.h" @@ -631,6 +632,19 @@ bool Controller::takeHighlightControlId(const QString &id) { return false; } +void Controller::checkHighlightControl( + const QString &id, + QWidget *widget, + Settings::HighlightArgs &&args) { + if (widget && takeHighlightControlId(id)) { + Settings::HighlightWidget(widget, std::move(args)); + } +} + +void Controller::checkHighlightControl(const QString &id, QWidget *widget) { + checkHighlightControl(id, widget, {}); +} + rpl::lifetime &Controller::lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index a855e9f4b4..e412176e2e 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -32,6 +32,10 @@ namespace Media::Player { class FloatDelegate; } // namespace Media::Player +namespace Settings { +struct HighlightArgs; +} // namespace Settings + namespace Window { class Controller final : public base::has_weak_ptr { @@ -145,6 +149,11 @@ public: void setHighlightControlId(const QString &id); [[nodiscard]] QString highlightControlId() const; [[nodiscard]] bool takeHighlightControlId(const QString &id); + void checkHighlightControl( + const QString &id, + QWidget *widget, + Settings::HighlightArgs &&args); + void checkHighlightControl(const QString &id, QWidget *widget); [[nodiscard]] rpl::lifetime &lifetime(); diff --git a/Telegram/SourceFiles/window/window_main_menu.cpp b/Telegram/SourceFiles/window/window_main_menu.cpp index bd838f89c9..566c082608 100644 --- a/Telegram/SourceFiles/window/window_main_menu.cpp +++ b/Telegram/SourceFiles/window/window_main_menu.cpp @@ -637,13 +637,11 @@ void MainMenu::parentResized() { void MainMenu::showFinished() { _showFinished = true; - if (_controller->takeHighlightControlId(u"main-menu/emoji-status"_q)) { - const auto radius = st::roundRadiusSmall; - Settings::HighlightWidget(_setEmojiStatus, { - .margin = { radius, 0, radius, 0 }, - .radius = radius, - }); - } + const auto radius = st::roundRadiusSmall; + _controller->checkHighlightControl( + u"main-menu/emoji-status"_q, + _setEmojiStatus, + { .margin = { -radius, 0, -radius, 0 }, .radius = radius }); } void MainMenu::setupMenu() { diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 91bf88746c..f210de4663 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -3692,6 +3692,19 @@ bool SessionController::takeHighlightControlId(const QString &id) { return _window->takeHighlightControlId(id); } +void SessionController::checkHighlightControl( + const QString &id, + QWidget *widget, + Settings::HighlightArgs &&args) { + _window->checkHighlightControl(id, widget, std::move(args)); +} + +void SessionController::checkHighlightControl( + const QString &id, + QWidget *widget) { + _window->checkHighlightControl(id, widget); +} + SessionController::~SessionController() { resetFakeUnreadWhileOpened(); dropSubsectionTabs(); diff --git a/Telegram/SourceFiles/window/window_session_controller.h b/Telegram/SourceFiles/window/window_session_controller.h index a1df1a4559..3853d1ebdc 100644 --- a/Telegram/SourceFiles/window/window_session_controller.h +++ b/Telegram/SourceFiles/window/window_session_controller.h @@ -90,6 +90,10 @@ namespace HistoryView::Reactions { class CachedIconFactory; } // namespace HistoryView::Reactions +namespace Settings { +struct HighlightArgs; +} // namespace Settings + namespace Window { using GifPauseReason = ChatHelpers::PauseReason; @@ -703,6 +707,11 @@ public: void setHighlightControlId(const QString &id); [[nodiscard]] QString highlightControlId() const; [[nodiscard]] bool takeHighlightControlId(const QString &id); + void checkHighlightControl( + const QString &id, + QWidget *widget, + Settings::HighlightArgs &&args); + void checkHighlightControl(const QString &id, QWidget *widget); [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime;