diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index 1726c85d3..896be5c50 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4869,7 +4869,7 @@ storyInteractionInfo view_count:int32 recent_viewer_user_ids:vector = Sto //@id Unique story identifier among stories of the given sender //@sender_user_id Identifier of the user that created the story //@date Point in time (Unix timestamp) when the story was published -//@is_pinned True, if the story is saved in the sender's profile and will be available there after the expiration +//@is_pinned True, if the story is saved in the sender's profile and will be available there after expiration //@interaction_info Information about interactions with the story; may be null if the story isn't owned or there were no interactions //@privacy_rules Pryvacy rules affecting story visibility; may be null if the story isn't owned //@is_public True, if the story is available for everyone @@ -7166,12 +7166,15 @@ readChatList chat_list:ChatList = Ok; //@content Content of the story //@caption Story caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters //@privacy_rules The privacy rules for the story -//@is_pinned Pass true to keep the story accessible after 24 hours +//@is_pinned Pass true to keep the story accessible after expiration sendStory content:InputStoryContent caption:formattedText privacy_rules:userPrivacySettingRules is_pinned:Bool = Story; //@description Changes privacy rules of a previously sent story @story_id Identifier of the story @privacy_rules The new privacy rules for the story setStoryPrivacyRules story_id:int32 privacy_rules:userPrivacySettingRules = Ok; +//@description Toggles whether a story is accessible after expiration @story_id Identifier of the story @is_pinned Pass true to make the story accessible after expiration; pass false to make it private +toggleStoryIsPinned story_id:int32 is_pinned:Bool = Ok; + //@description Returns the list of pinned stories of a given user. The stories are returned in a reverse chronological order (i.e., in order of decreasing story_id). //-For optimal performance, the number of returned stories is chosen by TDLib //@user_id User identifier diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index 84ad48a53..7a50f5737 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -158,6 +158,33 @@ class EditStoryPrivacyQuery final : public Td::ResultHandler { } }; +class ToggleStoryPinnedQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ToggleStoryPinnedQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(StoryId story_id, bool is_pinned) { + send_query(G()->net_query_creator().create(telegram_api::stories_togglePinned({story_id.get()}, is_pinned))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ToggleStoryPinnedQuery: " << ptr; + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class StoryManager::SendStoryQuery final : public Td::ResultHandler { FileId file_id_; unique_ptr pending_story_; @@ -469,6 +496,10 @@ StoryId StoryManager::on_get_story(DialogId owner_dialog_id, // story->last_edit_pts_ = 0; } + if (is_changed || need_save_to_database) { + change_story_files(story_full_id, story, old_file_ids); + } + auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(story_item->privacy_)); auto interaction_info = StoryInteractionInfo(td_, std::move(story_item->views_)); if (story->is_pinned_ != story_item->pinned_ || story->is_public_ != story_item->public_ || @@ -486,17 +517,22 @@ StoryId StoryManager::on_get_story(DialogId owner_dialog_id, is_changed = true; } - if (is_changed || need_save_to_database) { - change_story_files(story_full_id, story, old_file_ids); + on_story_changed(story_full_id, story, is_changed, need_save_to_database); - // save_story(story, story_id); - } - if (is_changed) { - // send_closure(G()->td(), &Td::send_update, td_api::make_object(get_story_object(story_id, story))); - } return story_id; } +void StoryManager::on_story_changed(StoryFullId story_full_id, const Story *story, bool is_changed, + bool need_save_to_database) { + if (is_changed || need_save_to_database) { + // save_story(story, story_id); + + if (is_changed) { + // send_closure(G()->td(), &Td::send_update, td_api::make_object(get_story_object(story_full_id, story))); + } + } +} + std::pair> StoryManager::on_get_stories( DialogId owner_dialog_id, telegram_api::object_ptr &&stories) { td_->contacts_manager_->on_get_users(std::move(stories->users_), "on_get_stories"); @@ -693,4 +729,29 @@ void StoryManager::set_story_privacy_rules(StoryId story_id, td_->create_handler(std::move(promise))->send(story_id, std::move(privacy_rules)); } +void StoryManager::toggle_story_is_pinned(StoryId story_id, bool is_pinned, Promise &&promise) { + DialogId dialog_id(td_->contacts_manager_->get_my_id()); + const Story *story = get_story({dialog_id, story_id}); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_id, is_pinned, promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StoryManager::on_toggle_story_is_pinned, story_id, is_pinned, std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(story_id, is_pinned); +} + +void StoryManager::on_toggle_story_is_pinned(StoryId story_id, bool is_pinned, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + DialogId dialog_id(td_->contacts_manager_->get_my_id()); + Story *story = get_story_editable({dialog_id, story_id}); + CHECK(story != nullptr); + story->is_pinned_ = is_pinned; + on_story_changed({dialog_id, story_id}, story, true, true); +} + } // namespace td diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 69e9e17c6..28e5096d0 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -74,6 +74,8 @@ class StoryManager final : public Actor { void set_story_privacy_rules(StoryId story_id, td_api::object_ptr &&rules, Promise &&promise); + void toggle_story_is_pinned(StoryId story_id, bool is_pinned, Promise &&promise); + void get_dialog_pinned_stories(DialogId owner_dialog_id, StoryId from_story_id, int32 limit, Promise> &&promise); @@ -106,6 +108,8 @@ class StoryManager final : public Actor { Story *get_story_editable(StoryFullId story_full_id); + void on_story_changed(StoryFullId story_full_id, const Story *story, bool is_changed, bool need_save_to_database); + td_api::object_ptr get_story_object(StoryFullId story_full_id, const Story *story) const; vector on_get_stories(DialogId owner_dialog_id, @@ -133,6 +137,8 @@ class StoryManager final : public Actor { void on_upload_story_error(FileId file_id, Status status); + void on_toggle_story_is_pinned(StoryId story_id, bool is_pinned, Promise &&promise); + std::shared_ptr upload_media_callback_; WaitFreeHashMap story_full_id_to_file_source_id_; diff --git a/td/telegram/Td.cpp b/td/telegram/Td.cpp index 67722dc86..1a3b22eee 100644 --- a/td/telegram/Td.cpp +++ b/td/telegram/Td.cpp @@ -5631,6 +5631,12 @@ void Td::on_request(uint64 id, td_api::setStoryPrivacyRules &request) { std::move(promise)); } +void Td::on_request(uint64 id, const td_api::toggleStoryIsPinned &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + story_manager_->toggle_story_is_pinned(StoryId(request.story_id_), request.is_pinned_, std::move(promise)); +} + void Td::on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request) { CREATE_REQUEST_PROMISE(); stickers_manager_->get_default_topic_icons(false, std::move(promise)); diff --git a/td/telegram/Td.h b/td/telegram/Td.h index 3deb70b96..6619d9625 100644 --- a/td/telegram/Td.h +++ b/td/telegram/Td.h @@ -790,6 +790,8 @@ class Td final : public Actor { void on_request(uint64 id, td_api::setStoryPrivacyRules &request); + void on_request(uint64 id, const td_api::toggleStoryIsPinned &request); + void on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request); void on_request(uint64 id, td_api::createForumTopic &request); diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index cace42b03..771bc5b1e 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -3957,6 +3957,11 @@ class CliClient final : public Actor { PrivacyRules rules; get_args(args, story_id, rules); send_request(td_api::make_object(story_id, rules)); + } else if (op == "tsip") { + StoryId story_id; + bool is_pinned; + get_args(args, story_id, is_pinned); + send_request(td_api::make_object(story_id, is_pinned)); } else if (op == "gups") { UserId user_id; StoryId from_story_id;