diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt
index dd4a7fe51..9149029ae 100644
--- a/Telegram/CMakeLists.txt
+++ b/Telegram/CMakeLists.txt
@@ -1074,6 +1074,8 @@ PRIVATE
profile/profile_cover_drop_area.h
settings/cloud_password/settings_cloud_password_common.cpp
settings/cloud_password/settings_cloud_password_common.h
+ settings/cloud_password/settings_cloud_password_hint.cpp
+ 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_start.cpp
diff --git a/Telegram/Resources/animations/cloud_password/hint.tgs b/Telegram/Resources/animations/cloud_password/hint.tgs
new file mode 100644
index 000000000..c85dd321d
Binary files /dev/null and b/Telegram/Resources/animations/cloud_password/hint.tgs differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 9060e836b..600a48a4c 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -561,6 +561,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_cloud_password_manage_email_new" = "Set Recovery Email";
"lng_settings_cloud_password_manage_email_change" = "Change Recovery Email";
"lng_settings_cloud_password_manage_password_change" = "Change Password";
+"lng_settings_cloud_password_skip_hint" = "Skip hint";
"lng_clear_payment_info_title" = "Clear payment info";
"lng_clear_payment_info_sure" = "Are you sure you want to clear your payment and shipping info?";
@@ -701,7 +702,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_cloud_password_enter_first" = "Enter a password";
"lng_cloud_password_enter_new" = "Enter password";
"lng_cloud_password_confirm_new" = "Re-enter password";
-"lng_cloud_password_hint" = "Enter password hint";
+"lng_cloud_password_hint" = "Enter Password Hint";
"lng_cloud_password_change_hint" = "Enter new password hint";
"lng_cloud_password_bad" = "Password and hint cannot be the same.";
"lng_cloud_password_email" = "Enter recovery email";
diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc
index 3b435db30..f8590c6bb 100644
--- a/Telegram/Resources/qrc/telegram/animations.qrc
+++ b/Telegram/Resources/qrc/telegram/animations.qrc
@@ -6,5 +6,6 @@
../../animations/local_passcode_enter.tgs
../../animations/cloud_password/intro.tgs
../../animations/cloud_password/password_input.tgs
+ ../../animations/cloud_password/hint.tgs
diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp
index fc9a3c9fc..c1414a27a 100644
--- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp
+++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.cpp
@@ -150,6 +150,19 @@ not_null AddPasswordField(
return field;
}
+not_null*> AddWrappedField(
+ not_null content,
+ rpl::producer &&placeholder,
+ const QString &text) {
+ return content->add(object_ptr>(
+ content,
+ object_ptr(
+ content,
+ st::settingLocalPasscodeInputField,
+ std::move(placeholder),
+ text)));
+}
+
not_null AddError(
not_null content,
Ui::PasswordInput *input) {
diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h
index 19db8ab35..cd226079d 100644
--- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h
+++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_common.h
@@ -11,7 +11,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/box_content_divider.h"
namespace Ui {
+template
+class CenterWrap;
class FlatLabel;
+class InputField;
class PasswordInput;
class RoundButton;
class VerticalLayout;
@@ -21,6 +24,7 @@ namespace Settings::CloudPassword {
struct StepData {
QString password;
+ QString hint;
};
void SetupHeader(
@@ -35,6 +39,11 @@ void SetupHeader(
rpl::producer &&placeholder,
const QString &text);
+[[nodiscard]] not_null*> AddWrappedField(
+ not_null content,
+ rpl::producer &&placeholder,
+ const QString &text);
+
[[nodiscard]] not_null AddError(
not_null content,
Ui::PasswordInput *input);
diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.cpp
new file mode 100644
index 000000000..b847268a0
--- /dev/null
+++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.cpp
@@ -0,0 +1,112 @@
+/*
+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_hint.h"
+
+#include "lang/lang_keys.h"
+#include "settings/cloud_password/settings_cloud_password_common.h"
+#include "settings/cloud_password/settings_cloud_password_email.h"
+#include "ui/widgets/buttons.h"
+#include "ui/widgets/input_fields.h"
+#include "ui/widgets/labels.h"
+#include "ui/wrap/padding_wrap.h"
+#include "ui/wrap/vertical_layout.h"
+#include "styles/style_boxes.h"
+#include "styles/style_settings.h"
+
+namespace Settings {
+namespace CloudPassword {
+
+class Hint : public TypedAbstractStep {
+public:
+ using TypedAbstractStep::TypedAbstractStep;
+
+ [[nodiscard]] rpl::producer title() override;
+ void setupContent();
+
+};
+
+rpl::producer Hint::title() {
+ return tr::lng_settings_cloud_password_hint_title();
+}
+
+void Hint::setupContent() {
+ const auto content = Ui::CreateChild(this);
+ auto currentStepData = stepData();
+ const auto currentStepDataHint = base::take(currentStepData.hint);
+ setStepData(currentStepData);
+
+ SetupHeader(
+ content,
+ u"cloud_password/hint"_q,
+ showFinishes(),
+ tr::lng_settings_cloud_password_hint_subtitle(),
+ tr::lng_settings_cloud_password_hint_about());
+
+ AddSkip(content, st::settingLocalPasscodeDescriptionBottomSkip);
+
+ const auto wrap = AddWrappedField(
+ content,
+ tr::lng_cloud_password_hint(),
+ currentStepDataHint);
+ const auto newInput = wrap->entity();
+ const auto error = AddError(content, nullptr);
+ QObject::connect(newInput, &Ui::InputField::changed, [=] {
+ error->hide();
+ });
+ AddSkipInsteadOfField(content);
+
+ const auto save = [=](const QString &hint) {
+ auto data = stepData();
+ data.hint = hint;
+ setStepData(std::move(data));
+ showOther(CloudPasswordEmailId());
+ };
+
+ const auto skip = Ui::CreateChild(
+ this,
+ tr::lng_settings_cloud_password_skip_hint(tr::now));
+ wrap->geometryValue(
+ ) | rpl::start_with_next([=](QRect r) {
+ r.translate(wrap->entity()->pos().x(), 0);
+ skip->moveToLeft(r.x(), r.y() + r.height() + st::passcodeTextLine);
+ }, skip->lifetime());
+ skip->setClickedCallback([=] {
+ save(QString());
+ });
+
+ const auto button = AddDoneButton(content, tr::lng_continue());
+ button->setClickedCallback([=] {
+ const auto newText = newInput->getLastText();
+ if (newText.isEmpty()) {
+ newInput->setFocus();
+ newInput->showError();
+ } else if (newText == stepData().password) {
+ error->show();
+ error->setText(tr::lng_cloud_password_bad(tr::now));
+ newInput->setFocus();
+ newInput->showError();
+ } else {
+ save(newText);
+ }
+ });
+
+ const auto submit = [=] { button->clicked({}, Qt::LeftButton); };
+ QObject::connect(newInput, &Ui::InputField::submitted, submit);
+
+ setFocusCallback([=] { newInput->setFocus(); });
+
+ Ui::ResizeFitChild(this, content);
+}
+
+} // namespace CloudPassword
+
+Type CloudPasswordHintId() {
+ return CloudPassword::Hint::Id();
+}
+
+} // namespace Settings
diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.h b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.h
new file mode 100644
index 000000000..6a4df1097
--- /dev/null
+++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_hint.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 CloudPasswordHintId();
+
+} // namespace Settings
+
diff --git a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp
index 907ced39c..80ba14bc7 100644
--- a/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp
+++ b/Telegram/SourceFiles/settings/cloud_password/settings_cloud_password_input.cpp
@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#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_hint.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
@@ -130,6 +131,7 @@ void Input::setupContent() {
auto data = stepData();
data.password = newText;
setStepData(std::move(data));
+ showOther(CloudPasswordHintId());
}
});