diff --git a/td/generate/scheme/td_api.tl b/td/generate/scheme/td_api.tl index c8e69c9df..41102e7f3 100644 --- a/td/generate/scheme/td_api.tl +++ b/td/generate/scheme/td_api.tl @@ -4931,8 +4931,12 @@ messageLink link:string is_public:Bool = MessageLink; messageLinkInfo is_public:Bool chat_id:int53 message_thread_id:int53 message:message media_timestamp:int32 for_album:Bool = MessageLinkInfo; -//@description Represents a viewer of a story @user_id User identifier of the viewer @view_date Approximate point in time (Unix timestamp) when the story was viewed -storyViewer user_id:int53 view_date:int32 = StoryViewer; +//@description Represents a viewer of a story +//@user_id User identifier of the viewer +//@view_date Approximate point in time (Unix timestamp) when the story was viewed +//@block_list Block list to which the user is added; may be null if none +//@chosen_reaction_type Type of the reaction that was chosen by the user; may be null if none +storyViewer user_id:int53 view_date:int32 block_list:BlockList chosen_reaction_type:ReactionType = StoryViewer; //@description Represents a list of story viewers @viewers List of story viewers storyViewers viewers:vector = StoryViewers; diff --git a/td/telegram/ReactionType.cpp b/td/telegram/ReactionType.cpp index fd9fdb48d..c273f9c0b 100644 --- a/td/telegram/ReactionType.cpp +++ b/td/telegram/ReactionType.cpp @@ -95,7 +95,9 @@ telegram_api::object_ptr ReactionType::get_input_reactio } td_api::object_ptr ReactionType::get_reaction_type_object() const { - CHECK(!is_empty()); + if (is_empty()) { + return nullptr; + } if (is_custom_reaction()) { return td_api::make_object(get_custom_emoji_id(reaction_)); } diff --git a/td/telegram/StoryInteractionInfo.cpp b/td/telegram/StoryInteractionInfo.cpp index ed7b1e24d..f82953be8 100644 --- a/td/telegram/StoryInteractionInfo.cpp +++ b/td/telegram/StoryInteractionInfo.cpp @@ -49,11 +49,15 @@ void StoryInteractionInfo::add_dependencies(Dependencies &dependencies) const { } } -void StoryInteractionInfo::set_recent_viewer_user_ids(vector &&user_ids) { +bool StoryInteractionInfo::set_recent_viewer_user_ids(vector &&user_ids) { if (user_ids.size() > MAX_RECENT_VIEWERS) { user_ids.resize(MAX_RECENT_VIEWERS); } - recent_viewer_user_ids_ = std::move(user_ids); + if (recent_viewer_user_ids_ != user_ids) { + recent_viewer_user_ids_ = std::move(user_ids); + return true; + } + return false; } bool StoryInteractionInfo::definitely_has_no_user(UserId user_id) const { diff --git a/td/telegram/StoryInteractionInfo.h b/td/telegram/StoryInteractionInfo.h index 6963f20e5..9d5c7da33 100644 --- a/td/telegram/StoryInteractionInfo.h +++ b/td/telegram/StoryInteractionInfo.h @@ -54,7 +54,7 @@ class StoryInteractionInfo { bool definitely_has_no_user(UserId user_id) const; - void set_recent_viewer_user_ids(vector &&user_ids); + bool set_recent_viewer_user_ids(vector &&user_ids); td_api::object_ptr get_story_interaction_info_object(Td *td) const; diff --git a/td/telegram/StoryManager.cpp b/td/telegram/StoryManager.cpp index bf2e20ccf..83b07df44 100644 --- a/td/telegram/StoryManager.cpp +++ b/td/telegram/StoryManager.cpp @@ -2341,12 +2341,12 @@ void StoryManager::get_story_viewers(StoryId story_id, const td_api::storyViewer offset_date = offset->view_date_; offset_user_id = offset->user_id_; } - StoryViewer offset_viewer{UserId(offset_user_id), offset_date}; + bool is_first = offset_user_id <= 0 && offset_date <= 0; auto query_promise = PromiseCreator::lambda( - [actor_id = actor_id(this), story_id, offset_viewer, promise = std::move(promise)]( + [actor_id = actor_id(this), story_id, is_first, promise = std::move(promise)]( Result> result) mutable { - send_closure(actor_id, &StoryManager::on_get_story_viewers, story_id, offset_viewer, std::move(result), + send_closure(actor_id, &StoryManager::on_get_story_viewers, story_id, is_first, std::move(result), std::move(promise)); }); @@ -2355,8 +2355,7 @@ void StoryManager::get_story_viewers(StoryId story_id, const td_api::storyViewer } void StoryManager::on_get_story_viewers( - StoryId story_id, StoryViewer offset, - Result> r_view_list, + StoryId story_id, bool is_first, Result> r_view_list, Promise> &&promise) { G()->ignore_result_if_closing(r_view_list); if (r_view_list.is_error()) { @@ -2382,10 +2381,14 @@ void StoryManager::on_get_story_viewers( StoryViewers story_viewers(std::move(view_list->views_)); if (story->content_ != nullptr) { + bool is_changed = false; if (story->interaction_info_.set_view_count(view_list->count_)) { - if (offset.is_empty()) { - story->interaction_info_.set_recent_viewer_user_ids(story_viewers.get_user_ids()); - } + is_changed = true; + } + if (is_first && story->interaction_info_.set_recent_viewer_user_ids(story_viewers.get_user_ids())) { + is_changed = true; + } + if (is_changed) { on_story_changed(story_full_id, story, true, true); } } diff --git a/td/telegram/StoryManager.h b/td/telegram/StoryManager.h index 5cb52a827..93c8cb999 100644 --- a/td/telegram/StoryManager.h +++ b/td/telegram/StoryManager.h @@ -522,7 +522,7 @@ class StoryManager final : public Actor { void set_story_stealth_mode(StoryStealthMode stealth_mode); - void on_get_story_viewers(StoryId story_id, StoryViewer offset, + void on_get_story_viewers(StoryId story_id, bool is_first, Result> r_view_list, Promise> &&promise); diff --git a/td/telegram/StoryViewer.cpp b/td/telegram/StoryViewer.cpp index d2498acc0..9dc22cf4a 100644 --- a/td/telegram/StoryViewer.cpp +++ b/td/telegram/StoryViewer.cpp @@ -6,6 +6,7 @@ // #include "td/telegram/StoryViewer.h" +#include "td/telegram/BlockListId.h" #include "td/telegram/ContactsManager.h" #include "td/utils/algorithm.h" @@ -14,22 +15,24 @@ namespace td { td_api::object_ptr StoryViewer::get_story_viewer_object(ContactsManager *contacts_manager) const { + auto block_list_id = BlockListId(is_blocked_, is_blocked_for_stories_); return td_api::make_object( - contacts_manager->get_user_id_object(user_id_, "get_story_viewer_object"), date_); + contacts_manager->get_user_id_object(user_id_, "get_story_viewer_object"), date_, + block_list_id.get_block_list_object(), reaction_type_.get_reaction_type_object()); } StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewer &viewer) { - return string_builder << '[' << viewer.user_id_ << " at " << viewer.date_ << ']'; + return string_builder << '[' << viewer.user_id_ << " with " << viewer.reaction_type_ << " at " << viewer.date_ << ']'; } StoryViewers::StoryViewers(vector> &&story_views) { for (auto &story_view : story_views) { - UserId user_id(story_view->user_id_); + story_viewers_.emplace_back(std::move(story_view)); + auto user_id = story_viewers_.back().get_user_id(); if (!user_id.is_valid()) { - LOG(ERROR) << "Receive " << user_id << " as story viewer"; - continue; + LOG(ERROR) << "Receive invalid " << user_id << " as a viewer of a story"; + story_viewers_.pop_back(); } - story_viewers_.emplace_back(user_id, story_view->date_); } } diff --git a/td/telegram/StoryViewer.h b/td/telegram/StoryViewer.h index 2685680e7..e2b442072 100644 --- a/td/telegram/StoryViewer.h +++ b/td/telegram/StoryViewer.h @@ -6,6 +6,7 @@ // #pragma once +#include "td/telegram/ReactionType.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -20,21 +21,25 @@ class ContactsManager; class StoryViewer { UserId user_id_; int32 date_ = 0; + bool is_blocked_ = false; + bool is_blocked_for_stories_ = false; + ReactionType reaction_type_; friend StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewer &viewer); public: - StoryViewer(UserId user_id, int32 date) : user_id_(user_id), date_(td::max(date, static_cast(0))) { + StoryViewer(telegram_api::object_ptr &&story_view) + : user_id_(story_view->user_id_) + , date_(td::max(story_view->date_, static_cast(0))) + , is_blocked_(story_view->blocked_) + , is_blocked_for_stories_(story_view->blocked_my_stories_from_) + , reaction_type_(story_view->reaction_) { } UserId get_user_id() const { return user_id_; } - bool is_empty() const { - return user_id_ == UserId() && date_ == 0; - } - td_api::object_ptr get_story_viewer_object(ContactsManager *contacts_manager) const; }; diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 11ae55e02..18b992468 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4155,7 +4155,8 @@ class CliClient final : public Actor { UserId offset_user_id; get_args(args, story_id, limit, offset_date, offset_user_id); send_request(td_api::make_object( - story_id, td_api::make_object(offset_user_id, offset_date), as_limit(limit))); + story_id, td_api::make_object(offset_user_id, offset_date, nullptr, nullptr), + as_limit(limit))); } else if (op == "rst") { ChatId story_sender_chat_id; StoryId story_id;