Handle ToS correctly when signing up.

This commit is contained in:
John Preston 2018-06-01 10:00:18 +03:00
parent 2878e46d2b
commit 80be464d95
12 changed files with 239 additions and 191 deletions

View File

@ -1496,7 +1496,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_terms_signup" = "By signing up,\nyou agree to the {link}."; "lng_terms_signup" = "By signing up,\nyou agree to the {link}.";
"lng_terms_signup_link" = "Terms of Service"; "lng_terms_signup_link" = "Terms of Service";
"lng_terms_header" = "Terms of Service"; "lng_terms_header" = "Terms of Service";
"lng_terms_age#one" = "I confirm that I am {count} or over";
"lng_terms_age#other" = "I confirm that I am {count} or over";
"lng_terms_agree" = "Agree & Continue"; "lng_terms_agree" = "Agree & Continue";
"lng_terms_decline" = "Decline";
"lng_terms_signup_sorry" = "We're very sorry, but this means you can't sign up for Telegram.\n\nUnlike others, we don't use your data for ad targeting or other commercial purposes. Telegram only stores the information it needs to function as a feature-rich cloud service. You can adjust how we use your data in Privacy & Security settings.\n\nBut if you're generally not OK with Telegram's modest needs, it won't be possible for us to provide this service.";
// Wnd specific // Wnd specific

View File

@ -295,7 +295,7 @@ geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone; auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
auth.sentCode#5e002502 flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int = auth.SentCode; auth.sentCode#38faab5f flags:# phone_registered:flags.0?true type:auth.SentCodeType phone_code_hash:string next_type:flags.1?auth.CodeType timeout:flags.2?int terms_of_service:flags.3?help.TermsOfService = auth.SentCode;
auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization; auth.authorization#cd050916 flags:# tmp_sessions:flags.0?int user:User = auth.Authorization;
@ -676,7 +676,7 @@ channels.channelParticipantsNotModified#f0173fe9 = channels.ChannelParticipants;
channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant; channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
help.termsOfService#f1ee3e90 text:string = help.TermsOfService; help.termsOfService#780a0310 flags:# popup:flags.0?true id:DataJSON text:string entities:Vector<MessageEntity> min_age_confirm:flags.1?int = help.TermsOfService;
foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif; foundGif#162ecc1f url:string thumb_url:string content_url:string content_type:string w:int h:int = FoundGif;
foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif; foundGifCached#9c750409 url:string photo:Photo document:Document = FoundGif;
@ -961,6 +961,9 @@ inputClientProxy#75588b3f address:string port:int = InputClientProxy;
help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData; help.proxyDataEmpty#e09e1fb8 expires:int = help.ProxyData;
help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData; help.proxyDataPromo#2bf7ee23 expires:int peer:Peer chats:Vector<Chat> users:Vector<User> = help.ProxyData;
help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
help.termsOfServiceUpdate#28ecf961 expires:int terms_of_service:help.TermsOfService = help.TermsOfServiceUpdate;
---functions--- ---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1158,11 +1161,12 @@ help.saveAppLog#6f02f748 events:Vector<InputAppEvent> = Bool;
help.getInviteText#4d392343 = help.InviteText; help.getInviteText#4d392343 = help.InviteText;
help.getSupport#9cdf08cd = help.Support; help.getSupport#9cdf08cd = help.Support;
help.getAppChangelog#9010ef6f prev_app_version:string = Updates; help.getAppChangelog#9010ef6f prev_app_version:string = Updates;
help.getTermsOfService#8e59b7e7 country_iso2:string = help.TermsOfService;
help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool; help.setBotUpdatesStatus#ec22cfcd pending_updates_count:int message:string = Bool;
help.getCdnConfig#52029342 = CdnConfig; help.getCdnConfig#52029342 = CdnConfig;
help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls; help.getRecentMeUrls#3dc0f114 referer:string = help.RecentMeUrls;
help.getProxyData#3d7758e1 = help.ProxyData; help.getProxyData#3d7758e1 = help.ProxyData;
help.getTermsOfServiceUpdate#2ca51fd1 = help.TermsOfServiceUpdate;
help.acceptTermsOfService#ee72f79a id:DataJSON = Bool;
channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool; channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages; channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
@ -1226,4 +1230,4 @@ langpack.getStrings#2e1ee318 lang_code:string keys:Vector<string> = Vector<LangP
langpack.getDifference#b2e4d7d from_version:int = LangPackDifference; langpack.getDifference#b2e4d7d from_version:int = LangPackDifference;
langpack.getLanguages#800fd57d = Vector<LangPackLanguage>; langpack.getLanguages#800fd57d = Vector<LangPackLanguage>;
// LAYER 79 // LAYER 80

View File

@ -55,8 +55,9 @@ addChildParentFlags('MTPDchannelForbidden', 'MTPDchannel');
parentFlagsCheck = {}; parentFlagsCheck = {};
countedTypeIdExceptions = {}; countedTypeIdExceptions = {};
countedTypeIdExceptions[77] = countedTypeIdExceptions[78] = countedTypeIdExceptions[79] = {} for i in range(77,81):
countedTypeIdExceptions[77]['channel'] = countedTypeIdExceptions[78]['channel'] = countedTypeIdExceptions[79]['channel'] = True countedTypeIdExceptions[i] = {}
countedTypeIdExceptions[i]['channel'] = True
countedTypeIdExceptions['ipPortSecret'] = True countedTypeIdExceptions['ipPortSecret'] = True
countedTypeIdExceptions['accessPointRule'] = True countedTypeIdExceptions['accessPointRule'] = True
countedTypeIdExceptions['help_configSimple'] = True countedTypeIdExceptions['help_configSimple'] = True

View File

@ -1979,6 +1979,7 @@ void HistoryWidget::updateNotifyControls() {
void HistoryWidget::refreshSilentToggle() { void HistoryWidget::refreshSilentToggle() {
if (!_silent && hasSilentToggle()) { if (!_silent && hasSilentToggle()) {
_silent.create(this, _peer->asChannel()); _silent.create(this, _peer->asChannel());
orderWidgets();
} else if (_silent && !hasSilentToggle()) { } else if (_silent && !hasSilentToggle()) {
_silent.destroy(); _silent.destroy();
} }

View File

@ -133,6 +133,7 @@ introTermsContent: FlatLabel(defaultFlatLabel) {
minWidth: 285px; minWidth: 285px;
} }
introTermsPadding: margins(23px, 0px, 16px, 0px); introTermsPadding: margins(23px, 0px, 16px, 0px);
introTermsAgePadding: margins(23px, 8px, 16px, 8px);
introCountryIcon: icon {{ "intro_country_dropdown", menuIconFg }}; introCountryIcon: icon {{ "intro_country_dropdown", menuIconFg }};
introCountryIconPosition: point(8px, 37px); introCountryIconPosition: point(8px, 37px);

View File

@ -274,7 +274,7 @@ void CodeWidget::onSendCall() {
void CodeWidget::callDone(const MTPauth_SentCode &v) { void CodeWidget::callDone(const MTPauth_SentCode &v) {
if (v.type() == mtpc_auth_sentCode) { if (v.type() == mtpc_auth_sentCode) {
fillSentCodeData(v.c_auth_sentCode().vtype); fillSentCodeData(v.c_auth_sentCode());
_code->setDigitsCountMax(getData()->codeLength); _code->setDigitsCountMax(getData()->codeLength);
} }
if (_callStatus == Widget::Data::CallStatus::Calling) { if (_callStatus == Widget::Data::CallStatus::Calling) {
@ -328,8 +328,8 @@ void CodeWidget::noTelegramCodeDone(const MTPauth_SentCode &result) {
return; return;
} }
auto &d = result.c_auth_sentCode(); const auto &d = result.c_auth_sentCode();
fillSentCodeData(d.vtype); fillSentCodeData(d);
_code->setDigitsCountMax(getData()->codeLength); _code->setDigitsCountMax(getData()->codeLength);
if (d.has_next_type() && d.vnext_type.type() == mtpc_auth_codeTypeCall) { if (d.has_next_type() && d.vnext_type.type() == mtpc_auth_codeTypeCall) {
getData()->callStatus = Widget::Data::CallStatus::Waiting; getData()->callStatus = Widget::Data::CallStatus::Waiting;

View File

@ -48,15 +48,6 @@ Locale: ") + Platform::SystemLanguage();
UrlClickHandler::doOpen(url); UrlClickHandler::doOpen(url);
} }
bool TermsAcceptRequired(const QString &countryCode) {
const auto codes = std::vector<QString>{
"AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE",
"GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT",
"RO", "SK", "SI", "ES", "SE", "GB"
};
return ranges::find(codes, countryCode.toUpper()) != end(codes);
}
} // namespace } // namespace
PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, data) PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, data)
@ -73,16 +64,6 @@ PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat
connect(_phone, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_phone, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_code, SIGNAL(changed()), this, SLOT(onInputChange())); connect(_code, SIGNAL(changed()), this, SLOT(onInputChange()));
connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest())); connect(_checkRequest, SIGNAL(timeout()), this, SLOT(onCheckRequest()));
connect(
_code,
&Ui::CountryCodeInput::codeChanged,
this,
&PhoneWidget::toggleTerms);
connect(
_country,
&CountryInput::codeChanged,
this,
&PhoneWidget::toggleTerms);
setTitleText(langFactory(lng_phone_title)); setTitleText(langFactory(lng_phone_title));
setDescriptionText(langFactory(lng_phone_desc)); setDescriptionText(langFactory(lng_phone_desc));
@ -94,10 +75,6 @@ PhoneWidget::PhoneWidget(QWidget *parent, Widget::Data *data) : Step(parent, dat
} }
_changed = false; _changed = false;
subscribe(Lang::Current().updated(), [this] {
_termsAccepted = false;
});
Messenger::Instance().destroyStaleAuthorizationKeys(); Messenger::Instance().destroyStaleAuthorizationKeys();
} }
@ -152,13 +129,6 @@ void PhoneWidget::countryChanged() {
} }
} }
void PhoneWidget::toggleTerms() {
_termsAccepted = false;
InvokeQueued(this, [=] {
Step::toggleTerms(_country->iso());
});
}
void PhoneWidget::onInputChange() { void PhoneWidget::onInputChange() {
_changed = true; _changed = true;
hidePhoneError(); hidePhoneError();
@ -173,33 +143,22 @@ void PhoneWidget::submit() {
return; return;
} }
const auto sendCode = [=] { hidePhoneError();
hidePhoneError();
_checkRequest->start(1000); _checkRequest->start(1000);
_sentPhone = fullNumber(); _sentPhone = fullNumber();
Messenger::Instance().mtp()->setUserPhone(_sentPhone); Messenger::Instance().mtp()->setUserPhone(_sentPhone);
//_sentRequest = MTP::send(MTPauth_CheckPhone(MTP_string(_sentPhone)), rpcDone(&PhoneWidget::phoneCheckDone), rpcFail(&PhoneWidget::phoneSubmitFail)); //_sentRequest = MTP::send(MTPauth_CheckPhone(MTP_string(_sentPhone)), rpcDone(&PhoneWidget::phoneCheckDone), rpcFail(&PhoneWidget::phoneSubmitFail));
_sentRequest = MTP::send( _sentRequest = MTP::send(
MTPauth_SendCode( MTPauth_SendCode(
MTP_flags(0), MTP_flags(0),
MTP_string(_sentPhone), MTP_string(_sentPhone),
MTPBool(), MTPBool(),
MTP_int(ApiId), MTP_int(ApiId),
MTP_string(ApiHash)), MTP_string(ApiHash)),
rpcDone(&PhoneWidget::phoneSubmitDone), rpcDone(&PhoneWidget::phoneSubmitDone),
rpcFail(&PhoneWidget::phoneSubmitFail)); rpcFail(&PhoneWidget::phoneSubmitFail));
};
const auto code = _country->iso();
if (true || !TermsAcceptRequired(code) || _termsAccepted) {
sendCode();
} else {
acceptTerms(code, base::lambda_guarded(this, [=] {
_termsAccepted = true;
sendCode();
}));
}
} }
void PhoneWidget::stopCheck() { void PhoneWidget::stopCheck() {
@ -244,8 +203,8 @@ void PhoneWidget::phoneSubmitDone(const MTPauth_SentCode &result) {
return; return;
} }
auto &d = result.c_auth_sentCode(); const auto &d = result.c_auth_sentCode();
fillSentCodeData(d.vtype); fillSentCodeData(d);
getData()->phone = _sentPhone; getData()->phone = _sentPhone;
getData()->phoneHash = qba(d.vphone_code_hash); getData()->phoneHash = qba(d.vphone_code_hash);
getData()->phoneIsRegistered = d.is_phone_registered(); getData()->phoneIsRegistered = d.is_phone_registered();

View File

@ -47,7 +47,6 @@ private slots:
private: private:
void updateSignupGeometry(); void updateSignupGeometry();
void countryChanged(); void countryChanged();
void toggleTerms();
//void phoneCheckDone(const MTPauth_CheckedPhone &result); //void phoneCheckDone(const MTPauth_CheckedPhone &result);
void phoneSubmitDone(const MTPauth_SentCode &result); void phoneSubmitDone(const MTPauth_SentCode &result);
@ -67,7 +66,6 @@ private:
object_ptr<CountryInput> _country; object_ptr<CountryInput> _country;
object_ptr<Ui::CountryCodeInput> _code; object_ptr<Ui::CountryCodeInput> _code;
object_ptr<Ui::PhonePartInput> _phone; object_ptr<Ui::PhonePartInput> _phone;
bool _termsAccepted = false;
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _signup = { nullptr }; object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _signup = { nullptr };

View File

@ -47,6 +47,10 @@ SignupWidget::SignupWidget(QWidget *parent, Widget::Data *data) : Step(parent, d
setMouseTracking(true); setMouseTracking(true);
} }
void SignupWidget::finishInit() {
showTerms();
}
void SignupWidget::refreshLang() { void SignupWidget::refreshLang() {
_invertOrder = langFirstNameGoesSecond(); _invertOrder = langFirstNameGoesSecond();
if (_invertOrder) { if (_invertOrder) {
@ -176,7 +180,9 @@ void SignupWidget::onInputChange() {
} }
void SignupWidget::submit() { void SignupWidget::submit() {
if (_sentRequest) return; if (_sentRequest) {
return;
}
if (_invertOrder) { if (_invertOrder) {
if ((_last->hasFocus() || _last->getLastText().trimmed().length()) && !_first->getLastText().trimmed().length()) { if ((_last->hasFocus() || _last->getLastText().trimmed().length()) && !_first->getLastText().trimmed().length()) {
_first->setFocus(); _first->setFocus();
@ -195,11 +201,31 @@ void SignupWidget::submit() {
} }
} }
hideError(); const auto send = [&] {
hideError();
_firstName = _first->getLastText().trimmed(); _firstName = _first->getLastText().trimmed();
_lastName = _last->getLastText().trimmed(); _lastName = _last->getLastText().trimmed();
_sentRequest = MTP::send(MTPauth_SignUp(MTP_string(getData()->phone), MTP_bytes(getData()->phoneHash), MTP_string(getData()->code), MTP_string(_firstName), MTP_string(_lastName)), rpcDone(&SignupWidget::nameSubmitDone), rpcFail(&SignupWidget::nameSubmitFail)); _sentRequest = MTP::send(
MTPauth_SignUp(
MTP_string(getData()->phone),
MTP_bytes(getData()->phoneHash),
MTP_string(getData()->code),
MTP_string(_firstName),
MTP_string(_lastName)),
rpcDone(&SignupWidget::nameSubmitDone),
rpcFail(&SignupWidget::nameSubmitFail));
};
if (_termsAccepted
|| getData()->termsText.text.isEmpty()
|| !getData()->termsPopup) {
send();
} else {
acceptTerms(base::lambda_guarded(this, [=] {
_termsAccepted = true;
send();
}));
}
} }
QString SignupWidget::nextButtonText() const { QString SignupWidget::nextButtonText() const {

View File

@ -23,6 +23,7 @@ class SignupWidget : public Widget::Step {
public: public:
SignupWidget(QWidget *parent, Widget::Data *data); SignupWidget(QWidget *parent, Widget::Data *data);
void finishInit() override;
void setInnerFocus() override; void setInnerFocus() override;
void activate() override; void activate() override;
void cancelled() override; void cancelled() override;
@ -53,6 +54,7 @@ private:
bool _invertOrder = false; bool _invertOrder = false;
bool _termsAccepted = false;
object_ptr<QTimer> _checkRequest; object_ptr<QTimer> _checkRequest;
}; };

View File

@ -24,7 +24,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text.h" #include "ui/text/text.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/widgets/checkbox.h"
#include "ui/wrap/fade_wrap.h" #include "ui/wrap/fade_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/effects/slide_animation.h" #include "ui/effects/slide_animation.h"
#include "core/update_checker.h" #include "core/update_checker.h"
#include "window/window_slide_animation.h" #include "window/window_slide_animation.h"
@ -45,10 +47,13 @@ class TermsBox : public BoxContent {
public: public:
TermsBox( TermsBox(
QWidget*, QWidget*,
const QString &text, const TextWithEntities &text,
base::lambda<QString()> button); base::lambda<QString()> agree,
base::lambda<QString()> cancel,
int age = 0);
rpl::producer<> agreeClicks() const; rpl::producer<> agreeClicks() const;
rpl::producer<> cancelClicks() const;
protected: protected:
void prepare() override; void prepare() override;
@ -56,37 +61,81 @@ protected:
void keyPressEvent(QKeyEvent *e) override; void keyPressEvent(QKeyEvent *e) override;
private: private:
QString _text; TextWithEntities _text;
base::lambda<QString()> _button; base::lambda<QString()> _agree;
base::lambda<QString()> _cancel;
int _age = 0;
rpl::event_stream<> _agreeClicks; rpl::event_stream<> _agreeClicks;
rpl::event_stream<> _cancelClicks;
}; };
TermsBox::TermsBox( TermsBox::TermsBox(
QWidget*, QWidget*,
const QString &text, const TextWithEntities &text,
base::lambda<QString()> button) base::lambda<QString()> agree,
base::lambda<QString()> cancel,
int age)
: _text(text) : _text(text)
, _button(button) { , _agree(agree)
, _cancel(cancel)
, _age(age) {
} }
rpl::producer<> TermsBox::agreeClicks() const { rpl::producer<> TermsBox::agreeClicks() const {
return _agreeClicks.events(); return _agreeClicks.events();
} }
rpl::producer<> TermsBox::cancelClicks() const {
return _cancelClicks.events();
}
void TermsBox::prepare() { void TermsBox::prepare() {
setTitle(langFactory(lng_terms_header)); setTitle(langFactory(lng_terms_header));
addButton(_button, [=] {})->clicks(
) | rpl::start_to_stream(_agreeClicks, lifetime());
const auto content = Ui::CreateChild<Ui::PaddingWrap<Ui::FlatLabel>>( const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
this, content->add(
object_ptr<Ui::FlatLabel>( object_ptr<Ui::FlatLabel> (
this, this,
_text, rpl::single(_text),
Ui::FlatLabel::InitType::Rich,
st::introTermsContent), st::introTermsContent),
st::introTermsPadding); st::introTermsPadding);
const auto age = (_age > 0)
? content->add(
object_ptr<Ui::Checkbox>(
this,
lng_terms_age(lt_count, _age)),
st::introTermsAgePadding)
: nullptr;
const auto refreshButtons = [=] {
clearButtons();
if (age && !age->checked()) {
addButton(langFactory(lng_cancel), [=] { closeBox(); });
} else {
addButton(_agree, [=] {})->clicks(
) | rpl::filter([=] {
if (age && !age->checked()) {
return false;
}
return true;
}) | rpl::start_to_stream(_agreeClicks, lifetime());
if (_cancel) {
addButton(_cancel, [=] {})->clicks(
) | rpl::start_to_stream(_cancelClicks, lifetime());
}
}
};
if (age) {
base::ObservableViewer(
age->checkedChanged
) | rpl::start_with_next([=] {
refreshButtons();
}, lifetime());
}
refreshButtons();
content->resizeToWidth(st::boxWideWidth); content->resizeToWidth(st::boxWideWidth);
content->heightValue( content->heightValue(
) | rpl::start_with_next([=](int height) { ) | rpl::start_with_next([=](int height) {
@ -255,6 +304,15 @@ void Widget::historyMove(Direction direction) {
} else if (direction == Direction::Replace) { } else if (direction == Direction::Replace) {
_stepHistory.removeAt(_stepHistory.size() - 2); _stepHistory.removeAt(_stepHistory.size() - 2);
} }
if (_resetAccount) {
hideAndDestroy(std::exchange(_resetAccount, { nullptr }));
}
if (_terms) {
hideAndDestroy(std::exchange(_terms, { nullptr }));
}
getStep()->finishInit();
getStep()->prepareShowAnimated(wasStep); getStep()->prepareShowAnimated(wasStep);
if (wasStep->hasCover() != getStep()->hasCover()) { if (wasStep->hasCover() != getStep()->hasCover()) {
_nextTopFrom = wasStep->contentTop() + st::introStepHeight; _nextTopFrom = wasStep->contentTop() + st::introStepHeight;
@ -276,12 +334,8 @@ void Widget::historyMove(Direction direction) {
_update->toggle(!stepHasCover, anim::type::normal); _update->toggle(!stepHasCover, anim::type::normal);
} }
_next->setText([this] { return getStep()->nextButtonText(); }); _next->setText([this] { return getStep()->nextButtonText(); });
if (_resetAccount) { if (_resetAccount) _resetAccount->show(anim::type::normal);
hideAndDestroy(std::exchange(_resetAccount, { nullptr })); if (_terms) _terms->show(anim::type::normal);
}
if (_terms) {
hideAndDestroy(std::exchange(_terms, { nullptr }));
}
if (_changeLanguage) { if (_changeLanguage) {
_changeLanguage->toggle( _changeLanguage->toggle(
!_resetAccount && !_terms, !_resetAccount && !_terms,
@ -335,13 +389,11 @@ void Widget::appendStep(Step *step) {
step->setShowResetCallback([=] { step->setShowResetCallback([=] {
showResetButton(); showResetButton();
}); });
step->setToggleTermsCallback([=](QString countryCode) { step->setShowTermsCallback([=]() {
toggleTerms(countryCode); showTerms();
}); });
step->setAcceptTermsCallback([=]( step->setAcceptTermsCallback([=](base::lambda<void()> callback) {
QString countryCode, acceptTerms(callback);
base::lambda<void()> callback) {
acceptTerms(countryCode, callback);
}); });
} }
@ -359,27 +411,25 @@ void Widget::showResetButton() {
} }
} }
void Widget::toggleTerms(const QString &countryCode) { void Widget::showTerms() {
_termsCountryCode = countryCode; if (getData()->termsText.text.isEmpty()) {
if (countryCode.isEmpty()) { _terms.destroy();
if (_terms) hideAndDestroy(std::exchange(_terms, { nullptr })); } else if (!_terms) {
} else { auto entity = object_ptr<Ui::FlatLabel>(
if (!_terms) { this,
auto entity = object_ptr<Ui::FlatLabel>( lng_terms_signup(
this, lt_link,
lng_terms_signup( textcmdLink(1, lang(lng_terms_signup_link))),
lt_link, Ui::FlatLabel::InitType::Rich,
textcmdLink(1, lang(lng_terms_signup_link))), st::introTermsLabel);
Ui::FlatLabel::InitType::Rich, _terms.create(this, std::move(entity));
st::introTermsLabel); _terms->entity()->setLink(
_terms.create(this, std::move(entity)); 1,
_terms->hide(anim::type::instant); std::make_shared<LambdaClickHandler>([=] {
_terms->entity()->setLink( showTerms(nullptr);
1, }));
std::make_shared<LambdaClickHandler>([=] { showTerms(); })); updateControlsGeometry();
updateControlsGeometry(); _terms->hide(anim::type::instant);
}
_terms->toggle(!_termsCountryCode.isEmpty(), anim::type::normal);
} }
if (_changeLanguage) { if (_changeLanguage) {
_changeLanguage->toggle( _changeLanguage->toggle(
@ -388,10 +438,7 @@ void Widget::toggleTerms(const QString &countryCode) {
} }
} }
void Widget::acceptTerms( void Widget::acceptTerms(base::lambda<void()> callback) {
const QString &countryCode,
base::lambda<void()> callback) {
_termsCountryCode = countryCode;
showTerms(callback); showTerms(callback);
} }
@ -451,53 +498,45 @@ void Widget::getNearestDC() {
} }
void Widget::showTerms(base::lambda<void()> callback) { void Widget::showTerms(base::lambda<void()> callback) {
if (_termsCountryCode.isEmpty()) { if (getData()->termsText.text.isEmpty()) {
return; return;
} }
const auto showLastTerms = [=] { const auto weak = make_weak(this);
const auto box = Ui::show(Box<TermsBox>(
getData()->termsText,
langFactory(callback ? lng_terms_agree : lng_box_ok),
callback ? langFactory(lng_terms_decline) : nullptr,
getData()->termsAge));
box->agreeClicks(
) | rpl::start_with_next([=] {
if (callback) {
callback();
}
if (box) {
box->closeBox();
}
}, box->lifetime());
box->cancelClicks(
) | rpl::start_with_next([=] {
const auto box = Ui::show(Box<TermsBox>( const auto box = Ui::show(Box<TermsBox>(
_termsLastText, TextWithEntities{ lang(lng_terms_signup_sorry) },
langFactory(callback ? lng_terms_agree : lng_box_ok))); langFactory(lng_intro_finish),
langFactory(lng_terms_decline)));
box->agreeClicks( box->agreeClicks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
if (callback) { if (weak) {
callback(); showTerms(callback);
} }
}, box->lifetime());
box->cancelClicks(
) | rpl::start_with_next([=] {
if (box) { if (box) {
box->closeBox(); box->closeBox();
} }
}, box->lifetime()); }, box->lifetime());
}; }, box->lifetime());
const auto langPack = Lang::Current().id();
const auto code = _termsCountryCode;
if (_termsLastCountryCode == code && _termsLastLangPack == langPack) {
showLastTerms();
return;
}
request(MTPhelp_GetTermsOfService(
MTP_string(code)
)).done([=](const MTPhelp_TermsOfService &result) {
const auto text = qs(result.c_help_termsOfService().vtext);
const auto match = QRegularExpression("\\[([^\\]]+)\\]").match(text);
const auto linked = [&] {
if (!match.hasMatch()) {
return text;
}
const auto from = match.capturedStart(0);
const auto till = from + match.capturedLength(0);
return text.mid(0, from)
+ textcmdLink(
"http://telegram.org/privacy",
text.mid(from + 1, till - from - 2))
+ text.mid(till);
}();
_termsLastCountryCode = code;
_termsLastLangPack = langPack;
_termsLastText = linked;
showLastTerms();
}).send();
} }
void Widget::showControls() { void Widget::showControls() {
@ -515,6 +554,9 @@ void Widget::showControls() {
!_resetAccount && !_terms, !_resetAccount && !_terms,
anim::type::instant); anim::type::instant);
} }
if (_terms) {
_terms->show(anim::type::instant);
}
_back->toggle(getStep()->hasBack(), anim::type::instant); _back->toggle(getStep()->hasBack(), anim::type::instant);
} }
@ -525,6 +567,7 @@ void Widget::hideControls() {
_settings->hide(anim::type::instant); _settings->hide(anim::type::instant);
if (_update) _update->hide(anim::type::instant); if (_update) _update->hide(anim::type::instant);
if (_changeLanguage) _changeLanguage->hide(anim::type::instant); if (_changeLanguage) _changeLanguage->hide(anim::type::instant);
if (_terms) _terms->hide(anim::type::instant);
_back->hide(anim::type::instant); _back->hide(anim::type::instant);
} }
@ -790,7 +833,22 @@ bool Widget::Step::paintAnimated(Painter &p, QRect clip) {
return true; return true;
} }
void Widget::Step::fillSentCodeData(const MTPauth_SentCodeType &type) { void Widget::Step::fillSentCodeData(const MTPDauth_sentCode &data) {
if (data.has_terms_of_service()) {
const auto &terms = data.vterms_of_service.c_help_termsOfService();
getData()->termsText = TextWithEntities{
TextUtilities::Clean(qs(terms.vtext)),
TextUtilities::EntitiesFromMTP(terms.ventities.v) };
getData()->termsPopup = terms.is_popup();
getData()->termsAge = terms.has_min_age_confirm()
? terms.vmin_age_confirm.v
: 0;
} else {
getData()->termsText = TextWithEntities();
getData()->termsAge = 0;
}
const auto &type = data.vtype;
switch (type.type()) { switch (type.type()) {
case mtpc_auth_sentCodeTypeApp: { case mtpc_auth_sentCodeTypeApp: {
getData()->codeByTelegram = true; getData()->codeByTelegram = true;
@ -1024,14 +1082,12 @@ void Widget::Step::setShowResetCallback(base::lambda<void()> callback) {
_showResetCallback = std::move(callback); _showResetCallback = std::move(callback);
} }
void Widget::Step::setToggleTermsCallback( void Widget::Step::setShowTermsCallback(base::lambda<void()> callback) {
base::lambda<void(QString countryCode)> callback) { _showTermsCallback = std::move(callback);
_toggleTermsCallback = std::move(callback);
} }
void Widget::Step::setAcceptTermsCallback(base::lambda<void( void Widget::Step::setAcceptTermsCallback(
QString countryCode, base::lambda<void(base::lambda<void()> callback)> callback) {
base::lambda<void()> callback)> callback) {
_acceptTermsCallback = std::move(callback); _acceptTermsCallback = std::move(callback);
} }

View File

@ -77,6 +77,10 @@ public:
bool hasRecovery = false; bool hasRecovery = false;
QString pwdHint; QString pwdHint;
TextWithEntities termsText;
bool termsPopup = false;
int termsAge = 0;
base::Observable<void> updated; base::Observable<void> updated;
}; };
@ -90,6 +94,8 @@ public:
public: public:
Step(QWidget *parent, Data *data, bool hasCover = false); Step(QWidget *parent, Data *data, bool hasCover = false);
virtual void finishInit() {
}
virtual void setInnerFocus() { virtual void setInnerFocus() {
setFocus(); setFocus();
} }
@ -97,11 +103,10 @@ public:
void setGoCallback( void setGoCallback(
base::lambda<void(Step *step, Direction direction)> callback); base::lambda<void(Step *step, Direction direction)> callback);
void setShowResetCallback(base::lambda<void()> callback); void setShowResetCallback(base::lambda<void()> callback);
void setToggleTermsCallback( void setShowTermsCallback(
base::lambda<void(QString countryCode)> callback); base::lambda<void()> callback);
void setAcceptTermsCallback(base::lambda<void( void setAcceptTermsCallback(
QString countryCode, base::lambda<void(base::lambda<void()> callback)> callback);
base::lambda<void()> callback)> callback);
void prepareShowAnimated(Step *after); void prepareShowAnimated(Step *after);
void showAnimated(Direction direction); void showAnimated(Direction direction);
@ -137,7 +142,7 @@ public:
void setDescriptionText(base::lambda<QString()> richDescriptionTextFactory); void setDescriptionText(base::lambda<QString()> richDescriptionTextFactory);
bool paintAnimated(Painter &p, QRect clip); bool paintAnimated(Painter &p, QRect clip);
void fillSentCodeData(const MTPauth_SentCodeType &type); void fillSentCodeData(const MTPDauth_sentCode &type);
void showDescription(); void showDescription();
void hideDescription(); void hideDescription();
@ -159,14 +164,12 @@ public:
void showResetButton() { void showResetButton() {
if (_showResetCallback) _showResetCallback(); if (_showResetCallback) _showResetCallback();
} }
void toggleTerms(const QString &countryCode) { void showTerms() {
if (_toggleTermsCallback) _toggleTermsCallback(countryCode); if (_showTermsCallback) _showTermsCallback();
} }
void acceptTerms( void acceptTerms(base::lambda<void()> callback) {
const QString &countryCode,
base::lambda<void()> callback) {
if (_acceptTermsCallback) { if (_acceptTermsCallback) {
_acceptTermsCallback(countryCode, callback); _acceptTermsCallback(callback);
} }
} }
@ -203,9 +206,8 @@ public:
bool _hasCover = false; bool _hasCover = false;
base::lambda<void(Step *step, Direction direction)> _goCallback; base::lambda<void(Step *step, Direction direction)> _goCallback;
base::lambda<void()> _showResetCallback; base::lambda<void()> _showResetCallback;
base::lambda<void(QString countryCode)> _toggleTermsCallback; base::lambda<void()> _showTermsCallback;
base::lambda<void( base::lambda<void(
QString countryCode,
base::lambda<void()> callback)> _acceptTermsCallback; base::lambda<void()> callback)> _acceptTermsCallback;
object_ptr<Ui::FlatLabel> _title; object_ptr<Ui::FlatLabel> _title;
@ -244,10 +246,8 @@ private:
void showResetButton(); void showResetButton();
void resetAccount(); void resetAccount();
void toggleTerms(const QString &countryCode); void showTerms();
void acceptTerms( void acceptTerms(base::lambda<void()> callback);
const QString &countryCode,
base::lambda<void()> callback);
void hideAndDestroy(object_ptr<Ui::FadeWrap<Ui::RpWidget>> widget); void hideAndDestroy(object_ptr<Ui::FadeWrap<Ui::RpWidget>> widget);
Step *getStep(int skip = 0) { Step *getStep(int skip = 0) {
@ -259,7 +259,7 @@ private:
void appendStep(Step *step); void appendStep(Step *step);
void getNearestDC(); void getNearestDC();
void showTerms(base::lambda<void()> callback = nullptr); void showTerms(base::lambda<void()> callback);
Animation _a_show; Animation _a_show;
bool _showBack = false; bool _showBack = false;
@ -281,10 +281,6 @@ private:
object_ptr<Ui::FadeWrap<Ui::LinkButton>> _changeLanguage = { nullptr }; object_ptr<Ui::FadeWrap<Ui::LinkButton>> _changeLanguage = { nullptr };
object_ptr<Ui::FadeWrap<Ui::RoundButton>> _resetAccount = { nullptr }; object_ptr<Ui::FadeWrap<Ui::RoundButton>> _resetAccount = { nullptr };
object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _terms = { nullptr }; object_ptr<Ui::FadeWrap<Ui::FlatLabel>> _terms = { nullptr };
QString _termsCountryCode;
QString _termsLastCountryCode;
QString _termsLastLangPack;
QString _termsLastText;
base::unique_qptr<Window::ConnectingWidget> _connecting; base::unique_qptr<Window::ConnectingWidget> _connecting;