Cache received story viewers.
This commit is contained in:
parent
c885e3f5fa
commit
4e2e6f6e61
@ -7284,10 +7284,12 @@ openStory story_sender_user_id:int53 story_id:int32 = Ok;
|
||||
//@story_id The identifier of the story
|
||||
closeStory story_sender_user_id:int53 story_id:int32 = Ok;
|
||||
|
||||
//@description Returns viewers of a recent outgoing story. The method can be called if story.can_get_viewers == true
|
||||
//@description Returns viewers of a recent outgoing story. The method can be called if story.can_get_viewers == true. The views are returned in a reverse chronological order (i.e., in order of decreasing view_date)
|
||||
//-For optimal performance, the number of returned stories is chosen by TDLib
|
||||
//@story_id Story identifier
|
||||
//@offset_viewer A viewer from which to return next viewers; pass null to get results from the beginning
|
||||
//@limit The maximum number of story viewers to return
|
||||
//-For optimal performance, the number of returned stories is chosen by TDLib and can be smaller than the specified limit
|
||||
getStoryViewers story_id:int32 offset_viewer:messageViewer limit:int32 = MessageViewers;
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@ MessageViewers::MessageViewers(vector<telegram_api::object_ptr<telegram_api::rea
|
||||
}
|
||||
|
||||
MessageViewers MessageViewers::get_sublist(const MessageViewer &offset, int32 limit) const {
|
||||
MessageViewers result{vector<telegram_api::object_ptr<telegram_api::storyView>>()};
|
||||
MessageViewers result;
|
||||
bool found = offset.is_empty();
|
||||
for (auto &message_viewer : message_viewers_) {
|
||||
if (found) {
|
||||
@ -68,6 +68,25 @@ MessageViewers MessageViewers::get_sublist(const MessageViewer &offset, int32 li
|
||||
return result;
|
||||
}
|
||||
|
||||
void MessageViewers::add_sublist(const MessageViewer &offset, const MessageViewers &sublist) {
|
||||
if (offset.is_empty()) {
|
||||
if (message_viewers_.empty()) {
|
||||
message_viewers_ = sublist.message_viewers_;
|
||||
} else {
|
||||
auto old_viewers = std::move(message_viewers_);
|
||||
for (auto &viewer : sublist.message_viewers_) {
|
||||
if (viewer == old_viewers[0]) {
|
||||
append(message_viewers_, old_viewers);
|
||||
return;
|
||||
}
|
||||
message_viewers_.push_back(viewer);
|
||||
}
|
||||
}
|
||||
} else if (!message_viewers_.empty() && message_viewers_.back() == offset) {
|
||||
append(message_viewers_, sublist.message_viewers_);
|
||||
}
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::messageViewers> MessageViewers::get_message_viewers_object(
|
||||
ContactsManager *contacts_manager) const {
|
||||
return td_api::make_object<td_api::messageViewers>(
|
||||
|
@ -51,12 +51,20 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &vi
|
||||
struct MessageViewers {
|
||||
vector<MessageViewer> message_viewers_;
|
||||
|
||||
MessageViewers() = default;
|
||||
|
||||
explicit MessageViewers(vector<telegram_api::object_ptr<telegram_api::storyView>> &&story_views);
|
||||
|
||||
explicit MessageViewers(vector<telegram_api::object_ptr<telegram_api::readParticipantDate>> &&read_dates);
|
||||
|
||||
bool is_empty() const {
|
||||
return message_viewers_.empty();
|
||||
}
|
||||
|
||||
MessageViewers get_sublist(const MessageViewer &offset, int32 limit) const;
|
||||
|
||||
void add_sublist(const MessageViewer &offset, const MessageViewers &sublist);
|
||||
|
||||
td_api::object_ptr<td_api::messageViewers> get_message_viewers_object(ContactsManager *contacts_manager) const;
|
||||
};
|
||||
|
||||
|
@ -44,6 +44,10 @@ class StoryInteractionInfo {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 get_view_count() const {
|
||||
return view_count_;
|
||||
}
|
||||
|
||||
td_api::object_ptr<td_api::storyInteractionInfo> get_story_interaction_info_object(Td *td) const;
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "td/telegram/logevent/LogEventHelper.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/MessagesManager.h"
|
||||
#include "td/telegram/MessageViewer.h"
|
||||
#include "td/telegram/OptionManager.h"
|
||||
#include "td/telegram/StoryContent.h"
|
||||
#include "td/telegram/StoryContentType.h"
|
||||
@ -695,6 +694,7 @@ void StoryManager::on_story_can_get_viewers_timeout(int64 story_global_id) {
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
td_api::make_object<td_api::updateStory>(get_story_object(story_full_id, story)));
|
||||
}
|
||||
cached_story_viewers_.erase(story_full_id);
|
||||
}
|
||||
|
||||
bool StoryManager::is_story_owned(DialogId owner_dialog_id) const {
|
||||
@ -1100,7 +1100,7 @@ void StoryManager::get_story_viewers(StoryId story_id, const td_api::messageView
|
||||
if (limit <= 0) {
|
||||
return promise.set_error(Status::Error(400, "Parameter limit must be positive"));
|
||||
}
|
||||
if (can_get_story_viewers(story_full_id, story).is_error()) {
|
||||
if (can_get_story_viewers(story_full_id, story).is_error() || story->interaction_info_.get_view_count() == 0) {
|
||||
return promise.set_value(td_api::object_ptr<td_api::messageViewers>());
|
||||
}
|
||||
|
||||
@ -1110,11 +1110,22 @@ void StoryManager::get_story_viewers(StoryId story_id, const td_api::messageView
|
||||
offset_date = offset->view_date_;
|
||||
offset_user_id = offset->user_id_;
|
||||
}
|
||||
MessageViewer offset_viewer{UserId(offset_user_id), offset_date};
|
||||
|
||||
auto &cached_viewers = cached_story_viewers_[story_full_id];
|
||||
if (cached_viewers != nullptr && story->content_ != nullptr &&
|
||||
(cached_viewers->total_count_ == story->interaction_info_.get_view_count() || !offset_viewer.is_empty())) {
|
||||
auto result = cached_viewers->viewers_.get_sublist(offset_viewer, limit);
|
||||
if (!result.is_empty()) {
|
||||
return promise.set_value(result.get_message_viewers_object(td_->contacts_manager_.get()));
|
||||
}
|
||||
}
|
||||
|
||||
auto query_promise = PromiseCreator::lambda(
|
||||
[actor_id = actor_id(this), story_id, promise = std::move(promise)](
|
||||
[actor_id = actor_id(this), story_id, offset_viewer, promise = std::move(promise)](
|
||||
Result<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> result) mutable {
|
||||
send_closure(actor_id, &StoryManager::on_get_story_viewers, story_id, std::move(result), std::move(promise));
|
||||
send_closure(actor_id, &StoryManager::on_get_story_viewers, story_id, offset_viewer, std::move(result),
|
||||
std::move(promise));
|
||||
});
|
||||
|
||||
td_->create_handler<GetStoryViewsListQuery>(std::move(query_promise))
|
||||
@ -1122,7 +1133,8 @@ void StoryManager::get_story_viewers(StoryId story_id, const td_api::messageView
|
||||
}
|
||||
|
||||
void StoryManager::on_get_story_viewers(
|
||||
StoryId story_id, Result<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> r_view_list,
|
||||
StoryId story_id, MessageViewer offset,
|
||||
Result<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> r_view_list,
|
||||
Promise<td_api::object_ptr<td_api::messageViewers>> &&promise) {
|
||||
G()->ignore_result_if_closing(r_view_list);
|
||||
if (r_view_list.is_error()) {
|
||||
@ -1140,11 +1152,29 @@ void StoryManager::on_get_story_viewers(
|
||||
|
||||
td_->contacts_manager_->on_get_users(std::move(view_list->users_), "on_get_story_viewers");
|
||||
|
||||
if (story->content_ != nullptr && story->interaction_info_.set_view_count(view_list->count_)) {
|
||||
on_story_changed(story_full_id, story, true, true);
|
||||
auto total_count = view_list->count_;
|
||||
if (total_count < 0 || static_cast<size_t>(total_count) < view_list->views_.size()) {
|
||||
LOG(ERROR) << "Receive total_count = " << total_count << " and " << view_list->views_.size() << " story viewers";
|
||||
total_count = static_cast<int32>(view_list->views_.size());
|
||||
}
|
||||
|
||||
MessageViewers story_viewers(std::move(view_list->views_));
|
||||
if (story->content_ != nullptr) {
|
||||
if (story->interaction_info_.set_view_count(view_list->count_)) {
|
||||
on_story_changed(story_full_id, story, true, true);
|
||||
}
|
||||
auto &cached_viewers = cached_story_viewers_[story_full_id];
|
||||
if (cached_viewers == nullptr) {
|
||||
cached_viewers = make_unique<CachedStoryViewers>();
|
||||
}
|
||||
if (total_count < cached_viewers->total_count_) {
|
||||
LOG(ERROR) << "Total viewer count decreased from " << cached_viewers->total_count_ << " to " << total_count;
|
||||
} else {
|
||||
cached_viewers->total_count_ = total_count;
|
||||
}
|
||||
cached_viewers->viewers_.add_sublist(offset, story_viewers);
|
||||
}
|
||||
|
||||
promise.set_value(story_viewers.get_message_viewers_object(td_->contacts_manager_.get()));
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "td/telegram/files/FileSourceId.h"
|
||||
#include "td/telegram/FullMessageId.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/MessageViewer.h"
|
||||
#include "td/telegram/StoryFullId.h"
|
||||
#include "td/telegram/StoryId.h"
|
||||
#include "td/telegram/StoryInteractionInfo.h"
|
||||
@ -82,6 +83,11 @@ class StoryManager final : public Actor {
|
||||
vector<StoryId> story_ids_;
|
||||
};
|
||||
|
||||
struct CachedStoryViewers {
|
||||
int32 total_count_ = -1;
|
||||
MessageViewers viewers_;
|
||||
};
|
||||
|
||||
public:
|
||||
StoryManager(Td *td, ActorShared<> parent);
|
||||
StoryManager(const StoryManager &) = delete;
|
||||
@ -284,7 +290,7 @@ class StoryManager final : public Actor {
|
||||
|
||||
void on_synchronized_archive_all_stories(bool set_archive_all_stories, Result<Unit> result);
|
||||
|
||||
void on_get_story_viewers(StoryId story_id,
|
||||
void on_get_story_viewers(StoryId story_id, MessageViewer offset,
|
||||
Result<telegram_api::object_ptr<telegram_api::stories_storyViewsList>> r_view_list,
|
||||
Promise<td_api::object_ptr<td_api::messageViewers>> &&promise);
|
||||
|
||||
@ -312,6 +318,8 @@ class StoryManager final : public Actor {
|
||||
|
||||
FlatHashMap<StoryFullId, uint32, StoryFullIdHash> opened_owned_stories_;
|
||||
|
||||
FlatHashMap<StoryFullId, unique_ptr<CachedStoryViewers>, StoryFullIdHash> cached_story_viewers_;
|
||||
|
||||
uint32 send_story_count_ = 0;
|
||||
|
||||
int64 max_story_global_id_ = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user