diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index 2f9a5eb00..e3d407960 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -711,9 +711,12 @@ class StoryManager::SendStoryQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for SendStoryQuery: " << to_string(ptr); - td_->updates_manager_->on_get_updates(std::move(ptr), Promise()); - - td_->story_manager_->delete_pending_story(file_id_, std::move(pending_story_), Status::OK()); + td_->updates_manager_->on_get_updates( + std::move(ptr), PromiseCreator::lambda([file_id = file_id_, pending_story = std::move(pending_story_)]( + Result &&result) mutable { + send_closure(G()->story_manager(), &StoryManager::delete_pending_story, file_id, std::move(pending_story), + result.is_ok() ? Status::OK() : result.move_as_error()); + })); } void on_error(Status status) final { @@ -2722,6 +2725,14 @@ StoryId StoryManager::on_get_new_story(DialogId owner_dialog_id, td_->messages_manager_->force_create_dialog(owner_dialog_id, "on_get_new_story"); + auto updates_story_ids_it = update_story_ids_.find(story_full_id); + if (updates_story_ids_it != update_story_ids_.end()) { + auto old_story_id = updates_story_ids_it->second; + update_story_ids_.erase(updates_story_ids_it); + + LOG(INFO) << "Receive sent " << old_story_id << " as " << story_full_id; + } + bool is_bot = td_->auth_manager_->is_bot(); auto caption = get_message_text(td_->contacts_manager_.get(), std::move(story_item->caption_), std::move(story_item->entities_), @@ -2947,6 +2958,8 @@ void StoryManager::on_delete_story(StoryFullId story_full_id) { return; } + update_story_ids_.erase(story_full_id); + inaccessible_story_full_ids_.set(story_full_id, Time::now()); send_closure_later(G()->messages_manager(), &MessagesManager::update_story_max_reply_media_timestamp_in_replied_messages, story_full_id); @@ -3388,6 +3401,35 @@ void StoryManager::save_active_stories(DialogId owner_dialog_id, const ActiveSto } } +void StoryManager::on_update_story_id(int64 random_id, StoryId new_story_id, const char *source) { + if (!new_story_id.is_server()) { + LOG(ERROR) << "Receive " << new_story_id << " with random_id " << random_id << " from " << source; + return; + } + + auto it = being_sent_stories_.find(random_id); + if (it == being_sent_stories_.end()) { + // update about a new story sent from another device + LOG(INFO) << "Receive not sent outgoing " << new_story_id << " with random_id = " << random_id; + return; + } + auto old_story_full_id = it->second; + being_sent_stories_.erase(it); + + if (!have_story_force(old_story_full_id)) { + LOG(INFO) << "Can't find sent story " << old_story_full_id; + // delete_sent_story_on_server(old_story_full_id, new_story_id); + return; + } + + auto old_story_id = old_story_full_id.get_story_id(); + auto new_story_full_id = StoryFullId(old_story_full_id.get_dialog_id(), new_story_id); + + LOG(INFO) << "Save correspondence from " << new_story_full_id << " to " << old_story_id; + CHECK(!old_story_id.is_server()); + update_story_ids_[new_story_full_id] = old_story_id; +} + bool StoryManager::on_update_read_stories(DialogId owner_dialog_id, StoryId max_read_story_id) { if (!td_->messages_manager_->have_dialog_info_force(owner_dialog_id)) { return false; @@ -3750,7 +3792,7 @@ void StoryManager::send_story(td_api::object_ptr &&in int64 random_id; do { random_id = Random::secure_int64(); - } while (random_id == 0); + } while (random_id == 0 || being_sent_stories_.count(random_id) > 0); auto story_ptr = story.get(); @@ -3758,8 +3800,6 @@ void StoryManager::send_story(td_api::object_ptr &&in td::make_unique(dialog_id, StoryId(), ++send_story_count_, random_id, std::move(story)); pending_story->log_event_id_ = save_send_story_log_event(pending_story.get()); - yet_unsent_stories_[dialog_id].insert(pending_story->send_story_num_); - do_send_story(std::move(pending_story), {}); promise.set_value(get_story_object({dialog_id, StoryId()}, story_ptr)); @@ -3799,6 +3839,12 @@ int64 StoryManager::save_send_story_log_event(const PendingStory *pending_story) void StoryManager::do_send_story(unique_ptr &&pending_story, vector bad_parts) { CHECK(pending_story != nullptr); CHECK(pending_story->story_ != nullptr); + + if (bad_parts.empty() && !pending_story->story_id_.is_server()) { + yet_unsent_stories_[pending_story->dialog_id_].insert(pending_story->send_story_num_); + being_sent_stories_[pending_story->random_id_] = StoryFullId(pending_story->dialog_id_, pending_story->story_id_); + } + auto content = pending_story->story_->content_.get(); CHECK(content != nullptr); auto upload_order = pending_story->send_story_num_; @@ -4135,6 +4181,7 @@ void StoryManager::delete_pending_story(FileId file_id, unique_ptr if (it->second.empty()) { yet_unsent_stories_.erase(it); } + being_sent_stories_.erase(pending_story->random_id_); try_send_story(pending_story->dialog_id_); if (pending_story->log_event_id_ != 0) { @@ -4381,7 +4428,6 @@ void StoryManager::on_binlog_events(vector &&events) { CHECK(!pending_story->story_id_.is_server()); pending_story->send_story_num_ = send_story_count_; pending_story->story_->content_ = dup_story_content(td_, pending_story->story_->content_.get()); - yet_unsent_stories_[pending_story->dialog_id_].insert(pending_story->send_story_num_); do_send_story(std::move(pending_story), {}); break; } diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 1038d0292..a913a07df 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -265,6 +265,8 @@ class StoryManager final : public Actor { telegram_api::object_ptr &&user_stories, Promise &&promise); + void on_update_story_id(int64 random_id, StoryId new_story_id, const char *source); + bool on_update_read_stories(DialogId owner_dialog_id, StoryId max_read_story_id); void on_update_story_stealth_mode(telegram_api::object_ptr &&stealth_mode); @@ -583,6 +585,10 @@ class StoryManager final : public Actor { FlatHashMap, DialogIdHash> yet_unsent_stories_; + FlatHashMap being_sent_stories_; + + FlatHashMap update_story_ids_; + FlatHashMap> ready_to_send_stories_; StoryList story_lists_[2]; diff --git a/td/telegram/UpdatesManager.cpp b/td/telegram/UpdatesManager.cpp index 2cd58a749..bd32a63c9 100644 --- a/td/telegram/UpdatesManager.cpp +++ b/td/telegram/UpdatesManager.cpp @@ -1807,6 +1807,14 @@ void UpdatesManager::process_get_difference_updates( CHECK(!running_get_difference_); } + if (constructor_id == telegram_api::updateStoryID::ID) { + LOG(INFO) << "Receive update about sent story " << to_string(update); + auto update_story_id = move_tl_object_as(update); + td_->story_manager_->on_update_story_id(update_story_id->random_id_, StoryId(update_story_id->id_), + "getDifference"); + CHECK(!running_get_difference_); + } + if (constructor_id == telegram_api::updateEncryption::ID) { on_update(move_tl_object_as(update), Promise()); CHECK(!running_get_difference_); @@ -2468,7 +2476,6 @@ void UpdatesManager::on_pending_updates(vectorget_id(); if (id == telegram_api::updateMessageID::ID) { - LOG(INFO) << "Receive from " << source << " " << to_string(update); auto sent_message_update = move_tl_object_as(update); MessageId message_id; if (ordinary_new_message_count != 0) { @@ -2483,6 +2490,11 @@ void UpdatesManager::on_pending_updates(vector(update); + td_->story_manager_->on_update_story_id(update_story_id->random_id_, StoryId(update_story_id->id_), source); + update = nullptr; + } if (id == telegram_api::updateFolderPeers::ID) { on_update(move_tl_object_as(update), get_promise()); update = nullptr; @@ -3347,6 +3359,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { LOG(ERROR) << "Receive not in getDifference and not in on_pending_updates " << to_string(update); + promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, @@ -4322,10 +4335,11 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + LOG(ERROR) << "Receive not in getDifference and not in on_pending_updates " << to_string(update); promise.set_value(Unit()); } +// unsupported updates + } // namespace td diff --git a/td/telegram/UpdatesManager.h b/td/telegram/UpdatesManager.h index d4d5b465c..0dc452772 100644 --- a/td/telegram/UpdatesManager.h +++ b/td/telegram/UpdatesManager.h @@ -628,9 +628,9 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); - // unsupported updates - void on_update(tl_object_ptr update, Promise &&promise); + + // unsupported updates }; } // namespace td