From 076aa9452e987d51d1013625937ab7c6c313f833 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 1 Sep 2023 17:34:05 +0400 Subject: [PATCH] Unblock the bot before sharing phone number. --- .../SourceFiles/api/api_blocked_peers.cpp | 103 +++++++++++++----- Telegram/SourceFiles/api/api_blocked_peers.h | 17 ++- .../inline_bots/bot_attach_web_view.cpp | 16 +++ .../SourceFiles/window/window_peer_menu.cpp | 4 +- .../window/window_session_controller.cpp | 2 +- 5 files changed, 108 insertions(+), 34 deletions(-) diff --git a/Telegram/SourceFiles/api/api_blocked_peers.cpp b/Telegram/SourceFiles/api/api_blocked_peers.cpp index 9dfc886b1e..0a79eb733b 100644 --- a/Telegram/SourceFiles/api/api_blocked_peers.cpp +++ b/Telegram/SourceFiles/api/api_blocked_peers.cpp @@ -77,45 +77,59 @@ void BlockedPeers::block(not_null peer) { _session->changes().peerUpdated( peer, Data::PeerUpdate::Flag::IsBlocked); - } else if (_blockRequests.find(peer) == end(_blockRequests)) { - const auto requestId = _api.request(MTPcontacts_Block( - MTP_flags(0), - peer->input - )).done([=] { - _blockRequests.erase(peer); - peer->setIsBlocked(true); - if (_slice) { - _slice->list.insert( - _slice->list.begin(), - { peer->id, base::unixtime::now() }); - ++_slice->total; - _changes.fire_copy(*_slice); - } - }).fail([=] { - _blockRequests.erase(peer); - }).send(); - - _blockRequests.emplace(peer, requestId); + return; + } else if (blockAlreadySent(peer, true)) { + return; } + const auto requestId = _api.request(MTPcontacts_Block( + MTP_flags(0), + peer->input + )).done([=] { + const auto data = _blockRequests.take(peer); + peer->setIsBlocked(true); + if (_slice) { + _slice->list.insert( + _slice->list.begin(), + { peer->id, base::unixtime::now() }); + ++_slice->total; + _changes.fire_copy(*_slice); + } + if (data) { + for (const auto &callback : data->callbacks) { + callback(false); + } + } + }).fail([=] { + if (const auto data = _blockRequests.take(peer)) { + for (const auto &callback : data->callbacks) { + callback(false); + } + } + }).send(); + + _blockRequests.emplace(peer, Request{ + .requestId = requestId, + .blocking = true, + }); } void BlockedPeers::unblock( not_null peer, - Fn onDone, + Fn done, bool force) { if (!force && !peer->isBlocked()) { _session->changes().peerUpdated( peer, Data::PeerUpdate::Flag::IsBlocked); return; - } else if (_blockRequests.find(peer) != end(_blockRequests)) { + } else if (blockAlreadySent(peer, false, done)) { return; } const auto requestId = _api.request(MTPcontacts_Unblock( MTP_flags(0), peer->input )).done([=] { - _blockRequests.erase(peer); + const auto data = _blockRequests.take(peer); peer->setIsBlocked(false); if (_slice) { auto &list = _slice->list; @@ -130,13 +144,46 @@ void BlockedPeers::unblock( } _changes.fire_copy(*_slice); } - if (onDone) { - onDone(); + if (data) { + for (const auto &callback : data->callbacks) { + callback(true); + } } }).fail([=] { - _blockRequests.erase(peer); + if (const auto data = _blockRequests.take(peer)) { + for (const auto &callback : data->callbacks) { + callback(false); + } + } }).send(); - _blockRequests.emplace(peer, requestId); + const auto i = _blockRequests.emplace(peer, Request{ + .requestId = requestId, + .blocking = false, + }).first; + if (done) { + i->second.callbacks.push_back(std::move(done)); + } +} + +bool BlockedPeers::blockAlreadySent( + not_null peer, + bool blocking, + Fn done) { + const auto i = _blockRequests.find(peer); + if (i == end(_blockRequests)) { + return false; + } else if (i->second.blocking == blocking) { + if (done) { + i->second.callbacks.push_back(std::move(done)); + } + return true; + } + const auto callbacks = base::take(i->second.callbacks); + _blockRequests.erase(i); + for (const auto &callback : callbacks) { + callback(false); + } + return false; } void BlockedPeers::reload() { @@ -160,7 +207,7 @@ auto BlockedPeers::slice() -> rpl::producer { : (_changes.events() | rpl::type_erased()); } -void BlockedPeers::request(int offset, Fn onDone) { +void BlockedPeers::request(int offset, Fn done) { if (_requestId) { return; } @@ -170,7 +217,7 @@ void BlockedPeers::request(int offset, Fn onDone) { MTP_int(offset ? kBlockedPerPage : kBlockedFirstSlice) )).done([=](const MTPcontacts_Blocked &result) { _requestId = 0; - onDone(TLToSlice(result, _session->data())); + done(TLToSlice(result, _session->data())); }).fail([=] { _requestId = 0; }).send(); diff --git a/Telegram/SourceFiles/api/api_blocked_peers.h b/Telegram/SourceFiles/api/api_blocked_peers.h index af184c4576..ca2000f67e 100644 --- a/Telegram/SourceFiles/api/api_blocked_peers.h +++ b/Telegram/SourceFiles/api/api_blocked_peers.h @@ -39,20 +39,31 @@ public: void reload(); rpl::producer slice(); - void request(int offset, Fn onDone); + void request(int offset, Fn done); void block(not_null peer); void unblock( not_null peer, - Fn onDone = nullptr, + Fn done = nullptr, bool force = false); private: + struct Request { + std::vector> callbacks; + mtpRequestId requestId = 0; + bool blocking = false; + }; + + [[nodiscard]] bool blockAlreadySent( + not_null peer, + bool blocking, + Fn done = nullptr); + const not_null _session; MTP::Sender _api; - base::flat_map, mtpRequestId> _blockRequests; + base::flat_map, Request> _blockRequests; mtpRequestId _requestId = 0; std::optional _slice; rpl::event_stream _changes; diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 410fa6b790..1a90cafd82 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "inline_bots/bot_attach_web_view.h" +#include "api/api_blocked_peers.h" #include "api/api_common.h" #include "core/click_handler_types.h" #include "data/data_bot_app.h" @@ -626,7 +627,22 @@ void AttachWebView::botAllowWriteAccess(Fn callback) { } void AttachWebView::botSharePhone(Fn callback) { + const auto bot = _bot; const auto history = _bot->owner().history(_bot); + if (_bot->isBlocked()) { + const auto done = [=](bool success) { + if (success && _bot == bot) { + Assert(!_bot->isBlocked()); + botSharePhone(callback); + } else { + callback(false); + } + }; + _bot->session().api().blockedPeers().unblock( + _bot, + crl::guard(this, done)); + return; + } auto action = Api::SendAction(history); action.clearDraft = false; const auto id = history->session().api().shareContact( diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 26571b1d68..6b9173ac11 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -1578,8 +1578,8 @@ void PeerMenuBlockUserBox( } void PeerMenuUnblockUserWithBotRestart(not_null user) { - user->session().api().blockedPeers().unblock(user, [=] { - if (user->isBot() && !user->isSupport()) { + user->session().api().blockedPeers().unblock(user, [=](bool success) { + if (success && user->isBot() && !user->isSupport()) { user->session().api().sendBotStart(user); } }); diff --git a/Telegram/SourceFiles/window/window_session_controller.cpp b/Telegram/SourceFiles/window/window_session_controller.cpp index 4ec3e2dfb2..268518eed2 100644 --- a/Telegram/SourceFiles/window/window_session_controller.cpp +++ b/Telegram/SourceFiles/window/window_session_controller.cpp @@ -314,7 +314,7 @@ void SessionNavigation::showPeerByLink(const PeerByLinkInfo &info) { if (info.startAutoSubmit) { peer->session().api().blockedPeers().unblock( peer, - [=] { showPeerByLinkResolved(peer, info); }, + [=](bool) { showPeerByLinkResolved(peer, info); }, true); } else { showPeerByLinkResolved(peer, info);