From 63ba72dce49c1fb43147fadf95902bfc03049de8 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 1 Aug 2023 20:37:37 +0300 Subject: [PATCH] Add editStory.areas. --- td/generate/scheme/td_api.tl | 3 +- td/telegram/StoryManager.cpp | 79 +++++++++++++++++++++++++++++++----- td/telegram/StoryManager.h | 3 ++ td/telegram/Td.cpp | 4 +- td/telegram/cli.cpp | 6 +-- 5 files changed, 79 insertions(+), 16 deletions(-) diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index e58942610..15f05705a 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -7377,8 +7377,9 @@ sendStory content:InputStoryContent areas:inputStoryAreas caption:formattedText //@description Changes content and caption of a previously sent story //@story_id Identifier of the story to edit //@content New content of the story; pass null to keep the current content +//@areas New clickable rectangle areas to be shown on the story media; pass null to keep the current areas //@caption New story caption; pass null to keep the current caption -editStory story_id:int32 content:InputStoryContent caption:formattedText = Ok; +editStory story_id:int32 content:InputStoryContent areas:inputStoryAreas caption:formattedText = Ok; //@description Changes privacy settings of a previously sent story @story_id Identifier of the story @privacy_settings The new privacy settigs for the story setStoryPrivacySettings story_id:int32 privacy_settings:StoryPrivacySettings = Ok; diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index cc6b6fd77..370fad363 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -657,6 +657,14 @@ class StoryManager::EditStoryQuery final : public Td::ResultHandler { CHECK(input_media != nullptr); flags |= telegram_api::stories_editStory::MEDIA_MASK; } + vector> media_areas; + if (edited_story->edit_media_areas_) { + flags |= telegram_api::stories_editStory::MEDIA_AREAS_MASK; + + for (const auto &media_area : edited_story->areas_) { + media_areas.push_back(media_area.get_input_media_area()); + } + } vector> entities; if (edited_story->edit_caption_) { flags |= telegram_api::stories_editStory::CAPTION_MASK; @@ -664,10 +672,11 @@ class StoryManager::EditStoryQuery final : public Td::ResultHandler { entities = get_input_message_entities(td_->contacts_manager_.get(), &edited_story->caption_, "EditStoryQuery"); } + send_query(G()->net_query_creator().create( telegram_api::stories_editStory(flags, pending_story_->story_id_.get(), std::move(input_media), - vector>(), - edited_story->caption_.text, std::move(entities), Auto()), + std::move(media_areas), edited_story->caption_.text, std::move(entities), + Auto()), {{StoryFullId{pending_story_->dialog_id_, pending_story_->story_id_}}})); } @@ -2360,6 +2369,7 @@ td_api::object_ptr StoryManager::get_story_object(StoryFullId sto auto story_id = story_full_id.get_story_id(); auto *content = story->content_.get(); + auto *areas = &story->areas_; auto *caption = &story->caption_; if (is_owned && story_id.is_server()) { auto it = being_edited_stories_.find(story_full_id); @@ -2367,6 +2377,9 @@ td_api::object_ptr StoryManager::get_story_object(StoryFullId sto if (it->second->content_ != nullptr) { content = it->second->content_.get(); } + if (it->second->edit_media_areas_) { + areas = &it->second->areas_; + } if (it->second->edit_caption_) { caption = &it->second->caption_; } @@ -2382,7 +2395,7 @@ td_api::object_ptr StoryManager::get_story_object(StoryFullId sto bool can_be_replied = story_id.is_server() && dialog_id != changelog_dialog_id; bool can_get_viewers = can_get_story_viewers(story_full_id, story).is_ok(); bool has_expired_viewers = !can_get_viewers && is_story_owned(dialog_id) && story_id.is_server(); - auto areas = transform(story->areas_, [](const MediaArea &media_area) { return media_area.get_story_area_object(); }); + auto story_areas = transform(*areas, [](const MediaArea &media_area) { return media_area.get_story_area_object(); }); story->is_update_sent_ = true; @@ -2390,7 +2403,7 @@ td_api::object_ptr StoryManager::get_story_object(StoryFullId sto story_id.get(), td_->messages_manager_->get_chat_id_object(dialog_id, "get_story_object"), story->date_, is_being_edited, is_edited, story->is_pinned_, is_visible_only_for_self, can_be_forwarded, can_be_replied, can_get_viewers, has_expired_viewers, story->interaction_info_.get_story_interaction_info_object(td_), - std::move(privacy_settings), get_story_content_object(td_, content), std::move(areas), + std::move(privacy_settings), get_story_content_object(td_, content), std::move(story_areas), get_formatted_text_object(*caption, true, get_story_content_duration(td_, content))); } @@ -2616,13 +2629,11 @@ StoryId StoryManager::on_get_new_story(DialogId owner_dialog_id, } if (story->areas_ != media_areas) { story->areas_ = std::move(media_areas); - /* if (edited_story != nullptr && edited_story->edit_media_areas_) { need_save_to_database = true; } else { is_changed = true; } - */ } Dependencies dependencies; @@ -3597,44 +3608,64 @@ class StoryManager::EditStoryLogEvent { public: const PendingStory *pending_story_in_; unique_ptr pending_story_out_; + bool edit_media_areas_; + vector areas_; bool edit_caption_; FormattedText caption_; EditStoryLogEvent() : pending_story_in_(nullptr), edit_caption_(false) { } - EditStoryLogEvent(const PendingStory *pending_story, bool edit_caption, const FormattedText &caption) - : pending_story_in_(pending_story), edit_caption_(edit_caption), caption_(caption) { + EditStoryLogEvent(const PendingStory *pending_story, bool edit_media_areas, vector areas, + bool edit_caption, const FormattedText &caption) + : pending_story_in_(pending_story) + , edit_media_areas_(edit_media_areas) + , areas_(std::move(areas)) + , edit_caption_(edit_caption) + , caption_(caption) { } template void store(StorerT &storer) const { bool has_caption = edit_caption_ && !caption_.text.empty(); + bool has_media_areas = edit_media_areas_ && !areas_.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(edit_caption_); STORE_FLAG(has_caption); + STORE_FLAG(edit_media_areas_); + STORE_FLAG(has_media_areas); END_STORE_FLAGS(); td::store(*pending_story_in_, storer); if (has_caption) { td::store(caption_, storer); } + if (has_media_areas) { + td::store(areas_, storer); + } } template void parse(ParserT &parser) { bool has_caption; + bool has_media_areas; BEGIN_PARSE_FLAGS(); PARSE_FLAG(edit_caption_); PARSE_FLAG(has_caption); + PARSE_FLAG(edit_media_areas_); + PARSE_FLAG(has_media_areas); END_PARSE_FLAGS(); td::parse(pending_story_out_, parser); if (has_caption) { td::parse(caption_, parser); } + if (has_media_areas) { + td::parse(areas_, parser); + } } }; void StoryManager::edit_story(StoryId story_id, td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, td_api::object_ptr &&input_caption, Promise &&promise) { DialogId dialog_id(td_->contacts_manager_->get_my_id()); StoryFullId story_full_id{dialog_id, story_id}; @@ -3648,12 +3679,30 @@ void StoryManager::edit_story(StoryId story_id, td_api::object_ptrauth_manager_->is_bot(); unique_ptr content; + bool are_media_areas_edited = input_areas != nullptr; + vector areas; bool is_caption_edited = input_caption != nullptr; FormattedText caption; if (input_story_content != nullptr) { TRY_RESULT_PROMISE_ASSIGN(promise, content, get_input_story_content(td_, std::move(input_story_content), dialog_id)); } + if (are_media_areas_edited) { + for (auto &input_area : input_areas->areas_) { + MediaArea media_area(td_, std::move(input_area), story->areas_); + if (media_area.is_valid()) { + areas.push_back(std::move(media_area)); + } + } + auto *current_areas = &story->areas_; + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end() && it->second->edit_media_areas_) { + current_areas = &it->second->areas_; + } + if (*current_areas == areas) { + are_media_areas_edited = false; + } + } if (is_caption_edited) { TRY_RESULT_PROMISE_ASSIGN( promise, caption, get_formatted_text(td_, DialogId(), std::move(input_caption), is_bot, true, false, false)); @@ -3666,7 +3715,7 @@ void StoryManager::edit_story(StoryId story_id, td_api::object_ptrcontent_ = std::move(content); edit_generation++; } + if (are_media_areas_edited) { + edited_story->areas_ = std::move(areas); + edited_story->edit_media_areas_ = true; + edit_generation++; + } if (is_caption_edited) { edited_story->caption_ = std::move(caption); edited_story->edit_caption_ = true; @@ -3693,7 +3747,8 @@ void StoryManager::edit_story(StoryId story_id, td_api::object_ptr(dialog_id, story_id, std::numeric_limits::max() - (++send_story_count_), edit_generation, std::move(new_story)); if (G()->use_message_database()) { - EditStoryLogEvent log_event(pending_story.get(), edited_story->edit_caption_, edited_story->caption_); + EditStoryLogEvent log_event(pending_story.get(), edited_story->edit_media_areas_, edited_story->areas_, + edited_story->edit_caption_, edited_story->caption_); auto storer = get_log_event_storer(log_event); auto &cur_log_event_id = edited_story->log_event_id_; if (cur_log_event_id == 0) { @@ -4045,6 +4100,10 @@ void StoryManager::on_binlog_events(vector &&events) { if (pending_story->story_->content_ != nullptr) { edited_story->content_ = std::move(pending_story->story_->content_); } + if (log_event.edit_media_areas_) { + edited_story->areas_ = std::move(log_event.areas_); + edited_story->edit_media_areas_ = true; + } if (log_event.edit_caption_) { edited_story->caption_ = std::move(log_event.caption_); edited_story->edit_caption_ = true; diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 1922bf4fb..95bc33c8c 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -92,7 +92,9 @@ class StoryManager final : public Actor { struct BeingEditedStory { unique_ptr content_; + vector areas_; FormattedText caption_; + bool edit_media_areas_ = false; bool edit_caption_ = false; vector> promises_; int64 log_event_id_ = 0; @@ -207,6 +209,7 @@ class StoryManager final : public Actor { void on_send_story_file_parts_missing(unique_ptr &&pending_story, vector &&bad_parts); void edit_story(StoryId story_id, td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, td_api::object_ptr &&input_caption, Promise &&promise); void set_story_privacy_settings(StoryId story_id, td_api::object_ptr &&settings, diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 6872117fa..e6e03a034 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5641,8 +5641,8 @@ void Td::on_request(uint64 id, td_api::sendStory &request) { void Td::on_request(uint64 id, td_api::editStory &request) { CHECK_IS_USER(); CREATE_OK_REQUEST_PROMISE(); - story_manager_->edit_story(StoryId(request.story_id_), std::move(request.content_), std::move(request.caption_), - std::move(promise)); + story_manager_->edit_story(StoryId(request.story_id_), std::move(request.content_), std::move(request.areas_), + std::move(request.caption_), std::move(promise)); } void Td::on_request(uint64 id, td_api::setStoryPrivacySettings &request) { diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index c5127e84a..8b4ea397c 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4066,7 +4066,7 @@ class CliClient final : public Actor { StoryId story_id; string caption; get_args(args, story_id, caption); - send_request(td_api::make_object(story_id, nullptr, as_caption(caption))); + send_request(td_api::make_object(story_id, nullptr, nullptr, as_caption(caption))); } else if (op == "esp") { StoryId story_id; string photo; @@ -4077,7 +4077,7 @@ class CliClient final : public Actor { td_api::make_object(story_id, td_api::make_object( as_input_file(photo), to_integers(sticker_file_ids)), - as_caption(caption))); + nullptr, as_caption(caption))); } else if (op == "esv") { StoryId story_id; string video; @@ -4089,7 +4089,7 @@ class CliClient final : public Actor { story_id, td_api::make_object(as_input_file(video), to_integers(sticker_file_ids), duration, false), - as_caption(caption))); + nullptr, as_caption(caption))); } else if (op == "ssps") { StoryId story_id; StoryPrivacySettings rules;