Unblock the bot before sharing phone number.

This commit is contained in:
John Preston 2023-09-01 17:34:05 +04:00
parent d77c7a70ab
commit 076aa9452e
5 changed files with 108 additions and 34 deletions

View File

@ -77,45 +77,59 @@ void BlockedPeers::block(not_null<PeerData*> 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<PeerData*> peer,
Fn<void()> onDone,
Fn<void(bool success)> 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<PeerData*> peer,
bool blocking,
Fn<void(bool success)> 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<BlockedPeers::Slice> {
: (_changes.events() | rpl::type_erased());
}
void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> onDone) {
void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> done) {
if (_requestId) {
return;
}
@ -170,7 +217,7 @@ void BlockedPeers::request(int offset, Fn<void(BlockedPeers::Slice)> 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();

View File

@ -39,20 +39,31 @@ public:
void reload();
rpl::producer<Slice> slice();
void request(int offset, Fn<void(Slice)> onDone);
void request(int offset, Fn<void(Slice)> done);
void block(not_null<PeerData*> peer);
void unblock(
not_null<PeerData*> peer,
Fn<void()> onDone = nullptr,
Fn<void(bool success)> done = nullptr,
bool force = false);
private:
struct Request {
std::vector<Fn<void(bool success)>> callbacks;
mtpRequestId requestId = 0;
bool blocking = false;
};
[[nodiscard]] bool blockAlreadySent(
not_null<PeerData*> peer,
bool blocking,
Fn<void(bool success)> done = nullptr);
const not_null<Main::Session*> _session;
MTP::Sender _api;
base::flat_map<not_null<PeerData*>, mtpRequestId> _blockRequests;
base::flat_map<not_null<PeerData*>, Request> _blockRequests;
mtpRequestId _requestId = 0;
std::optional<Slice> _slice;
rpl::event_stream<Slice> _changes;

View File

@ -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<void(bool allowed)> callback) {
}
void AttachWebView::botSharePhone(Fn<void(bool shared)> 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(

View File

@ -1578,8 +1578,8 @@ void PeerMenuBlockUserBox(
}
void PeerMenuUnblockUserWithBotRestart(not_null<UserData*> 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);
}
});

View File

@ -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);