Add td_api::StoryPrivacySettings.

This commit is contained in:
levlam 2023-07-18 16:00:06 +03:00
parent 689960ddcb
commit fc97956447
8 changed files with 146 additions and 50 deletions

View File

@ -4489,7 +4489,22 @@ jsonValueArray values:vector<JsonValue> = JsonValue;
jsonValueObject members:vector<jsonObjectMember> = JsonValue;
//@class UserPrivacySettingRule @description Represents a single rule for managing privacy settings
//@class StoryPrivacySettings @description Describes privacy settings of a story
//@description The story can be viewed by everyone
storyPrivacySettingsEveryone = StoryPrivacySettings;
//@description The story can be viewed by all contacts except chosen users @except_user_ids User identifiers of the contacts that can't see the story
storyPrivacySettingsContacts except_user_ids:vector<int53> = StoryPrivacySettings;
//@description The story can be viewed by all close friends
storyPrivacySettingsCloseFriends = StoryPrivacySettings;
//@description The story can be viewed by certain specified users @user_ids Identifiers of the users
storyPrivacySettingsSelectedContacts user_ids:vector<int53> = StoryPrivacySettings;
//@class UserPrivacySettingRule @description Represents a single rule for managing user privacy settings
//@description A rule to allow all users to do something
userPrivacySettingRuleAllowAll = UserPrivacySettingRule;
@ -4497,9 +4512,6 @@ userPrivacySettingRuleAllowAll = UserPrivacySettingRule;
//@description A rule to allow all contacts of the user to do something
userPrivacySettingRuleAllowContacts = UserPrivacySettingRule;
//@description A rule to allow all close friends of the user to do something
userPrivacySettingRuleAllowCloseFriends = UserPrivacySettingRule;
//@description A rule to allow certain specified users to do something @user_ids The user identifiers, total number of users in all rules must not exceed 1000
userPrivacySettingRuleAllowUsers user_ids:vector<int53> = UserPrivacySettingRule;
@ -4521,6 +4533,7 @@ userPrivacySettingRuleRestrictChatMembers chat_ids:vector<int53> = UserPrivacySe
//@description A list of privacy rules. Rules are matched in the specified order. The first matched rule defines the privacy setting for a given user. If no rule matches, the action is not allowed @rules A list of rules
userPrivacySettingRules rules:vector<UserPrivacySettingRule> = UserPrivacySettingRules;
//@class UserPrivacySetting @description Describes available user privacy settings
//@description A privacy setting for managing whether the user's online status is visible
@ -4955,10 +4968,10 @@ storyInteractionInfo view_count:int32 recent_viewer_user_ids:vector<int53> = Sto
//@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
//@interaction_info Information about interactions with the story; may be null if the story isn't owned or there were no interactions
//@privacy_rules Privacy rules affecting story visibility; may be null if the story isn't owned
//@privacy_settings Privacy rules affecting story visibility; may be null if the story isn't owned
//@content Content of the story
//@caption Caption of the story
story id:int32 sender_chat_id:int53 date:int32 is_being_edited:Bool is_edited:Bool is_pinned:Bool is_visible_only_for_self:Bool can_be_forwarded:Bool can_be_replied:Bool can_get_viewers:Bool has_expired_viewers:Bool interaction_info:storyInteractionInfo privacy_rules:userPrivacySettingRules content:StoryContent caption:formattedText = Story;
story id:int32 sender_chat_id:int53 date:int32 is_being_edited:Bool is_edited:Bool is_pinned:Bool is_visible_only_for_self:Bool can_be_forwarded:Bool can_be_replied:Bool can_get_viewers:Bool has_expired_viewers:Bool interaction_info:storyInteractionInfo privacy_settings:StoryPrivacySettings content:StoryContent caption:formattedText = Story;
//@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;
@ -7293,11 +7306,11 @@ getStory story_sender_chat_id:int53 story_id:int32 only_local:Bool = Story;
//@description Sends a new story. Returns a temporary story with identifier 0
//@content Content of the story
//@caption Story caption; pass null to use an empty caption; 0-getOption("story_caption_length_max") characters
//@privacy_rules The privacy rules for the story
//@privacy_settings The privacy settings for the story
//@active_period Period after which the story is moved to archive, in seconds; must be one of 6 * 3600, 12 * 3600, 86400, 2 * 86400, 3 * 86400, or 7 * 86400 for Telegram Premium users, and 86400 otherwise
//@is_pinned Pass true to keep the story accessible after expiration
//@protect_content Pass true if the content of the story must be protected from forwarding and screenshotting
sendStory content:InputStoryContent caption:formattedText privacy_rules:userPrivacySettingRules active_period:int32 is_pinned:Bool protect_content:Bool = Story;
sendStory content:InputStoryContent caption:formattedText privacy_settings:StoryPrivacySettings active_period:int32 is_pinned:Bool protect_content:Bool = Story;
//@description Changes content and caption of a previously sent story
//@story_id Identifier of the story to edit
@ -7305,8 +7318,8 @@ sendStory content:InputStoryContent caption:formattedText privacy_rules:userPriv
//@caption New story caption; pass null to keep the current caption
editStory story_id:int32 content:InputStoryContent caption:formattedText = Ok;
//@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 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;
//@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;

View File

@ -2273,16 +2273,13 @@ td_api::object_ptr<td_api::story> StoryManager::get_story_object(StoryFullId sto
return nullptr;
}
td_api::object_ptr<td_api::userPrivacySettingRules> privacy_rules;
if (story->is_public_ || story->is_for_close_friends_) {
privacy_rules = td_api::make_object<td_api::userPrivacySettingRules>();
if (story->is_public_) {
privacy_rules->rules_.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowAll>());
} else {
privacy_rules->rules_.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowCloseFriends>());
}
td_api::object_ptr<td_api::StoryPrivacySettings> privacy_settings;
if (story->is_public_) {
privacy_settings = td_api::make_object<td_api::storyPrivacySettingsEveryone>();
} else if (story->is_for_close_friends_) {
privacy_settings = td_api::make_object<td_api::storyPrivacySettingsCloseFriends>();
} else if (is_owned) {
privacy_rules = story->privacy_rules_.get_user_privacy_setting_rules_object(td_);
privacy_settings = story->privacy_rules_.get_story_privacy_settings_object(td_);
}
bool is_being_edited = false;
@ -2307,9 +2304,8 @@ td_api::object_ptr<td_api::story> StoryManager::get_story_object(StoryFullId sto
auto changelog_dialog_id = get_changelog_story_dialog_id();
bool is_visible_only_for_self =
!story_id.is_server() || dialog_id == changelog_dialog_id || (!story->is_pinned_ && !is_active_story(story));
bool can_be_forwarded = !story->noforwards_ && story_id.is_server() && privacy_rules != nullptr &&
privacy_rules->rules_.size() == 1u &&
privacy_rules->rules_[0]->get_id() == td_api::userPrivacySettingRuleAllowAll::ID;
bool can_be_forwarded = !story->noforwards_ && story_id.is_server() && privacy_settings != nullptr &&
privacy_settings->get_id() == td_api::storyPrivacySettingsEveryone::ID;
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();
@ -2320,7 +2316,7 @@ td_api::object_ptr<td_api::story> 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_rules), get_story_content_object(td_, content),
std::move(privacy_settings), get_story_content_object(td_, content),
get_formatted_text_object(*caption, true, get_story_content_duration(td_, content)));
}
@ -3286,7 +3282,7 @@ void StoryManager::do_get_story(StoryFullId story_full_id, Result<Unit> &&result
void StoryManager::send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content,
td_api::object_ptr<td_api::formattedText> &&input_caption,
td_api::object_ptr<td_api::userPrivacySettingRules> &&rules, int32 active_period,
td_api::object_ptr<td_api::StoryPrivacySettings> &&settings, int32 active_period,
bool is_pinned, bool protect_content,
Promise<td_api::object_ptr<td_api::story>> &&promise) {
bool is_bot = td_->auth_manager_->is_bot();
@ -3295,7 +3291,7 @@ void StoryManager::send_story(td_api::object_ptr<td_api::InputStoryContent> &&in
TRY_RESULT_PROMISE(promise, caption,
get_formatted_text(td_, DialogId(), std::move(input_caption), is_bot, true, false, false));
TRY_RESULT_PROMISE(promise, privacy_rules,
UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(rules)));
UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(settings)));
if (active_period != 86400 && !(G()->is_test_dc() && (active_period == 60 || active_period == 300))) {
bool is_premium = td_->option_manager_->get_option_boolean("is_premium");
if (!is_premium ||
@ -3659,16 +3655,16 @@ void StoryManager::delete_pending_story(FileId file_id, unique_ptr<PendingStory>
}
}
void StoryManager::set_story_privacy_rules(StoryId story_id,
td_api::object_ptr<td_api::userPrivacySettingRules> &&rules,
Promise<Unit> &&promise) {
void StoryManager::set_story_privacy_settings(StoryId story_id,
td_api::object_ptr<td_api::StoryPrivacySettings> &&settings,
Promise<Unit> &&promise) {
DialogId dialog_id(td_->contacts_manager_->get_my_id());
const Story *story = get_story({dialog_id, story_id});
if (story == nullptr || story->content_ == nullptr) {
return promise.set_error(Status::Error(400, "Story not found"));
}
TRY_RESULT_PROMISE(promise, privacy_rules,
UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(rules)));
UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(settings)));
td_->create_handler<EditStoryPrivacyQuery>(std::move(promise))->send(dialog_id, story_id, std::move(privacy_rules));
}

View File

@ -195,7 +195,7 @@ class StoryManager final : public Actor {
void send_story(td_api::object_ptr<td_api::InputStoryContent> &&input_story_content,
td_api::object_ptr<td_api::formattedText> &&input_caption,
td_api::object_ptr<td_api::userPrivacySettingRules> &&rules, int32 active_period, bool is_pinned,
td_api::object_ptr<td_api::StoryPrivacySettings> &&settings, int32 active_period, bool is_pinned,
bool protect_content, Promise<td_api::object_ptr<td_api::story>> &&promise);
void on_send_story_file_parts_missing(unique_ptr<PendingStory> &&pending_story, vector<int> &&bad_parts);
@ -203,8 +203,8 @@ class StoryManager final : public Actor {
void edit_story(StoryId story_id, td_api::object_ptr<td_api::InputStoryContent> &&input_story_content,
td_api::object_ptr<td_api::formattedText> &&input_caption, Promise<Unit> &&promise);
void set_story_privacy_rules(StoryId story_id, td_api::object_ptr<td_api::userPrivacySettingRules> &&rules,
Promise<Unit> &&promise);
void set_story_privacy_settings(StoryId story_id, td_api::object_ptr<td_api::StoryPrivacySettings> &&settings,
Promise<Unit> &&promise);
void toggle_story_is_pinned(StoryId story_id, bool is_pinned, Promise<Unit> &&promise);

View File

@ -5635,7 +5635,7 @@ void Td::on_request(uint64 id, td_api::sendStory &request) {
CHECK_IS_USER();
CREATE_REQUEST_PROMISE();
story_manager_->send_story(std::move(request.content_), std::move(request.caption_),
std::move(request.privacy_rules_), request.active_period_, request.is_pinned_,
std::move(request.privacy_settings_), request.active_period_, request.is_pinned_,
request.protect_content_, std::move(promise));
}
@ -5646,11 +5646,11 @@ void Td::on_request(uint64 id, td_api::editStory &request) {
std::move(promise));
}
void Td::on_request(uint64 id, td_api::setStoryPrivacyRules &request) {
void Td::on_request(uint64 id, td_api::setStoryPrivacySettings &request) {
CHECK_IS_USER();
CREATE_OK_REQUEST_PROMISE();
story_manager_->set_story_privacy_rules(StoryId(request.story_id_), std::move(request.privacy_rules_),
std::move(promise));
story_manager_->set_story_privacy_settings(StoryId(request.story_id_), std::move(request.privacy_settings_),
std::move(promise));
}
void Td::on_request(uint64 id, const td_api::toggleStoryIsPinned &request) {

View File

@ -792,7 +792,7 @@ class Td final : public Actor {
void on_request(uint64 id, td_api::editStory &request);
void on_request(uint64 id, td_api::setStoryPrivacyRules &request);
void on_request(uint64 id, td_api::setStoryPrivacySettings &request);
void on_request(uint64 id, const td_api::toggleStoryIsPinned &request);

View File

@ -53,9 +53,6 @@ UserPrivacySettingRule::UserPrivacySettingRule(Td *td, const td_api::UserPrivacy
case td_api::userPrivacySettingRuleAllowContacts::ID:
type_ = Type::AllowContacts;
break;
case td_api::userPrivacySettingRuleAllowCloseFriends::ID:
type_ = Type::AllowCloseFriends;
break;
case td_api::userPrivacySettingRuleAllowAll::ID:
type_ = Type::AllowAll;
break;
@ -160,7 +157,8 @@ td_api::object_ptr<td_api::UserPrivacySettingRule> UserPrivacySettingRule::get_u
case Type::AllowContacts:
return make_tl_object<td_api::userPrivacySettingRuleAllowContacts>();
case Type::AllowCloseFriends:
return make_tl_object<td_api::userPrivacySettingRuleAllowCloseFriends>();
LOG(ERROR) << "Have AllowCloseFriends rule";
return make_tl_object<td_api::userPrivacySettingRuleAllowUsers>();
case Type::AllowAll:
return make_tl_object<td_api::userPrivacySettingRuleAllowAll>();
case Type::AllowUsers:
@ -269,8 +267,7 @@ UserPrivacySettingRules UserPrivacySettingRules::get_user_privacy_setting_rules(
for (auto &rule : rules) {
result.rules_.push_back(UserPrivacySettingRule(td, std::move(rule)));
}
if (!result.rules_.empty() && result.rules_.back().get_user_privacy_setting_rule_object(td)->get_id() ==
td_api::userPrivacySettingRuleRestrictAll::ID) {
if (!result.rules_.empty() && result.rules_.back().type_ == UserPrivacySettingRule::Type::RestrictAll) {
result.rules_.pop_back();
}
return result;
@ -291,12 +288,70 @@ Result<UserPrivacySettingRules> UserPrivacySettingRules::get_user_privacy_settin
return result;
}
Result<UserPrivacySettingRules> UserPrivacySettingRules::get_user_privacy_setting_rules(
Td *td, td_api::object_ptr<td_api::StoryPrivacySettings> settings) {
if (settings == nullptr) {
return Status::Error(400, "StoryPrivacySettings must be non-empty");
}
UserPrivacySettingRules result;
switch (settings->get_id()) {
case td_api::storyPrivacySettingsEveryone::ID:
result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowAll());
break;
case td_api::storyPrivacySettingsContacts::ID: {
auto user_ids = std::move(static_cast<td_api::storyPrivacySettingsContacts &>(*settings).except_user_ids_);
if (!user_ids.empty()) {
result.rules_.emplace_back(td, td_api::userPrivacySettingRuleRestrictUsers(std::move(user_ids)));
}
result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowContacts());
break;
}
case td_api::storyPrivacySettingsCloseFriends::ID: {
UserPrivacySettingRule rule;
rule.type_ = UserPrivacySettingRule::Type::AllowCloseFriends;
result.rules_.push_back(std::move(rule));
break;
}
case td_api::storyPrivacySettingsSelectedContacts::ID: {
auto user_ids = std::move(static_cast<td_api::storyPrivacySettingsSelectedContacts &>(*settings).user_ids_);
result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowUsers(std::move(user_ids)));
break;
}
default:
UNREACHABLE();
}
return result;
}
td_api::object_ptr<td_api::userPrivacySettingRules> UserPrivacySettingRules::get_user_privacy_setting_rules_object(
Td *td) const {
return make_tl_object<td_api::userPrivacySettingRules>(
transform(rules_, [td](const auto &rule) { return rule.get_user_privacy_setting_rule_object(td); }));
}
td_api::object_ptr<td_api::StoryPrivacySettings> UserPrivacySettingRules::get_story_privacy_settings_object(
Td *td) const {
if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowAll) {
return td_api::make_object<td_api::storyPrivacySettingsEveryone>();
}
if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowContacts) {
return td_api::make_object<td_api::storyPrivacySettingsContacts>();
}
if (rules_.size() == 2u && rules_[0].type_ == UserPrivacySettingRule::Type::RestrictUsers &&
rules_[1].type_ == UserPrivacySettingRule::Type::AllowContacts) {
return td_api::make_object<td_api::storyPrivacySettingsContacts>(
td->contacts_manager_->get_user_ids_object(rules_[0].user_ids_, "storyPrivacySettingsContacts"));
}
if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowCloseFriends) {
return td_api::make_object<td_api::storyPrivacySettingsCloseFriends>();
}
if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowUsers) {
return td_api::make_object<td_api::storyPrivacySettingsSelectedContacts>(
td->contacts_manager_->get_user_ids_object(rules_[0].user_ids_, "storyPrivacySettingsSelectedContacts"));
}
return td_api::make_object<td_api::storyPrivacySettingsSelectedContacts>();
}
vector<telegram_api::object_ptr<telegram_api::InputPrivacyRule>> UserPrivacySettingRules::get_input_privacy_rules(
Td *td) const {
auto result = transform(rules_, [td](const auto &rule) { return rule.get_input_privacy_rule(td); });

View File

@ -88,6 +88,8 @@ class UserPrivacySettingRule {
RestrictChatParticipants
} type_ = Type::RestrictAll;
friend class UserPrivacySettingRules;
vector<UserId> user_ids_;
vector<DialogId> dialog_ids_;
@ -113,8 +115,13 @@ class UserPrivacySettingRules {
static Result<UserPrivacySettingRules> get_user_privacy_setting_rules(
Td *td, td_api::object_ptr<td_api::userPrivacySettingRules> rules);
static Result<UserPrivacySettingRules> get_user_privacy_setting_rules(
Td *td, td_api::object_ptr<td_api::StoryPrivacySettings> settings);
td_api::object_ptr<td_api::userPrivacySettingRules> get_user_privacy_setting_rules_object(Td *td) const;
td_api::object_ptr<td_api::StoryPrivacySettings> get_story_privacy_settings_object(Td *td) const;
vector<telegram_api::object_ptr<telegram_api::InputPrivacyRule>> get_input_privacy_rules(Td *td) const;
bool operator==(const UserPrivacySettingRules &other) const {

View File

@ -1127,8 +1127,6 @@ class CliClient final : public Actor {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowContacts>());
} else if (rules_str[i] == 'C') {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleRestrictContacts>());
} else if (rules_str[i] == 'f') {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowCloseFriends>());
} else if (rules_str[i] == 'u') {
rules.push_back(td_api::make_object<td_api::userPrivacySettingRuleAllowUsers>(std::move(arg)));
} else if (rules_str[i] == 'U') {
@ -1153,6 +1151,33 @@ class CliClient final : public Actor {
}
}
struct StoryPrivacySettings {
string settings;
operator td_api::object_ptr<td_api::StoryPrivacySettings>() const {
if (settings == "a" || settings == "e") {
return td_api::make_object<td_api::storyPrivacySettingsEveryone>();
}
if (settings == "f" || settings == "cf") {
return td_api::make_object<td_api::storyPrivacySettingsCloseFriends>();
}
if (!settings.empty()) {
auto user_ids = to_integers<int64>(Slice(settings).substr(1));
if (settings[0] == 'c') {
return td_api::make_object<td_api::storyPrivacySettingsContacts>(std::move(user_ids));
}
if (settings[0] == 'u') {
return td_api::make_object<td_api::storyPrivacySettingsSelectedContacts>(std::move(user_ids));
}
}
return td_api::make_object<td_api::storyPrivacySettingsContacts>();
}
};
void get_args(string &args, StoryPrivacySettings &arg) const {
arg.settings = trim(args);
}
template <class FirstType, class SecondType, class... Types>
void get_args(string &args, FirstType &first_arg, SecondType &second_arg, Types &...other_args) const {
string arg;
@ -3990,7 +4015,7 @@ class CliClient final : public Actor {
} else if (op == "ssp" || op == "sspp") {
string photo;
string caption;
PrivacyRules rules;
StoryPrivacySettings rules;
int32 active_period;
string sticker_file_ids;
bool protect_content;
@ -4002,7 +4027,7 @@ class CliClient final : public Actor {
} else if (op == "ssv" || op == "ssvp") {
string video;
string caption;
PrivacyRules rules;
StoryPrivacySettings rules;
int32 active_period;
double duration;
string sticker_file_ids;
@ -4040,11 +4065,11 @@ class CliClient final : public Actor {
td_api::make_object<td_api::inputStoryContentVideo>(as_input_file(video),
to_integers<int32>(sticker_file_ids), duration, false),
as_caption(caption)));
} else if (op == "sspr") {
} else if (op == "ssps") {
StoryId story_id;
PrivacyRules rules;
StoryPrivacySettings rules;
get_args(args, story_id, rules);
send_request(td_api::make_object<td_api::setStoryPrivacyRules>(story_id, rules));
send_request(td_api::make_object<td_api::setStoryPrivacySettings>(story_id, rules));
} else if (op == "tsip") {
StoryId story_id;
bool is_pinned;