Add td_api::setChatChatList.

GitOrigin-RevId: 42340bc1ce169eadc73d6f29a06f6e87b70fe948
This commit is contained in:
levlam 2019-08-27 17:23:01 +03:00
parent ae311f9973
commit 0aa0a3b967
9 changed files with 212 additions and 17 deletions

View File

@ -3327,6 +3327,9 @@ createNewSecretChat user_id:int32 = Chat;
upgradeBasicGroupChatToSupergroupChat chat_id:int53 = Chat;
//@description Moves a chat to a different chat list @chat_id Chat identifier @chat_list New chat list of the chat
setChatChatList chat_id:int53 chat_list:ChatList = Ok;
//@description Changes the chat title. Supported only for basic groups, supergroups and channels. Requires can_change_info rights. The title will not be changed until the request to the server has been completed
//@chat_id Chat identifier @title New title of the chat; 1-128 characters
setChatTitle chat_id:int53 title:string = Ok;

Binary file not shown.

View File

@ -3340,6 +3340,51 @@ class ReportPeerQuery : public Td::ResultHandler {
}
};
class EditPeerFoldersQuery : public Td::ResultHandler {
Promise<Unit> promise_;
DialogId dialog_id_;
public:
explicit EditPeerFoldersQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
}
void send(DialogId dialog_id, FolderId folder_id) {
dialog_id_ = dialog_id;
auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read);
CHECK(input_peer != nullptr);
vector<telegram_api::object_ptr<telegram_api::inputFolderPeer>> input_folder_peers;
input_folder_peers.push_back(
telegram_api::make_object<telegram_api::inputFolderPeer>(std::move(input_peer), folder_id.get()));
send_query(G()->net_query_creator().create(
create_storer(telegram_api::folders_editPeerFolders(std::move(input_folder_peers)))));
}
void on_result(uint64 id, BufferSlice packet) override {
auto result_ptr = fetch_result<telegram_api::folders_editPeerFolders>(packet);
if (result_ptr.is_error()) {
return on_error(id, result_ptr.move_as_error());
}
auto ptr = result_ptr.move_as_ok();
LOG(INFO) << "Receive result for EditPeerFoldersQuery: " << to_string(ptr);
td->updates_manager_->on_get_updates(std::move(ptr));
promise_.set_value(Unit());
}
void on_error(uint64 id, Status status) override {
if (!td->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditPeerFoldersQuery")) {
LOG(INFO) << "Receive error for EditPeerFoldersQuery: " << status;
}
// trying to repair folder ID for this dialog
td->messages_manager_->get_dialog_info_full(dialog_id_, Auto());
promise_.set_error(std::move(status));
}
};
class GetStatsUrlQuery : public Td::ResultHandler {
Promise<td_api::object_ptr<td_api::httpUrl>> promise_;
DialogId dialog_id_;
@ -22414,6 +22459,95 @@ SearchMessagesFilter MessagesManager::get_search_messages_filter(
}
}
void MessagesManager::set_dialog_folder_id(DialogId dialog_id, FolderId folder_id, Promise<Unit> &&promise) {
LOG(INFO) << "Receive setChatChatList request to change folder of " << dialog_id << " to " << folder_id;
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr) {
return promise.set_error(Status::Error(3, "Chat not found"));
}
if (d->order == DEFAULT_ORDER) {
return promise.set_error(Status::Error(400, "Chat is not in a chat list"));
}
if (d->folder_id == folder_id) {
return promise.set_value(Unit());
}
if (!have_input_peer(dialog_id, AccessRights::Read)) {
return promise.set_error(Status::Error(6, "Can't access the chat"));
}
set_dialog_folder_id(d, folder_id);
set_dialog_folder_id_on_server(dialog_id, false);
promise.set_value(Unit());
}
class MessagesManager::SetDialogFolderIdOnServerLogEvent {
public:
DialogId dialog_id_;
FolderId folder_id_;
template <class StorerT>
void store(StorerT &storer) const {
td::store(dialog_id_, storer);
td::store(folder_id_, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
td::parse(dialog_id_, parser);
td::parse(folder_id_, parser);
}
};
void MessagesManager::set_dialog_folder_id_on_server(DialogId dialog_id, bool from_binlog) {
auto d = get_dialog(dialog_id);
CHECK(d != nullptr);
if (!from_binlog && G()->parameters().use_message_db) {
SetDialogFolderIdOnServerLogEvent logevent;
logevent.dialog_id_ = dialog_id;
logevent.folder_id_ = d->folder_id;
auto storer = LogEventStorerImpl<SetDialogFolderIdOnServerLogEvent>(logevent);
if (d->set_folder_id_logevent_id == 0) {
d->set_folder_id_logevent_id =
binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SetDialogFolderIdOnServer, storer);
} else {
binlog_rewrite(G()->td_db()->get_binlog(), d->set_folder_id_logevent_id,
LogEvent::HandlerType::SetDialogFolderIdOnServer, storer);
}
d->set_folder_id_logevent_id_generation++;
}
Promise<> promise;
if (d->set_folder_id_logevent_id != 0) {
promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id,
generation = d->set_folder_id_logevent_id_generation](Result<Unit> result) {
if (!G()->close_flag()) {
send_closure(actor_id, &MessagesManager::on_updated_dialog_folder_id, dialog_id, generation);
}
});
}
// TODO do not send two queries simultaneously or use SequenceDispatcher
td_->create_handler<EditPeerFoldersQuery>(std::move(promise))->send(dialog_id, d->folder_id);
}
void MessagesManager::on_updated_dialog_folder_id(DialogId dialog_id, uint64 generation) {
auto d = get_dialog(dialog_id);
CHECK(d != nullptr);
LOG(INFO) << "Saved folder_id of " << dialog_id << " with logevent " << d->set_folder_id_logevent_id;
if (d->set_folder_id_logevent_id_generation == generation) {
CHECK(d->set_folder_id_logevent_id != 0);
LOG(INFO) << "Delete set folder_id logevent " << d->set_folder_id_logevent_id;
binlog_erase(G()->td_db()->get_binlog(), d->set_folder_id_logevent_id);
d->set_folder_id_logevent_id = 0;
}
}
void MessagesManager::set_dialog_photo(DialogId dialog_id, const tl_object_ptr<td_api::InputFile> &photo,
Promise<Unit> &&promise) {
LOG(INFO) << "Receive setChatPhoto request to change photo of " << dialog_id;
@ -22583,7 +22717,7 @@ void MessagesManager::set_dialog_permissions(DialogId dialog_id,
auto new_permissions = get_restricted_rights(permissions);
// TODO this can be wrong if there was previous change title requests
// TODO this can be wrong if there was previous change permissions requests
if (get_dialog_permissions(dialog_id) == new_permissions) {
return promise.set_value(Unit());
}
@ -26414,10 +26548,6 @@ void MessagesManager::on_get_channel_difference(
timeout = difference->timeout_;
}
// TODO
// pinned:flags.2?true unread_mark:flags.3?true notify_settings:PeerNotifySettings
// draft:flags.1?DraftMessage folder_id:flags.4?int
auto new_pts = dialog->pts_;
if (request_pts + request_limit > new_pts) {
LOG(ERROR) << "Receive channelDifferenceTooLong as result of getChannelDifference with pts = " << request_pts
@ -26431,6 +26561,24 @@ void MessagesManager::on_get_channel_difference(
td_->contacts_manager_->on_get_users(std::move(difference->users_), "updates.channelDifferenceTooLong");
td_->contacts_manager_->on_get_chats(std::move(difference->chats_), "updates.channelDifferenceTooLong");
set_dialog_folder_id(d, FolderId((dialog->flags_ & DIALOG_FLAG_HAS_FOLDER_ID) != 0 ? dialog->folder_id_ : 0));
on_update_dialog_notify_settings(dialog_id, std::move(dialog->notify_settings_), "on_get_dialogs");
bool is_pinned = (dialog->flags_ & DIALOG_FLAG_IS_PINNED) != 0;
bool was_pinned = d->pinned_order != DEFAULT_ORDER;
if (is_pinned != was_pinned) {
set_dialog_is_pinned(d, is_pinned);
}
bool is_marked_as_unread = (dialog->flags_ & telegram_api::dialog::UNREAD_MARK_MASK) != 0;
if (is_marked_as_unread != d->is_marked_as_unread) {
set_dialog_is_marked_as_unread(d, is_marked_as_unread);
}
update_dialog_draft_message(d, get_draft_message(td_->contacts_manager_.get(), std::move(dialog->draft_)), true,
false);
on_get_channel_dialog(dialog_id, MessageId(ServerMessageId(dialog->top_message_)),
MessageId(ServerMessageId(dialog->read_inbox_max_id_)), dialog->unread_count_,
dialog->unread_mentions_count_, MessageId(ServerMessageId(dialog->read_outbox_max_id_)),
@ -27145,6 +27293,29 @@ void MessagesManager::on_binlog_events(vector<BinlogEvent> &&events) {
change_dialog_report_spam_state_on_server(dialog_id, log_event.is_spam_dialog_, event.id_, Promise<Unit>());
break;
}
case LogEvent::HandlerType::SetDialogFolderIdOnServer: {
if (!G()->parameters().use_message_db) {
binlog_erase(G()->td_db()->get_binlog(), event.id_);
break;
}
SetDialogFolderIdOnServerLogEvent log_event;
log_event_parse(log_event, event.data_).ensure();
auto dialog_id = log_event.dialog_id_;
Dialog *d = get_dialog_force(dialog_id);
if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) {
binlog_erase(G()->td_db()->get_binlog(), event.id_);
break;
}
d->set_folder_id_logevent_id = event.id_;
d->set_folder_id_logevent_id_generation++;
set_dialog_folder_id(d, log_event.folder_id_);
set_dialog_folder_id_on_server(dialog_id, true);
break;
}
case LogEvent::HandlerType::GetDialogFromServer: {
if (!G()->parameters().use_message_db) {
binlog_erase(G()->td_db()->get_binlog(), event.id_);

View File

@ -415,6 +415,8 @@ class MessagesManager : public Actor {
void send_dialog_action(DialogId dialog_id, const tl_object_ptr<td_api::ChatAction> &action, Promise<Unit> &&promise);
void set_dialog_folder_id(DialogId dialog_id, FolderId folder_id, Promise<Unit> &&promise);
void set_dialog_photo(DialogId dialog_id, const tl_object_ptr<td_api::InputFile> &photo, Promise<Unit> &&promise);
void set_dialog_title(DialogId dialog_id, const string &title, Promise<Unit> &&promise);
@ -449,6 +451,8 @@ class MessagesManager : public Actor {
string get_dialog_invite_link(DialogId dialog_id);
void get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise);
int64 get_dialog_event_log(DialogId dialog_id, const string &query, int64 from_event_id, int32 limit,
const tl_object_ptr<td_api::chatEventLogFilters> &filters, const vector<UserId> &user_ids,
Promise<Unit> &&promise);
@ -988,6 +992,8 @@ class MessagesManager : public Actor {
uint64 save_notification_settings_logevent_id_generation = 0;
uint64 read_history_logevent_id = 0;
uint64 read_history_logevent_id_generation = 0;
uint64 set_folder_id_logevent_id = 0;
uint64 set_folder_id_logevent_id_generation = 0;
FolderId folder_id;
MessageId
@ -1312,6 +1318,7 @@ class MessagesManager : public Actor {
class UpdateScopeNotificationSettingsOnServerLogEvent;
class ResetAllNotificationSettingsOnServerLogEvent;
class ChangeDialogReportSpamStateOnServerLogEvent;
class SetDialogFolderIdOnServerLogEvent;
class SendBotStartMessageLogEvent;
class SendInlineQueryResultMessageLogEvent;
class SendMessageLogEvent;
@ -1953,8 +1960,6 @@ class MessagesManager : public Actor {
Message *on_get_message_from_database(DialogId dialog_id, Dialog *d, const BufferSlice &value, const char *source);
void get_dialog_info_full(DialogId dialog_id, Promise<Unit> &&promise);
void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, int64 random_id, bool after_database_search,
Promise<Unit> &&promise);
@ -2082,6 +2087,10 @@ class MessagesManager : public Actor {
void change_dialog_report_spam_state_on_server(DialogId dialog_id, bool is_spam_dialog, uint64 logevent_id,
Promise<Unit> &&promise);
void set_dialog_folder_id_on_server(DialogId dialog_id, bool from_binlog);
void on_updated_dialog_folder_id(DialogId dialog_id, uint64 generation);
int64 get_next_pinned_dialog_order();
void update_dialog_pos(Dialog *d, bool remove_from_dialog_list, const char *source,

View File

@ -5975,6 +5975,12 @@ void Td::on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupCh
CREATE_REQUEST(UpgradeGroupChatToSupergroupChatRequest, request.chat_id_);
}
void Td::on_request(uint64 id, const td_api::setChatChatList &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
messages_manager_->set_dialog_folder_id(DialogId(request.chat_id_), FolderId(request.chat_list_), std::move(promise));
}
void Td::on_request(uint64 id, td_api::setChatTitle &request) {
CLEAN_INPUT_STRING(request.title_);
CREATE_OK_REQUEST_PROMISE();

View File

@ -644,6 +644,8 @@ class Td final : public NetQueryCallback {
void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request);
void on_request(uint64 id, const td_api::setChatChatList &request);
void on_request(uint64 id, td_api::setChatTitle &request);
void on_request(uint64 id, const td_api::setChatPhoto &request);

View File

@ -107,6 +107,7 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue<Binlog> &binlog_p
case LogEvent::HandlerType::GetChannelDifference:
case LogEvent::HandlerType::ReadHistoryInSecretChat:
case LogEvent::HandlerType::ToggleDialogIsMarkedAsUnreadOnServer:
case LogEvent::HandlerType::SetDialogFolderIdOnServer:
events.to_messages_manager.push_back(event.clone());
break;
case LogEvent::HandlerType::AddMessagePushNotification:

View File

@ -452,6 +452,13 @@ class CliClient final : public Actor {
return to_integer<int64>(str);
}
static td_api::object_ptr<td_api::ChatList> as_chat_list(string chat_list) {
if (!chat_list.empty() && chat_list.back() == 'a') {
return td_api::make_object<td_api::chatListArchive>();
}
return td_api::make_object<td_api::chatListMain>();
}
vector<int64> as_chat_ids(Slice chat_ids, char delimiter = ' ') const {
return transform(full_split(trim(chat_ids), delimiter), [this](Slice str) { return as_chat_id(str); });
}
@ -1610,10 +1617,6 @@ class CliClient final : public Actor {
std::tie(limit, args) = split(args);
std::tie(offset_order_string, offset_chat_id) = split(args);
td_api::object_ptr<td_api::ChatList> chat_list;
if (op == "gca") {
chat_list = td_api::make_object<td_api::chatListArchive>();
}
if (limit.empty()) {
limit = "10000";
}
@ -1623,7 +1626,7 @@ class CliClient final : public Actor {
} else {
offset_order = to_integer<int64>(offset_order_string);
}
send_request(td_api::make_object<td_api::getChats>(std::move(chat_list), offset_order, as_chat_id(offset_chat_id),
send_request(td_api::make_object<td_api::getChats>(as_chat_list(op), offset_order, as_chat_id(offset_chat_id),
to_integer<int32>(limit)));
} else if (op == "gctest") {
send_request(td_api::make_object<td_api::getChats>(nullptr, std::numeric_limits<int64>::max(), 0, 1));
@ -2658,11 +2661,7 @@ class CliClient final : public Actor {
for (auto &chat_id_str : chat_ids_str) {
chat_ids.push_back(as_chat_id(chat_id_str));
}
td_api::object_ptr<td_api::ChatList> chat_list = td_api::make_object<td_api::chatListMain>();
if (op == "spchatsa") {
chat_list = td_api::make_object<td_api::chatListArchive>();
}
send_request(td_api::make_object<td_api::setPinnedChats>(std::move(chat_list), std::move(chat_ids)));
send_request(td_api::make_object<td_api::setPinnedChats>(as_chat_list(op), std::move(chat_ids)));
} else if (op == "sca") {
string chat_id;
string action;
@ -3263,6 +3262,9 @@ class CliClient final : public Actor {
std::tie(supergroup_id, force) = split(args);
send_request(td_api::make_object<td_api::createSupergroupChat>(as_supergroup_id(supergroup_id), as_bool(force)));
} else if (op == "sccl" || op == "sccla") {
string chat_id = args;
send_request(td_api::make_object<td_api::setChatChatList>(as_chat_id(chat_id), as_chat_list(op)));
} else if (op == "sct") {
string chat_id;
string title;

View File

@ -94,6 +94,7 @@ class LogEvent {
GetDialogFromServer = 0x113,
ReadHistoryInSecretChat = 0x114,
ToggleDialogIsMarkedAsUnreadOnServer = 0x115,
SetDialogFolderIdOnServer = 0x116,
GetChannelDifference = 0x140,
AddMessagePushNotification = 0x200,
EditMessagePushNotification = 0x201,