From b78db4d90295757f41140807589ec8d35f58108f Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 28 Apr 2019 20:21:44 +0300 Subject: [PATCH] Trying to keep files, needed for messages in other chats. GitOrigin-RevId: 454f3143aec958a08ea35edecc808ef99eb795cf --- td/telegram/FileReferenceManager.cpp | 17 ++++++++++++++- td/telegram/FileReferenceManager.h | 4 +++- td/telegram/MessagesManager.cpp | 31 +++++++++++++++++++++------- td/telegram/MessagesManager.h | 4 +++- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index c3064e83..c183b954 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -124,7 +124,7 @@ bool FileReferenceManager::remove_file_source(NodeId node_id, FileSourceId file_ return is_removed; } -std::vector FileReferenceManager::get_some_file_sources(NodeId node_id) { +vector FileReferenceManager::get_some_file_sources(NodeId node_id) { auto it = nodes_.find(node_id); if (it == nodes_.end()) { return {}; @@ -132,6 +132,21 @@ std::vector FileReferenceManager::get_some_file_sources(NodeId nod return it->second.file_source_ids.get_some_elements(); } +vector FileReferenceManager::get_some_message_file_sources(NodeId node_id) { + auto file_source_ids = get_some_file_sources(node_id); + + vector result; + for (auto file_source_id : file_source_ids) { + auto index = static_cast(file_source_id.get()) - 1; + CHECK(index < file_sources_.size()); + const auto &file_source = file_sources_[index]; + if (file_source.get_offset() == 0) { + result.push_back(file_source.get().full_message_id); + } + } + return result; +} + void FileReferenceManager::merge(NodeId to_node_id, NodeId from_node_id) { auto from_it = nodes_.find(from_node_id); if (from_it == nodes_.end()) { diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index 83e78d5c..af62f52a 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -50,7 +50,9 @@ class FileReferenceManager : public Actor { bool add_file_source(NodeId node_id, FileSourceId file_source_id); - std::vector get_some_file_sources(NodeId node_id); + vector get_some_file_sources(NodeId node_id); + + vector get_some_message_file_sources(NodeId node_id); bool remove_file_source(NodeId node_id, FileSourceId file_source_id); diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d5334f66..4b27583e 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -8945,7 +8945,7 @@ void MessagesManager::on_message_ttl_expired_impl(Dialog *d, Message *m) { CHECK(m != nullptr); CHECK(m->ttl > 0); CHECK(d->dialog_id.get_type() != DialogType::SecretChat); - delete_message_files(m); + delete_message_files(d->dialog_id, m); update_expired_message_content(m->content); m->ttl = 0; m->ttl_expires_at = 0; @@ -22463,8 +22463,10 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq auto new_file_ids = get_message_content_file_ids(m->content.get(), td_); if (new_file_ids != old_file_ids) { if (need_delete_message_files(d, m)) { + FullMessageId full_message_id{dialog_id, message_id}; for (auto file_id : old_file_ids) { - if (std::find(new_file_ids.begin(), new_file_ids.end(), file_id) == new_file_ids.end()) { + if (std::find(new_file_ids.begin(), new_file_ids.end(), file_id) == new_file_ids.end() && + need_delete_file(full_message_id, file_id)) { send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise<>(), "edit message in add_message_to_dialog"); } @@ -23128,12 +23130,25 @@ class MessagesManager::DeleteMessageLogEvent { } }; -void MessagesManager::delete_message_files(const Message *m) const { +void MessagesManager::delete_message_files(DialogId dialog_id, const Message *m) const { for (auto file_id : get_message_file_ids(m)) { - send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise<>(), "delete_message_files"); + if (need_delete_file({dialog_id, m->message_id}, file_id)) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise<>(), "delete_message_files"); + } } } +bool MessagesManager::need_delete_file(FullMessageId full_message_id, FileId file_id) const { + auto full_message_ids = td_->file_reference_manager_->get_some_message_file_sources(file_id); + for (auto other_full_messsage_id : full_message_ids) { + if (other_full_messsage_id != full_message_id) { + return false; + } + } + + return true; +} + bool MessagesManager::need_delete_message_files(Dialog *d, const Message *m) { CHECK(d != nullptr); if (m == nullptr || !m->message_id.is_server()) { @@ -23191,7 +23206,7 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ auto need_delete_files = need_delete_message_files(d, m); if (need_delete_files) { - delete_message_files(m); + delete_message_files(d->dialog_id, m); } if (!G()->parameters().use_message_db) { @@ -23230,8 +23245,10 @@ void MessagesManager::do_delete_message_logevent(const DeleteMessageLogEvent &lo auto lock = mpas.get_promise(); for (auto file_id : logevent.file_ids_) { - send_closure(G()->file_manager(), &FileManager::delete_file, file_id, mpas.get_promise(), - "do_delete_message_logevent"); + if (need_delete_file(logevent.full_message_id_, file_id)) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, mpas.get_promise(), + "do_delete_message_logevent"); + } } db_promise = mpas.get_promise(); lock.set_value(Unit()); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index 2cf764eb..587a9071 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -1558,6 +1558,8 @@ class MessagesManager : public Actor { void on_message_changed(const Dialog *d, const Message *m, bool need_send_update, const char *source); + bool need_delete_file(FullMessageId full_message_id, FileId file_id) const; + bool need_delete_message_files(Dialog *d, const Message *m); void add_message_to_database(const Dialog *d, const Message *m, const char *source); @@ -1566,7 +1568,7 @@ class MessagesManager : public Actor { void delete_message_from_database(Dialog *d, MessageId message_id, const Message *m, bool is_permanently_deleted); - void delete_message_files(const Message *m) const; + void delete_message_files(DialogId dialog_id, const Message *m) const; static void add_random_id_to_message_id_correspondence(Dialog *d, int64 random_id, MessageId message_id);