Add td_api::story.repost_info.

This commit is contained in:
levlam 2023-11-29 19:22:54 +03:00
parent da0d999c52
commit dcad0f413e
7 changed files with 248 additions and 3 deletions

View File

@ -485,6 +485,7 @@ set(TDLIB_SOURCE
td/telegram/StoryContent.cpp td/telegram/StoryContent.cpp
td/telegram/StoryContentType.cpp td/telegram/StoryContentType.cpp
td/telegram/StoryDb.cpp td/telegram/StoryDb.cpp
td/telegram/StoryForwardInfo.cpp
td/telegram/StoryInteractionInfo.cpp td/telegram/StoryInteractionInfo.cpp
td/telegram/StoryManager.cpp td/telegram/StoryManager.cpp
td/telegram/StoryStealthMode.cpp td/telegram/StoryStealthMode.cpp
@ -804,6 +805,7 @@ set(TDLIB_SOURCE
td/telegram/StoryDb.h td/telegram/StoryDb.h
td/telegram/StoryFullId.h td/telegram/StoryFullId.h
td/telegram/StoryId.h td/telegram/StoryId.h
td/telegram/StoryForwardInfo.h
td/telegram/StoryInteractionInfo.h td/telegram/StoryInteractionInfo.h
td/telegram/StoryListId.h td/telegram/StoryListId.h
td/telegram/StoryManager.h td/telegram/StoryManager.h
@ -893,6 +895,7 @@ set(TDLIB_SOURCE
td/telegram/StickerMaskPosition.hpp td/telegram/StickerMaskPosition.hpp
td/telegram/StickerPhotoSize.hpp td/telegram/StickerPhotoSize.hpp
td/telegram/StickersManager.hpp td/telegram/StickersManager.hpp
td/telegram/StoryForwardInfo.hpp
td/telegram/StoryInteractionInfo.hpp td/telegram/StoryInteractionInfo.hpp
td/telegram/StoryStealthMode.hpp td/telegram/StoryStealthMode.hpp
td/telegram/TranscriptionInfo.hpp td/telegram/TranscriptionInfo.hpp

View File

@ -3497,6 +3497,20 @@ storyListMain = StoryList;
storyListArchive = StoryList; storyListArchive = StoryList;
//@class StoryOrigin @description Contains information about the origin of a story that was reposted
//@description The original story was a public story with known sender @chat_id Identifier of the chat that posted original story @story_id Story identifier of the original story
storyOriginPublicStory chat_id:int53 story_id:int32 = StoryOrigin;
//@description The original story was sent by a user, which is hidden by their privacy settings @sender_name Name of the story sender
storyOriginHiddenUser sender_name:string = StoryOrigin;
//@description Contains information about original story that was reposted
//@origin Origin of the story that was reposted
//@is_content_modified True, if story content was modified during reposting; otherwise, story wasn't modified
storyRepostInfo origin:StoryOrigin is_content_modified:Bool = StoryRepostInfo;
//@description Contains information about interactions with a story //@description Contains information about interactions with a story
//@view_count Number of times the story was viewed //@view_count Number of times the story was viewed
//@forward_count Number of times the story was forwarded; 0 if none or unknown //@forward_count Number of times the story was forwarded; 0 if none or unknown
@ -3521,13 +3535,14 @@ storyInteractionInfo view_count:int32 forward_count:int32 reaction_count:int32 r
//@can_get_statistics True, if the story statistics are available through getStoryStatistics //@can_get_statistics True, if the story statistics are available through getStoryStatistics
//@can_get_viewers True, if users viewed the story can be received through getStoryViewers //@can_get_viewers True, if users viewed the story can be received through getStoryViewers
//@has_expired_viewers True, if users viewed the story can't be received, because the story has expired more than getOption("story_viewers_expiration_delay") seconds ago //@has_expired_viewers True, if users viewed the story can't be received, because the story has expired more than getOption("story_viewers_expiration_delay") seconds ago
//@repost_info Information about the original story; may be null if the story wasn't reposted
//@interaction_info Information about interactions with the story; may be null if the story isn't owned or there were no interactions //@interaction_info Information about interactions with the story; may be null if the story isn't owned or there were no interactions
//@chosen_reaction_type Type of the chosen reaction; may be null if none //@chosen_reaction_type Type of the chosen reaction; may be null if none
//@privacy_settings Privacy rules affecting story visibility; may be approximate for non-owned stories //@privacy_settings Privacy rules affecting story visibility; may be approximate for non-owned stories
//@content Content of the story //@content Content of the story
//@areas Clickable areas to be shown on the story content //@areas Clickable areas to be shown on the story content
//@caption Caption of the story //@caption Caption of the story
story id:int32 sender_chat_id:int53 date:int32 is_being_sent:Bool is_being_edited:Bool is_edited:Bool is_pinned:Bool is_visible_only_for_self:Bool can_be_deleted:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_replied:Bool can_toggle_is_pinned:Bool can_get_statistics:Bool can_get_viewers:Bool has_expired_viewers:Bool interaction_info:storyInteractionInfo chosen_reaction_type:ReactionType privacy_settings:StoryPrivacySettings content:StoryContent areas:vector<storyArea> caption:formattedText = Story; story id:int32 sender_chat_id:int53 date:int32 is_being_sent:Bool is_being_edited:Bool is_edited:Bool is_pinned:Bool is_visible_only_for_self:Bool can_be_deleted:Bool can_be_edited:Bool can_be_forwarded:Bool can_be_replied:Bool can_toggle_is_pinned:Bool can_get_statistics:Bool can_get_viewers:Bool has_expired_viewers:Bool repost_info:storyRepostInfo interaction_info:storyInteractionInfo chosen_reaction_type:ReactionType privacy_settings:StoryPrivacySettings content:StoryContent areas:vector<storyArea> caption:formattedText = Story;
//@description Represents a list of stories @total_count Approximate total number of stories found @stories The list of stories //@description Represents a list of stories @total_count Approximate total number of stories found @stories The list of stories
stories total_count:int32 stories:vector<story> = Stories; stories total_count:int32 stories:vector<story> = Stories;

View File

@ -0,0 +1,79 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include "td/telegram/StoryForwardInfo.h"
#include "td/telegram/ContactsManager.h"
#include "td/telegram/Dependencies.h"
#include "td/telegram/MessagesManager.h"
#include "td/telegram/Td.h"
#include "td/utils/logging.h"
namespace td {
StoryForwardInfo::StoryForwardInfo(Td *td, telegram_api::object_ptr<telegram_api::storyFwdHeader> &&fwd_header) {
CHECK(fwd_header != nullptr);
is_modified_ = fwd_header->modified_;
if (fwd_header->from_ != nullptr) {
dialog_id_ = DialogId(fwd_header->from_);
story_id_ = StoryId(fwd_header->story_id_);
if (!dialog_id_.is_valid() || !story_id_.is_server()) {
LOG(ERROR) << "Receive " << to_string(fwd_header);
dialog_id_ = {};
story_id_ = {};
} else {
td->messages_manager_->force_create_dialog(dialog_id_, "StoryForwardInfo", true);
}
} else if ((fwd_header->flags_ & telegram_api::storyFwdHeader::FROM_NAME_MASK) != 0) {
if (fwd_header->story_id_ != 0) {
LOG(ERROR) << "Receive " << to_string(fwd_header);
}
sender_name_ = std::move(fwd_header->from_name_);
} else {
LOG(ERROR) << "Receive " << to_string(fwd_header);
}
}
void StoryForwardInfo::hide_sender_if_needed(Td *td) {
if (dialog_id_.get_type() == DialogType::User) {
auto private_forward_name = td->contacts_manager_->get_user_private_forward_name(dialog_id_.get_user_id());
if (!private_forward_name.empty()) {
dialog_id_ = {};
story_id_ = {};
sender_name_ = std::move(private_forward_name);
}
}
}
void StoryForwardInfo::add_dependencies(Dependencies &dependencies) const {
// don't try to load original story
dependencies.add_dialog_and_dependencies(dialog_id_);
}
td_api::object_ptr<td_api::storyRepostInfo> StoryForwardInfo::get_story_repost_info_object(Td *td) const {
auto origin = [&]() -> td_api::object_ptr<td_api::StoryOrigin> {
if (dialog_id_.is_valid() && story_id_.is_valid()) {
return td_api::make_object<td_api::storyOriginPublicStory>(
td->messages_manager_->get_chat_id_object(dialog_id_, "storyOriginPublicStory"), story_id_.get());
}
return td_api::make_object<td_api::storyOriginHiddenUser>(sender_name_);
}();
return td_api::make_object<td_api::storyRepostInfo>(std::move(origin), is_modified_);
}
bool operator==(const unique_ptr<StoryForwardInfo> &lhs, const unique_ptr<StoryForwardInfo> &rhs) {
if (lhs == nullptr) {
return rhs == nullptr;
}
if (rhs == nullptr) {
return false;
}
return lhs->dialog_id_ == rhs->dialog_id_ && lhs->story_id_ == rhs->story_id_ &&
lhs->sender_name_ == rhs->sender_name_ && lhs->is_modified_ == rhs->is_modified_;
}
} // namespace td

View File

@ -0,0 +1,60 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/telegram/DialogId.h"
#include "td/telegram/StoryFullId.h"
#include "td/telegram/StoryId.h"
#include "td/telegram/td_api.h"
#include "td/telegram/telegram_api.h"
#include "td/utils/common.h"
#include <utility>
namespace td {
class Dependencies;
class Td;
class StoryForwardInfo {
DialogId dialog_id_;
StoryId story_id_;
string sender_name_;
bool is_modified_ = false;
friend bool operator==(const unique_ptr<StoryForwardInfo> &lhs, const unique_ptr<StoryForwardInfo> &rhs);
public:
StoryForwardInfo() = default;
StoryForwardInfo(Td *td, telegram_api::object_ptr<telegram_api::storyFwdHeader> &&fwd_header);
StoryForwardInfo(StoryFullId story_full_id, bool is_modified)
: dialog_id_(story_full_id.get_dialog_id()), story_id_(story_full_id.get_story_id()), is_modified_(is_modified) {
}
void hide_sender_if_needed(Td *td);
void add_dependencies(Dependencies &dependencies) const;
td_api::object_ptr<td_api::storyRepostInfo> get_story_repost_info_object(Td *td) const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
};
bool operator==(const unique_ptr<StoryForwardInfo> &lhs, const unique_ptr<StoryForwardInfo> &rhs);
inline bool operator!=(const unique_ptr<StoryForwardInfo> &lhs, const unique_ptr<StoryForwardInfo> &rhs) {
return !(lhs == rhs);
}
} // namespace td

View File

@ -0,0 +1,62 @@
//
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once
#include "td/telegram/StoryForwardInfo.h"
#include "td/utils/common.h"
#include "td/utils/tl_helpers.h"
namespace td {
template <class StorerT>
void StoryForwardInfo::store(StorerT &storer) const {
using td::store;
bool has_dialog_id = dialog_id_.is_valid();
bool has_story_id = story_id_.is_valid();
bool has_sender_name = !sender_name_.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_dialog_id);
STORE_FLAG(has_story_id);
STORE_FLAG(has_sender_name);
STORE_FLAG(is_modified_);
END_STORE_FLAGS();
if (has_dialog_id) {
store(dialog_id_, storer);
}
if (has_story_id) {
store(story_id_, storer);
}
if (has_sender_name) {
store(sender_name_, storer);
}
}
template <class ParserT>
void StoryForwardInfo::parse(ParserT &parser) {
using td::parse;
bool has_dialog_id;
bool has_story_id;
bool has_sender_name;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_dialog_id);
PARSE_FLAG(has_story_id);
PARSE_FLAG(has_sender_name);
PARSE_FLAG(is_modified_);
END_PARSE_FLAGS();
if (has_dialog_id) {
parse(dialog_id_, parser);
}
if (has_story_id) {
parse(story_id_, parser);
}
if (has_sender_name) {
parse(sender_name_, parser);
}
}
} // namespace td

View File

@ -27,6 +27,8 @@
#include "td/telegram/ReportReason.h" #include "td/telegram/ReportReason.h"
#include "td/telegram/StoryContent.h" #include "td/telegram/StoryContent.h"
#include "td/telegram/StoryContentType.h" #include "td/telegram/StoryContentType.h"
#include "td/telegram/StoryForwardInfo.h"
#include "td/telegram/StoryForwardInfo.hpp"
#include "td/telegram/StoryInteractionInfo.hpp" #include "td/telegram/StoryInteractionInfo.hpp"
#include "td/telegram/StoryStealthMode.hpp" #include "td/telegram/StoryStealthMode.hpp"
#include "td/telegram/StoryViewer.h" #include "td/telegram/StoryViewer.h"
@ -1057,6 +1059,7 @@ void StoryManager::Story::store(StorerT &storer) const {
bool has_caption = !caption_.text.empty(); bool has_caption = !caption_.text.empty();
bool has_areas = !areas_.empty(); bool has_areas = !areas_.empty();
bool has_chosen_reaction_type = !chosen_reaction_type_.is_empty(); bool has_chosen_reaction_type = !chosen_reaction_type_.is_empty();
bool has_forward_info = forward_info_ != nullptr;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(is_edited_); STORE_FLAG(is_edited_);
STORE_FLAG(is_pinned_); STORE_FLAG(is_pinned_);
@ -1073,6 +1076,7 @@ void StoryManager::Story::store(StorerT &storer) const {
STORE_FLAG(has_areas); STORE_FLAG(has_areas);
STORE_FLAG(has_chosen_reaction_type); STORE_FLAG(has_chosen_reaction_type);
STORE_FLAG(is_outgoing_); STORE_FLAG(is_outgoing_);
STORE_FLAG(has_forward_info);
END_STORE_FLAGS(); END_STORE_FLAGS();
store(date_, storer); store(date_, storer);
store(expire_date_, storer); store(expire_date_, storer);
@ -1097,6 +1101,9 @@ void StoryManager::Story::store(StorerT &storer) const {
if (has_chosen_reaction_type) { if (has_chosen_reaction_type) {
store(chosen_reaction_type_, storer); store(chosen_reaction_type_, storer);
} }
if (has_forward_info) {
store(forward_info_, storer);
}
} }
template <class ParserT> template <class ParserT>
@ -1109,6 +1116,7 @@ void StoryManager::Story::parse(ParserT &parser) {
bool has_caption; bool has_caption;
bool has_areas; bool has_areas;
bool has_chosen_reaction_type; bool has_chosen_reaction_type;
bool has_forward_info;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(is_edited_); PARSE_FLAG(is_edited_);
PARSE_FLAG(is_pinned_); PARSE_FLAG(is_pinned_);
@ -1125,6 +1133,7 @@ void StoryManager::Story::parse(ParserT &parser) {
PARSE_FLAG(has_areas); PARSE_FLAG(has_areas);
PARSE_FLAG(has_chosen_reaction_type); PARSE_FLAG(has_chosen_reaction_type);
PARSE_FLAG(is_outgoing_); PARSE_FLAG(is_outgoing_);
PARSE_FLAG(has_forward_info);
END_PARSE_FLAGS(); END_PARSE_FLAGS();
parse(date_, parser); parse(date_, parser);
parse(expire_date_, parser); parse(expire_date_, parser);
@ -1149,6 +1158,9 @@ void StoryManager::Story::parse(ParserT &parser) {
if (has_chosen_reaction_type) { if (has_chosen_reaction_type) {
parse(chosen_reaction_type_, parser); parse(chosen_reaction_type_, parser);
} }
if (has_forward_info) {
parse(forward_info_, parser);
}
} }
template <class StorerT> template <class StorerT>
@ -1804,6 +1816,9 @@ StoryManager::ActiveStories *StoryManager::on_get_active_stories_from_database(S
} }
void StoryManager::add_story_dependencies(Dependencies &dependencies, const Story *story) { void StoryManager::add_story_dependencies(Dependencies &dependencies, const Story *story) {
if (story->forward_info_ != nullptr) {
story->forward_info_->add_dependencies(dependencies);
}
story->interaction_info_.add_dependencies(dependencies); story->interaction_info_.add_dependencies(dependencies);
story->privacy_rules_.add_dependencies(dependencies); story->privacy_rules_.add_dependencies(dependencies);
if (story->content_ != nullptr) { if (story->content_ != nullptr) {
@ -3001,6 +3016,8 @@ td_api::object_ptr<td_api::story> StoryManager::get_story_object(StoryFullId sto
auto unix_time = G()->unix_time(); auto unix_time = G()->unix_time();
auto can_get_statistics = can_get_story_statistics(story_full_id, story); auto can_get_statistics = can_get_story_statistics(story_full_id, story);
auto can_get_viewers = can_get_story_viewers(story_full_id, story, unix_time).is_ok(); auto can_get_viewers = can_get_story_viewers(story_full_id, story, unix_time).is_ok();
auto repost_info =
story->forward_info_ != nullptr ? story->forward_info_->get_story_repost_info_object(td_) : nullptr;
auto interaction_info = story->interaction_info_.get_story_interaction_info_object(td_); auto interaction_info = story->interaction_info_.get_story_interaction_info_object(td_);
auto has_expired_viewers = is_my_story(owner_dialog_id) && story_id.is_server() && auto has_expired_viewers = is_my_story(owner_dialog_id) && story_id.is_server() &&
unix_time >= get_story_viewers_expire_date(story) && interaction_info != nullptr && unix_time >= get_story_viewers_expire_date(story) && interaction_info != nullptr &&
@ -3016,8 +3033,9 @@ td_api::object_ptr<td_api::story> StoryManager::get_story_object(StoryFullId sto
story_id.get(), td_->messages_manager_->get_chat_id_object(owner_dialog_id, "get_story_object"), story->date_, story_id.get(), td_->messages_manager_->get_chat_id_object(owner_dialog_id, "get_story_object"), story->date_,
is_being_sent, is_being_edited, is_edited, story->is_pinned_, is_visible_only_for_self, can_be_deleted, is_being_sent, is_being_edited, is_edited, story->is_pinned_, is_visible_only_for_self, can_be_deleted,
can_be_edited, can_be_forwarded, can_be_replied, can_toggle_is_pinned, can_get_statistics, can_get_viewers, can_be_edited, can_be_forwarded, can_be_replied, can_toggle_is_pinned, can_get_statistics, can_get_viewers,
has_expired_viewers, std::move(interaction_info), story->chosen_reaction_type_.get_reaction_type_object(), has_expired_viewers, std::move(repost_info), std::move(interaction_info),
std::move(privacy_settings), get_story_content_object(td_, content), std::move(story_areas), story->chosen_reaction_type_.get_reaction_type_object(), 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))); get_formatted_text_object(*caption, true, get_story_content_duration(td_, content)));
} }
@ -3241,6 +3259,12 @@ StoryId StoryManager::on_get_new_story(DialogId owner_dialog_id,
if (owner_dialog_id.get_type() == DialogType::User && !is_my_story(owner_dialog_id)) { if (owner_dialog_id.get_type() == DialogType::User && !is_my_story(owner_dialog_id)) {
story_item->min_ = false; story_item->min_ = false;
} }
unique_ptr<StoryForwardInfo> forward_info =
story_item->fwd_from_ != nullptr ? make_unique<StoryForwardInfo>(td_, std::move(story_item->fwd_from_)) : nullptr;
if (story->forward_info_ != forward_info) {
story->forward_info_ = std::move(forward_info);
is_changed = true;
}
if (!story_item->min_) { if (!story_item->min_) {
auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(story_item->privacy_)); 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_)); auto interaction_info = StoryInteractionInfo(td_, std::move(story_item->views_));

View File

@ -49,6 +49,7 @@ struct BinlogEvent;
class Dependencies; class Dependencies;
class ReportReason; class ReportReason;
class StoryContent; class StoryContent;
class StoryForwardInfo;
struct StoryDbStory; struct StoryDbStory;
class Td; class Td;
@ -66,6 +67,7 @@ class StoryManager final : public Actor {
bool is_outgoing_ = false; bool is_outgoing_ = false;
bool noforwards_ = false; bool noforwards_ = false;
mutable bool is_update_sent_ = false; // whether the story is known to the app mutable bool is_update_sent_ = false; // whether the story is known to the app
unique_ptr<StoryForwardInfo> forward_info_;
StoryInteractionInfo interaction_info_; StoryInteractionInfo interaction_info_;
ReactionType chosen_reaction_type_; ReactionType chosen_reaction_type_;
UserPrivacySettingRules privacy_rules_; UserPrivacySettingRules privacy_rules_;