From db46f84f2ca22b5f582273bd3abf94e59d1ea479 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sat, 7 May 2022 02:47:57 +0300 Subject: [PATCH] Added initial implementation of cloud password management to settings. --- Telegram/CMakeLists.txt | 2 + Telegram/Resources/langs/lang.strings | 2 +- .../settings_cloud_password_email.cpp | 6 +- .../settings_cloud_password_manage.cpp | 231 ++++++++++++++++++ .../settings_cloud_password_manage.h | 17 ++ .../settings/settings_local_passcode.cpp | 2 +- 6 files changed, 257 insertions(+), 3 deletions(-) create mode 100644 Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp create mode 100644 Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index e9d46d619..1eb0d76e2 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1080,6 +1080,8 @@ PRIVATE settings/cloud_password/settings_cloud_password_hint.h settings/cloud_password/settings_cloud_password_input.cpp settings/cloud_password/settings_cloud_password_input.h + settings/cloud_password/settings_cloud_password_manage.cpp + settings/cloud_password/settings_cloud_password_manage.h settings/cloud_password/settings_cloud_password_start.cpp settings/cloud_password/settings_cloud_password_start.h settings/settings_advanced.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 7228bbccc..64e3ca476 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -492,7 +492,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_sessions_about" = "Control your sessions on other devices."; "lng_settings_passcode_disable" = "Disable Passcode"; "lng_settings_passcode_disable_sure" = "Are you sure you want to disable passcode?"; -"lng_settings_password_disable" = "Disable cloud password"; +"lng_settings_password_disable" = "Disable Cloud Password"; "lng_settings_password_abort" = "Abort two-step verification setup"; "lng_settings_password_reenter_email" = "Re-enter recovery email"; "lng_settings_about_bio" = "Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco"; diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp index c225e56df..432e537dc 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_email.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_cloud_password.h" #include "lang/lang_keys.h" #include "settings/cloud_password/settings_cloud_password_common.h" +#include "settings/cloud_password/settings_cloud_password_manage.h" #include "ui/boxes/confirm_box.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" @@ -86,8 +87,11 @@ void Email::setupContent() { _requestLifetime.destroy(); auto empty = StepData(); - empty.currentPassword = stepData().password; + empty.currentPassword = stepData().password.isEmpty() + ? stepData().currentPassword + : stepData().password; setStepData(std::move(empty)); + showOther(CloudPasswordManageId()); }); if (close) { diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp new file mode 100644 index 000000000..7e950eb08 --- /dev/null +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.cpp @@ -0,0 +1,231 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "settings/cloud_password/settings_cloud_password_manage.h" + +#include "api/api_cloud_password.h" +#include "core/core_cloud_password.h" +#include "lang/lang_keys.h" +#include "lottie/lottie_icon.h" +#include "settings/cloud_password/settings_cloud_password_common.h" +#include "settings/cloud_password/settings_cloud_password_email.h" +#include "settings/cloud_password/settings_cloud_password_hint.h" +#include "settings/cloud_password/settings_cloud_password_input.h" +#include "settings/cloud_password/settings_cloud_password_start.h" +#include "ui/boxes/confirm_box.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/labels.h" +#include "ui/wrap/vertical_layout.h" +#include "window/window_session_controller.h" +#include "styles/style_boxes.h" +#include "styles/style_layers.h" +#include "styles/style_settings.h" + +namespace Settings { +namespace CloudPassword { +namespace { + +void SetupTopContent( + not_null parent, + rpl::producer<> showFinished) { + const auto divider = Ui::CreateChild(parent.get()); + const auto verticalLayout = parent->add( + object_ptr(parent.get())); + + auto icon = CreateLottieIcon( + verticalLayout, + { + .name = u"cloud_password/intro"_q, + .sizeOverride = { + st::settingsFilterIconSize, + st::settingsFilterIconSize, + }, + }, + st::settingsFilterIconPadding); + std::move( + showFinished + ) | rpl::start_with_next([animate = std::move(icon.animate)] { + animate(anim::repeat::once); + }, verticalLayout->lifetime()); + verticalLayout->add(std::move(icon.widget)); + + verticalLayout->add( + object_ptr>( + verticalLayout, + object_ptr( + verticalLayout, + tr::lng_settings_cloud_password_manage_about1(), + st::settingsFilterDividerLabel)), + st::settingsFilterDividerLabelPadding); + + verticalLayout->geometryValue( + ) | rpl::start_with_next([=](const QRect &r) { + divider->setGeometry(r); + }, divider->lifetime()); + +} + +} // namespace + +class Manage : public TypedAbstractStep { +public: + using TypedAbstractStep::TypedAbstractStep; + + [[nodiscard]] rpl::producer title() override; + void setupContent(); + + [[nodiscard]] rpl::producer> removeFromStack() override; + + [[nodiscard]] QPointer createPinnedToBottom( + not_null parent) override; + +private: + rpl::variable _isBottomFillerShown; + + QString _currentPassword; + + rpl::lifetime _requestLifetime; + +}; + +rpl::producer Manage::title() { + return tr::lng_settings_cloud_password_start_title(); +} + +rpl::producer> Manage::removeFromStack() { + return rpl::single(std::vector{ + CloudPasswordStartId(), + CloudPasswordInputId(), + CloudPasswordHintId(), + CloudPasswordEmailId(), + CloudPasswordManageId(), + }); +} + +void Manage::setupContent() { + const auto content = Ui::CreateChild(this); + auto currentStepData = stepData(); + _currentPassword = base::take(currentStepData.currentPassword); + // If we go back from Password Manage to Privacy Settings + // we should forget the current password. + setStepData(std::move(currentStepData)); + + const auto state = cloudPassword().stateCurrent(); + if (!state) { + setStepData(StepData()); + showBack(); + return; + } + cloudPassword().state( + ) | rpl::start_with_next([=](const Core::CloudPasswordState &state) { + if (!_requestLifetime && !state.hasPassword) { + setStepData(StepData()); + showBack(); + } + }, lifetime()); + + SetupTopContent(content, showFinishes()); + + AddSkip(content); + AddButton( + content, + tr::lng_settings_cloud_password_manage_password_change(), + st::settingsButton, + { &st::settingsIconKey, kIconLightBlue } + )->setClickedCallback([=] { + // Remember the current password to have ability + // to return from Change Password to Password Manage. + auto data = stepData(); + data.currentPassword = _currentPassword; + setStepData(std::move(data)); + + showOther(CloudPasswordInputId()); + }); + AddButton( + content, + state->hasRecovery + ? tr::lng_settings_cloud_password_manage_email_change() + : tr::lng_settings_cloud_password_manage_email_new(), + st::settingsButton, + { &st::settingsIconEmail, kIconLightOrange } + )->setClickedCallback([=] { + }); + AddSkip(content); + + using Divider = CloudPassword::OneEdgeBoxContentDivider; + const auto divider = Ui::CreateChild(this); + divider->lower(); + const auto about = content->add( + object_ptr>( + content, + object_ptr( + content, + tr::lng_settings_cloud_password_manage_about2(), + st::boxDividerLabel), + st::settingsDividerLabelPadding)); + rpl::combine( + about->geometryValue(), + content->widthValue() + ) | rpl::start_with_next([=](QRect r, int w) { + r.setWidth(w); + divider->setGeometry(r); + }, divider->lifetime()); + _isBottomFillerShown.value( + ) | rpl::start_with_next([=](bool shown) { + divider->skipEdge(Qt::BottomEdge, shown); + }, divider->lifetime()); + + Ui::ResizeFitChild(this, content); +} + +QPointer Manage::createPinnedToBottom( + not_null parent) { + + const auto disable = [=](Fn close) { + if (_requestLifetime) { + return; + } + _requestLifetime = cloudPassword().set( + _currentPassword, + QString(), + QString(), + false, + QString() + ) | rpl::start_with_done([=] { + setStepData(StepData()); + close(); + showBack(); + }); + }; + + auto callback = [=] { + controller()->show( + Ui::MakeConfirmBox({ + .text = tr::lng_settings_cloud_password_manage_disable_sure(), + .confirmed = disable, + .confirmText = tr::lng_settings_auto_night_disable(), + .confirmStyle = &st::attentionBoxButton, + })); + }; + auto bottomButton = CloudPassword::CreateBottomDisableButton( + parent, + geometryValue(), + tr::lng_settings_password_disable(), + std::move(callback)); + + _isBottomFillerShown = base::take(bottomButton.isBottomFillerShown); + + return bottomButton.content; +} + +} // namespace CloudPassword + +Type CloudPasswordManageId() { + return CloudPassword::Manage::Id(); +} + +} // namespace Settings diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.h b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.h new file mode 100644 index 000000000..a54228708 --- /dev/null +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_manage.h @@ -0,0 +1,17 @@ +/* +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 Settings { + +Type CloudPasswordManageId(); + +} // namespace Settings + diff --git a/Telegram/SourceFiles/settings/settings_local_passcode.cpp b/Telegram/SourceFiles/settings/settings_local_passcode.cpp index 72f01c894..025807561 100644 --- a/Telegram/SourceFiles/settings/settings_local_passcode.cpp +++ b/Telegram/SourceFiles/settings/settings_local_passcode.cpp @@ -397,7 +397,7 @@ public: [[nodiscard]] rpl::producer> removeFromStack() override; [[nodiscard]] QPointer createPinnedToBottom( - not_null parent) override; + not_null parent) override; private: void setupContent();