diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index a3e005712..11d1be17a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -689,6 +689,9 @@ chatListArchive = ChatList; //@description A list of chats belonging to a chat filter @chat_filter_id Chat filter identifier chatListFilter chat_filter_id:int32 = ChatList; +//@description Contains a list of chat lists @chat_lists List of chat lists +chatLists chat_lists:vector = ChatLists; + //@class ChatSource @description Describes a reason why an external chat is shown in a chat list @@ -3712,8 +3715,11 @@ createNewSecretChat user_id:int32 = Chat; upgradeBasicGroupChatToSupergroupChat chat_id:int53 = Chat; -//@description Adds a chat to a chat list. A chat can't be simultaneously in Main and Archive chat lists, so it is automatically removed from another one if needed. The chat with the current user (Saved Messages) and the chat 777000 (Telegram) can't be moved to the Archive chat list -//@chat_id Chat identifier @chat_list The chat list +//@description Returns chat lists to which the chat can be added. This is an offline request @chat_id Chat identifier +getChatListsToAddChat chat_id:int53 = ChatLists; + +//@description Adds a chat to a chat list. A chat can't be simultaneously in Main and Archive chat lists, so it is automatically removed from another one if needed +//@chat_id Chat identifier @chat_list The chat list. Use getChatListsToAddChat to get suitable chat lists addChatToList chat_id:int53 chat_list:ChatList = Ok; //@description Returns information about a chat filter by its identifier @chat_filter_id Chat filter identifier diff --git a/td/generate/scheme/td_api.tlo b/td/generate/scheme/td_api.tlo index 54b9b3afd..e7e9afcf3 100644 Binary files a/td/generate/scheme/td_api.tlo and b/td/generate/scheme/td_api.tlo differ diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index e806792d9..e875a3bda 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -14366,7 +14366,7 @@ void MessagesManager::on_get_dialog_filters(Result old_server_dialog_filters; - for (auto &filter : server_dialog_filters_) { + for (const auto &filter : server_dialog_filters_) { old_server_dialog_filters.emplace(filter->dialog_filter_id, filter.get()); } for (const auto &new_server_filter : new_server_dialog_filters) { @@ -14405,7 +14405,7 @@ void MessagesManager::on_get_dialog_filters(Result left_old_server_dialog_filter_ids; - for (auto &filter : server_dialog_filters_) { + for (const auto &filter : server_dialog_filters_) { if (old_server_dialog_filters.count(filter->dialog_filter_id) == 0) { left_old_server_dialog_filter_ids.push_back(filter->dialog_filter_id); } @@ -14496,7 +14496,7 @@ void MessagesManager::synchronize_dialog_filters() { LOG(INFO) << "Synchronize chat filter changes with server having local " << get_dialog_filter_ids(dialog_filters_) << " and server " << get_dialog_filter_ids(server_dialog_filters_); - for (auto &server_dialog_filter : server_dialog_filters_) { + for (const auto &server_dialog_filter : server_dialog_filters_) { if (get_dialog_filter(server_dialog_filter->dialog_filter_id) == nullptr) { return delete_dialog_filter_on_server(server_dialog_filter->dialog_filter_id); } @@ -26942,6 +26942,45 @@ SearchMessagesFilter MessagesManager::get_search_messages_filter( } } +vector MessagesManager::get_dialog_lists_to_add_dialog(DialogId dialog_id) { + vector result; + const Dialog *d = get_dialog_force(dialog_id); + if (d == nullptr || d->order == DEFAULT_ORDER || !have_input_peer(dialog_id, AccessRights::Read)) { + return result; + } + + if (dialog_id != get_my_dialog_id() && + dialog_id != DialogId(td_->contacts_manager_->get_service_notifications_user_id())) { + result.push_back(DialogListId(d->folder_id == FolderId::archive() ? FolderId::main() : FolderId::archive())); + } + + for (const auto &dialog_filter : dialog_filters_) { + auto dialog_filter_id = dialog_filter->dialog_filter_id; + if (!InputDialogId::contains(dialog_filter->included_dialog_ids, dialog_id) && + !InputDialogId::contains(dialog_filter->pinned_dialog_ids, dialog_id)) { + // the dialog isn't added yet to the dialog list + // check that it can be actually added + if (dialog_filter->included_dialog_ids.size() + dialog_filter->pinned_dialog_ids.size() < + MAX_INCLUDED_FILTER_DIALOGS) { + // fast path + result.push_back(DialogListId(dialog_filter_id)); + continue; + } + + auto new_dialog_filter = make_unique(*dialog_filter); + new_dialog_filter->included_dialog_ids.push_back(get_input_dialog_id(dialog_id)); + td::remove_if(new_dialog_filter->excluded_dialog_ids, [dialog_id](InputDialogId input_dialog_id) { + return dialog_id == input_dialog_id.get_dialog_id(); + }); + + if (check_dialog_filter_limits(new_dialog_filter.get()).is_ok()) { + result.push_back(DialogListId(dialog_filter_id)); + } + } + } + return result; +} + void MessagesManager::add_dialog_to_list(DialogId dialog_id, DialogListId dialog_list_id, Promise &&promise) { LOG(INFO) << "Receive addChatToList request to add " << dialog_id << " to " << dialog_list_id; @@ -31002,7 +31041,7 @@ MessagesManager::Dialog *MessagesManager::on_load_dialog_from_database(DialogId } const MessagesManager::DialogFilter *MessagesManager::get_server_dialog_filter(DialogFilterId dialog_filter_id) const { - for (auto &filter : server_dialog_filters_) { + for (const auto &filter : server_dialog_filters_) { if (filter->dialog_filter_id == dialog_filter_id) { return filter.get(); } @@ -31020,7 +31059,7 @@ MessagesManager::DialogFilter *MessagesManager::get_dialog_filter(DialogFilterId } const MessagesManager::DialogFilter *MessagesManager::get_dialog_filter(DialogFilterId dialog_filter_id) const { - for (auto &filter : dialog_filters_) { + for (const auto &filter : dialog_filters_) { if (filter->dialog_filter_id == dialog_filter_id) { return filter.get(); } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index fe9f8d7c8..286fb4c13 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -447,6 +447,8 @@ class MessagesManager : public Actor { void send_dialog_action(DialogId dialog_id, const tl_object_ptr &action, Promise &&promise); + vector get_dialog_lists_to_add_dialog(DialogId dialog_id); + void add_dialog_to_list(DialogId dialog_id, DialogListId dialog_list_id, Promise &&promise); void set_dialog_photo(DialogId dialog_id, const tl_object_ptr &photo, Promise &&promise); diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 3cc3185b4..dc6a5a30b 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5874,6 +5874,14 @@ 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::getChatListsToAddChat &request) { + CHECK_IS_USER(); + auto dialog_lists = messages_manager_->get_dialog_lists_to_add_dialog(DialogId(request.chat_id_)); + auto chat_lists = + transform(dialog_lists, [](DialogListId dialog_list_id) { return dialog_list_id.get_chat_list_object(); }); + send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(std::move(chat_lists))); +} + void Td::on_request(uint64 id, const td_api::addChatToList &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 916a0d04e..659636837 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -673,6 +673,8 @@ class Td final : public NetQueryCallback { void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request); + void on_request(uint64 id, const td_api::getChatListsToAddChat &request); + void on_request(uint64 id, const td_api::addChatToList &request); void on_request(uint64 id, const td_api::getChatFilter &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 3f691fbce..e42ab1295 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3510,6 +3510,9 @@ class CliClient final : public Actor { std::tie(supergroup_id, force) = split(args); send_request(td_api::make_object(as_supergroup_id(supergroup_id), as_bool(force))); + } else if (op == "gcltac") { + string chat_id = args; + send_request(td_api::make_object(as_chat_id(chat_id))); } else if (op == "actl" || op == "actla" || begins_with(op, "actl-")) { string chat_id = args; send_request(td_api::make_object(as_chat_id(chat_id), as_chat_list(op)));