mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-26 23:43:06 +02:00
Added support of suggestion to validate cloud password to settings.
This commit is contained in:
parent
727acca217
commit
1ae3122c20
12 changed files with 324 additions and 30 deletions
|
@ -1446,6 +1446,8 @@ PRIVATE
|
||||||
settings/cloud_password/settings_cloud_password_start.h
|
settings/cloud_password/settings_cloud_password_start.h
|
||||||
settings/cloud_password/settings_cloud_password_step.cpp
|
settings/cloud_password/settings_cloud_password_step.cpp
|
||||||
settings/cloud_password/settings_cloud_password_step.h
|
settings/cloud_password/settings_cloud_password_step.h
|
||||||
|
settings/cloud_password/settings_cloud_password_validate_icon.cpp
|
||||||
|
settings/cloud_password/settings_cloud_password_validate_icon.h
|
||||||
settings/settings_active_sessions.cpp
|
settings/settings_active_sessions.cpp
|
||||||
settings/settings_active_sessions.h
|
settings/settings_active_sessions.h
|
||||||
settings/settings_advanced.cpp
|
settings/settings_advanced.cpp
|
||||||
|
|
BIN
Telegram/Resources/animations/cloud_password/validate.tgs
Normal file
BIN
Telegram/Resources/animations/cloud_password/validate.tgs
Normal file
Binary file not shown.
|
@ -840,6 +840,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_suggestion_phone_number_about" = "Keep your number up to date to ensure you can always log into Telegram. {link}";
|
"lng_settings_suggestion_phone_number_about" = "Keep your number up to date to ensure you can always log into Telegram. {link}";
|
||||||
"lng_settings_suggestion_phone_number_about_link" = "https://telegram.org/faq#q-i-have-a-new-phone-number-what-do-i-do";
|
"lng_settings_suggestion_phone_number_about_link" = "https://telegram.org/faq#q-i-have-a-new-phone-number-what-do-i-do";
|
||||||
"lng_settings_suggestion_phone_number_change" = "Please change your phone number in the official Telegram app on your phone as soon as possible. {emoji}";
|
"lng_settings_suggestion_phone_number_change" = "Please change your phone number in the official Telegram app on your phone as soon as possible. {emoji}";
|
||||||
|
"lng_settings_suggestion_password_title" = "Your password";
|
||||||
|
"lng_settings_suggestion_password_about" = "Your account is protected by 2-Step Veritifaction. Do you still remember your password?";
|
||||||
|
"lng_settings_suggestion_password_yes" = "Yes, definitely";
|
||||||
|
"lng_settings_suggestion_password_no" = "Not sure";
|
||||||
|
"lng_settings_suggestion_password_step_input_title" = "Enter your password";
|
||||||
|
"lng_settings_suggestion_password_step_input_about" = "Do you still remember your password?";
|
||||||
|
"lng_settings_suggestion_password_step_finish_title" = "Perfect!";
|
||||||
|
"lng_settings_suggestion_password_step_finish_about" = "You still remember your password.";
|
||||||
|
|
||||||
"lng_settings_power_menu" = "Battery and Animations";
|
"lng_settings_power_menu" = "Battery and Animations";
|
||||||
"lng_settings_power_title" = "Power Usage";
|
"lng_settings_power_title" = "Power Usage";
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<file alias="cloud_password/password_input.tgs">../../animations/cloud_password/password_input.tgs</file>
|
<file alias="cloud_password/password_input.tgs">../../animations/cloud_password/password_input.tgs</file>
|
||||||
<file alias="cloud_password/hint.tgs">../../animations/cloud_password/hint.tgs</file>
|
<file alias="cloud_password/hint.tgs">../../animations/cloud_password/hint.tgs</file>
|
||||||
<file alias="cloud_password/email.tgs">../../animations/cloud_password/email.tgs</file>
|
<file alias="cloud_password/email.tgs">../../animations/cloud_password/email.tgs</file>
|
||||||
|
<file alias="cloud_password/validate.tgs">../../animations/cloud_password/validate.tgs</file>
|
||||||
<file alias="ttl.tgs">../../animations/ttl.tgs</file>
|
<file alias="ttl.tgs">../../animations/ttl.tgs</file>
|
||||||
<file alias="discussion.tgs">../../animations/discussion.tgs</file>
|
<file alias="discussion.tgs">../../animations/discussion.tgs</file>
|
||||||
<file alias="stats.tgs">../../animations/stats.tgs</file>
|
<file alias="stats.tgs">../../animations/stats.tgs</file>
|
||||||
|
|
|
@ -306,4 +306,9 @@ std::optional<UserIds> PromoSuggestions::knownBirthdaysToday() const {
|
||||||
return _contactBirthdaysToday;
|
return _contactBirthdaysToday;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString PromoSuggestions::SugValidatePassword() {
|
||||||
|
static const auto key = u"VALIDATE_PASSWORD"_q;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
[[nodiscard]] auto knownBirthdaysToday() const
|
[[nodiscard]] auto knownBirthdaysToday() const
|
||||||
-> std::optional<std::vector<UserId>>;
|
-> std::optional<std::vector<UserId>>;
|
||||||
|
|
||||||
|
[[nodiscard]] static QString SugValidatePassword();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setTopPromoted(
|
void setTopPromoted(
|
||||||
History *promoted,
|
History *promoted,
|
||||||
|
|
|
@ -34,6 +34,7 @@ struct StepData {
|
||||||
QString email;
|
QString email;
|
||||||
int unconfirmedEmailLengthCode;
|
int unconfirmedEmailLengthCode;
|
||||||
bool setOnlyRecoveryEmail = false;
|
bool setOnlyRecoveryEmail = false;
|
||||||
|
bool suggestionValidate = false;
|
||||||
|
|
||||||
struct ProcessRecover {
|
struct ProcessRecover {
|
||||||
bool setNewPassword = false;
|
bool setNewPassword = false;
|
||||||
|
|
|
@ -12,20 +12,26 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "core/core_cloud_password.h"
|
#include "core/core_cloud_password.h"
|
||||||
|
#include "data/components/promo_suggestions.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "lottie/lottie_icon.h"
|
#include "lottie/lottie_icon.h"
|
||||||
|
#include "main/main_session.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_email_confirm.h"
|
#include "settings/cloud_password/settings_cloud_password_email_confirm.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 "settings/cloud_password/settings_cloud_password_manage.h"
|
||||||
#include "settings/cloud_password/settings_cloud_password_step.h"
|
#include "settings/cloud_password/settings_cloud_password_step.h"
|
||||||
|
#include "settings/cloud_password/settings_cloud_password_validate_icon.h"
|
||||||
|
#include "ui/boxes/boost_box.h" // Ui::StartFireworks.
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "ui/rect.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
|
#include "ui/ui_utility.h"
|
||||||
|
#include "ui/vertical_list.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/fields/password_input.h"
|
#include "ui/widgets/fields/password_input.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
#include "ui/vertical_list.h"
|
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
#include "styles/style_layers.h"
|
#include "styles/style_layers.h"
|
||||||
|
@ -53,6 +59,10 @@ RecreateResetPassword:
|
||||||
– Continue to RecreateResetHint.
|
– Continue to RecreateResetHint.
|
||||||
– Clear password and Back to Settings.
|
– Clear password and Back to Settings.
|
||||||
– Back to Settings.
|
– Back to Settings.
|
||||||
|
|
||||||
|
ValidatePassword:
|
||||||
|
- Submit to show good validate.
|
||||||
|
- Back to Main Settings.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
@ -72,9 +82,7 @@ Icon CreateInteractiveLottieIcon(
|
||||||
const auto raw = object.data();
|
const auto raw = object.data();
|
||||||
|
|
||||||
const auto width = descriptor.sizeOverride.width();
|
const auto width = descriptor.sizeOverride.width();
|
||||||
raw->resize(QRect(
|
raw->resize((Rect(descriptor.sizeOverride) + padding).size());
|
||||||
QPoint(),
|
|
||||||
descriptor.sizeOverride).marginsAdded(padding).size());
|
|
||||||
|
|
||||||
auto owned = Lottie::MakeIcon(std::move(descriptor));
|
auto owned = Lottie::MakeIcon(std::move(descriptor));
|
||||||
const auto icon = owned.get();
|
const auto icon = owned.get();
|
||||||
|
@ -118,7 +126,10 @@ public:
|
||||||
using TypedAbstractStep::TypedAbstractStep;
|
using TypedAbstractStep::TypedAbstractStep;
|
||||||
|
|
||||||
[[nodiscard]] rpl::producer<QString> title() override;
|
[[nodiscard]] rpl::producer<QString> title() override;
|
||||||
|
[[nodiscard]] QPointer<Ui::RpWidget> createPinnedToTop(
|
||||||
|
not_null<QWidget*> parent) override;
|
||||||
void setupContent();
|
void setupContent();
|
||||||
|
void setupValidateGood();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
[[nodiscard]] rpl::producer<std::vector<Type>> removeTypes() override;
|
[[nodiscard]] rpl::producer<std::vector<Type>> removeTypes() override;
|
||||||
|
@ -130,6 +141,8 @@ private:
|
||||||
not_null<Ui::FlatLabel*> info,
|
not_null<Ui::FlatLabel*> info,
|
||||||
Fn<void()> recoverCallback);
|
Fn<void()> recoverCallback);
|
||||||
|
|
||||||
|
QWidget *_parent = nullptr;
|
||||||
|
|
||||||
rpl::variable<std::vector<Type>> _removesFromStack;
|
rpl::variable<std::vector<Type>> _removesFromStack;
|
||||||
rpl::lifetime _requestLifetime;
|
rpl::lifetime _requestLifetime;
|
||||||
|
|
||||||
|
@ -143,12 +156,58 @@ rpl::producer<QString> Input::title() {
|
||||||
return tr::lng_settings_cloud_password_password_title();
|
return tr::lng_settings_cloud_password_password_title();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPointer<Ui::RpWidget> Input::createPinnedToTop(
|
||||||
|
not_null<QWidget*> parent) {
|
||||||
|
_parent = parent;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Input::setupValidateGood() {
|
||||||
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
|
|
||||||
|
if (_parent) {
|
||||||
|
Ui::StartFireworks(_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto owned = CreateValidateGoodIcon(&controller()->session())) {
|
||||||
|
owned->setParent(content);
|
||||||
|
content->add(
|
||||||
|
object_ptr<Ui::CenterWrap<>>(
|
||||||
|
content,
|
||||||
|
std::move(owned)),
|
||||||
|
QMargins(0, st::lineWidth * 75, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
SetupHeader(
|
||||||
|
content,
|
||||||
|
QString(),
|
||||||
|
rpl::never<>(),
|
||||||
|
tr::lng_settings_suggestion_password_step_finish_title(),
|
||||||
|
tr::lng_settings_suggestion_password_step_finish_about());
|
||||||
|
|
||||||
|
const auto button = AddDoneButton(content, tr::lng_share_done());
|
||||||
|
button->setClickedCallback([=] {
|
||||||
|
showBack();
|
||||||
|
});
|
||||||
|
|
||||||
|
Ui::ToggleChildrenVisibility(this, true);
|
||||||
|
Ui::ResizeFitChild(this, content);
|
||||||
|
content->resizeToWidth(width());
|
||||||
|
Ui::SendPendingMoveResizeEvents(content);
|
||||||
|
}
|
||||||
|
|
||||||
void Input::setupContent() {
|
void Input::setupContent() {
|
||||||
|
if (QWidget::children().count() > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||||
auto currentStepData = stepData();
|
auto currentStepData = stepData();
|
||||||
const auto currentStepDataPassword = base::take(currentStepData.password);
|
const auto currentStepDataPassword = base::take(currentStepData.password);
|
||||||
const auto currentStepProcessRecover = base::take(
|
const auto currentStepProcessRecover = base::take(
|
||||||
currentStepData.processRecover);
|
currentStepData.processRecover);
|
||||||
|
const auto currentStepValidate = base::take(
|
||||||
|
currentStepData.suggestionValidate);
|
||||||
setStepData(currentStepData);
|
setStepData(currentStepData);
|
||||||
|
|
||||||
const auto currentState = cloudPassword().stateCurrent();
|
const auto currentState = cloudPassword().stateCurrent();
|
||||||
|
@ -167,11 +226,10 @@ void Input::setupContent() {
|
||||||
const auto icon = CreateInteractiveLottieIcon(
|
const auto icon = CreateInteractiveLottieIcon(
|
||||||
content,
|
content,
|
||||||
{
|
{
|
||||||
.name = u"cloud_password/password_input"_q,
|
.name = currentStepValidate
|
||||||
.sizeOverride = {
|
? u"cloud_password/validate"_q
|
||||||
st::settingsCloudPasswordIconSize,
|
: u"cloud_password/password_input"_q,
|
||||||
st::settingsCloudPasswordIconSize
|
.sizeOverride = Size(st::settingsCloudPasswordIconSize),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
st::settingLocalPasscodeIconPadding);
|
st::settingLocalPasscodeIconPadding);
|
||||||
|
|
||||||
|
@ -179,12 +237,16 @@ void Input::setupContent() {
|
||||||
content,
|
content,
|
||||||
QString(),
|
QString(),
|
||||||
rpl::never<>(),
|
rpl::never<>(),
|
||||||
isCheck
|
currentStepValidate
|
||||||
|
? tr::lng_settings_suggestion_password_step_input_title()
|
||||||
|
: isCheck
|
||||||
? tr::lng_settings_cloud_password_check_subtitle()
|
? tr::lng_settings_cloud_password_check_subtitle()
|
||||||
: hasPassword
|
: hasPassword
|
||||||
? tr::lng_settings_cloud_password_manage_password_change()
|
? tr::lng_settings_cloud_password_manage_password_change()
|
||||||
: tr::lng_settings_cloud_password_password_subtitle(),
|
: tr::lng_settings_cloud_password_password_subtitle(),
|
||||||
isCheck
|
currentStepValidate
|
||||||
|
? tr::lng_settings_suggestion_password_step_input_about()
|
||||||
|
: isCheck
|
||||||
? tr::lng_settings_cloud_password_manage_about1()
|
? tr::lng_settings_cloud_password_manage_about1()
|
||||||
: tr::lng_cloud_password_about());
|
: tr::lng_cloud_password_about());
|
||||||
|
|
||||||
|
@ -340,7 +402,9 @@ void Input::setupContent() {
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!newInput->text().isEmpty()) {
|
if (currentStepValidate) {
|
||||||
|
icon.icon->animate(icon.update, 0, icon.icon->framesCount() - 1);
|
||||||
|
} else if (!newInput->text().isEmpty()) {
|
||||||
icon.icon->jumpTo(icon.icon->framesCount() / 2, icon.update);
|
icon.icon->jumpTo(icon.icon->framesCount() / 2, icon.update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,10 +440,18 @@ void Input::setupContent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto data = stepData();
|
if (currentStepValidate) {
|
||||||
data.currentPassword = pass;
|
controller()->session().promoSuggestions().dismiss(
|
||||||
setStepData(std::move(data));
|
Data::PromoSuggestions::SugValidatePassword());
|
||||||
showOther(CloudPasswordManageId());
|
setupValidateGood();
|
||||||
|
delete content;
|
||||||
|
} else {
|
||||||
|
auto data = stepData();
|
||||||
|
data.currentPassword = pass;
|
||||||
|
setStepData(std::move(data));
|
||||||
|
showOther(CloudPasswordManageId());
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -412,17 +484,19 @@ void Input::setupContent() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
base::qt_signal_producer(
|
if (!currentStepValidate) {
|
||||||
newInput.get(),
|
base::qt_signal_producer(
|
||||||
&QLineEdit::textChanged // Covers Undo.
|
newInput.get(),
|
||||||
) | rpl::map([=] {
|
&QLineEdit::textChanged // Covers Undo.
|
||||||
return newInput->text().isEmpty();
|
) | rpl::map([=] {
|
||||||
}) | rpl::distinct_until_changed(
|
return newInput->text().isEmpty();
|
||||||
) | rpl::start_with_next([=](bool empty) {
|
}) | rpl::distinct_until_changed(
|
||||||
const auto from = icon.icon->frameIndex();
|
) | rpl::start_with_next([=](bool empty) {
|
||||||
const auto to = empty ? 0 : (icon.icon->framesCount() / 2 - 1);
|
const auto from = icon.icon->frameIndex();
|
||||||
icon.icon->animate(icon.update, from, to);
|
const auto to = empty ? 0 : (icon.icon->framesCount() / 2 - 1);
|
||||||
}, content->lifetime());
|
icon.icon->animate(icon.update, from, to);
|
||||||
|
}, content->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
const auto submit = [=] {
|
const auto submit = [=] {
|
||||||
if (!reenterInput || reenterInput->hasFocus()) {
|
if (!reenterInput || reenterInput->hasFocus()) {
|
||||||
|
@ -437,7 +511,7 @@ void Input::setupContent() {
|
||||||
QObject::connect(reenterInput, &MaskedInputField::submitted, submit);
|
QObject::connect(reenterInput, &MaskedInputField::submitted, submit);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFocusCallback([=] {
|
setFocusCallback(crl::guard(content, [=] {
|
||||||
if (isCheck || newInput->text().isEmpty()) {
|
if (isCheck || newInput->text().isEmpty()) {
|
||||||
newInput->setFocus();
|
newInput->setFocus();
|
||||||
} else if (reenterInput->text().isEmpty()) {
|
} else if (reenterInput->text().isEmpty()) {
|
||||||
|
@ -445,7 +519,7 @@ void Input::setupContent() {
|
||||||
} else {
|
} else {
|
||||||
newInput->setFocus();
|
newInput->setFocus();
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
Ui::ResizeFitChild(this, content);
|
Ui::ResizeFitChild(this, content);
|
||||||
}
|
}
|
||||||
|
@ -586,10 +660,33 @@ void Input::setupRecoverButton(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SuggestionInput : public Input {
|
||||||
|
public:
|
||||||
|
SuggestionInput(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<Window::SessionController*> controller)
|
||||||
|
: Input(parent, controller)
|
||||||
|
, _stepData(StepData{ .suggestionValidate = true }) {
|
||||||
|
setStepDataReference(_stepData);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] static Type Id() {
|
||||||
|
return SectionFactory<SuggestionInput>::Instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::any _stepData;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace CloudPassword
|
} // namespace CloudPassword
|
||||||
|
|
||||||
Type CloudPasswordInputId() {
|
Type CloudPasswordInputId() {
|
||||||
return CloudPassword::Input::Id();
|
return CloudPassword::Input::Id();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type CloudPasswordSuggestionInputId() {
|
||||||
|
return CloudPassword::SuggestionInput::Id();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
Type CloudPasswordInputId();
|
Type CloudPasswordInputId();
|
||||||
|
Type CloudPasswordSuggestionInputId();
|
||||||
|
|
||||||
} // namespace Settings
|
} // namespace Settings
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
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_validate_icon.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "base/object_ptr.h"
|
||||||
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
|
#include "data/stickers/data_stickers.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "ui/rect.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] DocumentData *EmojiValidateGood(
|
||||||
|
not_null<Main::Session*> session) {
|
||||||
|
auto emoji = TextWithEntities{
|
||||||
|
.text = (QString(QChar(0xD83D)) + QChar(0xDC4D)),
|
||||||
|
};
|
||||||
|
if (const auto e = Ui::Emoji::Find(emoji.text)) {
|
||||||
|
const auto sticker = session->emojiStickersPack().stickerForEmoji(e);
|
||||||
|
return sticker.document;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
object_ptr<Ui::RpWidget> CreateValidateGoodIcon(
|
||||||
|
not_null<Main::Session*> session) {
|
||||||
|
const auto document = EmojiValidateGood(session);
|
||||||
|
if (!document) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto owned = object_ptr<Ui::RpWidget>((QWidget*)nullptr);
|
||||||
|
const auto widget = owned.data();
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
std::unique_ptr<Ui::Text::CustomEmoji> emoji;
|
||||||
|
};
|
||||||
|
const auto state = widget->lifetime().make_state<State>();
|
||||||
|
const auto size = st::settingsCloudPasswordIconSize;
|
||||||
|
state->emoji = std::make_unique<Ui::Text::LimitedLoopsEmoji>(
|
||||||
|
session->data().customEmojiManager().create(
|
||||||
|
document,
|
||||||
|
[=] { widget->update(); },
|
||||||
|
Data::CustomEmojiManager::SizeTag::Normal,
|
||||||
|
size),
|
||||||
|
1,
|
||||||
|
true);
|
||||||
|
widget->paintRequest() | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(widget);
|
||||||
|
state->emoji->paint(p, Ui::Text::CustomEmojiPaintContext{
|
||||||
|
.textColor = st::windowFg->c,
|
||||||
|
.now = crl::now(),
|
||||||
|
});
|
||||||
|
}, widget->lifetime());
|
||||||
|
const auto padding = st::settingLocalPasscodeIconPadding;
|
||||||
|
widget->resize((Rect(Size(size)) + padding).size());
|
||||||
|
|
||||||
|
return owned;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
template <typename Object>
|
||||||
|
class object_ptr;
|
||||||
|
|
||||||
|
namespace Main {
|
||||||
|
class Session;
|
||||||
|
} // namespace Main
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
[[nodiscard]] object_ptr<Ui::RpWidget> CreateValidateGoodIcon(
|
||||||
|
not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
} // namespace Settings
|
||||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "settings/settings_main.h"
|
#include "settings/settings_main.h"
|
||||||
|
|
||||||
|
#include "settings/cloud_password/settings_cloud_password_input.h"
|
||||||
#include "api/api_credits.h"
|
#include "api/api_credits.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
@ -467,7 +468,7 @@ void SetupValidatePhoneNumberSuggestion(
|
||||||
yes->setClickedCallback([=] {
|
yes->setClickedCallback([=] {
|
||||||
controller->session().promoSuggestions().dismiss(
|
controller->session().promoSuggestions().dismiss(
|
||||||
kSugValidatePhone.utf8());
|
kSugValidatePhone.utf8());
|
||||||
mainWrap->toggle(false, anim::type::normal);
|
mainWrap->toggle(false, anim::type::normal);
|
||||||
});
|
});
|
||||||
const auto no = Ui::CreateChild<Ui::RoundButton>(
|
const auto no = Ui::CreateChild<Ui::RoundButton>(
|
||||||
wrap,
|
wrap,
|
||||||
|
@ -522,6 +523,77 @@ void SetupValidatePhoneNumberSuggestion(
|
||||||
Ui::AddSkip(content);
|
Ui::AddSkip(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupValidatePasswordSuggestion(
|
||||||
|
not_null<Window::SessionController*> controller,
|
||||||
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
Fn<void(Type)> showOther) {
|
||||||
|
if (!controller->session().promoSuggestions().current(
|
||||||
|
Data::PromoSuggestions::SugValidatePassword())
|
||||||
|
|| controller->session().promoSuggestions().current(
|
||||||
|
kSugValidatePhone.utf8())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto mainWrap = container->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
container,
|
||||||
|
object_ptr<Ui::VerticalLayout>(container)));
|
||||||
|
const auto content = mainWrap->entity();
|
||||||
|
Ui::AddSubsectionTitle(
|
||||||
|
content,
|
||||||
|
tr::lng_settings_suggestion_password_title(),
|
||||||
|
QMargins(
|
||||||
|
st::boxRowPadding.left()
|
||||||
|
- st::defaultSubsectionTitlePadding.left(),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0));
|
||||||
|
const auto label = content->add(
|
||||||
|
object_ptr<Ui::FlatLabel>(
|
||||||
|
content,
|
||||||
|
tr::lng_settings_suggestion_password_about(),
|
||||||
|
st::boxLabel),
|
||||||
|
st::boxRowPadding);
|
||||||
|
|
||||||
|
Ui::AddSkip(content);
|
||||||
|
Ui::AddSkip(content);
|
||||||
|
|
||||||
|
const auto wrap = content->add(
|
||||||
|
object_ptr<Ui::FixedHeightWidget>(
|
||||||
|
content,
|
||||||
|
st::inviteLinkButton.height),
|
||||||
|
st::inviteLinkButtonsPadding);
|
||||||
|
const auto yes = Ui::CreateChild<Ui::RoundButton>(
|
||||||
|
wrap,
|
||||||
|
tr::lng_settings_suggestion_password_yes(),
|
||||||
|
st::inviteLinkButton);
|
||||||
|
yes->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
|
yes->setClickedCallback([=] {
|
||||||
|
controller->session().promoSuggestions().dismiss(
|
||||||
|
Data::PromoSuggestions::SugValidatePassword());
|
||||||
|
mainWrap->toggle(false, anim::type::normal);
|
||||||
|
});
|
||||||
|
const auto no = Ui::CreateChild<Ui::RoundButton>(
|
||||||
|
wrap,
|
||||||
|
tr::lng_settings_suggestion_password_no(),
|
||||||
|
st::inviteLinkButton);
|
||||||
|
no->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
|
no->setClickedCallback([=] {
|
||||||
|
showOther(Settings::CloudPasswordSuggestionInputId());
|
||||||
|
});
|
||||||
|
|
||||||
|
wrap->widthValue() | rpl::start_with_next([=](int width) {
|
||||||
|
const auto buttonWidth = (width - st::inviteLinkButtonsSkip) / 2;
|
||||||
|
yes->setFullWidth(buttonWidth);
|
||||||
|
no->setFullWidth(buttonWidth);
|
||||||
|
yes->moveToLeft(0, 0, width);
|
||||||
|
no->moveToRight(0, 0, width);
|
||||||
|
}, wrap->lifetime());
|
||||||
|
Ui::AddSkip(content);
|
||||||
|
Ui::AddSkip(content);
|
||||||
|
Ui::AddDivider(content);
|
||||||
|
Ui::AddSkip(content);
|
||||||
|
}
|
||||||
|
|
||||||
void SetupSections(
|
void SetupSections(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
|
@ -533,6 +605,10 @@ void SetupSections(
|
||||||
controller,
|
controller,
|
||||||
container,
|
container,
|
||||||
showOther);
|
showOther);
|
||||||
|
SetupValidatePasswordSuggestion(
|
||||||
|
controller,
|
||||||
|
container,
|
||||||
|
showOther);
|
||||||
|
|
||||||
const auto addSection = [&](
|
const auto addSection = [&](
|
||||||
rpl::producer<QString> label,
|
rpl::producer<QString> label,
|
||||||
|
|
Loading…
Add table
Reference in a new issue