Allow to enter phone and email in the passport.

This commit is contained in:
John Preston 2018-04-06 15:54:01 +04:00
parent 94bfd59b76
commit f1519b76f6
11 changed files with 340 additions and 3 deletions

View File

@ -1541,10 +1541,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_passport_country" = "Country";
"lng_passport_document_number" = "Card Number";
"lng_passport_expiry_date" = "Expiry date";
"lng_passport_address" = "Address";
"lng_passport_street" = "Street";
"lng_passport_city" = "City";
"lng_passport_state" = "State";
"lng_passport_postcode" = "Postcode";
"lng_passport_use_existing" = "USE {existing}";
"lng_passport_use_existing_phone" = "Use the same phone number as on Telegram.";
"lng_passport_new_phone" = "Or enter a new phone number";
"lng_passport_new_phone_code" = "Note: You will receive a confirmation code on the phone number you provide.";
"lng_passport_use_existing_email" = "Use the same email as on Telegram.";
"lng_passport_new_email" = "Or enter a new email";
"lng_passport_new_email_code" = "Note: You will receive a confirmation code on the email address you provide.";
"lng_passport_email_enter_code" = "Please enter the confirmation code we've just sent to {email}.";
// Wnd specific

View File

@ -115,10 +115,13 @@ passportFormUserpic: UserpicButton(passportPasswordUserpic) {
}
passportFormUserpicPadding: margins(0px, 5px, 0px, 10px);
passportFormDividerHeight: 13px;
passportFormPolicy: FlatLabel(defaultFlatLabel) {
passportFormLabel: FlatLabel(defaultFlatLabel) {
minWidth: 285px;
align: align(topleft);
textFg: windowSubTextFg;
}
passportFormLabelPadding: margins(22px, 7px, 22px, 14px);
passportFormPolicy: FlatLabel(passportFormLabel) {
style: TextStyle(defaultTextStyle) {
linkFont: font(fsize semibold underline);
linkFontOver: font(fsize semibold underline);
@ -128,6 +131,8 @@ passportFormPolicy: FlatLabel(defaultFlatLabel) {
}
}
passportFormPolicyPadding: margins(22px, 7px, 22px, 28px);
passportContactNewFieldPadding: margins(22px, 0px, 22px, 28px);
passportContactFieldPadding: margins(22px, 14px, 22px, 28px);
passportRowPadding: margins(22px, 8px, 25px, 8px);
passportRowSkip: 2px;
@ -180,6 +185,9 @@ passportDetailsField: InputField(defaultInputField) {
heightMin: 32px;
font: normalFont;
}
passportContactField: InputField(defaultInputField) {
font: normalFont;
}
passportDetailsFieldLeft: 116px;
passportDetailsFieldTop: 2px;
passportDetailsFieldSkipMin: 12px;

View File

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "passport/passport_panel_edit_document.h"
#include "passport/passport_panel_edit_contact.h"
#include "passport/passport_panel.h"
#include "boxes/confirm_box.h"
#include "layout.h"
@ -41,6 +42,7 @@ PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
switch (type) {
case Scope::Type::Identity: {
auto result = Scheme();
result.rowsHeader = lang(lng_passport_personal_details);
result.rows = {
{
Scheme::ValueType::Fields,
@ -90,6 +92,7 @@ PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
case Scope::Type::Address: {
auto result = Scheme();
result.rowsHeader = lang(lng_passport_address);
result.rows = {
{
Scheme::ValueType::Fields,
@ -134,6 +137,48 @@ PanelEditDocument::Scheme GetDocumentScheme(Scope::Type type) {
Unexpected("Type in GetDocumentScheme().");
}
PanelEditContact::Scheme GetContactScheme(Scope::Type type) {
using Scheme = PanelEditContact::Scheme;
switch (type) {
case Scope::Type::Phone: {
auto result = Scheme();
result.aboutExisting = lang(lng_passport_use_existing_phone);
result.newHeader = lang(lng_passport_new_phone);
result.aboutNew = lang(lng_passport_new_phone_code);
result.validate = [](const QString &value) {
return QRegularExpression(
"^\\d{2,12}$"
).match(value).hasMatch();
};
result.preprocess = [](const QString &value) {
return App::formatPhone(value);
};
result.postprocess = [](QString value) {
return value.replace(QRegularExpression("[^\\d]"), QString());
};
return result;
} break;
case Scope::Type::Email: {
auto result = Scheme();
result.aboutExisting = lang(lng_passport_use_existing_email);
result.newHeader = lang(lng_passport_new_email);
result.newPlaceholder = langFactory(lng_passport_email_title);
result.aboutNew = lang(lng_passport_new_email_code);
result.validate = [](const QString &value) {
const auto at = value.indexOf('@');
const auto dot = value.lastIndexOf('.');
return (at > 0) && (dot > at);
};
result.preprocess = result.postprocess = [](const QString &value) {
return value.trimmed();
};
return result;
} break;
}
Unexpected("Type in GetContactScheme().");
}
} // namespace
BoxPointer::BoxPointer(QPointer<BoxContent> value)
@ -324,6 +369,16 @@ ScanInfo PanelController::collectScanInfo(const EditFile &file) const {
file.deleted };
}
QString PanelController::getDefaultContactValue(Scope::Type type) const {
switch (type) {
case Scope::Type::Phone:
return _form->defaultPhoneNumber();
case Scope::Type::Email:
return _form->defaultEmail();
}
Unexpected("Type in PanelController::getDefaultContactValue().");
}
void PanelController::showAskPassword() {
ensurePanelCreated();
_panel->showAskPassword();
@ -376,8 +431,19 @@ void PanelController::editScope(int index) {
this,
std::move(GetDocumentScheme(_editScope->type)),
_editScope->fields->data.parsed);
case Scope::Type::Phone:
case Scope::Type::Email: {
const auto &fields = _editScope->fields->data.parsed.fields;
const auto valueIt = fields.find("value");
return object_ptr<PanelEditContact>(
_panel.get(),
this,
std::move(GetContactScheme(_editScope->type)),
(valueIt == end(fields)) ? QString() : valueIt->second,
getDefaultContactValue(_editScope->type));
} break;
}
return { nullptr };
Unexpected("Type in PanelController::editScope().");
}();
if (content) {
_panel->setBackAllowed(true);

View File

@ -83,6 +83,7 @@ private:
std::vector<ScanInfo> valueFiles(const Value &value) const;
ScanInfo collectScanInfo(const EditFile &file) const;
QString getDefaultContactValue(Scope::Type type) const;
not_null<FormController*> _form;
std::vector<Scope> _scopes;

View File

@ -12,6 +12,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Passport {
int PanelLabel::naturalWidth() const {
return -1;
}
void PanelLabel::resizeEvent(QResizeEvent *e) {
_background->lower();
_background->setGeometry(rect());
return PaddingWrap::resizeEvent(e);
}
PanelDetailsRow::PanelDetailsRow(
QWidget *parent,
const QString &label,

View File

@ -8,6 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "ui/rp_widget.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/widgets/labels.h"
#include "boxes/abstract_box.h"
namespace Ui {
class InputField;
@ -15,6 +18,20 @@ class InputField;
namespace Passport {
class PanelLabel : public Ui::PaddingWrap<Ui::FlatLabel> {
public:
using PaddingWrap::PaddingWrap;
int naturalWidth() const override;
protected:
void resizeEvent(QResizeEvent *e) override;
private:
object_ptr<BoxContentDivider> _background = object_ptr<BoxContentDivider>(this);
};
class PanelDetailsRow : public Ui::RpWidget {
public:
PanelDetailsRow(

View File

@ -0,0 +1,151 @@
/*
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 "passport/passport_panel_edit_contact.h"
#include "passport/passport_panel_controller.h"
#include "passport/passport_panel_details_row.h"
#include "info/profile/info_profile_button.h"
#include "info/profile/info_profile_values.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h"
#include "ui/wrap/vertical_layout.h"
#include "boxes/abstract_box.h"
#include "lang/lang_keys.h"
#include "styles/style_passport.h"
namespace Passport {
PanelEditContact::PanelEditContact(
QWidget*,
not_null<PanelController*> controller,
Scheme scheme,
const QString &data,
const QString &existing)
: _controller(controller)
, _scheme(std::move(scheme))
, _content(this)
, _bottomShadow(this)
, _done(
this,
langFactory(lng_passport_save_value),
st::passportPanelSaveValue) {
setupControls(data, existing);
}
void PanelEditContact::setupControls(
const QString &data,
const QString &existing) {
widthValue(
) | rpl::start_with_next([=](int width) {
_content->resizeToWidth(width);
}, _content->lifetime());
_content->add(object_ptr<BoxContentDivider>(
_content,
st::passportFormDividerHeight));
if (!existing.isEmpty()) {
_content->add(
object_ptr<Info::Profile::Button>(
_content,
Lang::Viewer(
lng_passport_use_existing__tagged
) | rpl::map([=] {
return lng_passport_use_existing(
lt_existing,
(_scheme.preprocess
? _scheme.preprocess(existing)
: existing));
}),
st::passportUploadButton),
st::passportUploadButtonPadding
)->addClickHandler([=] {
save(existing);
});
_content->add(
object_ptr<PanelLabel>(
_content,
object_ptr<Ui::FlatLabel>(
_content,
_scheme.aboutExisting,
Ui::FlatLabel::InitType::Simple,
st::passportFormLabel),
st::passportFormLabelPadding));
_content->add(
object_ptr<Ui::FlatLabel>(
_content,
_scheme.newHeader,
Ui::FlatLabel::InitType::Simple,
st::passportFormHeader),
st::passportDetailsHeaderPadding);
_field = _content->add(
object_ptr<Ui::InputField>(
_content,
st::passportDetailsField),
st::passportContactNewFieldPadding);
} else {
_field = _content->add(
object_ptr<Ui::InputField>(
_content,
st::passportContactField,
_scheme.newPlaceholder),
st::passportContactFieldPadding);
}
_content->add(
object_ptr<PanelLabel>(
_content,
object_ptr<Ui::FlatLabel>(
_content,
_scheme.aboutNew,
Ui::FlatLabel::InitType::Simple,
st::passportFormLabel),
st::passportFormLabelPadding));
_done->addClickHandler([=] {
crl::on_main(this, [=] {
save();
});
});
}
void PanelEditContact::focusInEvent(QFocusEvent *e) {
_field->setFocusFast();
}
void PanelEditContact::resizeEvent(QResizeEvent *e) {
updateControlsGeometry();
}
void PanelEditContact::updateControlsGeometry() {
const auto submitTop = height() - _done->height();
_bottomShadow->resizeToWidth(width());
_bottomShadow->moveToLeft(0, submitTop - st::lineWidth);
_done->resizeToWidth(width());
_done->moveToLeft(0, submitTop);
}
void PanelEditContact::save() {
const auto result = _field->getLastText();
const auto processed = _scheme.postprocess
? _scheme.postprocess(result)
: result;
if (_scheme.validate && !_scheme.validate(processed)) {
_field->showError();
return;
}
save(processed);
}
void PanelEditContact::save(const QString &value) {
auto data = ValueMap();
data.fields["value"] = value;
_controller->saveScope(std::move(data), {});
}
} // namespace Passport

View File

@ -0,0 +1,72 @@
/*
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 "ui/rp_widget.h"
namespace Ui {
class InputField;
class PlainShadow;
class RoundButton;
class VerticalLayout;
} // namespace Ui
namespace Passport {
class PanelController;
class PanelEditContact : public Ui::RpWidget {
public:
struct Scheme {
enum class ValueType {
Phone,
Text,
};
ValueType type = ValueType::Phone;
QString aboutExisting;
QString newHeader;
base::lambda<QString()> newPlaceholder;
QString aboutNew;
base::lambda<bool(const QString &value)> validate;
base::lambda<QString(const QString &value)> preprocess;
base::lambda<QString(const QString &value)> postprocess;
};
PanelEditContact(
QWidget *parent,
not_null<PanelController*> controller,
Scheme scheme,
const QString &data,
const QString &existing);
protected:
void focusInEvent(QFocusEvent *e) override;
void resizeEvent(QResizeEvent *e) override;
private:
void setupControls(
const QString &data,
const QString &existing);
void updateControlsGeometry();
void save();
void save(const QString &value);
not_null<PanelController*> _controller;
Scheme _scheme;
object_ptr<Ui::VerticalLayout> _content;
QPointer<Ui::InputField> _field;
object_ptr<Ui::PlainShadow> _bottomShadow;
object_ptr<Ui::RoundButton> _done;
};
} // namespace Passport

View File

@ -100,7 +100,7 @@ not_null<Ui::RpWidget*> PanelEditDocument::setupContent(
inner->add(
object_ptr<Ui::FlatLabel>(
inner,
lang(lng_passport_personal_details),
_scheme.rowsHeader,
Ui::FlatLabel::InitType::Simple,
st::passportFormHeader),
st::passportDetailsHeaderPadding);

View File

@ -39,6 +39,7 @@ public:
base::lambda<bool(const QString &value)> validate;
};
std::vector<Row> rows;
QString rowsHeader;
};

View File

@ -466,6 +466,8 @@
<(src_loc)/passport/passport_panel_controller.h
<(src_loc)/passport/passport_panel_details_row.cpp
<(src_loc)/passport/passport_panel_details_row.h
<(src_loc)/passport/passport_panel_edit_contact.cpp
<(src_loc)/passport/passport_panel_edit_contact.h
<(src_loc)/passport/passport_panel_edit_document.cpp
<(src_loc)/passport/passport_panel_edit_document.h
<(src_loc)/passport/passport_panel_edit_scans.cpp