Support supergroups with location.

GitOrigin-RevId: 976b72eaf8d5fd2226b6d548ed8bca167b385264
This commit is contained in:
levlam 2019-10-13 20:58:32 +03:00
parent 0d72fd638e
commit af527d0c9e
5 changed files with 71 additions and 43 deletions

View File

@ -437,13 +437,14 @@ basicGroupFullInfo description:string creator_user_id:int32 members:vector<chatM
//@status Status of the current user in the supergroup or channel
//@member_count Member count; 0 if unknown. Currently it is guaranteed to be known only if the supergroup or channel was found through SearchPublicChats
//@has_linked_chat True, if the channel has a discussion group, or the supergroup is a discussion group for a channel
//@has_location True, if the supergroup has a chat location
//@sign_messages True, if messages sent to the channel should contain information about the sender. This field is only applicable to channels
//@is_channel True, if the supergroup is a channel
//@is_verified True, if the supergroup or channel is verified
//@restriction_reason If non-empty, contains the reason why access to this supergroup or channel must be restricted. Format of the string is "{type}: {description}".
//-{type} Contains the type of the restriction and at least one of the suffixes "-all", "-ios", "-android", or "-wp", which describe the platforms on which access should be restricted. (For example, "terms-ios-android". {description} contains a human-readable description of the restriction, which can be shown to the user)
//@is_scam True, if many users reported this supergroup as a scam
supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_count:int32 has_linked_chat:Bool sign_messages:Bool is_channel:Bool is_verified:Bool restriction_reason:string is_scam:Bool = Supergroup;
supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_count:int32 has_linked_chat:Bool has_location:Bool sign_messages:Bool is_channel:Bool is_verified:Bool restriction_reason:string is_scam:Bool = Supergroup;
//@description Contains full information about a supergroup or channel
//@param_description Supergroup or channel description
@ -453,7 +454,7 @@ supergroup id:int32 username:string date:int32 status:ChatMemberStatus member_co
//@banned_count Number of users banned from chat; 0 if unknown
//@linked_chat_id Chat identifier of a discussion group for the channel, or a channel, for which the supergroup is a discussion group; 0 if none or unknown
//@can_get_members True, if members of the chat can be retrieved
//@can_set_username True, if the chat can be made public
//@can_set_username True, if the chat can have username
//@can_set_sticker_set True, if the supergroup sticker set can be changed
//@can_view_statistics True, if the channel statistics is available through getChatStatisticsUrl
//@is_all_history_available True, if new chat members will have access to old messages. In public or discussion groups and both public and private channels, old messages are always available, so this option affects only private supergroups without a linked chat. The value of this field is only available for chat administrators
@ -653,7 +654,7 @@ chatInviteLink invite_link:string = ChatInviteLink;
//@photo Chat photo; may be null
//@member_count Number of members
//@member_user_ids User identifiers of some chat members that may be known to the current user
//@is_public True, if the chat is a public supergroup or a channel with a username
//@is_public True, if the chat is a public supergroup or a channel with a username or a location
chatInviteLinkInfo chat_id:int53 type:ChatType title:string photo:chatPhoto member_count:int32 member_user_ids:vector<int32> is_public:Bool = ChatInviteLinkInfo;
@ -2380,7 +2381,7 @@ chatReportReasonUnrelatedLocation = ChatReportReason;
chatReportReasonCustom text:string = ChatReportReason;
//@description Contains a public HTTPS link to a message in a public supergroup or channel with a username @link Message link @html HTML-code for embedding the message
//@description Contains a public HTTPS link to a message in a supergroup or a channel with a username @link Message link @html HTML-code for embedding the message
publicMessageLink link:string html:string = PublicMessageLink;
//@description Contains information about a link to a message in a chat
@ -2560,7 +2561,7 @@ topChatCategoryForwardChats = TopChatCategory;
//@description A URL linking to a user @user_id Identifier of the user
tMeUrlTypeUser user_id:int32 = TMeUrlType;
//@description A URL linking to a public supergroup or channel @supergroup_id Identifier of the supergroup or channel
//@description A URL linking to a public supergroup or a channel @supergroup_id Identifier of the supergroup or channel
tMeUrlTypeSupergroup supergroup_id:int53 = TMeUrlType;
//@description A chat invite link @info Chat invite link info
@ -3160,7 +3161,7 @@ removeNotification notification_group_id:int32 notification_id:int32 = Ok;
removeNotificationGroup notification_group_id:int32 max_notification_id:int32 = Ok;
//@description Returns a public HTTPS link to a message. Available only for messages in supergroups and channels with username
//@description Returns a public HTTPS link to a message. Available only for messages in supergroups and channels with a username
//@chat_id Identifier of the chat to which the message belongs
//@message_id Identifier of the message
//@for_album Pass true if a link for a whole media album should be returned

Binary file not shown.

View File

@ -2943,6 +2943,7 @@ void ContactsManager::Channel::store(StorerT &storer) const {
STORE_FLAG(is_scam);
STORE_FLAG(has_cache_version);
STORE_FLAG(has_linked_channel);
STORE_FLAG(has_location);
END_STORE_FLAGS();
store(status, storer);
@ -3004,6 +3005,7 @@ void ContactsManager::Channel::parse(ParserT &parser) {
PARSE_FLAG(is_scam);
PARSE_FLAG(has_cache_version);
PARSE_FLAG(has_linked_channel);
PARSE_FLAG(has_location);
END_PARSE_FLAGS();
if (use_new_rights) {
@ -3350,7 +3352,7 @@ bool ContactsManager::have_input_peer_channel(const Channel *c, ChannelId channe
return false;
}
if (access_rights == AccessRights::Read) {
if (!c->username.empty()) {
if (!c->username.empty() || c->has_location) {
return true;
}
if (!from_linked && c->has_linked_channel) {
@ -4644,9 +4646,10 @@ void ContactsManager::toggle_channel_is_all_history_available(ChannelId channel_
if (get_channel_type(c) != ChannelType::Megagroup) {
return promise.set_error(Status::Error(6, "Message history can be hidden in supergroups only"));
}
if (c->has_linked_channel) {
if (c->has_linked_channel && !is_all_history_available) {
return promise.set_error(Status::Error(6, "Message history can't be hidden in discussion supergroups"));
}
// it can be toggled in public chats, but will not affect them
td_->create_handler<ToggleChannelIsAllHistoryAvailableQuery>(std::move(promise))
->send(channel_id, is_all_history_available);
@ -8485,11 +8488,19 @@ bool ContactsManager::on_get_channel_error(ChannelId channel_id, const Status &s
telegram_api::channelForbidden update(flags, false /*ignored*/, false /*ignored*/, channel_id.get(),
c->access_hash, c->title, 0);
on_chat_update(update, "CHANNEL_PRIVATE");
} else if (!c->username.empty()) {
LOG(INFO) << "Drop username of " << channel_id;
on_update_channel_username(c, channel_id, "");
update_channel(c, channel_id);
} else {
if (!c->username.empty()) {
LOG(INFO) << "Drop username of " << channel_id;
on_update_channel_username(c, channel_id, "");
update_channel(c, channel_id);
}
if (c->has_location) {
LOG(INFO) << "Drop location of " << channel_id;
c->has_location = false;
update_channel(c, channel_id);
}
}
invalidate_channel_full(channel_id, false);
LOG_IF(ERROR, have_input_peer_channel(c, channel_id, AccessRights::Read))
<< "Have read access to channel after receiving CHANNEL_PRIVATE. Channel state: "
<< oneline(to_string(get_supergroup_object(channel_id, c)))
@ -10270,6 +10281,14 @@ FileSourceId ContactsManager::get_chat_photo_file_source_id(ChatId chat_id) {
return source_id;
}
bool ContactsManager::is_channel_public(ChannelId channel_id) const {
return is_channel_public(get_channel(channel_id));
}
bool ContactsManager::is_channel_public(const Channel *c) {
return c != nullptr && (!c->username.empty() || c->has_location);
}
ChannelType ContactsManager::get_channel_type(ChannelId channel_id) const {
auto c = get_channel(channel_id);
if (c == nullptr) {
@ -11118,6 +11137,7 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
auto access_hash = has_access_hash ? channel.access_hash_ : 0;
bool has_linked_channel = (channel.flags_ & CHANNEL_FLAG_HAS_LINKED_CHAT) != 0;
bool has_location = (channel.flags_ & CHANNEL_FLAG_HAS_LOCATION) != 0;
bool sign_messages = (channel.flags_ & CHANNEL_FLAG_SIGN_MESSAGES) != 0;
bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0;
bool is_verified = (channel.flags_ & CHANNEL_FLAG_IS_VERIFIED) != 0;
@ -11209,10 +11229,11 @@ void ContactsManager::on_chat_update(telegram_api::channel &channel, const char
c->need_send_update = true;
}
if (c->has_linked_channel != has_linked_channel || c->sign_messages != sign_messages ||
c->is_megagroup != is_megagroup || c->is_verified != is_verified || c->restriction_reason != restriction_reason ||
c->is_scam != is_scam) {
if (c->has_linked_channel != has_linked_channel || c->has_location != has_location ||
c->sign_messages != sign_messages || c->is_megagroup != is_megagroup || c->is_verified != is_verified ||
c->restriction_reason != restriction_reason || c->is_scam != is_scam) {
c->has_linked_channel = has_linked_channel;
c->has_location = has_location;
c->sign_messages = sign_messages;
c->is_megagroup = is_megagroup;
c->is_verified = is_verified;
@ -11268,6 +11289,7 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co
on_update_channel_default_permissions(c, channel_id, get_restricted_rights(banned_rights));
bool has_linked_channel = false;
bool has_location = false;
bool sign_messages = false;
bool is_megagroup = (channel.flags_ & CHANNEL_FLAG_IS_MEGAGROUP) != 0;
bool is_verified = false;
@ -11290,10 +11312,11 @@ void ContactsManager::on_chat_update(telegram_api::channelForbidden &channel, co
c->need_send_update = true;
}
if (c->has_linked_channel != has_linked_channel || c->sign_messages != sign_messages ||
c->is_megagroup != is_megagroup || c->is_verified != is_verified || c->restriction_reason != restriction_reason ||
c->is_scam != is_scam) {
if (c->has_linked_channel != has_linked_channel || c->has_location != has_location ||
c->sign_messages != sign_messages || c->is_megagroup != is_megagroup || c->is_verified != is_verified ||
c->restriction_reason != restriction_reason || c->is_scam != is_scam) {
c->has_linked_channel = has_linked_channel;
c->has_location = has_location;
c->sign_messages = sign_messages;
c->is_megagroup = is_megagroup;
c->is_verified = is_verified;
@ -11458,21 +11481,20 @@ tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId
return get_basic_group_object(chat_id, get_chat(chat_id));
}
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId chat_id, const Chat *chat) {
if (chat == nullptr) {
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object(ChatId chat_id, const Chat *c) {
if (c == nullptr) {
return nullptr;
}
if (chat->migrated_to_channel_id.is_valid()) {
get_channel_force(chat->migrated_to_channel_id);
if (c->migrated_to_channel_id.is_valid()) {
get_channel_force(c->migrated_to_channel_id);
}
return get_basic_group_object_const(chat_id, chat);
return get_basic_group_object_const(chat_id, c);
}
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object_const(ChatId chat_id,
const Chat *chat) const {
tl_object_ptr<td_api::basicGroup> ContactsManager::get_basic_group_object_const(ChatId chat_id, const Chat *c) const {
return make_tl_object<td_api::basicGroup>(
chat_id.get(), chat->participant_count, get_chat_status(chat).get_chat_member_status_object(), chat->is_active,
get_supergroup_id_object(chat->migrated_to_channel_id, "get_basic_group_object"));
chat_id.get(), c->participant_count, get_chat_status(c).get_chat_member_status_object(), c->is_active,
get_supergroup_id_object(c->migrated_to_channel_id, "get_basic_group_object"));
}
tl_object_ptr<td_api::basicGroupFullInfo> ContactsManager::get_basic_group_full_info_object(ChatId chat_id) const {
@ -11496,7 +11518,7 @@ int32 ContactsManager::get_supergroup_id_object(ChannelId channel_id, const char
send_closure(G()->td(), &Td::send_update,
td_api::make_object<td_api::updateSupergroup>(td_api::make_object<td_api::supergroup>(
channel_id.get(), string(), 0, DialogParticipantStatus::Banned(0).get_chat_member_status_object(),
0, false, false, true, false, "", false)));
0, false, false, false, true, false, "", false)));
}
return channel_id.get();
}
@ -11505,15 +11527,14 @@ tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(Channel
return get_supergroup_object(channel_id, get_channel(channel_id));
}
tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(ChannelId channel_id,
const Channel *channel) const {
if (channel == nullptr) {
tl_object_ptr<td_api::supergroup> ContactsManager::get_supergroup_object(ChannelId channel_id, const Channel *c) const {
if (c == nullptr) {
return nullptr;
}
return make_tl_object<td_api::supergroup>(
channel_id.get(), channel->username, channel->date, get_channel_status(channel).get_chat_member_status_object(),
channel->participant_count, channel->has_linked_channel, channel->sign_messages, !channel->is_megagroup,
channel->is_verified, channel->restriction_reason, channel->is_scam);
return make_tl_object<td_api::supergroup>(channel_id.get(), c->username, c->date,
get_channel_status(c).get_chat_member_status_object(), c->participant_count,
c->has_linked_channel, c->has_location, c->sign_messages, !c->is_megagroup,
c->is_verified, c->restriction_reason, c->is_scam);
}
tl_object_ptr<td_api::supergroupFullInfo> ContactsManager::get_supergroup_full_info_object(ChannelId channel_id) const {
@ -11649,7 +11670,7 @@ tl_object_ptr<td_api::chatInviteLinkInfo> ContactsManager::get_chat_invite_link_
if (c != nullptr) {
title = c->title;
photo = &c->photo;
is_public = !c->username.empty();
is_public = is_channel_public(c);
is_megagroup = c->is_megagroup;
participant_count = c->participant_count;
} else {

View File

@ -391,6 +391,8 @@ class ContactsManager : public Actor {
void reload_channel(ChannelId chnanel_id, Promise<Unit> &&promise);
bool get_channel_full(ChannelId channel_id, Promise<Unit> &&promise);
bool is_channel_public(ChannelId channel_id) const;
bool have_secret_chat(SecretChatId secret_chat_id) const;
bool have_secret_chat_force(SecretChatId secret_chat_id);
bool get_secret_chat(SecretChatId secret_chat_id, bool force, Promise<Unit> &&promise);
@ -667,10 +669,11 @@ class ContactsManager : public Actor {
int32 date = 0;
int32 participant_count = 0;
static constexpr uint32 CACHE_VERSION = 2;
static constexpr uint32 CACHE_VERSION = 3;
uint32 cache_version = 0;
bool has_linked_channel = false;
bool has_location = false;
bool sign_messages = false;
bool is_megagroup = false;
@ -844,6 +847,7 @@ class ContactsManager : public Actor {
static constexpr int32 CHANNEL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 17;
static constexpr int32 CHANNEL_FLAG_IS_SCAM = 1 << 19;
static constexpr int32 CHANNEL_FLAG_HAS_LINKED_CHAT = 1 << 20;
static constexpr int32 CHANNEL_FLAG_HAS_LOCATION = 1 << 21;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_PARTICIPANT_COUNT = 1 << 0;
static constexpr int32 CHANNEL_FULL_FLAG_HAS_ADMINISTRATOR_COUNT = 1 << 1;
@ -1106,6 +1110,8 @@ class ContactsManager : public Actor {
void on_clear_imported_contacts(vector<Contact> &&contacts, vector<size_t> contacts_unique_id,
std::pair<vector<size_t>, vector<Contact>> &&to_add, Promise<Unit> &&promise);
static bool is_channel_public(const Channel *c);
static bool is_valid_invite_link(const string &invite_link);
bool update_invite_link(string &invite_link, tl_object_ptr<telegram_api::ExportedChatInvite> &&invite_link_ptr);
@ -1133,13 +1139,13 @@ class ContactsManager : public Actor {
tl_object_ptr<td_api::userFullInfo> get_user_full_info_object(UserId user_id, const UserFull *user_full) const;
tl_object_ptr<td_api::basicGroup> get_basic_group_object(ChatId chat_id, const Chat *chat);
tl_object_ptr<td_api::basicGroup> get_basic_group_object(ChatId chat_id, const Chat *c);
tl_object_ptr<td_api::basicGroup> get_basic_group_object_const(ChatId chat_id, const Chat *chat) const;
tl_object_ptr<td_api::basicGroup> get_basic_group_object_const(ChatId chat_id, const Chat *c) const;
tl_object_ptr<td_api::basicGroupFullInfo> get_basic_group_full_info_object(const ChatFull *chat_full) const;
tl_object_ptr<td_api::supergroup> get_supergroup_object(ChannelId channel_id, const Channel *channel) const;
tl_object_ptr<td_api::supergroup> get_supergroup_object(ChannelId channel_id, const Channel *c) const;
tl_object_ptr<td_api::supergroupFullInfo> get_supergroup_full_info_object(const ChannelFull *channel_full) const;

View File

@ -8266,7 +8266,7 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from
if (is_broadcast_channel(dialog_id)) {
return promise.set_error(Status::Error(3, "Can't delete chat history in a channel"));
}
if (!get_dialog_username(dialog_id).empty()) {
if (td_->contacts_manager_->is_channel_public(dialog_id.get_channel_id())) {
return promise.set_error(Status::Error(3, "Can't delete chat history in a public supergroup"));
}
break;
@ -13013,7 +13013,7 @@ std::pair<string, string> MessagesManager::get_public_message_link(FullMessageId
if (dialog_id.get_type() != DialogType::Channel ||
td_->contacts_manager_->get_channel_username(dialog_id.get_channel_id()).empty()) {
promise.set_error(Status::Error(
6, "Public message links are available only for messages in public supergroups and channel chats"));
6, "Public message links are available only for messages in supergroups and channel chats with a username"));
return {};
}
@ -14450,7 +14450,7 @@ td_api::object_ptr<td_api::chat> MessagesManager::get_chat_object(const Dialog *
break;
case DialogType::Channel:
if (is_broadcast_channel(d->dialog_id) ||
!td_->contacts_manager_->get_channel_username(d->dialog_id.get_channel_id()).empty()) {
td_->contacts_manager_->is_channel_public(d->dialog_id.get_channel_id())) {
// deleteChatHistory can't be used in channels and public supergroups
} else {
// private supergroups can be deleted for self