diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 78a649937..b84d103d2 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -230,8 +230,6 @@ PRIVATE boxes/background_box.h boxes/background_preview_box.cpp boxes/background_preview_box.h - boxes/change_phone_box.cpp - boxes/change_phone_box.h boxes/choose_filter_box.cpp boxes/choose_filter_box.h boxes/connection_box.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index e43ba3a8a..570b7b3ed 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1056,17 +1056,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_self_destruct_sessions_title" = "Session termination"; "lng_self_destruct_sessions_description" = "If you don't come online from a specific session at least once within this period, it will be terminated."; -"lng_change_phone_title" = "Change phone number"; -"lng_change_phone_about" = "You can change your Telegram number\nhere. Your account and all your cloud data\n— messages, media, contacts, etc. will be\nmoved to the new number.\n\n**Important**: all your Telegram contacts will\nget your **new number** added to their address\nbook, provided they had your old number and\nyou haven't blocked them in Telegram."; -"lng_change_phone_warning" = "All your Telegram contacts will get your new number added to their address book, provided they had your old number and you haven't blocked them in Telegram."; -"lng_change_phone_occupied" = "The number {phone} is already connected to a Telegram account. Please delete that account before migrating to the new number."; -"lng_change_phone_button" = "Change number"; -"lng_change_phone_new_title" = "Enter new number"; -"lng_change_phone_new_description" = "We will send an SMS with a confirmation code to your new number."; "lng_change_phone_new_submit" = "Submit"; "lng_change_phone_code_title" = "Enter code"; -"lng_change_phone_code_description" = "We've sent an SMS with a confirmation code to your phone {phone}."; -"lng_change_phone_success" = "Your phone number has been changed."; +"lng_change_phone_error" = "You can only change your phone number using mobile Telegram apps. Please use an official Telegram app on your phone to update your number."; "lng_mute_menu_mute" = "Mute"; "lng_mute_menu_unmute" = "Unmute"; diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 01ab9a5f7..28b0c58cc 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -1,6 +1,5 @@ - ../../animations/change_number.tgs ../../animations/blocked_peers_empty.tgs ../../animations/filters.tgs ../../animations/cloud_filters.tgs diff --git a/Telegram/SourceFiles/boxes/change_phone_box.cpp b/Telegram/SourceFiles/boxes/change_phone_box.cpp deleted file mode 100644 index d9032c5a4..000000000 --- a/Telegram/SourceFiles/boxes/change_phone_box.cpp +++ /dev/null @@ -1,569 +0,0 @@ -/* -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 "boxes/change_phone_box.h" - -#include "core/file_utilities.h" -#include "lang/lang_keys.h" -#include "ui/widgets/labels.h" -#include "ui/widgets/sent_code_field.h" -#include "ui/widgets/buttons.h" -#include "ui/wrap/fade_wrap.h" -#include "ui/toast/toast.h" -#include "ui/text/format_values.h" // Ui::FormatPhone -#include "ui/text/text_utilities.h" -#include "ui/widgets/fields/special_fields.h" -#include "ui/boxes/confirm_box.h" -#include "boxes/phone_banned_box.h" -#include "countries/countries_instance.h" // Countries::ExtractPhoneCode. -#include "main/main_account.h" -#include "main/main_session.h" -#include "data/data_session.h" -#include "data/data_user.h" -#include "info/profile/info_profile_values.h" -#include "lottie/lottie_icon.h" -#include "mtproto/sender.h" -#include "apiwrap.h" -#include "window/window_session_controller.h" -#include "styles/style_layers.h" -#include "styles/style_boxes.h" - -namespace { - -void CreateErrorLabel( - QWidget *parent, - object_ptr> &label, - const QString &text, - int x, - int y) { - if (label) { - label->hide(anim::type::normal); - - auto saved = label.data(); - auto destroy = [old = std::move(label)]() mutable { - old.destroyDelayed(); - }; - - using namespace rpl::mappers; - saved->shownValue() - | rpl::filter(_1 == false) - | rpl::take(1) - | rpl::start_with_done( - std::move(destroy), - saved->lifetime()); - } - if (!text.isEmpty()) { - label.create( - parent, - object_ptr( - parent, - text, - st::changePhoneError)); - label->hide(anim::type::instant); - label->moveToLeft(x, y); - label->show(anim::type::normal); - } -} - -[[nodiscard]] int ErrorSkip() { - return st::boxLittleSkip + st::changePhoneError.style.font->height; -} - -} // namespace - -namespace Settings { - -class ChangePhone::EnterPhone : public Ui::BoxContent { -public: - EnterPhone(QWidget*, not_null controller); - - void setInnerFocus() override { - _phone->setFocusFast(); - } - -protected: - void prepare() override; - -private: - void submit(); - void sendPhoneDone( - const MTPauth_SentCode &result, - const QString &phoneNumber); - void sendPhoneFail(const MTP::Error &error, const QString &phoneNumber); - void showError(const QString &text); - void hideError() { - showError(QString()); - } - - const not_null _controller; - MTP::Sender _api; - - object_ptr _phone = { nullptr }; - object_ptr> _error = { nullptr }; - mtpRequestId _requestId = 0; - -}; - -class ChangePhone::EnterCode : public Ui::BoxContent { -public: - EnterCode( - QWidget*, - not_null controller, - const QString &phone, - const QString &hash, - const QString &openUrl, - int codeLength, - int callTimeout); - - void setInnerFocus() override { - _code->setFocusFast(); - } - -protected: - void prepare() override; - -private: - void submit(const QString &code); - void sendCall(); - void updateCall(); - void sendCodeFail(const MTP::Error &error); - void showError(const QString &text); - void hideError() { - showError(QString()); - } - [[nodiscard]] int countHeight() const; - - const not_null _controller; - MTP::Sender _api; - - QString _phone; - QString _hash; - QString _openUrl; - int _codeLength = 0; - int _callTimeout = 0; - object_ptr _code = { nullptr }; - object_ptr> _error = { nullptr }; - object_ptr _callLabel = { nullptr }; - object_ptr _fragment = { nullptr }; - mtpRequestId _requestId = 0; - Ui::SentCodeCall _call; - -}; - -ChangePhone::EnterPhone::EnterPhone( - QWidget*, - not_null controller) -: _controller(controller) -, _api(&controller->session().mtp()) { -} - -void ChangePhone::EnterPhone::prepare() { - setTitle(tr::lng_change_phone_title()); - - const auto phoneValue = QString(); - _phone.create( - this, - st::defaultInputField, - tr::lng_change_phone_new_title(), - Countries::ExtractPhoneCode(_controller->session().user()->phone()), - phoneValue, - [](const QString &s) { return Countries::Groups(s); }); - - _phone->resize( - st::boxWidth - 2 * st::boxPadding.left(), - _phone->height()); - _phone->moveToLeft(st::boxPadding.left(), st::boxLittleSkip); - connect(_phone, &Ui::PhoneInput::submitted, [=] { submit(); }); - - const auto description = object_ptr( - this, - tr::lng_change_phone_new_description(tr::now), - st::changePhoneLabel); - description->moveToLeft( - st::boxPadding.left(), - _phone->y() + _phone->height() + ErrorSkip() + st::boxLittleSkip); - - setDimensions( - st::boxWidth, - description->bottomNoMargins() + st::boxLittleSkip); - - addButton(tr::lng_change_phone_new_submit(), [this] { submit(); }); - addButton(tr::lng_cancel(), [this] { closeBox(); }); -} - -void ChangePhone::EnterPhone::submit() { - if (_requestId) { - return; - } - hideError(); - - const auto phoneNumber = _phone->getLastText().trimmed(); - _requestId = _api.request(MTPaccount_SendChangePhoneCode( - MTP_string(phoneNumber), - MTP_codeSettings( - MTP_flags(0), - MTPVector(), - MTPstring(), - MTPBool()) - )).done([=](const MTPauth_SentCode &result) { - _requestId = 0; - sendPhoneDone(result, phoneNumber); - }).fail([=](const MTP::Error &error) { - _requestId = 0; - sendPhoneFail(error, phoneNumber); - }).handleFloodErrors().send(); -} - -void ChangePhone::EnterPhone::sendPhoneDone( - const MTPauth_SentCode &result, - const QString &phoneNumber) { - const auto data = result.match([](const MTPDauth_sentCode &data) { - return &data; - }, [](const MTPDauth_sentCodeSuccess &) -> const MTPDauth_sentCode* { - LOG(("API Error: Unexpected auth.sentCodeSuccess " - "(ChangePhone::EnterPhone).")); - return nullptr; - }); - if (!data) { - showError(Lang::Hard::ServerError()); - return; - } - - const auto bad = [&](const char *type) { - LOG(("API Error: Should not be '%1'.").arg(type)); - showError(Lang::Hard::ServerError()); - return false; - }; - auto codeLength = 0; - auto codeByFragmentUrl = QString(); - const auto hasLength = data->vtype().match([&]( - const MTPDauth_sentCodeTypeApp &typeData) { - LOG(("Error: should not be in-app code!")); - showError(Lang::Hard::ServerError()); - return false; - }, [&](const MTPDauth_sentCodeTypeSms &typeData) { - codeLength = typeData.vlength().v; - return true; - }, [&](const MTPDauth_sentCodeTypeFragmentSms &typeData) { - codeLength = typeData.vlength().v; - codeByFragmentUrl = qs(typeData.vurl()); - return true; - }, [&](const MTPDauth_sentCodeTypeCall &typeData) { - codeLength = typeData.vlength().v; - return true; - }, [&](const MTPDauth_sentCodeTypeFlashCall &) { - return bad("FlashCall"); - }, [&](const MTPDauth_sentCodeTypeMissedCall &) { - return bad("MissedCall"); - }, [&](const MTPDauth_sentCodeTypeFirebaseSms &) { - return bad("FirebaseSms"); - }, [&](const MTPDauth_sentCodeTypeEmailCode &) { - return bad("EmailCode"); - }, [&](const MTPDauth_sentCodeTypeSetUpEmailRequired &) { - return bad("SetUpEmailRequired"); - }); - if (!hasLength) { - return; - } - const auto phoneCodeHash = qs(data->vphone_code_hash()); - const auto callTimeout = [&] { - if (const auto nextType = data->vnext_type()) { - return nextType->match([&](const MTPDauth_sentCodeTypeCall &) { - return data->vtimeout().value_or(60); - }, [](const auto &) { - return 0; - }); - } - return 0; - }(); - _controller->show(Box( - _controller, - phoneNumber, - phoneCodeHash, - codeByFragmentUrl, - codeLength, - callTimeout)); -} - -void ChangePhone::EnterPhone::sendPhoneFail( - const MTP::Error &error, - const QString &phoneNumber) { - if (MTP::IsFloodError(error)) { - showError(tr::lng_flood_error(tr::now)); - } else if (error.type() == u"PHONE_NUMBER_INVALID"_q) { - showError(tr::lng_bad_phone(tr::now)); - } else if (error.type() == u"PHONE_NUMBER_BANNED"_q) { - Ui::ShowPhoneBannedError(&_controller->window(), phoneNumber); - } else if (error.type() == u"PHONE_NUMBER_OCCUPIED"_q) { - _controller->show( - Ui::MakeInformBox( - tr::lng_change_phone_occupied( - tr::now, - lt_phone, - Ui::FormatPhone(phoneNumber))), - Ui::LayerOption::CloseOther); - } else { - showError(Lang::Hard::ServerError()); - } -} - -void ChangePhone::EnterPhone::showError(const QString &text) { - CreateErrorLabel( - this, - _error, - text, - st::boxPadding.left(), - _phone->y() + _phone->height() + st::boxLittleSkip); - if (!text.isEmpty()) { - _phone->showError(); - } -} - -ChangePhone::EnterCode::EnterCode( - QWidget*, - not_null controller, - const QString &phone, - const QString &hash, - const QString &openUrl, - int codeLength, - int callTimeout) -: _controller(controller) -, _api(&controller->session().mtp()) -, _phone(phone) -, _hash(hash) -, _openUrl(openUrl) -, _codeLength(codeLength) -, _callTimeout(callTimeout) -, _call([this] { sendCall(); }, [this] { updateCall(); }) { -} - -void ChangePhone::EnterCode::prepare() { - const auto width = st::boxWidth; - setTitle(tr::lng_change_phone_title()); - - const auto descriptionText = tr::lng_change_phone_code_description( - tr::now, - lt_phone, - Ui::Text::Bold(Ui::FormatPhone(_phone)), - Ui::Text::WithEntities); - const auto description = object_ptr( - this, - rpl::single(descriptionText), - st::changePhoneLabel); - description->moveToLeft(st::boxPadding.left(), 0); - - const auto submitInput = [=] { submit(_code->getDigitsOnly()); }; - - const auto phoneValue = QString(); - _code.create( - this, - st::defaultInputField, - tr::lng_change_phone_code_title(), - phoneValue); - _code->setAutoSubmit(_codeLength, submitInput); - _code->setChangedCallback([=] { hideError(); }); - - _code->resize(width - 2 * st::boxPadding.left(), _code->height()); - _code->moveToLeft(st::boxPadding.left(), description->bottomNoMargins()); - connect(_code, &Ui::InputField::submitted, submitInput); - - if (!_openUrl.isEmpty()) { - _fragment.create( - this, - tr::lng_intro_fragment_button(), - st::fragmentBoxButton); - _fragment->setClickedCallback([=] { File::OpenUrl(_openUrl); }); - _fragment->setTextTransform( - Ui::RoundButton::TextTransform::NoTransform); - const auto codeBottom = _code->y() + _code->height(); - _fragment->setFullWidth(_code->width()); - _fragment->moveToLeft( - (width - _fragment->width()) / 2, - codeBottom + ErrorSkip() + st::boxLittleSkip); - } - - _controller->session().account().setHandleLoginCode([=](QString code) { - submit(code); - }); - boxClosing( - ) | rpl::start_with_next([controller = _controller] { - controller->session().account().setHandleLoginCode(nullptr); - }, lifetime()); - - setDimensions(width, countHeight()); - - if (_callTimeout > 0) { - _call.setStatus({ Ui::SentCodeCall::State::Waiting, _callTimeout }); - updateCall(); - } - - addButton(tr::lng_change_phone_new_submit(), submitInput); - addButton(tr::lng_cancel(), [=] { closeBox(); }); -} - -int ChangePhone::EnterCode::countHeight() const { - return _code->bottomNoMargins() - + ErrorSkip() - + 3 * st::boxLittleSkip - + (_fragment ? _fragment->height() : 0); -} - -void ChangePhone::EnterCode::submit(const QString &code) { - if (_requestId) { - return; - } - hideError(); - - const auto session = &_controller->session(); - const auto weak = Ui::MakeWeak(this); - _requestId = session->api().request(MTPaccount_ChangePhone( - MTP_string(_phone), - MTP_string(_hash), - MTP_string(code) - )).done([=, show = _controller->uiShow()](const MTPUser &result) { - _requestId = 0; - session->data().processUser(result); - if (weak) { - show->hideLayer(); - } - show->showToast(tr::lng_change_phone_success(tr::now)); - }).fail(crl::guard(this, [=](const MTP::Error &error) { - _requestId = 0; - sendCodeFail(error); - })).handleFloodErrors().send(); -} - -void ChangePhone::EnterCode::sendCall() { - _api.request(MTPauth_ResendCode( - MTP_string(_phone), - MTP_string(_hash) - )).done([=] { - _call.callDone(); - }).send(); -} - -void ChangePhone::EnterCode::updateCall() { - const auto text = _call.getText(); - if (text.isEmpty()) { - _callLabel.destroy(); - } else if (!_callLabel) { - _callLabel.create(this, text, st::changePhoneLabel); - _callLabel->moveToLeft( - st::boxPadding.left(), - countHeight() - _callLabel->height()); - _callLabel->show(); - } else { - _callLabel->setText(text); - } -} - -void ChangePhone::EnterCode::showError(const QString &text) { - CreateErrorLabel( - this, - _error, - text, - st::boxPadding.left(), - _code->y() + _code->height() + st::boxLittleSkip); - if (!text.isEmpty()) { - _code->showError(); - } -} - -void ChangePhone::EnterCode::sendCodeFail(const MTP::Error &error) { - if (MTP::IsFloodError(error)) { - showError(tr::lng_flood_error(tr::now)); - } else if (error.type() == u"PHONE_CODE_EMPTY"_q - || error.type() == u"PHONE_CODE_INVALID"_q) { - showError(tr::lng_bad_code(tr::now)); - } else if (error.type() == u"PHONE_CODE_EXPIRED"_q - || error.type() == u"PHONE_NUMBER_BANNED"_q) { - closeBox(); // Go back to phone input. - } else if (error.type() == u"PHONE_NUMBER_INVALID"_q) { - showError(tr::lng_bad_phone(tr::now)); - } else { - showError(Lang::Hard::ServerError()); - } -} - -ChangePhone::ChangePhone( - QWidget *parent, - not_null controller) -: Section(parent) -, _controller(controller) { - setupContent(); -} - -rpl::producer ChangePhone::title() { - return Info::Profile::PhoneValue( - _controller->session().user() - ) | rpl::map([](const TextWithEntities &text) { - return text.text; - }); -} - -void ChangePhone::setupContent() { - const auto content = Ui::CreateChild(this); - - auto icon = CreateLottieIcon(content, { - .name = u"change_number"_q, - .sizeOverride = { - st::changePhoneIconSize, - st::changePhoneIconSize, - }, - }, st::changePhoneIconPadding); - content->add(std::move(icon.widget)); - _animate = std::move(icon.animate); - - content->add( - object_ptr>( - content, - object_ptr( - content, - tr::lng_change_phone_button(), - st::changePhoneTitle)), - st::changePhoneTitlePadding); - - content->add( - object_ptr>( - content, - object_ptr( - content, - tr::lng_change_phone_about(Ui::Text::RichLangValue), - st::changePhoneDescription)), - st::changePhoneDescriptionPadding); - - const auto button = content->add( - object_ptr>( - content, - object_ptr( - content, - tr::lng_change_phone_button(), - st::changePhoneButton)), - st::changePhoneButtonPadding)->entity(); - button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform); - button->setClickedCallback([=] { - auto callback = [=] { - _controller->show( - Box(_controller), - Ui::LayerOption::CloseOther); - }; - _controller->show( - Ui::MakeConfirmBox({ - .text = tr::lng_change_phone_warning(), - .confirmed = std::move(callback), - }), - Ui::LayerOption::CloseOther); - }); - - Ui::ResizeFitChild(this, content); -} - -void ChangePhone::showFinished() { - _animate(anim::repeat::loop); -} - -} // namespace Settings diff --git a/Telegram/SourceFiles/boxes/change_phone_box.h b/Telegram/SourceFiles/boxes/change_phone_box.h deleted file mode 100644 index b837079e9..000000000 --- a/Telegram/SourceFiles/boxes/change_phone_box.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -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 "boxes/abstract_box.h" -#include "settings/settings_common.h" - -namespace Lottie { -class Icon; -} // namespace Lottie - -namespace Window { -class SessionController; -} // namespace Window - -namespace Settings { - -class ChangePhone : public Section { -public: - ChangePhone( - QWidget *parent, - not_null controller); - - void showFinished() override; - [[nodiscard]] rpl::producer title() override; - -private: - class EnterPhone; - class EnterCode; - - void setupContent(); - - const not_null _controller; - Fn _animate; - -}; - -} // namespace Settings diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index 60f65f230..1e6cda40f 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -26,7 +26,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/sticker_set_box.h" #include "boxes/sessions_box.h" #include "boxes/language_box.h" -#include "boxes/change_phone_box.h" #include "passport/passport_form_controller.h" #include "window/window_session_controller.h" #include "ui/toast/toast.h" @@ -503,7 +502,9 @@ bool ResolveSettings( } else if (section == u"themes"_q) { return ::Settings::Chat::Id(); } else if (section == u"change_number"_q) { - return ::Settings::ChangePhone::Id(); + controller->show( + Ui::MakeInformBox(tr::lng_change_phone_error())); + return {}; } else if (section == u"auto_delete"_q) { return ::Settings::GlobalTTLId(); } else if (section == u"information"_q) { diff --git a/Telegram/SourceFiles/settings/settings_information.cpp b/Telegram/SourceFiles/settings/settings_information.cpp index 7a001d74d..fd04b4af8 100644 --- a/Telegram/SourceFiles/settings/settings_information.cpp +++ b/Telegram/SourceFiles/settings/settings_information.cpp @@ -29,7 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/core_settings.h" #include "chat_helpers/emoji_suggestions_widget.h" #include "boxes/add_contact_box.h" -#include "boxes/change_phone_box.h" #include "boxes/premium_limits_box.h" #include "boxes/username_box.h" #include "data/data_session.h" @@ -374,7 +373,8 @@ void SetupRows( { &st::settingsIconUser, kIconLightBlue }); const auto showChangePhone = [=] { - controller->showSettings(ChangePhone::Id()); + controller->show( + Ui::MakeInformBox(tr::lng_change_phone_error())); controller->window().activate(); }; AddRow(