Support usernames without editable username.

This commit is contained in:
levlam 2022-10-14 17:45:58 +03:00
parent b3ab397bcd
commit 9b0cea912a
4 changed files with 49 additions and 36 deletions

View File

@ -489,7 +489,7 @@ emojiStatuses emoji_statuses:vector<emojiStatus> = EmojiStatuses;
//@description Describes usernames assigned to a user, a supergroup, or a channel //@description Describes usernames assigned to a user, a supergroup, or a channel
//@active_usernames List of active usernames; the first one must be shown as the primary username. The order of active usernames can be changed with reorderActiveUsernames or reorderSupergroupActiveUsernames //@active_usernames List of active usernames; the first one must be shown as the primary username. The order of active usernames can be changed with reorderActiveUsernames or reorderSupergroupActiveUsernames
//@disabled_usernames List of currently disabled usernames; the username can be activated or disabled with toggleUsernameIsActive/toggleSupergroupUsernameIsActive //@disabled_usernames List of currently disabled usernames; the username can be activated or disabled with toggleUsernameIsActive/toggleSupergroupUsernameIsActive
//@editable_username The active username, which can be changed with setUsername/setSupergroupUsername; if there is at least one active username, then the username can't be empty //@editable_username The active username, which can be changed with setUsername/setSupergroupUsername
usernames active_usernames:vector<string> disabled_usernames:vector<string> editable_username:string = Usernames; usernames active_usernames:vector<string> disabled_usernames:vector<string> editable_username:string = Usernames;

View File

@ -6827,7 +6827,7 @@ void ContactsManager::set_channel_username(ChannelId channel_id, const string &u
return promise.set_error(Status::Error(400, "Username is invalid")); return promise.set_error(Status::Error(400, "Username is invalid"));
} }
if (!username.empty() && c->usernames.is_empty()) { if (!username.empty() && !c->usernames.has_editable_username()) {
auto channel_full = get_channel_full(channel_id, false, "set_channel_username"); auto channel_full = get_channel_full(channel_id, false, "set_channel_username");
if (channel_full != nullptr && !channel_full->can_set_username) { if (channel_full != nullptr && !channel_full->can_set_username) {
return promise.set_error(Status::Error(400, "Can't set supergroup username")); return promise.set_error(Status::Error(400, "Can't set supergroup username"));
@ -8363,7 +8363,7 @@ void ContactsManager::finish_get_created_public_dialogs(PublicDialogType type, R
void ContactsManager::update_created_public_channels(Channel *c, ChannelId channel_id) { void ContactsManager::update_created_public_channels(Channel *c, ChannelId channel_id) {
if (created_public_channels_inited_[0]) { if (created_public_channels_inited_[0]) {
bool was_changed = false; bool was_changed = false;
if (c->usernames.is_empty() || !c->status.is_creator()) { if (!c->usernames.has_editable_username() || !c->status.is_creator()) {
was_changed = td::remove(created_public_channels_[0], channel_id); was_changed = td::remove(created_public_channels_[0], channel_id);
} else { } else {
if (!td::contains(created_public_channels_[0], channel_id)) { if (!td::contains(created_public_channels_[0], channel_id)) {
@ -14392,7 +14392,7 @@ void ContactsManager::on_update_channel_usernames(Channel *c, ChannelId channel_
void ContactsManager::on_channel_usernames_changed(const Channel *c, ChannelId channel_id, void ContactsManager::on_channel_usernames_changed(const Channel *c, ChannelId channel_id,
const Usernames &old_usernames, const Usernames &new_usernames) { const Usernames &old_usernames, const Usernames &new_usernames) {
bool have_channel_full = get_channel_full(channel_id) != nullptr; bool have_channel_full = get_channel_full(channel_id) != nullptr;
if (old_usernames.is_empty() || new_usernames.is_empty()) { if (!old_usernames.has_first_username() || !new_usernames.has_first_username()) {
// moving channel from private to public can change availability of chat members // moving channel from private to public can change availability of chat members
invalidate_channel_full(channel_id, !c->is_slow_mode_enabled); invalidate_channel_full(channel_id, !c->is_slow_mode_enabled);
} }
@ -15365,7 +15365,7 @@ bool ContactsManager::is_channel_public(ChannelId channel_id) const {
} }
bool ContactsManager::is_channel_public(const Channel *c) { bool ContactsManager::is_channel_public(const Channel *c) {
return c != nullptr && (!c->usernames.is_empty() || c->has_location); return c != nullptr && (c->usernames.has_first_username() || c->has_location);
} }
ChannelType ContactsManager::get_channel_type(ChannelId channel_id) const { ChannelType ContactsManager::get_channel_type(ChannelId channel_id) const {

View File

@ -22,7 +22,7 @@ Usernames::Usernames(string &&first_username, vector<telegram_api::object_ptr<te
return; return;
} }
if (!first_username.empty() && usernames[0]->username_ != first_username) { if (!first_username.empty()) {
LOG(ERROR) << "Receive first username " << first_username << " with " << to_string(usernames); LOG(ERROR) << "Receive first username " << first_username << " with " << to_string(usernames);
return; return;
} }
@ -44,10 +44,6 @@ Usernames::Usernames(string &&first_username, vector<telegram_api::object_ptr<te
was_editable = true; was_editable = true;
} }
} }
if (!was_editable) {
LOG(ERROR) << "Receive no editable username in " << to_string(usernames);
return;
}
for (size_t i = 0; i < usernames.size(); i++) { for (size_t i = 0; i < usernames.size(); i++) {
if (usernames[i]->active_) { if (usernames[i]->active_) {
@ -59,15 +55,16 @@ Usernames::Usernames(string &&first_username, vector<telegram_api::object_ptr<te
disabled_usernames_.push_back(std::move(usernames[i]->username_)); disabled_usernames_.push_back(std::move(usernames[i]->username_));
} }
} }
CHECK(editable_username_pos_ != -1); CHECK((editable_username_pos_ != -1) == was_editable);
} }
tl_object_ptr<td_api::usernames> Usernames::get_usernames_object() const { tl_object_ptr<td_api::usernames> Usernames::get_usernames_object() const {
if (is_empty()) { if (is_empty()) {
return nullptr; return nullptr;
} }
return make_tl_object<td_api::usernames>(vector<string>(active_usernames_), vector<string>(disabled_usernames_), return make_tl_object<td_api::usernames>(
active_usernames_[editable_username_pos_]); vector<string>(active_usernames_), vector<string>(disabled_usernames_),
editable_username_pos_ == -1 ? string() : active_usernames_[editable_username_pos_]);
} }
bool Usernames::can_reorder_to(const vector<string> &new_username_order) const { bool Usernames::can_reorder_to(const vector<string> &new_username_order) const {
@ -91,20 +88,18 @@ bool Usernames::can_reorder_to(const vector<string> &new_username_order) const {
Usernames Usernames::reorder_to(vector<string> &&new_username_order) const { Usernames Usernames::reorder_to(vector<string> &&new_username_order) const {
Usernames result; Usernames result;
if (is_empty()) {
CHECK(new_username_order.empty());
return result;
}
result.active_usernames_ = std::move(new_username_order); result.active_usernames_ = std::move(new_username_order);
result.disabled_usernames_ = disabled_usernames_; result.disabled_usernames_ = disabled_usernames_;
const string &editable_username = active_usernames_[editable_username_pos_]; if (editable_username_pos_ != -1) {
for (size_t i = 0; i < result.active_usernames_.size(); i++) { const string &editable_username = active_usernames_[editable_username_pos_];
if (result.active_usernames_[i] == editable_username) { for (size_t i = 0; i < result.active_usernames_.size(); i++) {
result.editable_username_pos_ = narrow_cast<int32>(i); if (result.active_usernames_[i] == editable_username) {
break; result.editable_username_pos_ = narrow_cast<int32>(i);
break;
}
} }
CHECK(result.editable_username_pos_ != -1);
} }
CHECK(!is_empty());
return result; return result;
} }
@ -136,12 +131,14 @@ bool operator!=(const Usernames &lhs, const Usernames &rhs) {
StringBuilder &operator<<(StringBuilder &string_builder, const Usernames &usernames) { StringBuilder &operator<<(StringBuilder &string_builder, const Usernames &usernames) {
string_builder << "Usernames["; string_builder << "Usernames[";
if (usernames.editable_username_pos_ != -1) {
string_builder << usernames.active_usernames_[usernames.editable_username_pos_];
}
if (!usernames.active_usernames_.empty()) { if (!usernames.active_usernames_.empty()) {
string_builder << usernames.active_usernames_[usernames.editable_username_pos_] << ' ' string_builder << ", active " << usernames.active_usernames_;
<< usernames.active_usernames_;
} }
if (!usernames.disabled_usernames_.empty()) { if (!usernames.disabled_usernames_.empty()) {
string_builder << usernames.disabled_usernames_; string_builder << ", disabled " << usernames.disabled_usernames_;
} }
return string_builder << ']'; return string_builder << ']';
} }

View File

@ -34,23 +34,31 @@ class Usernames {
td_api::object_ptr<td_api::usernames> get_usernames_object() const; td_api::object_ptr<td_api::usernames> get_usernames_object() const;
bool is_empty() const { bool is_empty() const {
return editable_username_pos_ == -1; return editable_username_pos_ == -1 && active_usernames_.empty() && disabled_usernames_.empty();
} }
string get_first_username() const { string get_first_username() const {
if (is_empty()) { if (!has_first_username()) {
return string(); return string();
} }
return active_usernames_[0]; return active_usernames_[0];
} }
bool has_first_username() const {
return !active_usernames_.empty();
}
string get_editable_username() const { string get_editable_username() const {
if (is_empty()) { if (!has_editable_username()) {
return string(); return string();
} }
return active_usernames_[editable_username_pos_]; return active_usernames_[editable_username_pos_];
} }
bool has_editable_username() const {
return editable_username_pos_ != -1;
}
const vector<string> &get_active_usernames() const { const vector<string> &get_active_usernames() const {
return active_usernames_; return active_usernames_;
} }
@ -61,20 +69,22 @@ class Usernames {
template <class StorerT> template <class StorerT>
void store(StorerT &storer) const { void store(StorerT &storer) const {
CHECK(!is_empty()) CHECK(!is_empty());
CHECK(!active_usernames_.empty())
bool has_many_active_usernames = active_usernames_.size() > 0; bool has_many_active_usernames = active_usernames_.size() > 0;
bool has_disabled_usernames = !disabled_usernames_.empty(); bool has_disabled_usernames = !disabled_usernames_.empty();
bool has_editable_username = editable_username_pos_ != -1;
BEGIN_STORE_FLAGS(); BEGIN_STORE_FLAGS();
STORE_FLAG(has_many_active_usernames); STORE_FLAG(has_many_active_usernames);
STORE_FLAG(has_disabled_usernames); STORE_FLAG(has_disabled_usernames);
STORE_FLAG(has_editable_username);
END_STORE_FLAGS(); END_STORE_FLAGS();
if (has_many_active_usernames) { if (has_many_active_usernames) {
td::store(active_usernames_, storer); td::store(active_usernames_, storer);
td::store(editable_username_pos_, storer); if (has_editable_username) {
td::store(editable_username_pos_, storer);
}
} else { } else {
td::store(active_usernames_[0], storer); td::store(active_usernames_[0], storer);
CHECK(editable_username_pos_ == 0);
} }
if (has_disabled_usernames) { if (has_disabled_usernames) {
td::store(disabled_usernames_, storer); td::store(disabled_usernames_, storer);
@ -86,18 +96,24 @@ class Usernames {
using td::parse; using td::parse;
bool has_many_active_usernames; bool has_many_active_usernames;
bool has_disabled_usernames; bool has_disabled_usernames;
bool has_editable_username;
BEGIN_PARSE_FLAGS(); BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_many_active_usernames); PARSE_FLAG(has_many_active_usernames);
PARSE_FLAG(has_disabled_usernames); PARSE_FLAG(has_disabled_usernames);
PARSE_FLAG(has_editable_username);
END_PARSE_FLAGS(); END_PARSE_FLAGS();
if (has_many_active_usernames) { if (has_many_active_usernames) {
td::parse(active_usernames_, parser); td::parse(active_usernames_, parser);
td::parse(editable_username_pos_, parser); if (has_editable_username) {
CHECK(static_cast<size_t>(editable_username_pos_) < active_usernames_.size()); td::parse(editable_username_pos_, parser);
CHECK(static_cast<size_t>(editable_username_pos_) < active_usernames_.size());
}
} else { } else {
active_usernames_.resize(1); active_usernames_.resize(1);
td::parse(active_usernames_[0], parser); td::parse(active_usernames_[0], parser);
editable_username_pos_ = 0; if (has_editable_username) {
editable_username_pos_ = 0;
}
} }
if (has_disabled_usernames) { if (has_disabled_usernames) {
td::parse(disabled_usernames_, parser); td::parse(disabled_usernames_, parser);