Move bot command handling functions to BotCommand.cpp.
This commit is contained in:
parent
e8b32d9b05
commit
9b85516cfd
@ -6,13 +6,103 @@
|
||||
//
|
||||
#include "td/telegram/BotCommand.h"
|
||||
|
||||
#include "td/telegram/BotCommandScope.h"
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/misc.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
#include "td/utils/algorithm.h"
|
||||
#include "td/utils/buffer.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
class SetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit SetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code, vector<std::pair<string, string>> &&commands) {
|
||||
send_query(G()->net_query_creator().create(telegram_api::bots_setBotCommands(
|
||||
scope.get_input_bot_command_scope(td), language_code, transform(commands, [](const auto &command) {
|
||||
return make_tl_object<telegram_api::botCommand>(command.first, command.second);
|
||||
}))));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_setBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
if (!result_ptr.ok()) {
|
||||
LOG(ERROR) << "Set bot commands request failed";
|
||||
}
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class ResetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit ResetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code) {
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::bots_resetBotCommands(scope.get_input_bot_command_scope(td), language_code)));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_resetBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class GetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> promise_;
|
||||
|
||||
public:
|
||||
explicit GetBotCommandsQuery(Promise<td_api::object_ptr<td_api::botCommands>> &&promise)
|
||||
: promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code) {
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::bots_getBotCommands(scope.get_input_bot_command_scope(td), language_code)));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_getBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
BotCommands commands(td->contacts_manager_->get_my_id(), result_ptr.move_as_ok());
|
||||
promise_.set_value(commands.get_bot_commands_object(td));
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
BotCommand::BotCommand(telegram_api::object_ptr<telegram_api::botCommand> &&bot_command) {
|
||||
CHECK(bot_command != nullptr);
|
||||
command_ = std::move(bot_command->command_);
|
||||
@ -44,4 +134,90 @@ bool operator==(const BotCommands &lhs, const BotCommands &rhs) {
|
||||
return lhs.bot_user_id_ == rhs.bot_user_id_ && lhs.commands_ == rhs.commands_;
|
||||
}
|
||||
|
||||
void set_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
vector<std::pair<string, string>> new_commands;
|
||||
for (auto &command : commands) {
|
||||
if (command == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Command must be non-empty"));
|
||||
}
|
||||
if (!clean_input_string(command->command_)) {
|
||||
return promise.set_error(Status::Error(400, "Command must be encoded in UTF-8"));
|
||||
}
|
||||
if (!clean_input_string(command->description_)) {
|
||||
return promise.set_error(Status::Error(400, "Command description must be encoded in UTF-8"));
|
||||
}
|
||||
|
||||
const size_t MAX_COMMAND_TEXT_LENGTH = 32;
|
||||
command->command_ = trim(command->command_);
|
||||
if (command->command_[0] == '/') {
|
||||
command->command_ = command->command_.substr(1);
|
||||
}
|
||||
if (command->command_.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Command must be non-empty"));
|
||||
}
|
||||
if (utf8_length(command->command_) > MAX_COMMAND_TEXT_LENGTH) {
|
||||
return promise.set_error(
|
||||
Status::Error(400, PSLICE() << "Command length must not exceed " << MAX_COMMAND_TEXT_LENGTH));
|
||||
}
|
||||
|
||||
const size_t MIN_COMMAND_DESCRIPTION_LENGTH = 3;
|
||||
const size_t MAX_COMMAND_DESCRIPTION_LENGTH = 256;
|
||||
command->description_ = trim(command->description_);
|
||||
auto description_length = utf8_length(command->description_);
|
||||
if (description_length < MIN_COMMAND_DESCRIPTION_LENGTH) {
|
||||
return promise.set_error(Status::Error(
|
||||
400, PSLICE() << "Command description length must be at least " << MIN_COMMAND_DESCRIPTION_LENGTH));
|
||||
}
|
||||
if (description_length > MAX_COMMAND_DESCRIPTION_LENGTH) {
|
||||
return promise.set_error(Status::Error(
|
||||
400, PSLICE() << "Command description length must not exceed " << MAX_COMMAND_DESCRIPTION_LENGTH));
|
||||
}
|
||||
|
||||
new_commands.emplace_back(std::move(command->command_), std::move(command->description_));
|
||||
}
|
||||
|
||||
td->create_handler<SetBotCommandsQuery>(std::move(promise))->send(scope, language_code, std::move(new_commands));
|
||||
}
|
||||
|
||||
void delete_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<Unit> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
td->create_handler<ResetBotCommandsQuery>(std::move(promise))->send(scope, language_code);
|
||||
}
|
||||
|
||||
void get_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
td->create_handler<GetBotCommandsQuery>(std::move(promise))->send(scope, language_code);
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "td/telegram/telegram_api.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/tl_helpers.h"
|
||||
|
||||
@ -85,4 +87,13 @@ inline bool operator!=(const BotCommands &lhs, const BotCommands &rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
void set_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise);
|
||||
|
||||
void delete_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void get_commands(Td *td, td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> &&promise);
|
||||
|
||||
} // namespace td
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "td/telegram/telegram_api.hpp"
|
||||
|
||||
#include "td/telegram/AuthManager.h"
|
||||
#include "td/telegram/BotCommandScope.h"
|
||||
#include "td/telegram/ConfigManager.h"
|
||||
#include "td/telegram/ConfigShared.h"
|
||||
#include "td/telegram/Dependencies.h"
|
||||
@ -980,91 +979,6 @@ class UpdateUsernameQuery : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class SetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit SetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code, vector<std::pair<string, string>> &&commands) {
|
||||
send_query(G()->net_query_creator().create(telegram_api::bots_setBotCommands(
|
||||
scope.get_input_bot_command_scope(td), language_code, transform(commands, [](const auto &command) {
|
||||
return make_tl_object<telegram_api::botCommand>(command.first, command.second);
|
||||
}))));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_setBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
if (!result_ptr.ok()) {
|
||||
LOG(ERROR) << "Set bot commands request failed";
|
||||
}
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class ResetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit ResetBotCommandsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code) {
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::bots_resetBotCommands(scope.get_input_bot_command_scope(td), language_code)));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_resetBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class GetBotCommandsQuery : public Td::ResultHandler {
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> promise_;
|
||||
|
||||
public:
|
||||
explicit GetBotCommandsQuery(Promise<td_api::object_ptr<td_api::botCommands>> &&promise)
|
||||
: promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(BotCommandScope scope, const string &language_code) {
|
||||
send_query(G()->net_query_creator().create(
|
||||
telegram_api::bots_getBotCommands(scope.get_input_bot_command_scope(td), language_code)));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::bots_getBotCommands>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
BotCommands commands(td->contacts_manager_->get_my_id(), result_ptr.move_as_ok());
|
||||
promise_.set_value(commands.get_bot_commands_object(td));
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class CheckChannelUsernameQuery : public Td::ResultHandler {
|
||||
Promise<bool> promise_;
|
||||
ChannelId channel_id_;
|
||||
@ -6310,92 +6224,6 @@ void ContactsManager::set_username(const string &username, Promise<Unit> &&promi
|
||||
td_->create_handler<UpdateUsernameQuery>(std::move(promise))->send(username);
|
||||
}
|
||||
|
||||
void ContactsManager::set_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td_, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td_)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
vector<std::pair<string, string>> new_commands;
|
||||
for (auto &command : commands) {
|
||||
if (command == nullptr) {
|
||||
return promise.set_error(Status::Error(400, "Command must be non-empty"));
|
||||
}
|
||||
if (!clean_input_string(command->command_)) {
|
||||
return promise.set_error(Status::Error(400, "Command must be encoded in UTF-8"));
|
||||
}
|
||||
if (!clean_input_string(command->description_)) {
|
||||
return promise.set_error(Status::Error(400, "Command description must be encoded in UTF-8"));
|
||||
}
|
||||
|
||||
const size_t MAX_COMMAND_TEXT_LENGTH = 32;
|
||||
command->command_ = trim(command->command_);
|
||||
if (command->command_[0] == '/') {
|
||||
command->command_ = command->command_.substr(1);
|
||||
}
|
||||
if (command->command_.empty()) {
|
||||
return promise.set_error(Status::Error(400, "Command must be non-empty"));
|
||||
}
|
||||
if (utf8_length(command->command_) > MAX_COMMAND_TEXT_LENGTH) {
|
||||
return promise.set_error(
|
||||
Status::Error(400, PSLICE() << "Command length must not exceed " << MAX_COMMAND_TEXT_LENGTH));
|
||||
}
|
||||
|
||||
const size_t MIN_COMMAND_DESCRIPTION_LENGTH = 3;
|
||||
const size_t MAX_COMMAND_DESCRIPTION_LENGTH = 256;
|
||||
command->description_ = trim(command->description_);
|
||||
auto description_length = utf8_length(command->description_);
|
||||
if (description_length < MIN_COMMAND_DESCRIPTION_LENGTH) {
|
||||
return promise.set_error(Status::Error(
|
||||
400, PSLICE() << "Command description length must be at least " << MIN_COMMAND_DESCRIPTION_LENGTH));
|
||||
}
|
||||
if (description_length > MAX_COMMAND_DESCRIPTION_LENGTH) {
|
||||
return promise.set_error(Status::Error(
|
||||
400, PSLICE() << "Command description length must not exceed " << MAX_COMMAND_DESCRIPTION_LENGTH));
|
||||
}
|
||||
|
||||
new_commands.emplace_back(std::move(command->command_), std::move(command->description_));
|
||||
}
|
||||
|
||||
td_->create_handler<SetBotCommandsQuery>(std::move(promise))->send(scope, language_code, std::move(new_commands));
|
||||
}
|
||||
|
||||
void ContactsManager::delete_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<Unit> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td_, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td_)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
td_->create_handler<ResetBotCommandsQuery>(std::move(promise))->send(scope, language_code);
|
||||
}
|
||||
|
||||
void ContactsManager::get_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> &&promise) {
|
||||
TRY_RESULT_PROMISE(promise, scope, BotCommandScope::get_bot_command_scope(td_, std::move(scope_ptr)));
|
||||
|
||||
if (!language_code.empty() && (language_code.size() != 2 || language_code[0] < 'a' || language_code[0] > 'z' ||
|
||||
language_code[1] < 'a' || language_code[1] > 'z')) {
|
||||
return promise.set_error(Status::Error(400, "Invalid language code specified"));
|
||||
}
|
||||
if (!scope.have_input_bot_command_scope(td_)) {
|
||||
return promise.set_error(Status::Error(400, "Invalid scope specified"));
|
||||
}
|
||||
|
||||
td_->create_handler<GetBotCommandsQuery>(std::move(promise))->send(scope, language_code);
|
||||
}
|
||||
|
||||
void ContactsManager::set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise) {
|
||||
auto new_description = strip_empty_characters(description, MAX_DESCRIPTION_LENGTH);
|
||||
auto c = get_chat(chat_id);
|
||||
|
@ -329,15 +329,6 @@ class ContactsManager : public Actor {
|
||||
|
||||
void set_username(const string &username, Promise<Unit> &&promise);
|
||||
|
||||
void set_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
vector<td_api::object_ptr<td_api::botCommand>> &&commands, Promise<Unit> &&promise);
|
||||
|
||||
void delete_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<Unit> &&promise);
|
||||
|
||||
void get_commands(td_api::object_ptr<td_api::BotCommandScope> &&scope_ptr, string &&language_code,
|
||||
Promise<td_api::object_ptr<td_api::botCommands>> &&promise);
|
||||
|
||||
void set_chat_description(ChatId chat_id, const string &description, Promise<Unit> &&promise);
|
||||
|
||||
void set_channel_username(ChannelId channel_id, const string &username, Promise<Unit> &&promise);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "td/telegram/BackgroundId.h"
|
||||
#include "td/telegram/BackgroundManager.h"
|
||||
#include "td/telegram/BackgroundType.h"
|
||||
#include "td/telegram/BotCommand.h"
|
||||
#include "td/telegram/CallbackQueriesManager.h"
|
||||
#include "td/telegram/CallId.h"
|
||||
#include "td/telegram/CallManager.h"
|
||||
@ -6874,20 +6875,20 @@ void Td::on_request(uint64 id, td_api::setUsername &request) {
|
||||
void Td::on_request(uint64 id, td_api::setCommands &request) {
|
||||
CHECK_IS_BOT();
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
contacts_manager_->set_commands(std::move(request.scope_), std::move(request.language_code_),
|
||||
std::move(request.commands_), std::move(promise));
|
||||
set_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(request.commands_),
|
||||
std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::deleteCommands &request) {
|
||||
CHECK_IS_BOT();
|
||||
CREATE_OK_REQUEST_PROMISE();
|
||||
contacts_manager_->delete_commands(std::move(request.scope_), std::move(request.language_code_), std::move(promise));
|
||||
delete_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, td_api::getCommands &request) {
|
||||
CHECK_IS_BOT();
|
||||
CREATE_REQUEST_PROMISE();
|
||||
contacts_manager_->get_commands(std::move(request.scope_), std::move(request.language_code_), std::move(promise));
|
||||
get_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(promise));
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::setLocation &request) {
|
||||
|
Loading…
Reference in New Issue
Block a user