mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added step section of password input to cloud password settings.
This commit is contained in:
parent
5a4d1a1e85
commit
5e2acdeaa3
9 changed files with 234 additions and 6 deletions
|
@ -1074,6 +1074,8 @@ PRIVATE
|
||||||
profile/profile_cover_drop_area.h
|
profile/profile_cover_drop_area.h
|
||||||
settings/cloud_password/settings_cloud_password_common.cpp
|
settings/cloud_password/settings_cloud_password_common.cpp
|
||||||
settings/cloud_password/settings_cloud_password_common.h
|
settings/cloud_password/settings_cloud_password_common.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
|
settings/cloud_password/settings_cloud_password_start.cpp
|
||||||
settings/cloud_password/settings_cloud_password_start.h
|
settings/cloud_password/settings_cloud_password_start.h
|
||||||
settings/settings_advanced.cpp
|
settings/settings_advanced.cpp
|
||||||
|
|
BIN
Telegram/Resources/animations/cloud_password/password_input.tgs
Normal file
BIN
Telegram/Resources/animations/cloud_password/password_input.tgs
Normal file
Binary file not shown.
|
@ -699,8 +699,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_cloud_password_reset_cancel" = "Cancel password reset";
|
"lng_cloud_password_reset_cancel" = "Cancel password reset";
|
||||||
"lng_cloud_password_enter_old" = "Enter current password";
|
"lng_cloud_password_enter_old" = "Enter current password";
|
||||||
"lng_cloud_password_enter_first" = "Enter a password";
|
"lng_cloud_password_enter_first" = "Enter a password";
|
||||||
"lng_cloud_password_enter_new" = "Enter new password";
|
"lng_cloud_password_enter_new" = "Enter password";
|
||||||
"lng_cloud_password_confirm_new" = "Re-enter new 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_change_hint" = "Enter new password hint";
|
||||||
"lng_cloud_password_bad" = "Password and hint cannot be the same.";
|
"lng_cloud_password_bad" = "Password and hint cannot be the same.";
|
||||||
|
|
|
@ -5,5 +5,6 @@
|
||||||
<file alias="filters.tgs">../../animations/filters.tgs</file>
|
<file alias="filters.tgs">../../animations/filters.tgs</file>
|
||||||
<file alias="local_passcode_enter.tgs">../../animations/local_passcode_enter.tgs</file>
|
<file alias="local_passcode_enter.tgs">../../animations/local_passcode_enter.tgs</file>
|
||||||
<file alias="cloud_password/intro.tgs">../../animations/cloud_password/intro.tgs</file>
|
<file alias="cloud_password/intro.tgs">../../animations/cloud_password/intro.tgs</file>
|
||||||
|
<file alias="cloud_password/password_input.tgs">../../animations/cloud_password/password_input.tgs</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -244,6 +244,24 @@ rpl::producer<> AbstractStep::sectionShowBack() {
|
||||||
return _showBack.events();
|
return _showBack.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractStep::setStepDataReference(std::any &data) {
|
||||||
|
_stepData = &data;
|
||||||
|
}
|
||||||
|
|
||||||
|
StepData AbstractStep::stepData() const {
|
||||||
|
if (!_stepData || !_stepData->has_value()) {
|
||||||
|
StepData();
|
||||||
|
}
|
||||||
|
const auto my = std::any_cast<StepData>(_stepData);
|
||||||
|
return my ? (*my) : StepData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractStep::setStepData(StepData data) {
|
||||||
|
if (_stepData) {
|
||||||
|
*_stepData = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AbstractStep::~AbstractStep() = default;
|
AbstractStep::~AbstractStep() = default;
|
||||||
|
|
||||||
} // namespace Settings::CloudPassword
|
} // namespace Settings::CloudPassword
|
||||||
|
|
|
@ -19,6 +19,10 @@ class VerticalLayout;
|
||||||
|
|
||||||
namespace Settings::CloudPassword {
|
namespace Settings::CloudPassword {
|
||||||
|
|
||||||
|
struct StepData {
|
||||||
|
QString password;
|
||||||
|
};
|
||||||
|
|
||||||
void SetupHeader(
|
void SetupHeader(
|
||||||
not_null<Ui::VerticalLayout*> content,
|
not_null<Ui::VerticalLayout*> content,
|
||||||
const QString &lottie,
|
const QString &lottie,
|
||||||
|
@ -79,6 +83,8 @@ public:
|
||||||
[[nodiscard]] rpl::producer<Type> sectionShowOther() override;
|
[[nodiscard]] rpl::producer<Type> sectionShowOther() override;
|
||||||
[[nodiscard]] rpl::producer<> sectionShowBack() override;
|
[[nodiscard]] rpl::producer<> sectionShowBack() override;
|
||||||
|
|
||||||
|
void setStepDataReference(std::any &data) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[nodiscard]] not_null<Window::SessionController*> controller() const;
|
[[nodiscard]] not_null<Window::SessionController*> controller() const;
|
||||||
|
|
||||||
|
@ -89,6 +95,9 @@ protected:
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<> showFinishes() const;
|
[[nodiscard]] rpl::producer<> showFinishes() const;
|
||||||
|
|
||||||
|
StepData stepData() const;
|
||||||
|
void setStepData(StepData data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
|
|
||||||
|
@ -98,15 +107,17 @@ private:
|
||||||
rpl::event_stream<Type> _showOther;
|
rpl::event_stream<Type> _showOther;
|
||||||
rpl::event_stream<> _showBack;
|
rpl::event_stream<> _showBack;
|
||||||
|
|
||||||
|
std::any *_stepData;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename SectionType>
|
template <typename SectionType>
|
||||||
class TypedAbstractStep : public AbstractStep {
|
class TypedAbstractStep : public AbstractStep {
|
||||||
public:
|
public:
|
||||||
TypedAbstractStep(
|
using AbstractStep::AbstractStep;
|
||||||
QWidget *parent,
|
|
||||||
not_null<Window::SessionController*> controller)
|
void setStepDataReference(std::any &data) override final {
|
||||||
: AbstractStep(parent, controller) {
|
AbstractStep::setStepDataReference(data);
|
||||||
static_cast<SectionType*>(this)->setupContent();
|
static_cast<SectionType*>(this)->setupContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
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_input.h"
|
||||||
|
|
||||||
|
#include "base/qt_signal_producer.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "lottie/lottie_icon.h"
|
||||||
|
#include "settings/cloud_password/settings_cloud_password_common.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/widgets/input_fields.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
#include "styles/style_boxes.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
namespace CloudPassword {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct Icon {
|
||||||
|
not_null<Lottie::Icon*> icon;
|
||||||
|
Fn<void()> update;
|
||||||
|
};
|
||||||
|
|
||||||
|
Icon CreateInteractiveLottieIcon(
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
Lottie::IconDescriptor &&descriptor,
|
||||||
|
style::margins padding) {
|
||||||
|
auto object = object_ptr<Ui::RpWidget>(container);
|
||||||
|
const auto raw = object.data();
|
||||||
|
|
||||||
|
const auto width = descriptor.sizeOverride.width();
|
||||||
|
raw->resize(QRect(
|
||||||
|
QPoint(),
|
||||||
|
descriptor.sizeOverride).marginsAdded(padding).size());
|
||||||
|
|
||||||
|
auto owned = Lottie::MakeIcon(std::move(descriptor));
|
||||||
|
const auto icon = owned.get();
|
||||||
|
|
||||||
|
raw->lifetime().add([kept = std::move(owned)]{});
|
||||||
|
|
||||||
|
raw->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(raw);
|
||||||
|
const auto left = (raw->width() - width) / 2;
|
||||||
|
icon->paint(p, left, padding.top());
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
container->add(std::move(object));
|
||||||
|
return { .icon = icon, .update = [=] { raw->update(); } };
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class Input : public TypedAbstractStep<Input> {
|
||||||
|
public:
|
||||||
|
using TypedAbstractStep::TypedAbstractStep;
|
||||||
|
|
||||||
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
void setupContent();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
rpl::producer<QString> Input::title() {
|
||||||
|
return tr::lng_settings_cloud_password_password_title();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::setupContent() {
|
||||||
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
auto currentStepData = stepData();
|
||||||
|
const auto currentStepDataPassword = base::take(currentStepData.password);
|
||||||
|
setStepData(currentStepData);
|
||||||
|
|
||||||
|
const auto icon = CreateInteractiveLottieIcon(
|
||||||
|
content,
|
||||||
|
{
|
||||||
|
.name = u"cloud_password/password_input"_q,
|
||||||
|
.sizeOverride = {
|
||||||
|
st::changePhoneIconSize,
|
||||||
|
st::changePhoneIconSize
|
||||||
|
},
|
||||||
|
},
|
||||||
|
st::settingLocalPasscodeIconPadding);
|
||||||
|
|
||||||
|
SetupHeader(
|
||||||
|
content,
|
||||||
|
QString(),
|
||||||
|
rpl::never<>(),
|
||||||
|
tr::lng_settings_cloud_password_password_subtitle(),
|
||||||
|
tr::lng_cloud_password_about());
|
||||||
|
|
||||||
|
AddSkip(content, st::settingLocalPasscodeDescriptionBottomSkip);
|
||||||
|
|
||||||
|
const auto newInput = AddPasswordField(
|
||||||
|
content,
|
||||||
|
tr::lng_cloud_password_enter_new(),
|
||||||
|
currentStepDataPassword);
|
||||||
|
const auto reenterInput = AddPasswordField(
|
||||||
|
content,
|
||||||
|
tr::lng_cloud_password_confirm_new(),
|
||||||
|
currentStepDataPassword);
|
||||||
|
const auto error = AddError(content, reenterInput);
|
||||||
|
|
||||||
|
if (!newInput->text().isEmpty()) {
|
||||||
|
icon.icon->jumpTo(icon.icon->framesCount() / 2, icon.update);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto button = AddDoneButton(content, tr::lng_continue());
|
||||||
|
button->setClickedCallback([=] {
|
||||||
|
const auto newText = newInput->text();
|
||||||
|
const auto reenterText = reenterInput->text();
|
||||||
|
if (newText.isEmpty()) {
|
||||||
|
newInput->setFocus();
|
||||||
|
newInput->showError();
|
||||||
|
} else if (reenterText.isEmpty()) {
|
||||||
|
reenterInput->setFocus();
|
||||||
|
reenterInput->showError();
|
||||||
|
} else if (newText != reenterText) {
|
||||||
|
reenterInput->setFocus();
|
||||||
|
reenterInput->showError();
|
||||||
|
reenterInput->selectAll();
|
||||||
|
error->show();
|
||||||
|
error->setText(tr::lng_cloud_password_differ(tr::now));
|
||||||
|
} else {
|
||||||
|
auto data = stepData();
|
||||||
|
data.password = newText;
|
||||||
|
setStepData(std::move(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
base::qt_signal_producer(
|
||||||
|
newInput.get(),
|
||||||
|
&QLineEdit::textChanged // Covers Undo.
|
||||||
|
) | rpl::map([=] {
|
||||||
|
return newInput->text().isEmpty();
|
||||||
|
}) | rpl::distinct_until_changed(
|
||||||
|
) | rpl::start_with_next([=](bool empty) {
|
||||||
|
const auto from = icon.icon->frameIndex();
|
||||||
|
const auto to = empty ? 0 : (icon.icon->framesCount() / 2 - 1);
|
||||||
|
icon.icon->animate(icon.update, from, to);
|
||||||
|
}, content->lifetime());
|
||||||
|
|
||||||
|
const auto submit = [=] {
|
||||||
|
if (reenterInput->hasFocus()) {
|
||||||
|
button->clicked({}, Qt::LeftButton);
|
||||||
|
} else {
|
||||||
|
reenterInput->setFocus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
QObject::connect(newInput, &Ui::MaskedInputField::submitted, submit);
|
||||||
|
QObject::connect(reenterInput, &Ui::MaskedInputField::submitted, submit);
|
||||||
|
|
||||||
|
setFocusCallback([=] {
|
||||||
|
if (newInput->text().isEmpty()) {
|
||||||
|
newInput->setFocus();
|
||||||
|
} else if (reenterInput->text().isEmpty()) {
|
||||||
|
reenterInput->setFocus();
|
||||||
|
} else {
|
||||||
|
newInput->setFocus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace CloudPassword
|
||||||
|
|
||||||
|
Type CloudPasswordInputId() {
|
||||||
|
return CloudPassword::Input::Id();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -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 CloudPasswordInputId();
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.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_input.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "styles/style_settings.h"
|
#include "styles/style_settings.h"
|
||||||
|
@ -49,6 +50,7 @@ void Start::setupContent() {
|
||||||
content,
|
content,
|
||||||
tr::lng_settings_cloud_password_password_subtitle()
|
tr::lng_settings_cloud_password_password_subtitle()
|
||||||
)->setClickedCallback([=] {
|
)->setClickedCallback([=] {
|
||||||
|
showOther(CloudPasswordInputId());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ui::ResizeFitChild(this, content);
|
Ui::ResizeFitChild(this, content);
|
||||||
|
|
Loading…
Add table
Reference in a new issue