Improved step section of password input for checking cloud password.

This commit is contained in:
23rd 2022-05-07 03:58:41 +03:00
parent db46f84f2c
commit 3967e58627

View file

@ -7,11 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "settings/cloud_password/settings_cloud_password_input.h" #include "settings/cloud_password/settings_cloud_password_input.h"
#include "api/api_cloud_password.h"
#include "base/qt_signal_producer.h" #include "base/qt_signal_producer.h"
#include "core/core_cloud_password.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "lottie/lottie_icon.h" #include "lottie/lottie_icon.h"
#include "settings/cloud_password/settings_cloud_password_common.h" #include "settings/cloud_password/settings_cloud_password_common.h"
#include "settings/cloud_password/settings_cloud_password_hint.h" #include "settings/cloud_password/settings_cloud_password_hint.h"
#include "settings/cloud_password/settings_cloud_password_manage.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
@ -65,6 +68,9 @@ public:
[[nodiscard]] rpl::producer<QString> title() override; [[nodiscard]] rpl::producer<QString> title() override;
void setupContent(); void setupContent();
private:
rpl::lifetime _requestLifetime;
}; };
rpl::producer<QString> Input::title() { rpl::producer<QString> Input::title() {
@ -77,6 +83,10 @@ void Input::setupContent() {
const auto currentStepDataPassword = base::take(currentStepData.password); const auto currentStepDataPassword = base::take(currentStepData.password);
setStepData(currentStepData); setStepData(currentStepData);
const auto currentState = cloudPassword().stateCurrent();
const auto hasPassword = currentState ? currentState->hasPassword : false;
const auto isCheck = stepData().currentPassword.isEmpty() && hasPassword;
const auto icon = CreateInteractiveLottieIcon( const auto icon = CreateInteractiveLottieIcon(
content, content,
{ {
@ -92,41 +102,108 @@ void Input::setupContent() {
content, content,
QString(), QString(),
rpl::never<>(), rpl::never<>(),
tr::lng_settings_cloud_password_password_subtitle(), isCheck
? tr::lng_settings_cloud_password_check_subtitle()
: hasPassword
? tr::lng_settings_cloud_password_manage_password_change()
: tr::lng_settings_cloud_password_password_subtitle(),
tr::lng_cloud_password_about()); tr::lng_cloud_password_about());
AddSkip(content, st::settingLocalPasscodeDescriptionBottomSkip); AddSkip(content, st::settingLocalPasscodeDescriptionBottomSkip);
const auto newInput = AddPasswordField( const auto newInput = AddPasswordField(
content, content,
tr::lng_cloud_password_enter_new(), isCheck
currentStepDataPassword); ? tr::lng_cloud_password_enter_old()
const auto reenterInput = AddPasswordField( : tr::lng_cloud_password_enter_new(),
content, currentStepDataPassword);
tr::lng_cloud_password_confirm_new(), const auto reenterInput = isCheck
currentStepDataPassword); ? (Ui::PasswordInput*)(nullptr)
const auto error = AddError(content, reenterInput); : AddPasswordField(
content,
tr::lng_cloud_password_confirm_new(),
currentStepDataPassword).get();
const auto error = AddError(content, newInput);
if (reenterInput) {
QObject::connect(reenterInput, &Ui::MaskedInputField::changed, [=] {
error->hide();
});
}
if (isCheck) {
const auto hint = currentState ? currentState->hint : QString();
const auto hintInfo = Ui::CreateChild<Ui::FlatLabel>(
error->parentWidget(),
tr::lng_signin_hint(tr::now, lt_password_hint, hint),
st::defaultFlatLabel);
hintInfo->setVisible(!hint.isEmpty());
error->geometryValue(
) | rpl::start_with_next([=](const QRect &r) {
hintInfo->setGeometry(r);
}, hintInfo->lifetime());
error->shownValue(
) | rpl::start_with_next([=](bool shown) {
if (shown) {
hintInfo->hide();
} else {
hintInfo->setVisible(!hint.isEmpty());
}
}, hintInfo->lifetime());
}
if (!newInput->text().isEmpty()) { if (!newInput->text().isEmpty()) {
icon.icon->jumpTo(icon.icon->framesCount() / 2, icon.update); icon.icon->jumpTo(icon.icon->framesCount() / 2, icon.update);
} }
const auto button = AddDoneButton(content, tr::lng_continue()); const auto checkPassword = [=](const QString &pass) {
if (_requestLifetime) {
return;
}
_requestLifetime = cloudPassword().check(
pass
) | rpl::start_with_error_done([=](const QString &type) {
_requestLifetime.destroy();
newInput->setFocus();
newInput->showError();
newInput->selectAll();
error->show();
if (type == u"PASSWORD_HASH_INVALID"_q
|| type == u"SRP_PASSWORD_CHANGED"_q) {
error->setText(tr::lng_cloud_password_wrong(tr::now));
} else {
error->setText(Lang::Hard::ServerError());
}
}, [=] {
_requestLifetime.destroy();
auto data = stepData();
data.currentPassword = pass;
setStepData(std::move(data));
showOther(CloudPasswordManageId());
});
};
const auto button = AddDoneButton(
content,
isCheck ? tr::lng_passcode_check_button() : tr::lng_continue());
button->setClickedCallback([=] { button->setClickedCallback([=] {
const auto newText = newInput->text(); const auto newText = newInput->text();
const auto reenterText = reenterInput->text(); const auto reenterText = isCheck ? QString() : reenterInput->text();
if (newText.isEmpty()) { if (newText.isEmpty()) {
newInput->setFocus(); newInput->setFocus();
newInput->showError(); newInput->showError();
} else if (reenterText.isEmpty()) { } else if (reenterInput && reenterText.isEmpty()) {
reenterInput->setFocus(); reenterInput->setFocus();
reenterInput->showError(); reenterInput->showError();
} else if (newText != reenterText) { } else if (reenterInput && (newText != reenterText)) {
reenterInput->setFocus(); reenterInput->setFocus();
reenterInput->showError(); reenterInput->showError();
reenterInput->selectAll(); reenterInput->selectAll();
error->show(); error->show();
error->setText(tr::lng_cloud_password_differ(tr::now)); error->setText(tr::lng_cloud_password_differ(tr::now));
} else if (isCheck) {
checkPassword(newText);
} else { } else {
auto data = stepData(); auto data = stepData();
data.password = newText; data.password = newText;
@ -148,17 +225,20 @@ void Input::setupContent() {
}, content->lifetime()); }, content->lifetime());
const auto submit = [=] { const auto submit = [=] {
if (reenterInput->hasFocus()) { if (!reenterInput || reenterInput->hasFocus()) {
button->clicked({}, Qt::LeftButton); button->clicked({}, Qt::LeftButton);
} else { } else {
reenterInput->setFocus(); reenterInput->setFocus();
} }
}; };
QObject::connect(newInput, &Ui::MaskedInputField::submitted, submit); QObject::connect(newInput, &Ui::MaskedInputField::submitted, submit);
QObject::connect(reenterInput, &Ui::MaskedInputField::submitted, submit); if (reenterInput) {
using namespace Ui;
QObject::connect(reenterInput, &MaskedInputField::submitted, submit);
}
setFocusCallback([=] { setFocusCallback([=] {
if (newInput->text().isEmpty()) { if (isCheck || newInput->text().isEmpty()) {
newInput->setFocus(); newInput->setFocus();
} else if (reenterInput->text().isEmpty()) { } else if (reenterInput->text().isEmpty()) {
reenterInput->setFocus(); reenterInput->setFocus();