diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 5e4efdbc25..1e7b918509 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1434,6 +1434,8 @@ PRIVATE settings/cloud_password/settings_cloud_password_input.h settings/cloud_password/settings_cloud_password_login_email.cpp settings/cloud_password/settings_cloud_password_login_email.h + settings/cloud_password/settings_cloud_password_login_email_confirm.cpp + settings/cloud_password/settings_cloud_password_login_email_confirm.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 diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email.cpp index e639b97b57..ee2de55865 100644 --- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email.cpp +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email.cpp @@ -13,7 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "main/main_session.h" #include "settings/cloud_password/settings_cloud_password_common.h" -#include "settings/cloud_password/settings_cloud_password_email_confirm.h" +#include "settings/cloud_password/settings_cloud_password_login_email_confirm.h" #include "settings/cloud_password/settings_cloud_password_manage.h" #include "settings/cloud_password/settings_cloud_password_step.h" #include "ui/boxes/confirm_box.h" @@ -92,7 +92,7 @@ void LoginEmail::setupContent() { auto data = stepData(); data.unconfirmedEmailLengthCode = length; setStepData(std::move(data)); - showOther(CloudPasswordEmailConfirmId()); + showOther(CloudLoginEmailConfirmId()); }; const auto fail = [=](const QString &type) { _api.reset(); diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.cpp new file mode 100644 index 0000000000..211c6dff48 --- /dev/null +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.cpp @@ -0,0 +1,181 @@ +/* +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_login_email_confirm.h" + +#include "api/api_cloud_password.h" +#include "apiwrap.h" +#include "base/unixtime.h" +#include "core/core_cloud_password.h" +#include "intro/intro_code_input.h" +#include "lang/lang_keys.h" +#include "main/main_session.h" +#include "mainwidget.h" +#include "settings/cloud_password/settings_cloud_password_common.h" +#include "settings/cloud_password/settings_cloud_password_login_email.h" +#include "settings/cloud_password/settings_cloud_password_step.h" +#include "ui/boxes/boost_box.h" // Ui::StartFireworks. +#include "ui/boxes/confirm_box.h" +#include "ui/text/text_utilities.h" +#include "ui/vertical_list.h" +#include "ui/widgets/buttons.h" +#include "ui/widgets/menu/menu_add_action_callback.h" +#include "ui/widgets/sent_code_field.h" +#include "ui/wrap/padding_wrap.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_menu_icons.h" +#include "styles/style_settings.h" + +/* +Available actions for follow states. + +LoginEmailConfirm from LoginEmail: +– Continue to Settings. +– Back to LoginEmail. +*/ + +namespace Settings { +namespace CloudPassword { + +class LoginEmailConfirm : public TypedAbstractStep { +public: + using TypedAbstractStep::TypedAbstractStep; + + [[nodiscard]] rpl::producer title() override; + + void setupContent(); + +protected: + [[nodiscard]] rpl::producer> removeTypes() override; + +private: + QString _collectedCode; + std::optional _api; + + rpl::event_stream<> _processFinishes; + +}; + +rpl::producer> LoginEmailConfirm::removeTypes() { + return _processFinishes.events() | rpl::map([] { + return std::vector{ CloudLoginEmailId() }; + }); +} + +rpl::producer LoginEmailConfirm::title() { + return tr::lng_settings_cloud_login_email_section_title(); +} + +void LoginEmailConfirm::setupContent() { + const auto content = Ui::CreateChild(this); + auto currentStepData = stepData(); + const auto currentStepDataCodeLength = base::take( + currentStepData.unconfirmedEmailLengthCode); + const auto newEmail = currentStepData.email; + setStepData(currentStepData); + + if (!currentStepDataCodeLength) { + setStepData(StepData()); + showBack(); + return; + } + cloudPassword().state( + ) | rpl::start_with_next([=](const Core::CloudPasswordState &state) { + if (state.loginEmailPattern.isEmpty()) { + setStepData(StepData()); + showBack(); + } + }, lifetime()); + + SetupHeader( + content, + u"cloud_password/email"_q, + showFinishes(), + tr::lng_settings_cloud_login_email_code_title(), + tr::lng_settings_cloud_login_email_code_about( + lt_email, + rpl::single(Ui::Text::WrapEmailPattern(newEmail)), + TextWithEntities::Simple)); + + Ui::AddSkip(content, st::settingLocalPasscodeDescriptionBottomSkip); + + const auto wrap = content->add( + object_ptr>( + content, + object_ptr(content))); + const auto newInput = wrap->entity(); + newInput->setDigitsCountMax(currentStepDataCodeLength); + + Ui::AddSkip(content); + const auto error = AddError(content, nullptr); + AddSkipInsteadOfField(content); + + const auto submit = [=] { + _api.emplace(&controller()->session().mtp()); + const auto newText = _collectedCode; + if (newText.isEmpty()) { + newInput->setFocus(); + newInput->showError(); + } else { + const auto weak = Ui::MakeWeak(controller()->content()); + const auto done = [=] { + _api.reset(); + _processFinishes.fire({}); + cloudPassword().reload(); + setStepData(StepData()); + showBack(); + if (const auto strong = weak) { + Ui::StartFireworks(strong); + } + }; + const auto fail = [=](const QString &type) { + _api.reset(); + + newInput->setFocus(); + newInput->showError(); + error->show(); + + if (MTP::IsFloodError(type)) { + error->setText(tr::lng_flood_error(tr::now)); + } else if (type == u"EMAIL_NOT_ALLOWED"_q) { + error->setText( + tr::lng_settings_error_email_not_alowed(tr::now)); + } else if (type == u"CODE_INVALID"_q) { + error->setText(tr::lng_signin_wrong_code(tr::now)); + } else if (type == u"EMAIL_HASH_EXPIRED"_q) { + // Show box? + error->setText(Lang::Hard::EmailConfirmationExpired()); + } else { + error->setText(Lang::Hard::ServerError()); + } + }; + Api::VerifyLoginEmail(*_api, newText, done, fail); + } + }; + + newInput->codeCollected( + ) | rpl::start_with_next([=](const QString &code) { + _collectedCode = code; + error->hide(); + submit(); + }, lifetime()); + + setFocusCallback([=] { newInput->setFocus(); }); + + Ui::ResizeFitChild(this, content); +} + +} // namespace CloudPassword + +Type CloudLoginEmailConfirmId() { + return CloudPassword::LoginEmailConfirm::Id(); +} + +} // namespace Settings diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.h b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.h new file mode 100644 index 0000000000..6acfb53227 --- /dev/null +++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_login_email_confirm.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 CloudLoginEmailConfirmId(); + +} // namespace Settings +