Add chatMemberStatusMember.member_until_date.

This commit is contained in:
levlam 2024-07-30 09:25:10 +03:00
parent d3e95a5e85
commit 815d6fd0eb
5 changed files with 53 additions and 48 deletions

View File

@ -1132,7 +1132,8 @@ chatMemberStatusCreator custom_title:string is_anonymous:Bool is_member:Bool = C
chatMemberStatusAdministrator custom_title:string can_be_edited:Bool rights:chatAdministratorRights = ChatMemberStatus; chatMemberStatusAdministrator custom_title:string can_be_edited:Bool rights:chatAdministratorRights = ChatMemberStatus;
//@description The user is a member of the chat, without any additional privileges or restrictions //@description The user is a member of the chat, without any additional privileges or restrictions
chatMemberStatusMember = ChatMemberStatus; //@member_until_date Point in time (Unix timestamp) when the user will be removed from the chat because of the expired subscription; 0 if never. Ignored in setChatMemberStatus
chatMemberStatusMember member_until_date:int32 = ChatMemberStatus;
//@description The user is under certain restrictions in the chat. Not supported in basic groups and channels //@description The user is under certain restrictions in the chat. Not supported in basic groups and channels
//@is_member True, if the user is a member of the chat //@is_member True, if the user is a member of the chat

View File

@ -1811,7 +1811,7 @@ void ChatManager::Chat::parse(ParserT &parser) {
} else if (is_administrator && !everyone_is_administrator) { } else if (is_administrator && !everyone_is_administrator) {
status = DialogParticipantStatus::GroupAdministrator(false); status = DialogParticipantStatus::GroupAdministrator(false);
} else { } else {
status = DialogParticipantStatus::Member(); status = DialogParticipantStatus::Member(0);
} }
default_permissions = RestrictedRights(true, true, true, true, true, true, true, true, true, true, true, true, true, default_permissions = RestrictedRights(true, true, true, true, true, true, true, true, true, true, true, true, true,
everyone_is_administrator, everyone_is_administrator, everyone_is_administrator, everyone_is_administrator,
@ -2118,7 +2118,7 @@ void ChatManager::Channel::parse(ParserT &parser) {
} else if (can_edit || can_moderate) { } else if (can_edit || can_moderate) {
status = DialogParticipantStatus::ChannelAdministrator(false, is_megagroup); status = DialogParticipantStatus::ChannelAdministrator(false, is_megagroup);
} else { } else {
status = DialogParticipantStatus::Member(); status = DialogParticipantStatus::Member(0);
} }
} }
parse(access_hash, parser); parse(access_hash, parser);
@ -2199,7 +2199,7 @@ void ChatManager::Channel::parse(ParserT &parser) {
} }
if (!is_megagroup && status.is_restricted()) { if (!is_megagroup && status.is_restricted()) {
if (status.is_member()) { if (status.is_member()) {
status = DialogParticipantStatus::Member(); status = DialogParticipantStatus::Member(0);
} else { } else {
status = DialogParticipantStatus::Left(); status = DialogParticipantStatus::Left();
} }
@ -6324,7 +6324,7 @@ void ChatManager::on_update_chat_add_user(ChatId chat_id, UserId inviter_user_id
chat_full->participants.push_back(DialogParticipant{DialogId(user_id), inviter_user_id, date, chat_full->participants.push_back(DialogParticipant{DialogId(user_id), inviter_user_id, date,
user_id == chat_full->creator_user_id user_id == chat_full->creator_user_id
? DialogParticipantStatus::Creator(true, false, string()) ? DialogParticipantStatus::Creator(true, false, string())
: DialogParticipantStatus::Member()}); : DialogParticipantStatus::Member(0)});
update_chat_online_member_count(chat_full, chat_id, false); update_chat_online_member_count(chat_full, chat_id, false);
chat_full->is_changed = true; chat_full->is_changed = true;
update_chat_full(chat_full, chat_id, "on_update_chat_add_user"); update_chat_full(chat_full, chat_id, "on_update_chat_add_user");
@ -6373,7 +6373,7 @@ void ChatManager::on_update_chat_edit_administrator(ChatId chat_id, UserId user_
CHECK(c->version >= 0); CHECK(c->version >= 0);
auto status = is_administrator ? DialogParticipantStatus::GroupAdministrator(c->status.is_creator()) auto status = is_administrator ? DialogParticipantStatus::GroupAdministrator(c->status.is_creator())
: DialogParticipantStatus::Member(); : DialogParticipantStatus::Member(0);
if (version > c->version) { if (version > c->version) {
if (version != c->version + 1) { if (version != c->version + 1) {
LOG(INFO) << "Administrators of " << chat_id << " with version " << c->version LOG(INFO) << "Administrators of " << chat_id << " with version " << c->version
@ -8223,7 +8223,7 @@ void ChatManager::on_get_chat(telegram_api::chat &chat, const char *source) {
} else if (has_left) { } else if (has_left) {
return DialogParticipantStatus::Left(); return DialogParticipantStatus::Left();
} else { } else {
return DialogParticipantStatus::Member(); return DialogParticipantStatus::Member(0);
} }
}(); }();
@ -8401,27 +8401,6 @@ void ChatManager::on_get_channel(telegram_api::channel &channel, const char *sou
SuggestedAction{SuggestedAction::Type::ConvertToGigagroup, DialogId(channel_id)}); SuggestedAction{SuggestedAction::Type::ConvertToGigagroup, DialogId(channel_id)});
} }
DialogParticipantStatus status = [&] {
bool has_left = (channel.flags_ & CHANNEL_FLAG_USER_HAS_LEFT) != 0;
bool is_creator = (channel.flags_ & CHANNEL_FLAG_USER_IS_CREATOR) != 0;
if (is_creator) {
bool is_anonymous = channel.admin_rights_ != nullptr &&
(channel.admin_rights_->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0;
return DialogParticipantStatus::Creator(!has_left, is_anonymous, string());
} else if (channel.admin_rights_ != nullptr) {
return DialogParticipantStatus(false, std::move(channel.admin_rights_), string(),
is_megagroup ? ChannelType::Megagroup : ChannelType::Broadcast);
} else if (channel.banned_rights_ != nullptr) {
return DialogParticipantStatus(!has_left, std::move(channel.banned_rights_),
is_megagroup ? ChannelType::Megagroup : ChannelType::Broadcast);
} else if (has_left) {
return DialogParticipantStatus::Left();
} else {
return DialogParticipantStatus::Member();
}
}();
if (is_min) { if (is_min) {
Channel *c = get_channel_force(channel_id, source); Channel *c = get_channel_force(channel_id, source);
if (c != nullptr) { if (c != nullptr) {
@ -8507,6 +8486,26 @@ void ChatManager::on_get_channel(telegram_api::channel &channel, const char *sou
return; return;
} }
DialogParticipantStatus status = [&] {
bool has_left = (channel.flags_ & CHANNEL_FLAG_USER_HAS_LEFT) != 0;
bool is_creator = (channel.flags_ & CHANNEL_FLAG_USER_IS_CREATOR) != 0;
if (is_creator) {
bool is_anonymous = channel.admin_rights_ != nullptr &&
(channel.admin_rights_->flags_ & telegram_api::chatAdminRights::ANONYMOUS_MASK) != 0;
return DialogParticipantStatus::Creator(!has_left, is_anonymous, string());
} else if (channel.admin_rights_ != nullptr) {
return DialogParticipantStatus(false, std::move(channel.admin_rights_), string(),
is_megagroup ? ChannelType::Megagroup : ChannelType::Broadcast);
} else if (channel.banned_rights_ != nullptr) {
return DialogParticipantStatus(!has_left, std::move(channel.banned_rights_),
is_megagroup ? ChannelType::Megagroup : ChannelType::Broadcast);
} else if (has_left) {
return DialogParticipantStatus::Left();
} else {
return DialogParticipantStatus::Member(channel.subscription_until_date_);
}
}();
if (status.is_creator()) { if (status.is_creator()) {
// to correctly calculate is_ownership_transferred in on_update_channel_status // to correctly calculate is_ownership_transferred in on_update_channel_status
get_channel_force(channel_id, source); get_channel_force(channel_id, source);

View File

@ -433,7 +433,7 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(AdministratorRigh
bool can_be_edited) { bool can_be_edited) {
uint64 flags = administrator_rights.flags_; uint64 flags = administrator_rights.flags_;
if (flags == 0) { if (flags == 0) {
return Member(); return Member(0);
} }
flags = flags | (static_cast<uint64>(can_be_edited) * CAN_BE_EDITED); flags = flags | (static_cast<uint64>(can_be_edited) * CAN_BE_EDITED);
return DialogParticipantStatus( return DialogParticipantStatus(
@ -442,15 +442,16 @@ DialogParticipantStatus DialogParticipantStatus::Administrator(AdministratorRigh
std::move(rank)); std::move(rank));
} }
DialogParticipantStatus DialogParticipantStatus::Member() { DialogParticipantStatus DialogParticipantStatus::Member(int32 member_until_date) {
return DialogParticipantStatus(Type::Member, IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS, 0, string()); return DialogParticipantStatus(Type::Member, IS_MEMBER | RestrictedRights::ALL_RESTRICTED_RIGHTS, member_until_date,
string());
} }
DialogParticipantStatus DialogParticipantStatus::Restricted(RestrictedRights restricted_rights, bool is_member, DialogParticipantStatus DialogParticipantStatus::Restricted(RestrictedRights restricted_rights, bool is_member,
int32 restricted_until_date, ChannelType channel_type) { int32 restricted_until_date, ChannelType channel_type) {
uint64 flags = restricted_rights.flags_; uint64 flags = restricted_rights.flags_;
if (flags == RestrictedRights::ALL_RESTRICTED_RIGHTS || channel_type == ChannelType::Broadcast) { if (flags == RestrictedRights::ALL_RESTRICTED_RIGHTS || channel_type == ChannelType::Broadcast) {
return is_member ? Member() : Left(); return is_member ? Member(0) : Left();
} }
flags |= (static_cast<uint64>(is_member) * IS_MEMBER); flags |= (static_cast<uint64>(is_member) * IS_MEMBER);
return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string()); return DialogParticipantStatus(Type::Restricted, flags, fix_until_date(restricted_until_date), string());
@ -494,7 +495,7 @@ DialogParticipantStatus::DialogParticipantStatus(bool is_member,
return; return;
} }
if (channel_type == ChannelType::Broadcast) { if (channel_type == ChannelType::Broadcast) {
*this = is_member ? Member() : Left(); *this = is_member ? Member(0) : Left();
return; return;
} }
@ -522,7 +523,7 @@ tl_object_ptr<td_api::ChatMemberStatus> DialogParticipantStatus::get_chat_member
return td_api::make_object<td_api::chatMemberStatusAdministrator>( return td_api::make_object<td_api::chatMemberStatusAdministrator>(
rank_, can_be_edited(), get_administrator_rights().get_chat_administrator_rights_object()); rank_, can_be_edited(), get_administrator_rights().get_chat_administrator_rights_object());
case Type::Member: case Type::Member:
return td_api::make_object<td_api::chatMemberStatusMember>(); return td_api::make_object<td_api::chatMemberStatusMember>(until_date_);
case Type::Restricted: case Type::Restricted:
return td_api::make_object<td_api::chatMemberStatusRestricted>( return td_api::make_object<td_api::chatMemberStatusRestricted>(
is_member(), until_date_, get_restricted_rights().get_chat_permissions_object()); is_member(), until_date_, get_restricted_rights().get_chat_permissions_object());
@ -596,7 +597,7 @@ void DialogParticipantStatus::update_restrictions() const {
type_ = Type::Left; type_ = Type::Left;
} }
flags_ |= RestrictedRights::ALL_RESTRICTED_RIGHTS; flags_ |= RestrictedRights::ALL_RESTRICTED_RIGHTS;
} else if (type_ == Type::Banned) { } else if (type_ == Type::Banned || type_ == Type::Member) {
type_ = Type::Left; type_ = Type::Left;
} else { } else {
UNREACHABLE(); UNREACHABLE();
@ -637,7 +638,11 @@ StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant
} }
return string_builder; return string_builder;
case DialogParticipantStatus::Type::Member: case DialogParticipantStatus::Type::Member:
return string_builder << "Member"; string_builder << "Member";
if (status.until_date_ != 0) {
string_builder << " until " << status.until_date_;
}
return string_builder;
case DialogParticipantStatus::Type::Restricted: case DialogParticipantStatus::Type::Restricted:
string_builder << status.get_restricted_rights(); string_builder << status.get_restricted_rights();
if (status.until_date_ == 0) { if (status.until_date_ == 0) {
@ -702,7 +707,7 @@ DialogParticipantStatus get_dialog_participant_status(const td_api::object_ptr<t
std::move(custom_title), true /*st->can_be_edited_*/); std::move(custom_title), true /*st->can_be_edited_*/);
} }
case td_api::chatMemberStatusMember::ID: case td_api::chatMemberStatusMember::ID:
return DialogParticipantStatus::Member(); return DialogParticipantStatus::Member(0);
case td_api::chatMemberStatusRestricted::ID: { case td_api::chatMemberStatusRestricted::ID: {
auto st = static_cast<const td_api::chatMemberStatusRestricted *>(status.get()); auto st = static_cast<const td_api::chatMemberStatusRestricted *>(status.get());
return DialogParticipantStatus::Restricted(RestrictedRights(st->permissions_, channel_type), st->is_member_, return DialogParticipantStatus::Restricted(RestrictedRights(st->permissions_, channel_type), st->is_member_,
@ -716,7 +721,7 @@ DialogParticipantStatus get_dialog_participant_status(const td_api::object_ptr<t
} }
default: default:
UNREACHABLE(); UNREACHABLE();
return DialogParticipantStatus::Member(); return DialogParticipantStatus::Member(0);
} }
} }
@ -739,7 +744,7 @@ DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChatParticipant
case telegram_api::chatParticipant::ID: { case telegram_api::chatParticipant::ID: {
auto participant = move_tl_object_as<telegram_api::chatParticipant>(participant_ptr); auto participant = move_tl_object_as<telegram_api::chatParticipant>(participant_ptr);
*this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_, *this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_,
DialogParticipantStatus::Member()}; DialogParticipantStatus::Member(0)};
break; break;
} }
case telegram_api::chatParticipantCreator::ID: { case telegram_api::chatParticipantCreator::ID: {
@ -767,13 +772,13 @@ DialogParticipant::DialogParticipant(tl_object_ptr<telegram_api::ChannelParticip
case telegram_api::channelParticipant::ID: { case telegram_api::channelParticipant::ID: {
auto participant = move_tl_object_as<telegram_api::channelParticipant>(participant_ptr); auto participant = move_tl_object_as<telegram_api::channelParticipant>(participant_ptr);
*this = {DialogId(UserId(participant->user_id_)), UserId(), participant->date_, *this = {DialogId(UserId(participant->user_id_)), UserId(), participant->date_,
DialogParticipantStatus::Member()}; DialogParticipantStatus::Member(participant->subscription_until_date_)};
break; break;
} }
case telegram_api::channelParticipantSelf::ID: { case telegram_api::channelParticipantSelf::ID: {
auto participant = move_tl_object_as<telegram_api::channelParticipantSelf>(participant_ptr); auto participant = move_tl_object_as<telegram_api::channelParticipantSelf>(participant_ptr);
*this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_, *this = {DialogId(UserId(participant->user_id_)), UserId(participant->inviter_id_), participant->date_,
DialogParticipantStatus::Member()}; DialogParticipantStatus::Member(participant->subscription_until_date_)};
break; break;
} }
case telegram_api::channelParticipantCreator::ID: { case telegram_api::channelParticipantCreator::ID: {

View File

@ -321,7 +321,7 @@ class DialogParticipantStatus {
enum class Type : int32 { Creator, Administrator, Member, Restricted, Left, Banned }; enum class Type : int32 { Creator, Administrator, Member, Restricted, Left, Banned };
// all fields are logically const, but should be updated in update_restrictions() // all fields are logically const, but should be updated in update_restrictions()
mutable Type type_; mutable Type type_;
mutable int32 until_date_; // restricted and banned only mutable int32 until_date_; // member, restricted and banned only
mutable uint64 flags_; mutable uint64 flags_;
string rank_; // creator and administrator only string rank_; // creator and administrator only
@ -343,7 +343,7 @@ class DialogParticipantStatus {
static DialogParticipantStatus Administrator(AdministratorRights administrator_rights, string &&rank, static DialogParticipantStatus Administrator(AdministratorRights administrator_rights, string &&rank,
bool can_be_edited); bool can_be_edited);
static DialogParticipantStatus Member(); static DialogParticipantStatus Member(int32 member_until_date);
static DialogParticipantStatus Restricted(RestrictedRights restricted_rights, bool is_member, static DialogParticipantStatus Restricted(RestrictedRights restricted_rights, bool is_member,
int32 restricted_until_date, ChannelType channel_type); int32 restricted_until_date, ChannelType channel_type);
@ -655,7 +655,7 @@ struct DialogParticipant {
static DialogParticipant private_member(UserId user_id, UserId other_user_id) { static DialogParticipant private_member(UserId user_id, UserId other_user_id) {
auto inviter_user_id = other_user_id.is_valid() ? other_user_id : user_id; auto inviter_user_id = other_user_id.is_valid() ? other_user_id : user_id;
return {DialogId(user_id), inviter_user_id, 0, DialogParticipantStatus::Member()}; return {DialogId(user_id), inviter_user_id, 0, DialogParticipantStatus::Member(0)};
} }
bool is_valid() const; bool is_valid() const;

View File

@ -1383,7 +1383,7 @@ void DialogParticipantManager::on_update_bot_stopped(UserId user_id, int32 date,
} }
DialogParticipant old_dialog_participant(DialogId(my_user_id), user_id, date, DialogParticipantStatus::Banned(0)); DialogParticipant old_dialog_participant(DialogId(my_user_id), user_id, date, DialogParticipantStatus::Banned(0));
DialogParticipant new_dialog_participant(DialogId(my_user_id), user_id, date, DialogParticipantStatus::Member()); DialogParticipant new_dialog_participant(DialogId(my_user_id), user_id, date, DialogParticipantStatus::Member(0));
if (is_stopped) { if (is_stopped) {
std::swap(old_dialog_participant.status_, new_dialog_participant.status_); std::swap(old_dialog_participant.status_, new_dialog_participant.status_);
} }
@ -2341,7 +2341,7 @@ void DialogParticipantManager::add_channel_participant(
return promise.set_error(Status::Error(400, "Not enough rights to invite members to the supergroup chat")); return promise.set_error(Status::Error(400, "Not enough rights to invite members to the supergroup chat"));
} }
speculative_add_channel_user(channel_id, user_id, DialogParticipantStatus::Member(), old_status); speculative_add_channel_user(channel_id, user_id, DialogParticipantStatus::Member(0), old_status);
vector<tl_object_ptr<telegram_api::InputUser>> input_users; vector<tl_object_ptr<telegram_api::InputUser>> input_users;
input_users.push_back(std::move(input_user)); input_users.push_back(std::move(input_user));
td_->create_handler<InviteToChannelQuery>(std::move(promise))->send(channel_id, {user_id}, std::move(input_users)); td_->create_handler<InviteToChannelQuery>(std::move(promise))->send(channel_id, {user_id}, std::move(input_users));
@ -2395,7 +2395,7 @@ void DialogParticipantManager::add_channel_participants(
} }
input_users.push_back(std::move(input_user)); input_users.push_back(std::move(input_user));
speculative_add_channel_user(channel_id, user_id, DialogParticipantStatus::Member(), speculative_add_channel_user(channel_id, user_id, DialogParticipantStatus::Member(0),
DialogParticipantStatus::Left()); DialogParticipantStatus::Left());
} }
@ -2837,7 +2837,7 @@ void DialogParticipantManager::add_cached_channel_participants(ChannelId channel
} }
if (!is_found) { if (!is_found) {
is_participants_cache_changed = true; is_participants_cache_changed = true;
participants.emplace_back(DialogId(user_id), inviter_user_id, date, DialogParticipantStatus::Member()); participants.emplace_back(DialogId(user_id), inviter_user_id, date, DialogParticipantStatus::Member(0));
} }
} }
if (is_participants_cache_changed) { if (is_participants_cache_changed) {