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
//@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
//@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;

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"));
}
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");
if (channel_full != nullptr && !channel_full->can_set_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) {
if (created_public_channels_inited_[0]) {
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);
} else {
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,
const Usernames &old_usernames, const Usernames &new_usernames) {
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
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) {
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 {

View File

@ -22,7 +22,7 @@ Usernames::Usernames(string &&first_username, vector<telegram_api::object_ptr<te
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);
return;
}
@ -44,10 +44,6 @@ Usernames::Usernames(string &&first_username, vector<telegram_api::object_ptr<te
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++) {
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_));
}
}
CHECK(editable_username_pos_ != -1);
CHECK((editable_username_pos_ != -1) == was_editable);
}
tl_object_ptr<td_api::usernames> Usernames::get_usernames_object() const {
if (is_empty()) {
return nullptr;
}
return make_tl_object<td_api::usernames>(vector<string>(active_usernames_), vector<string>(disabled_usernames_),
active_usernames_[editable_username_pos_]);
return make_tl_object<td_api::usernames>(
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 {
@ -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 result;
if (is_empty()) {
CHECK(new_username_order.empty());
return result;
}
result.active_usernames_ = std::move(new_username_order);
result.disabled_usernames_ = disabled_usernames_;
const string &editable_username = active_usernames_[editable_username_pos_];
for (size_t i = 0; i < result.active_usernames_.size(); i++) {
if (result.active_usernames_[i] == editable_username) {
result.editable_username_pos_ = narrow_cast<int32>(i);
break;
if (editable_username_pos_ != -1) {
const string &editable_username = active_usernames_[editable_username_pos_];
for (size_t i = 0; i < result.active_usernames_.size(); i++) {
if (result.active_usernames_[i] == editable_username) {
result.editable_username_pos_ = narrow_cast<int32>(i);
break;
}
}
CHECK(result.editable_username_pos_ != -1);
}
CHECK(!is_empty());
return result;
}
@ -136,12 +131,14 @@ bool operator!=(const Usernames &lhs, const Usernames &rhs) {
StringBuilder &operator<<(StringBuilder &string_builder, const Usernames &usernames) {
string_builder << "Usernames[";
if (usernames.editable_username_pos_ != -1) {
string_builder << usernames.active_usernames_[usernames.editable_username_pos_];
}
if (!usernames.active_usernames_.empty()) {
string_builder << usernames.active_usernames_[usernames.editable_username_pos_] << ' '
<< usernames.active_usernames_;
string_builder << ", active " << usernames.active_usernames_;
}
if (!usernames.disabled_usernames_.empty()) {
string_builder << usernames.disabled_usernames_;
string_builder << ", disabled " << usernames.disabled_usernames_;
}
return string_builder << ']';
}

View File

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