Extracted api code from ConfirmPhoneBox to separated file.

This commit is contained in:
23rd 2021-10-18 22:49:42 +03:00
parent f9976005f7
commit fa6725c54a
8 changed files with 255 additions and 192 deletions

View File

@ -114,6 +114,8 @@ PRIVATE
api/api_cloud_password.cpp
api/api_cloud_password.h
api/api_common.h
api/api_confirm_phone.cpp
api/api_confirm_phone.h
api/api_editing.cpp
api/api_editing.h
api/api_global_privacy.cpp

View File

@ -0,0 +1,125 @@
/*
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 "api/api_confirm_phone.h"
#include "apiwrap.h"
#include "boxes/confirm_box.h"
#include "boxes/confirm_phone_box.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "window/window_session_controller.h"
namespace Api {
ConfirmPhone::ConfirmPhone(not_null<ApiWrap*> api)
: _api(&api->instance()) {
}
void ConfirmPhone::resolve(
not_null<Window::SessionController*> controller,
const QString &phone,
const QString &hash) {
if (_sendRequestId) {
return;
}
_sendRequestId = _api.request(MTPaccount_SendConfirmPhoneCode(
MTP_string(hash),
MTP_codeSettings(MTP_flags(0))
)).done([=](const MTPauth_SentCode &result) {
_sendRequestId = 0;
result.match([&](const MTPDauth_sentCode &data) {
const auto sentCodeLength = data.vtype().match([&](
const MTPDauth_sentCodeTypeApp &data) {
LOG(("Error: should not be in-app code!"));
return 0;
}, [&](const MTPDauth_sentCodeTypeSms &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeCall &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeFlashCall &data) {
LOG(("Error: should not be flashcall!"));
return 0;
});
const auto phoneHash = qs(data.vphone_code_hash());
const auto timeout = [&]() -> std::optional<int> {
if (const auto nextType = data.vnext_type()) {
if (nextType->type() == mtpc_auth_codeTypeCall) {
return data.vtimeout().value_or(60);
}
}
return std::nullopt;
}();
auto box = Box<ConfirmPhoneBox>(
phone,
sentCodeLength,
timeout);
const auto boxWeak = Ui::MakeWeak(box.data());
box->resendRequests(
) | rpl::start_with_next([=] {
_api.request(MTPauth_ResendCode(
MTP_string(phone),
MTP_string(phoneHash)
)).done([=](const MTPauth_SentCode &result) {
if (boxWeak) {
boxWeak->callDone();
}
}).send();
}, box->lifetime());
box->checkRequests(
) | rpl::start_with_next([=](const QString &code) {
if (_checkRequestId) {
return;
}
_checkRequestId = _api.request(MTPaccount_ConfirmPhone(
MTP_string(phoneHash),
MTP_string(code)
)).done([=](const MTPBool &result) {
_checkRequestId = 0;
controller->show(
Box<InformBox>(
tr::lng_confirm_phone_success(
tr::now,
lt_phone,
Ui::FormatPhone(phone))),
Ui::LayerOption::CloseOther);
}).fail([=](const MTP::Error &error) {
_checkRequestId = 0;
if (!boxWeak) {
return;
}
const auto errorText = MTP::IsFloodError(error)
? tr::lng_flood_error(tr::now)
: (error.type() == (u"PHONE_CODE_EMPTY"_q)
|| error.type() == (u"PHONE_CODE_INVALID"_q))
? tr::lng_bad_code(tr::now)
: Lang::Hard::ServerError();
boxWeak->showServerError(errorText);
}).handleFloodErrors().send();
}, box->lifetime());
controller->show(std::move(box), Ui::LayerOption::CloseOther);
});
}).fail([=](const MTP::Error &error) {
_sendRequestId = 0;
_checkRequestId = 0;
const auto errorText = MTP::IsFloodError(error)
? tr::lng_flood_error(tr::now)
: (error.code() == 400)
? tr::lng_confirm_phone_link_invalid(tr::now)
: Lang::Hard::ServerError();
controller->show(
Box<InformBox>(errorText),
Ui::LayerOption::CloseOther);
}).handleFloodErrors().send();
}
} // namespace Api

View File

@ -0,0 +1,36 @@
/*
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 "mtproto/sender.h"
class ApiWrap;
namespace Window {
class SessionController;
} // namespace Window
namespace Api {
class ConfirmPhone final {
public:
explicit ConfirmPhone(not_null<ApiWrap*> api);
void resolve(
not_null<Window::SessionController*> controller,
const QString &phone,
const QString &hash);
private:
MTP::Sender _api;
mtpRequestId _sendRequestId = 0;
mtpRequestId _checkRequestId = 0;
};
} // namespace Api

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_updates.h"
#include "api/api_user_privacy.h"
#include "api/api_views.h"
#include "api/api_confirm_phone.h"
#include "data/stickers/data_stickers.h"
#include "data/data_drafts.h"
#include "data/data_changes.h"
@ -143,7 +144,8 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _globalPrivacy(std::make_unique<Api::GlobalPrivacy>(this))
, _userPrivacy(std::make_unique<Api::UserPrivacy>(this))
, _inviteLinks(std::make_unique<Api::InviteLinks>(this))
, _views(std::make_unique<Api::ViewsManager>(this)) {
, _views(std::make_unique<Api::ViewsManager>(this))
, _confirmPhone(std::make_unique<Api::ConfirmPhone>(this)) {
crl::on_main(session, [=] {
// You can't use _session->lifetime() in the constructor,
// only queued, because it is not constructed yet.
@ -4703,6 +4705,10 @@ Api::ViewsManager &ApiWrap::views() {
return *_views;
}
Api::ConfirmPhone &ApiWrap::confirmPhone() {
return *_confirmPhone;
}
void ApiWrap::createPoll(
const PollData &data,
const SendAction &action,

View File

@ -63,6 +63,7 @@ class GlobalPrivacy;
class UserPrivacy;
class InviteLinks;
class ViewsManager;
class ConfirmPhone;
namespace details {
@ -402,6 +403,7 @@ public:
[[nodiscard]] Api::UserPrivacy &userPrivacy();
[[nodiscard]] Api::InviteLinks &inviteLinks();
[[nodiscard]] Api::ViewsManager &views();
[[nodiscard]] Api::ConfirmPhone &confirmPhone();
void createPoll(
const PollData &data,
@ -723,6 +725,7 @@ private:
const std::unique_ptr<Api::UserPrivacy> _userPrivacy;
const std::unique_ptr<Api::InviteLinks> _inviteLinks;
const std::unique_ptr<Api::ViewsManager> _views;
const std::unique_ptr<Api::ConfirmPhone> _confirmPhone;
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;

View File

@ -9,119 +9,28 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/confirm_box.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
#include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_utilities.h"
#include "core/click_handler_types.h" // UrlClickHandler
#include "base/qthelp_url.h" // qthelp::url_encode
#include "base/platform/base_platform_info.h"
#include "main/main_session.h"
#include "mainwidget.h"
#include "lang/lang_keys.h"
#include "mtproto/facade.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
namespace {
object_ptr<ConfirmPhoneBox> CurrentConfirmPhoneBox = { nullptr };
} // namespace
void ConfirmPhoneBox::Start(
not_null<Main::Session*> session,
const QString &phone,
const QString &hash) {
if (CurrentConfirmPhoneBox
&& (CurrentConfirmPhoneBox->getPhone() != phone
|| &CurrentConfirmPhoneBox->session() != session)) {
CurrentConfirmPhoneBox.destroyDelayed();
}
if (!CurrentConfirmPhoneBox) {
CurrentConfirmPhoneBox = Box<ConfirmPhoneBox>(session, phone, hash);
}
CurrentConfirmPhoneBox->checkPhoneAndHash();
}
ConfirmPhoneBox::ConfirmPhoneBox(
QWidget*,
not_null<Main::Session*> session,
const QString &phone,
const QString &hash)
: _session(session)
, _api(&session->mtp())
, _phone(phone)
, _hash(hash)
int codeLength,
std::optional<int> timeout)
: _phone(phone)
, _sentCodeLength(codeLength)
, _call([this] { sendCall(); }, [this] { update(); }) {
if (timeout) {
_call.setStatus({ Ui::SentCodeCall::State::Waiting, *timeout });
}
}
void ConfirmPhoneBox::sendCall() {
_api.request(MTPauth_ResendCode(
MTP_string(_phone),
MTP_string(_phoneHash)
)).done([=](const MTPauth_SentCode &result) {
callDone(result);
}).send();
}
void ConfirmPhoneBox::checkPhoneAndHash() {
if (_sendCodeRequestId) {
return;
}
_sendCodeRequestId = _api.request(MTPaccount_SendConfirmPhoneCode(
MTP_string(_hash),
MTP_codeSettings(MTP_flags(0))
)).done([=](const MTPauth_SentCode &result) {
sendCodeDone(result);
}).fail([=](const MTP::Error &error) {
sendCodeFail(error);
}).handleFloodErrors().send();
}
void ConfirmPhoneBox::sendCodeDone(const MTPauth_SentCode &result) {
result.match([&](const MTPDauth_sentCode &data) {
_sendCodeRequestId = 0;
_sentCodeLength = data.vtype().match([&](const MTPDauth_sentCodeTypeApp &data) {
LOG(("Error: should not be in-app code!"));
return 0;
}, [&](const MTPDauth_sentCodeTypeSms &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeCall &data) {
return data.vlength().v;
}, [&](const MTPDauth_sentCodeTypeFlashCall &data) {
LOG(("Error: should not be flashcall!"));
return 0;
});
_phoneHash = qs(data.vphone_code_hash());
if (const auto nextType = data.vnext_type()) {
if (nextType->type() == mtpc_auth_codeTypeCall) {
_call.setStatus({ Ui::SentCodeCall::State::Waiting, data.vtimeout().value_or(60) });
}
}
launch();
});
}
void ConfirmPhoneBox::sendCodeFail(const MTP::Error &error) {
auto errorText = Lang::Hard::ServerError();
if (MTP::IsFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else if (error.code() == 400) {
errorText = tr::lng_confirm_phone_link_invalid(tr::now);
}
_sendCodeRequestId = 0;
Ui::show(Box<InformBox>(errorText));
if (this == CurrentConfirmPhoneBox) {
CurrentConfirmPhoneBox.destroyDelayed();
} else {
deleteLater();
}
}
void ConfirmPhoneBox::launch() {
if (!CurrentConfirmPhoneBox) return;
Ui::show(std::move(CurrentConfirmPhoneBox));
_resendRequests.fire({});
}
void ConfirmPhoneBox::prepare() {
@ -142,19 +51,21 @@ void ConfirmPhoneBox::prepare() {
addButton(tr::lng_confirm_phone_send(), [=] { sendCode(); });
addButton(tr::lng_cancel(), [=] { closeBox(); });
setDimensions(st::boxWidth, st::usernamePadding.top() + _code->height() + st::usernameSkip + _about->height() + st::usernameSkip);
setDimensions(
st::boxWidth,
st::usernamePadding.top()
+ _code->height()
+ st::usernameSkip
+ _about->height()
+ st::usernameSkip);
connect(_code, &Ui::InputField::submitted, [=] { sendCode(); });
showChildren();
}
void ConfirmPhoneBox::callDone(const MTPauth_SentCode &result) {
_call.callDone();
}
void ConfirmPhoneBox::sendCode() {
if (_sendCodeRequestId) {
if (_isWaitingCheck) {
return;
}
const auto code = _code->getDigitsOnly();
@ -168,35 +79,8 @@ void ConfirmPhoneBox::sendCode() {
showError(QString());
_sendCodeRequestId = _api.request(MTPaccount_ConfirmPhone(
MTP_string(_phoneHash),
MTP_string(code)
)).done([=](const MTPBool &result) {
confirmDone(result);
}).fail([=](const MTP::Error &error) {
confirmFail(error);
}).handleFloodErrors().send();
}
void ConfirmPhoneBox::confirmDone(const MTPBool &result) {
_sendCodeRequestId = 0;
Ui::show(Box<InformBox>(tr::lng_confirm_phone_success(tr::now, lt_phone, Ui::FormatPhone(_phone))));
}
void ConfirmPhoneBox::confirmFail(const MTP::Error &error) {
auto errorText = Lang::Hard::ServerError();
if (MTP::IsFloodError(error)) {
errorText = tr::lng_flood_error(tr::now);
} else {
auto &errorType = error.type();
if (errorType == qstr("PHONE_CODE_EMPTY") || errorType == qstr("PHONE_CODE_INVALID")) {
errorText = tr::lng_bad_code(tr::now);
}
}
_sendCodeRequestId = 0;
_code->setDisabled(false);
_code->setFocus();
showError(errorText);
_checkRequests.fire_copy(code);
_isWaitingCheck = true;
}
void ConfirmPhoneBox::showError(const QString &error) {
@ -213,13 +97,14 @@ void ConfirmPhoneBox::paintEvent(QPaintEvent *e) {
Painter p(this);
p.setFont(st::boxTextFont);
auto callText = _call.getText();
const auto callText = _call.getText();
if (!callText.isEmpty()) {
p.setPen(st::usernameDefaultFg);
auto callTextRectLeft = st::usernamePadding.left();
auto callTextRectTop = _about->y() + _about->height();
auto callTextRectWidth = width() - 2 * st::usernamePadding.left();
auto callTextRect = QRect(callTextRectLeft, callTextRectTop, callTextRectWidth, st::usernameSkip);
const auto callTextRect = QRect(
st::usernamePadding.left(),
_about->y() + _about->height(),
width() - 2 * st::usernamePadding.left(),
st::usernameSkip);
p.drawText(callTextRect, callText, style::al_left);
}
auto errorText = _error;
@ -229,22 +114,50 @@ void ConfirmPhoneBox::paintEvent(QPaintEvent *e) {
} else {
p.setPen(st::boxTextFgError);
}
auto errorTextRectLeft = st::usernamePadding.left();
auto errorTextRectTop = _code->y() + _code->height();
auto errorTextRectWidth = width() - 2 * st::usernamePadding.left();
auto errorTextRect = QRect(errorTextRectLeft, errorTextRectTop, errorTextRectWidth, st::usernameSkip);
const auto errorTextRect = QRect(
st::usernamePadding.left(),
_code->y() + _code->height(),
width() - 2 * st::usernamePadding.left(),
st::usernameSkip);
p.drawText(errorTextRect, errorText, style::al_left);
}
void ConfirmPhoneBox::resizeEvent(QResizeEvent *e) {
BoxContent::resizeEvent(e);
_code->resize(width() - st::usernamePadding.left() - st::usernamePadding.right(), _code->height());
_code->resize(
width() - st::usernamePadding.left() - st::usernamePadding.right(),
_code->height());
_code->moveToLeft(st::usernamePadding.left(), st::usernamePadding.top());
_about->moveToLeft(st::usernamePadding.left(), _code->y() + _code->height() + st::usernameSkip);
_about->moveToLeft(
st::usernamePadding.left(),
_code->y() + _code->height() + st::usernameSkip);
}
void ConfirmPhoneBox::setInnerFocus() {
_code->setFocusFast();
}
rpl::producer<QString> ConfirmPhoneBox::checkRequests() const {
return _checkRequests.events();
}
rpl::producer<> ConfirmPhoneBox::resendRequests() const {
return _resendRequests.events();
}
void ConfirmPhoneBox::callDone() {
_call.callDone();
}
void ConfirmPhoneBox::showServerError(const QString &text) {
_isWaitingCheck = false;
_code->setDisabled(false);
_code->setFocus();
showError(text);
}
QString ConfirmPhoneBox::getPhone() const {
return _phone;
}

View File

@ -8,30 +8,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "boxes/abstract_box.h"
#include "base/timer.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/sent_code_field.h"
#include "mtproto/sender.h"
namespace Ui {
class InputField;
class FlatLabel;
} // namespace Ui
namespace Main {
class Session;
} // namespace Main
class ConfirmPhoneBox final : public Ui::BoxContent {
public:
static void Start(
not_null<Main::Session*> session,
ConfirmPhoneBox(
QWidget*,
const QString &phone,
const QString &hash);
int codeLength,
std::optional<int> timeout);
[[nodiscard]] Main::Session &session() const {
return *_session;
}
[[nodiscard]] rpl::producer<QString> checkRequests() const;
[[nodiscard]] rpl::producer<> resendRequests() const;
void callDone();
void showServerError(const QString &text);
protected:
void prepare() override;
@ -41,45 +36,21 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
ConfirmPhoneBox(
QWidget*,
not_null<Main::Session*> session,
const QString &phone,
const QString &hash);
friend class object_ptr<ConfirmPhoneBox>;
void sendCode();
void sendCall();
void checkPhoneAndHash();
void sendCodeDone(const MTPauth_SentCode &result);
void sendCodeFail(const MTP::Error &error);
void callDone(const MTPauth_SentCode &result);
void confirmDone(const MTPBool &result);
void confirmFail(const MTP::Error &error);
QString getPhone() const {
return _phone;
}
void launch();
QString getPhone() const;
void showError(const QString &error);
const not_null<Main::Session*> _session;
MTP::Sender _api;
mtpRequestId _sendCodeRequestId = 0;
// _hash from the link for account.sendConfirmPhoneCode call.
// _phoneHash from auth.sentCode for account.confirmPhone call.
QString _phone, _hash;
QString _phoneHash;
const QString _phone;
// If we receive the code length, we autosubmit _code field when enough symbols is typed.
int _sentCodeLength = 0;
const int _sentCodeLength = 0;
mtpRequestId _checkCodeRequestId = 0;
bool _isWaitingCheck = false;
object_ptr<Ui::FlatLabel> _about = { nullptr };
object_ptr<Ui::SentCodeField> _code = { nullptr };
@ -87,4 +58,7 @@ private:
QString _error;
Ui::SentCodeCall _call;
rpl::event_stream<QString> _checkRequests;
rpl::event_stream<> _resendRequests;
};

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/local_url_handlers.h"
#include "api/api_authorizations.h"
#include "api/api_confirm_phone.h"
#include "api/api_text_entities.h"
#include "api/api_chat_invite.h"
#include "base/qthelp_regex.h"
@ -136,15 +137,18 @@ bool ConfirmPhone(
if (!controller) {
return false;
}
auto params = url_parse_params(
const auto params = url_parse_params(
match->captured(1),
qthelp::UrlParamNameTransform::ToLower);
auto phone = params.value(qsl("phone"));
auto hash = params.value(qsl("hash"));
const auto phone = params.value(qsl("phone"));
const auto hash = params.value(qsl("hash"));
if (phone.isEmpty() || hash.isEmpty()) {
return false;
}
ConfirmPhoneBox::Start(&controller->session(), phone, hash);
controller->session().api().confirmPhone().resolve(
controller,
phone,
hash);
return true;
}