diff --git a/Telegram/SourceFiles/api/api_cloud_password.cpp b/Telegram/SourceFiles/api/api_cloud_password.cpp index a8a14fd1d..3a06ffda3 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.cpp +++ b/Telegram/SourceFiles/api/api_cloud_password.cpp @@ -41,24 +41,6 @@ void CloudPassword::reload() { }).send(); } -void CloudPassword::applyPendingReset( - const MTPaccount_ResetPasswordResult &data) { - if (!_state) { - reload(); - return; - } - data.match([&](const MTPDaccount_resetPasswordOk &data) { - reload(); - }, [&](const MTPDaccount_resetPasswordRequestedWait &data) { - const auto until = data.vuntil_date().v; - if (_state->pendingResetDate != until) { - _state->pendingResetDate = until; - _stateChanges.fire_copy(*_state); - } - }, [&](const MTPDaccount_resetPasswordFailedWait &data) { - }); -} - void CloudPassword::clearUnconfirmedPassword() { _requestId = _api.request(MTPaccount_CancelPasswordEmail( )).done([=](const MTPBool &result) { @@ -83,4 +65,48 @@ auto CloudPassword::stateCurrent() const : std::nullopt; } +auto CloudPassword::resetPassword() +-> rpl::producer { + return [=](auto consumer) { + _api.request(MTPaccount_ResetPassword( + )).done([=](const MTPaccount_ResetPasswordResult &result) { + result.match([&](const MTPDaccount_resetPasswordOk &data) { + reload(); + }, [&](const MTPDaccount_resetPasswordRequestedWait &data) { + if (!_state) { + reload(); + return; + } + const auto until = data.vuntil_date().v; + if (_state->pendingResetDate != until) { + _state->pendingResetDate = until; + _stateChanges.fire_copy(*_state); + } + }, [&](const MTPDaccount_resetPasswordFailedWait &data) { + consumer.put_next_copy(data.vretry_date().v); + }); + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).send(); + + return rpl::lifetime(); + }; +} + +auto CloudPassword::cancelResetPassword() +-> rpl::producer { + return [=](auto consumer) { + _api.request(MTPaccount_DeclinePasswordReset( + )).done([=] { + reload(); + consumer.put_done(); + }).fail([=](const MTP::Error &error) { + consumer.put_error_copy(error.type()); + }).send(); + + return rpl::lifetime(); + }; +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_cloud_password.h b/Telegram/SourceFiles/api/api_cloud_password.h index 2fdd7394c..00adf3ddb 100644 --- a/Telegram/SourceFiles/api/api_cloud_password.h +++ b/Telegram/SourceFiles/api/api_cloud_password.h @@ -23,14 +23,17 @@ namespace Api { class CloudPassword final { public: + using ResetRetryDate = int; explicit CloudPassword(not_null api); void reload(); - void applyPendingReset(const MTPaccount_ResetPasswordResult &data); void clearUnconfirmedPassword(); rpl::producer state() const; std::optional stateCurrent() const; + rpl::producer resetPassword(); + rpl::producer cancelResetPassword(); + private: MTP::Sender _api; mtpRequestId _requestId = 0; diff --git a/Telegram/SourceFiles/boxes/passcode_box.cpp b/Telegram/SourceFiles/boxes/passcode_box.cpp index 0dcbd9f99..d8b093b79 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.cpp +++ b/Telegram/SourceFiles/boxes/passcode_box.cpp @@ -102,49 +102,53 @@ void StartPendingReset( not_null context, Fn close) { const auto weak = Ui::MakeWeak(context.get()); - session->api().request(MTPaccount_ResetPassword( - )).done([=](const MTPaccount_ResetPasswordResult &result) { - session->api().cloudPassword().applyPendingReset(result); - result.match([&](const MTPDaccount_resetPasswordOk &data) { - }, [&](const MTPDaccount_resetPasswordRequestedWait &data) { - }, [&](const MTPDaccount_resetPasswordFailedWait &data) { - constexpr auto kMinute = 60; - constexpr auto kHour = 3600; - constexpr auto kDay = 86400; - const auto left = std::max( - data.vretry_date().v - base::unixtime::now(), - kMinute); - const auto days = (left / kDay); - const auto hours = (left / kHour); - const auto minutes = (left / kMinute); - const auto duration = days - ? tr::lng_group_call_duration_days(tr::now, lt_count, days) - : hours - ? tr::lng_group_call_duration_hours(tr::now, lt_count, hours) - : tr::lng_group_call_duration_minutes( - tr::now, - lt_count, - minutes); - if (const auto strong = weak.data()) { - strong->getDelegate()->show(Box( - tr::lng_cloud_password_reset_later( - tr::now, - lt_duration, - duration))); + auto lifetime = std::make_shared(); + + auto finish = [=](const QString &message) mutable { + if (const auto strong = weak.data()) { + if (!message.isEmpty()) { + strong->getDelegate()->show(Box(message)); } - }); - if (const auto strong = weak.data()) { strong->closeBox(); } close(); - }).fail([=](const MTP::Error &error) { - if (const auto strong = weak.data()) { - strong->getDelegate()->show( - Box("Error: " + error.type())); - strong->closeBox(); + if (lifetime) { + base::take(lifetime)->destroy(); } - close(); - }).send(); + }; + + session->api().cloudPassword().resetPassword( + ) | rpl::start_with_next_error_done([=]( + Api::CloudPassword::ResetRetryDate retryDate) { + constexpr auto kMinute = 60; + constexpr auto kHour = 3600; + constexpr auto kDay = 86400; + const auto left = std::max( + retryDate - base::unixtime::now(), + kMinute); + const auto days = (left / kDay); + const auto hours = (left / kHour); + const auto minutes = (left / kMinute); + const auto duration = days + ? tr::lng_group_call_duration_days(tr::now, lt_count, days) + : hours + ? tr::lng_group_call_duration_hours(tr::now, lt_count, hours) + : tr::lng_group_call_duration_minutes( + tr::now, + lt_count, + minutes); + if (const auto strong = weak.data()) { + strong->getDelegate()->show(Box( + tr::lng_cloud_password_reset_later( + tr::now, + lt_duration, + duration))); + } + }, [=](const QString &error) mutable { + finish("Error: " + error); + }, [=]() mutable { + finish({}); + }, *lifetime); } } // namespace diff --git a/Telegram/SourceFiles/settings/settings_privacy_security.cpp b/Telegram/SourceFiles/settings/settings_privacy_security.cpp index 65d0e5df6..907a324e1 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_security.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_security.cpp @@ -558,7 +558,7 @@ void SetupCloudPassword( ) | rpl::map([](TimeId time) { return time != 0; })); - const auto sent = std::make_shared(0); + const auto sent = std::make_shared(false); reset->entity()->addClickHandler([=] { const auto api = &session->api(); const auto state = api->cloudPassword().stateCurrent(); @@ -566,23 +566,23 @@ void SetupCloudPassword( if (!date || *sent) { return; } else if (base::unixtime::now() >= date) { - *sent = api->request(MTPaccount_ResetPassword( - )).done([=](const MTPaccount_ResetPasswordResult &result) { - *sent = 0; - api->cloudPassword().applyPendingReset(result); - }).fail([=](const MTP::Error &error) { - *sent = 0; - }).send(); + *sent = true; + api->cloudPassword().resetPassword( + ) | rpl::start_with_error_done([=](const QString &error) { + *sent = false; + }, [=] { + *sent = false; + }, container->lifetime()); } else { const auto cancel = [=] { Ui::hideLayer(); - *sent = api->request(MTPaccount_DeclinePasswordReset( - )).done([=] { - *sent = 0; - api->cloudPassword().reload(); - }).fail([=](const MTP::Error &error) { - *sent = 0; - }).send(); + *sent = true; + api->cloudPassword().cancelResetPassword( + ) | rpl::start_with_error_done([=](const QString &error) { + *sent = false; + }, [=] { + *sent = false; + }, container->lifetime()); }; Ui::show(Box( tr::lng_cloud_password_reset_cancel_sure(tr::now),