Added usernames list to peer type box for public channels.

This commit is contained in:
23rd 2022-10-12 20:24:49 +03:00 committed by John Preston
parent 113d9742f4
commit d55ff7aa4a
5 changed files with 91 additions and 26 deletions

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h" #include "apiwrap.h"
#include "api/api_peer_photo.h" #include "api/api_peer_photo.h"
#include "api/api_user_names.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "boxes/add_contact_box.h" #include "boxes/add_contact_box.h"
#include "ui/boxes/confirm_box.h" #include "ui/boxes/confirm_box.h"
@ -264,6 +265,7 @@ private:
}; };
struct Saving { struct Saving {
std::optional<QString> username; std::optional<QString> username;
std::optional<std::vector<QString>> usernamesOrder;
std::optional<QString> title; std::optional<QString> title;
std::optional<QString> description; std::optional<QString> description;
std::optional<bool> hiddenPreHistory; std::optional<bool> hiddenPreHistory;
@ -303,6 +305,7 @@ private:
void deleteChannel(); void deleteChannel();
[[nodiscard]] std::optional<Saving> validate() const; [[nodiscard]] std::optional<Saving> validate() const;
[[nodiscard]] bool validateUsernamesOrder(Saving &to) const;
[[nodiscard]] bool validateUsername(Saving &to) const; [[nodiscard]] bool validateUsername(Saving &to) const;
[[nodiscard]] bool validateLinkedChat(Saving &to) const; [[nodiscard]] bool validateLinkedChat(Saving &to) const;
[[nodiscard]] bool validateTitle(Saving &to) const; [[nodiscard]] bool validateTitle(Saving &to) const;
@ -315,6 +318,7 @@ private:
[[nodiscard]] bool validateRequestToJoin(Saving &to) const; [[nodiscard]] bool validateRequestToJoin(Saving &to) const;
void save(); void save();
void saveUsernamesOrder();
void saveUsername(); void saveUsername();
void saveLinkedChat(); void saveLinkedChat();
void saveTitle(); void saveTitle();
@ -1266,7 +1270,8 @@ void Controller::submitDescription() {
std::optional<Controller::Saving> Controller::validate() const { std::optional<Controller::Saving> Controller::validate() const {
auto result = Saving(); auto result = Saving();
if (validateUsername(result) if (validateUsernamesOrder(result)
&& validateUsername(result)
&& validateLinkedChat(result) && validateLinkedChat(result)
&& validateTitle(result) && validateTitle(result)
&& validateDescription(result) && validateDescription(result)
@ -1281,6 +1286,17 @@ std::optional<Controller::Saving> Controller::validate() const {
return {}; return {};
} }
bool Controller::validateUsernamesOrder(Saving &to) const {
if (!_typeDataSavedValue) {
return true;
} else if (_typeDataSavedValue->privacy != Privacy::HasUsername) {
to.usernamesOrder = std::vector<QString>();
return true;
}
to.usernamesOrder = _typeDataSavedValue->usernamesOrder;
return true;
}
bool Controller::validateUsername(Saving &to) const { bool Controller::validateUsername(Saving &to) const {
if (!_typeDataSavedValue) { if (!_typeDataSavedValue) {
return true; return true;
@ -1290,7 +1306,8 @@ bool Controller::validateUsername(Saving &to) const {
} }
const auto username = _typeDataSavedValue->username; const auto username = _typeDataSavedValue->username;
if (username.isEmpty()) { if (username.isEmpty()) {
return false; to.username = QString();
return true;
} }
to.username = username; to.username = username;
return true; return true;
@ -1387,6 +1404,7 @@ void Controller::save() {
} }
if (const auto saving = validate()) { if (const auto saving = validate()) {
_savingData = *saving; _savingData = *saving;
pushSaveStage([=] { saveUsernamesOrder(); });
pushSaveStage([=] { saveUsername(); }); pushSaveStage([=] { saveUsername(); });
pushSaveStage([=] { saveLinkedChat(); }); pushSaveStage([=] { saveLinkedChat(); });
pushSaveStage([=] { saveTitle(); }); pushSaveStage([=] { saveTitle(); });
@ -1418,6 +1436,46 @@ void Controller::cancelSave() {
_saveStagesQueue.clear(); _saveStagesQueue.clear();
} }
void Controller::saveUsernamesOrder() {
const auto channel = _peer->asChannel();
if (!_savingData.usernamesOrder || !channel) {
return continueSave();
}
if (_savingData.usernamesOrder->empty()) {
_api.request(MTPchannels_DeactivateAllUsernames(
channel->inputChannel
)).done([=] {
channel->setUsernames(channel->username().isEmpty()
? Data::Usernames()
: Data::Usernames{
{ channel->username(), true, true }
});
continueSave();
}).send();
} else {
const auto lifetime = std::make_shared<rpl::lifetime>();
const auto newUsernames = (*_savingData.usernamesOrder);
_peer->session().api().usernames().reorder(
_peer,
newUsernames
) | rpl::start_with_done([=] {
channel->setUsernames(ranges::views::all(
newUsernames
) | ranges::views::transform([&](QString username) {
const auto editable =
(channel->username() == username);
return Data::Username{
.username = std::move(username),
.active = true,
.editable = editable,
};
}) | ranges::to_vector);
continueSave();
lifetime->destroy();
}, *lifetime);
}
}
void Controller::saveUsername() { void Controller::saveUsername() {
const auto channel = _peer->asChannel(); const auto channel = _peer->asChannel();
const auto username = (channel ? channel->username() : QString()); const auto username = (channel ? channel->username() : QString());
@ -1437,13 +1495,14 @@ void Controller::saveUsername() {
return; return;
} }
const auto newUsername = (*_savingData.username);
_api.request(MTPchannels_UpdateUsername( _api.request(MTPchannels_UpdateUsername(
channel->inputChannel, channel->inputChannel,
MTP_string(*_savingData.username) MTP_string(newUsername)
)).done([=] { )).done([=] {
channel->setName( channel->setName(
TextUtilities::SingleLine(channel->name()), TextUtilities::SingleLine(channel->name()),
*_savingData.username); newUsername);
continueSave(); continueSave();
}).fail([=](const MTP::Error &error) { }).fail([=](const MTP::Error &error) {
const auto &type = error.type(); const auto &type = error.type();

View file

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/edit_peer_info_box.h" // CreateButton. #include "boxes/peers/edit_peer_info_box.h" // CreateButton.
#include "boxes/peers/edit_peer_invite_link.h" #include "boxes/peers/edit_peer_invite_link.h"
#include "boxes/peers/edit_peer_invite_links.h" #include "boxes/peers/edit_peer_invite_links.h"
#include "boxes/peers/edit_peer_usernames_list.h"
#include "chat_helpers/emoji_suggestions_widget.h" #include "chat_helpers/emoji_suggestions_widget.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_chat.h" #include "data/data_chat.h"
@ -58,6 +59,7 @@ public:
void createContent(); void createContent();
[[nodiscard]] QString getUsernameInput() const; [[nodiscard]] QString getUsernameInput() const;
[[nodiscard]] std::vector<QString> usernamesOrder() const;
void setFocusUsername(); void setFocusUsername();
[[nodiscard]] rpl::producer<QString> getTitle() const { [[nodiscard]] rpl::producer<QString> getTitle() const {
@ -96,6 +98,7 @@ private:
std::shared_ptr<Ui::RadioenumGroup<Privacy>> privacy; std::shared_ptr<Ui::RadioenumGroup<Privacy>> privacy;
Ui::SlideWrap<Ui::RpWidget> *usernameWrap = nullptr; Ui::SlideWrap<Ui::RpWidget> *usernameWrap = nullptr;
Ui::UsernameInput *usernameInput = nullptr; Ui::UsernameInput *usernameInput = nullptr;
UsernamesList *usernamesList = nullptr;
base::unique_qptr<Ui::FlatLabel> usernameResult; base::unique_qptr<Ui::FlatLabel> usernameResult;
const style::FlatLabel *usernameResultStyle = nullptr; const style::FlatLabel *usernameResultStyle = nullptr;
@ -199,21 +202,6 @@ void Controller::createContent() {
} }
using namespace Settings; using namespace Settings;
AddSkip(_wrap.get());
_wrap->add(EditPeerInfoBox::CreateButton(
_wrap.get(),
tr::lng_group_invite_manage(),
rpl::single(QString()),
[=] {
const auto admin = _peer->session().user();
_show->showBox(
Box(ManageInviteLinksBox, _peer, admin, 0, 0),
Ui::LayerOption::KeepOther);
},
st::manageGroupButton,
{ &st::infoRoundedIconInviteLinks, Settings::kIconLightOrange }));
AddSkip(_wrap.get());
AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about());
if (!_linkOnly) { if (!_linkOnly) {
if (_peer->isMegagroup()) { if (_peer->isMegagroup()) {
@ -402,6 +390,10 @@ QString Controller::getUsernameInput() const {
return _controls.usernameInput->getLastText().trimmed(); return _controls.usernameInput->getLastText().trimmed();
} }
std::vector<QString> Controller::usernamesOrder() const {
return _controls.usernamesList->order();
}
object_ptr<Ui::RpWidget> Controller::createUsernameEdit() { object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
Expects(_wrap != nullptr); Expects(_wrap != nullptr);
@ -454,6 +446,9 @@ object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
container, container,
tr::lng_create_channel_link_about()); tr::lng_create_channel_link_about());
_controls.usernamesList = container->add(
object_ptr<UsernamesList>(container, channel, _show));
QObject::connect( QObject::connect(
_controls.usernameInput, _controls.usernameInput,
&Ui::UsernameInput::changed, &Ui::UsernameInput::changed,
@ -738,8 +733,11 @@ void EditPeerTypeBox::prepare() {
addButton(tr::lng_settings_save(), [=] { addButton(tr::lng_settings_save(), [=] {
const auto v = controller->getPrivacy(); const auto v = controller->getPrivacy();
if ((v == Privacy::HasUsername) && !controller->goodUsername()) { if ((v == Privacy::HasUsername) && !controller->goodUsername()) {
controller->setFocusUsername(); if (!controller->getUsernameInput().isEmpty()
return; || controller->usernamesOrder().empty()) {
controller->setFocusUsername();
return;
}
} }
auto local = std::move(*_savedCallback); auto local = std::move(*_savedCallback);
@ -748,6 +746,9 @@ void EditPeerTypeBox::prepare() {
.username = (v == Privacy::HasUsername .username = (v == Privacy::HasUsername
? controller->getUsernameInput() ? controller->getUsernameInput()
: QString()), : QString()),
.usernamesOrder = (v == Privacy::HasUsername
? controller->usernamesOrder()
: std::vector<QString>()),
.noForwards = controller->noForwards(), .noForwards = controller->noForwards(),
.joinToWrite = controller->joinToWrite(), .joinToWrite = controller->joinToWrite(),
.requestToJoin = controller->requestToJoin(), .requestToJoin = controller->requestToJoin(),

View file

@ -36,6 +36,7 @@ enum class UsernameState {
struct EditPeerTypeData { struct EditPeerTypeData {
Privacy privacy = Privacy::NoUsername; Privacy privacy = Privacy::NoUsername;
QString username; QString username;
std::vector<QString> usernamesOrder;
bool hasLinkedChat = false; bool hasLinkedChat = false;
bool noForwards = false; bool noForwards = false;
bool joinToWrite = false; bool joinToWrite = false;

View file

@ -361,7 +361,7 @@ void PublicsController::rowRightActionClicked(not_null<PeerListRow*> row) {
tr::now); tr::now);
const auto closeBox = _closeBox; const auto closeBox = _closeBox;
const auto once = std::make_shared<bool>(false); const auto once = std::make_shared<bool>(false);
auto callback = crl::guard(_navigation, [=](Fn<void()> &&close) { auto callback = crl::guard(_navigation, [=](Fn<void()> close) {
if (*once) { if (*once) {
return; return;
} }
@ -369,9 +369,13 @@ void PublicsController::rowRightActionClicked(not_null<PeerListRow*> row) {
peer->session().api().request(MTPchannels_UpdateUsername( peer->session().api().request(MTPchannels_UpdateUsername(
peer->asChannel()->inputChannel, peer->asChannel()->inputChannel,
MTP_string() MTP_string()
)).done([=, close = std::move(close)] { )).done([=] {
closeBox(); peer->session().api().request(MTPchannels_DeactivateAllUsernames(
close(); peer->asChannel()->inputChannel
)).done([=] {
closeBox();
close();
}).send();
}).send(); }).send();
}); });
_navigation->parentController()->show( _navigation->parentController()->show(

View file

@ -636,7 +636,7 @@ editPeerHistoryVisibilityLabelMargins: margins(34px, 0px, 48px, 0px);
editPeerPrivacyLabelMargins: margins(42px, 0px, 34px, 0px); editPeerPrivacyLabelMargins: margins(42px, 0px, 34px, 0px);
editPeerPreHistoryLabelMargins: margins(34px, 0px, 34px, 0px); editPeerPreHistoryLabelMargins: margins(34px, 0px, 34px, 0px);
editPeerUsernameTitleLabelMargins: margins(22px, 17px, 22px, 10px); editPeerUsernameTitleLabelMargins: margins(22px, 17px, 22px, 10px);
editPeerUsernameFieldMargins: margins(22px, 0px, 22px, 20px); editPeerUsernameFieldMargins: margins(22px, 0px, 22px, 16px);
editPeerUsername: setupChannelLink; editPeerUsername: setupChannelLink;
editPeerUsernameSkip: 8px; editPeerUsernameSkip: 8px;
editPeerInviteLink: FlatLabel(defaultFlatLabel) { editPeerInviteLink: FlatLabel(defaultFlatLabel) {