Moved usernames data management to separated class.

This commit is contained in:
23rd 2022-10-14 18:49:40 +03:00 committed by John Preston
parent c8ae7c7402
commit ad70942d0e
12 changed files with 179 additions and 69 deletions

View File

@ -549,6 +549,7 @@ PRIVATE
data/data_user.h
data/data_user_photos.cpp
data/data_user_photos.h
data/data_user_names.cpp
data/data_user_names.h
data/data_wall_paper.cpp
data/data_wall_paper.h

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_updates.h"
#include "api/api_authorizations.h"
#include "api/api_user_names.h"
#include "api/api_chat_participants.h"
#include "api/api_ringtones.h"
#include "api/api_text_entities.h"
@ -1888,6 +1889,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
TextUtilities::SingleLine(last),
user->nameOrPhone,
TextUtilities::SingleLine(username));
user->setUsernames(Api::Usernames::FromTL(d.vusernames()));
}
} break;

View File

@ -723,7 +723,7 @@ void Controller::fillPrivacyTypeButton() {
? Privacy::HasUsername
: Privacy::NoUsername),
.username = (_peer->isChannel()
? _peer->asChannel()->username()
? _peer->asChannel()->editableUsername()
: QString()),
.noForwards = !_peer->allowsForwarding(),
.joinToWrite = (_peer->isMegagroup()
@ -1452,10 +1452,10 @@ void Controller::saveUsernamesOrder() {
_api.request(MTPchannels_DeactivateAllUsernames(
channel->inputChannel
)).done([=] {
channel->setUsernames(channel->username().isEmpty()
channel->setUsernames(channel->editableUsername().isEmpty()
? Data::Usernames()
: Data::Usernames{
{ channel->username(), true, true }
{ channel->editableUsername(), true, true }
});
continueSave();
}).send();
@ -1470,7 +1470,7 @@ void Controller::saveUsernamesOrder() {
newUsernames
) | ranges::views::transform([&](QString username) {
const auto editable =
(channel->username() == username);
(channel->editableUsername() == username);
return Data::Username{
.username = std::move(username),
.active = true,
@ -1485,7 +1485,7 @@ void Controller::saveUsernamesOrder() {
void Controller::saveUsername() {
const auto channel = _peer->asChannel();
const auto username = (channel ? channel->username() : QString());
const auto username = (channel ? channel->editableUsername() : QString());
if (!_savingData.username || *_savingData.username == username) {
return continueSave();
} else if (!channel) {
@ -1583,7 +1583,9 @@ void Controller::saveTitle() {
if (type == qstr("CHAT_NOT_MODIFIED")
|| type == qstr("CHAT_TITLE_NOT_MODIFIED")) {
if (const auto channel = _peer->asChannel()) {
channel->setName(*_savingData.title, channel->username());
channel->setName(
*_savingData.title,
channel->editableUsername());
} else if (const auto chat = _peer->asChat()) {
chat->setName(*_savingData.title);
}

View File

@ -176,7 +176,7 @@ Controller::Controller(
, _isGroup(_peer->isChat() || _peer->isMegagroup())
, _goodUsername(_dataSavedValue
? !_dataSavedValue->username.isEmpty()
: (_peer->isChannel() && !_peer->asChannel()->username().isEmpty()))
: (_peer->isChannel() && !_peer->asChannel()->editableUsername().isEmpty()))
, _wrap(container)
, _checkUsernameTimer([=] { checkUsernameAvailability(); }) {
_peer->updateFull();
@ -400,7 +400,7 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
const auto channel = _peer->asChannel();
const auto username = (!_dataSavedValue || !channel)
? QString()
: channel->username();
: channel->editableUsername();
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap,
@ -530,7 +530,7 @@ void Controller::checkUsernameAvailability() {
_api.request(_checkUsernameRequestId).cancel();
}
const auto channel = _peer->migrateToOrMe()->asChannel();
const auto username = channel ? channel->username() : QString();
const auto username = channel ? channel->editableUsername() : QString();
_checkUsernameRequestId = _api.request(MTPchannels_CheckUsername(
channel ? channel->inputChannel : MTP_inputChannelEmpty(),
MTP_string(checking)

View File

@ -79,10 +79,10 @@ UsernameEditor::UsernameEditor(
this,
st::defaultInputField,
rpl::single(qsl("@username")),
session->user()->username(),
session->user()->editableUsername(),
QString())
, _checkTimer([=] { check(); }) {
_goodText = _session->user()->username().isEmpty()
_goodText = _session->user()->editableUsername().isEmpty()
? QString()
: tr::lng_username_available(tr::now);
@ -183,7 +183,7 @@ void UsernameEditor::check() {
_checkRequestId = 0;
_errorText = (mtpIsTrue(result)
|| _checkUsername == _session->user()->username())
|| _checkUsername == _session->user()->editableUsername())
? QString()
: tr::lng_username_occupied(tr::now);
_goodText = _errorText.isEmpty()
@ -241,7 +241,7 @@ void UsernameEditor::changed() {
void UsernameEditor::updateFail(const QString &error) {
const auto self = _session->user();
if ((error == qstr("USERNAME_NOT_MODIFIED"))
|| (_sentUsername == self->username())) {
|| (_sentUsername == self->editableUsername())) {
self->setName(
TextUtilities::SingleLine(self->firstName),
TextUtilities::SingleLine(self->lastName),
@ -269,7 +269,7 @@ void UsernameEditor::checkFail(const QString &error) {
_errorText = tr::lng_username_invalid(tr::now);
update();
} else if ((error == qstr("USERNAME_OCCUPIED"))
&& (_checkUsername != _session->user()->username())) {
&& (_checkUsername != _session->user()->editableUsername())) {
_errorText = tr::lng_username_occupied(tr::now);
update();
} else {

View File

@ -103,32 +103,36 @@ void ChannelData::setName(
}
void ChannelData::setUsername(const QString &username) {
if (_username != username) {
_username = username;
}
_username.setUsername(username);
}
void ChannelData::setUsernames(const Data::Usernames &usernames) {
auto newUsernames = ranges::views::all(
usernames
) | ranges::views::filter([&](const Data::Username &username) {
return username.active;
}) | ranges::views::transform([&](const Data::Username &username) {
return username.username;
}) | ranges::to_vector;
if (!ranges::equal(_usernames, newUsernames)) {
_usernames = std::move(newUsernames);
session().changes().peerUpdated(this, UpdateFlag::Usernames);
}
void ChannelData::setUsernames(const Data::Usernames &newUsernames) {
const auto wasUsername = username();
const auto wasUsernames = usernames();
_username.setUsernames(newUsernames);
const auto nowUsername = username();
const auto nowUsernames = usernames();
session().changes().peerUpdated(
this,
UpdateFlag()
| ((wasUsername != nowUsername)
? UpdateFlag::Username
: UpdateFlag())
| (!ranges::equal(wasUsernames, nowUsernames)
? UpdateFlag::Usernames
: UpdateFlag()));
}
QString ChannelData::username() const {
return _username;
return _username.username();
}
QString ChannelData::editableUsername() const {
return _username.editableUsername();
}
const std::vector<QString> &ChannelData::usernames() const {
return _usernames;
return _username.usernames();
}
void ChannelData::setAccessHash(uint64 accessHash) {

View File

@ -12,10 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_location.h"
#include "data/data_chat_participant_status.h"
#include "data/data_peer_bot_commands.h"
namespace Data {
struct Username;
} // namespace Data
#include "data/data_user_names.h"
struct ChannelLocation {
QString address;
@ -151,7 +148,7 @@ public:
void setName(const QString &name, const QString &username);
void setUsername(const QString &username);
void setUsernames(const std::vector<Data::Username> &usernames);
void setUsernames(const Data::Usernames &newUsernames);
void setPhoto(const MTPChatPhoto &photo);
void setAccessHash(uint64 accessHash);
@ -166,6 +163,7 @@ public:
}
[[nodiscard]] QString username() const;
[[nodiscard]] QString editableUsername() const;
[[nodiscard]] const std::vector<QString> &usernames() const;
[[nodiscard]] int membersCount() const {
@ -466,8 +464,7 @@ private:
PtsWaiter _ptsWaiter;
QString _username;
std::vector<QString> _usernames;
Data::UsernamesInfo _username;
int _membersCount = -1;
int _adminsCount = 1;

View File

@ -198,11 +198,11 @@ void PeerData::updateNameDelayed(
if (_name == newName && _nameVersion > 1) {
if (isUser()) {
if (asUser()->nameOrPhone == newNameOrPhone
&& asUser()->username() == newUsername) {
&& asUser()->editableUsername() == newUsername) {
return;
}
} else if (isChannel()) {
if (asChannel()->username() == newUsername) {
if (asChannel()->editableUsername() == newUsername) {
return;
}
} else if (isChat()) {
@ -220,15 +220,15 @@ void PeerData::updateNameDelayed(
flags |= UpdateFlag::Name;
}
if (isUser()) {
if (asUser()->username() != newUsername) {
if (asUser()->editableUsername() != newUsername) {
asUser()->setUsername(newUsername);
flags |= UpdateFlag::Username;
}
asUser()->setNameOrPhone(newNameOrPhone);
} else if (isChannel()) {
if (asChannel()->username() != newUsername) {
if (asChannel()->editableUsername() != newUsername) {
asChannel()->setUsername(newUsername);
if (newUsername.isEmpty()) {
if (asChannel()->username().isEmpty()) {
asChannel()->removeFlags(ChannelDataFlag::Username);
} else {
asChannel()->addFlags(ChannelDataFlag::Username);

View File

@ -120,25 +120,25 @@ void UserData::setName(const QString &newFirstName, const QString &newLastName,
updateNameDelayed(newFullName, newPhoneName, newUsername);
}
void UserData::setUsernames(const Data::Usernames &usernames) {
auto newUsernames = ranges::views::all(
usernames
) | ranges::views::filter([&](const Data::Username &username) {
return username.active;
}) | ranges::views::transform([&](const Data::Username &username) {
return username.username;
}) | ranges::to_vector;
if (!ranges::equal(_usernames, newUsernames)) {
_usernames = std::move(newUsernames);
session().changes().peerUpdated(this, UpdateFlag::Usernames);
}
void UserData::setUsernames(const Data::Usernames &newUsernames) {
const auto wasUsername = username();
const auto wasUsernames = usernames();
_username.setUsernames(newUsernames);
const auto nowUsername = username();
const auto nowUsernames = usernames();
session().changes().peerUpdated(
this,
UpdateFlag()
| ((wasUsername != nowUsername)
? UpdateFlag::Username
: UpdateFlag())
| (!ranges::equal(wasUsernames, nowUsernames)
? UpdateFlag::Usernames
: UpdateFlag()));
}
void UserData::setUsername(const QString &username) {
if (_username != username) {
_username = username;
}
_username.setUsername(username);
}
void UserData::setPhone(const QString &newPhone) {
@ -303,12 +303,16 @@ bool UserData::canShareThisContactFast() const {
return !_phone.isEmpty();
}
const QString &UserData::username() const {
return _username;
QString UserData::username() const {
return _username.username();
}
QString UserData::editableUsername() const {
return _username.editableUsername();;
}
const std::vector<QString> &UserData::usernames() const {
return _usernames;
return _username.usernames();
}
const QString &UserData::phone() const {

View File

@ -9,11 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer.h"
#include "data/data_chat_participant_status.h"
#include "data/data_user_names.h"
#include "dialogs/dialogs_key.h"
namespace Data {
struct BotCommand;
struct Username;
} // namespace Data
struct BotInfo {
@ -74,7 +74,7 @@ public:
const QString &newLastName,
const QString &newPhoneName,
const QString &newUsername);
void setUsernames(const std::vector<Data::Username> &usernames);
void setUsernames(const Data::Usernames &newUsernames);
void setEmojiStatus(DocumentId emojiStatusId, TimeId until = 0);
[[nodiscard]] DocumentId emojiStatusId() const;
@ -130,7 +130,8 @@ public:
QString firstName;
QString lastName;
[[nodiscard]] const QString &phone() const;
[[nodiscard]] const QString &username() const;
[[nodiscard]] QString username() const;
[[nodiscard]] QString editableUsername() const;
[[nodiscard]] const std::vector<QString> &usernames() const;
QString nameOrPhone;
TimeId onlineTill = 0;
@ -168,15 +169,14 @@ private:
Flags _flags;
Data::UsernamesInfo _username;
std::vector<Data::UnavailableReason> _unavailableReasons;
QString _username;
QString _phone;
ContactStatus _contactStatus = ContactStatus::Unknown;
CallsStatus _callsStatus = CallsStatus::Unknown;
int _commonChatsCount = 0;
std::vector<QString> _usernames;
uint64 _accessHash = 0;
static constexpr auto kInaccessibleAccessHashOld
= 0xFFFFFFFFFFFFFFFFULL;

View File

@ -0,0 +1,83 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_user_names.h"
namespace Data {
UsernamesInfo::UsernamesInfo() = default;
void UsernamesInfo::setUsername(const QString &username) {
if (_usernames.empty()) {
if (username.isEmpty()) {
_indexEditableUsername = -1;
} else {
_usernames.push_back(username);
_indexEditableUsername = 0;
}
} else if ((_indexEditableUsername < 0)
|| (_indexEditableUsername >= _usernames.size())) {
if (username.isEmpty()) {
_indexEditableUsername = -1;
} else {
_usernames.push_back(username);
_indexEditableUsername = 0;
}
} else if (_usernames[_indexEditableUsername] != username) {
if (username.isEmpty()) {
_usernames.erase(begin(_usernames) + _indexEditableUsername);
_indexEditableUsername = -1;
} else {
_usernames[_indexEditableUsername] = username;
}
}
}
void UsernamesInfo::setUsernames(const Usernames &usernames) {
auto editableUsername = QString();
auto newUsernames = ranges::views::all(
usernames
) | ranges::views::filter([&](const Data::Username &username) {
if (username.editable) {
editableUsername = username.username;
return true;
}
return username.active;
}) | ranges::views::transform([](const Data::Username &username) {
return username.username;
}) | ranges::to_vector;
if (!ranges::equal(_usernames, newUsernames)) {
_usernames = std::move(newUsernames);
}
if (!editableUsername.isEmpty()) {
for (auto i = 0; i < _usernames.size(); i++) {
if (_usernames[i] == editableUsername) {
_indexEditableUsername = i;
break;
}
}
} else {
_indexEditableUsername = -1;
}
}
QString UsernamesInfo::username() const {
return _usernames.empty() ? QString() : _usernames.front();
}
QString UsernamesInfo::editableUsername() const {
return (_indexEditableUsername < 0)
? QString()
: _usernames[_indexEditableUsername];
}
const std::vector<QString> &UsernamesInfo::usernames() const {
return _usernames;
}
} // namespace Data

View File

@ -17,4 +17,21 @@ struct Username final {
using Usernames = std::vector<Username>;
class UsernamesInfo final {
public:
UsernamesInfo();
void setUsername(const QString &username);
void setUsernames(const Usernames &usernames);
[[nodiscard]] QString username() const;
[[nodiscard]] QString editableUsername() const;
[[nodiscard]] const std::vector<QString> &usernames() const;
private:
std::vector<QString> _usernames;
short _indexEditableUsername = -1;
};
} // namespace Data