From d55ff7aa4af6597eeca4978a44bcb317f57571c5 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 12 Oct 2022 20:24:49 +0300 Subject: [PATCH] Added usernames list to peer type box for public channels. --- .../boxes/peers/edit_peer_info_box.cpp | 67 +++++++++++++++++-- .../boxes/peers/edit_peer_type_box.cpp | 35 +++++----- .../boxes/peers/edit_peer_type_box.h | 1 + .../SourceFiles/boxes/premium_limits_box.cpp | 12 ++-- Telegram/SourceFiles/info/info.style | 2 +- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 1f96380ef3..e2da7b5431 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "api/api_peer_photo.h" +#include "api/api_user_names.h" #include "main/main_session.h" #include "boxes/add_contact_box.h" #include "ui/boxes/confirm_box.h" @@ -264,6 +265,7 @@ private: }; struct Saving { std::optional username; + std::optional> usernamesOrder; std::optional title; std::optional description; std::optional hiddenPreHistory; @@ -303,6 +305,7 @@ private: void deleteChannel(); [[nodiscard]] std::optional validate() const; + [[nodiscard]] bool validateUsernamesOrder(Saving &to) const; [[nodiscard]] bool validateUsername(Saving &to) const; [[nodiscard]] bool validateLinkedChat(Saving &to) const; [[nodiscard]] bool validateTitle(Saving &to) const; @@ -315,6 +318,7 @@ private: [[nodiscard]] bool validateRequestToJoin(Saving &to) const; void save(); + void saveUsernamesOrder(); void saveUsername(); void saveLinkedChat(); void saveTitle(); @@ -1266,7 +1270,8 @@ void Controller::submitDescription() { std::optional Controller::validate() const { auto result = Saving(); - if (validateUsername(result) + if (validateUsernamesOrder(result) + && validateUsername(result) && validateLinkedChat(result) && validateTitle(result) && validateDescription(result) @@ -1281,6 +1286,17 @@ std::optional Controller::validate() const { return {}; } +bool Controller::validateUsernamesOrder(Saving &to) const { + if (!_typeDataSavedValue) { + return true; + } else if (_typeDataSavedValue->privacy != Privacy::HasUsername) { + to.usernamesOrder = std::vector(); + return true; + } + to.usernamesOrder = _typeDataSavedValue->usernamesOrder; + return true; +} + bool Controller::validateUsername(Saving &to) const { if (!_typeDataSavedValue) { return true; @@ -1290,7 +1306,8 @@ bool Controller::validateUsername(Saving &to) const { } const auto username = _typeDataSavedValue->username; if (username.isEmpty()) { - return false; + to.username = QString(); + return true; } to.username = username; return true; @@ -1387,6 +1404,7 @@ void Controller::save() { } if (const auto saving = validate()) { _savingData = *saving; + pushSaveStage([=] { saveUsernamesOrder(); }); pushSaveStage([=] { saveUsername(); }); pushSaveStage([=] { saveLinkedChat(); }); pushSaveStage([=] { saveTitle(); }); @@ -1418,6 +1436,46 @@ void Controller::cancelSave() { _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(); + 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() { const auto channel = _peer->asChannel(); const auto username = (channel ? channel->username() : QString()); @@ -1437,13 +1495,14 @@ void Controller::saveUsername() { return; } + const auto newUsername = (*_savingData.username); _api.request(MTPchannels_UpdateUsername( channel->inputChannel, - MTP_string(*_savingData.username) + MTP_string(newUsername) )).done([=] { channel->setName( TextUtilities::SingleLine(channel->name()), - *_savingData.username); + newUsername); continueSave(); }).fail([=](const MTP::Error &error) { const auto &type = error.type(); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index 11357d8f03..821dbc31bf 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -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_invite_link.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 "data/data_channel.h" #include "data/data_chat.h" @@ -58,6 +59,7 @@ public: void createContent(); [[nodiscard]] QString getUsernameInput() const; + [[nodiscard]] std::vector usernamesOrder() const; void setFocusUsername(); [[nodiscard]] rpl::producer getTitle() const { @@ -96,6 +98,7 @@ private: std::shared_ptr> privacy; Ui::SlideWrap *usernameWrap = nullptr; Ui::UsernameInput *usernameInput = nullptr; + UsernamesList *usernamesList = nullptr; base::unique_qptr usernameResult; const style::FlatLabel *usernameResultStyle = nullptr; @@ -199,21 +202,6 @@ void Controller::createContent() { } 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 (_peer->isMegagroup()) { @@ -402,6 +390,10 @@ QString Controller::getUsernameInput() const { return _controls.usernameInput->getLastText().trimmed(); } +std::vector Controller::usernamesOrder() const { + return _controls.usernamesList->order(); +} + object_ptr Controller::createUsernameEdit() { Expects(_wrap != nullptr); @@ -454,6 +446,9 @@ object_ptr Controller::createUsernameEdit() { container, tr::lng_create_channel_link_about()); + _controls.usernamesList = container->add( + object_ptr(container, channel, _show)); + QObject::connect( _controls.usernameInput, &Ui::UsernameInput::changed, @@ -738,8 +733,11 @@ void EditPeerTypeBox::prepare() { addButton(tr::lng_settings_save(), [=] { const auto v = controller->getPrivacy(); if ((v == Privacy::HasUsername) && !controller->goodUsername()) { - controller->setFocusUsername(); - return; + if (!controller->getUsernameInput().isEmpty() + || controller->usernamesOrder().empty()) { + controller->setFocusUsername(); + return; + } } auto local = std::move(*_savedCallback); @@ -748,6 +746,9 @@ void EditPeerTypeBox::prepare() { .username = (v == Privacy::HasUsername ? controller->getUsernameInput() : QString()), + .usernamesOrder = (v == Privacy::HasUsername + ? controller->usernamesOrder() + : std::vector()), .noForwards = controller->noForwards(), .joinToWrite = controller->joinToWrite(), .requestToJoin = controller->requestToJoin(), diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h index d69c79e92b..ae77872074 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h @@ -36,6 +36,7 @@ enum class UsernameState { struct EditPeerTypeData { Privacy privacy = Privacy::NoUsername; QString username; + std::vector usernamesOrder; bool hasLinkedChat = false; bool noForwards = false; bool joinToWrite = false; diff --git a/Telegram/SourceFiles/boxes/premium_limits_box.cpp b/Telegram/SourceFiles/boxes/premium_limits_box.cpp index dda1ae2d04..94f945cee0 100644 --- a/Telegram/SourceFiles/boxes/premium_limits_box.cpp +++ b/Telegram/SourceFiles/boxes/premium_limits_box.cpp @@ -361,7 +361,7 @@ void PublicsController::rowRightActionClicked(not_null row) { tr::now); const auto closeBox = _closeBox; const auto once = std::make_shared(false); - auto callback = crl::guard(_navigation, [=](Fn &&close) { + auto callback = crl::guard(_navigation, [=](Fn close) { if (*once) { return; } @@ -369,9 +369,13 @@ void PublicsController::rowRightActionClicked(not_null row) { peer->session().api().request(MTPchannels_UpdateUsername( peer->asChannel()->inputChannel, MTP_string() - )).done([=, close = std::move(close)] { - closeBox(); - close(); + )).done([=] { + peer->session().api().request(MTPchannels_DeactivateAllUsernames( + peer->asChannel()->inputChannel + )).done([=] { + closeBox(); + close(); + }).send(); }).send(); }); _navigation->parentController()->show( diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 18067e8160..309017a964 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -636,7 +636,7 @@ editPeerHistoryVisibilityLabelMargins: margins(34px, 0px, 48px, 0px); editPeerPrivacyLabelMargins: margins(42px, 0px, 34px, 0px); editPeerPreHistoryLabelMargins: margins(34px, 0px, 34px, 0px); editPeerUsernameTitleLabelMargins: margins(22px, 17px, 22px, 10px); -editPeerUsernameFieldMargins: margins(22px, 0px, 22px, 20px); +editPeerUsernameFieldMargins: margins(22px, 0px, 22px, 16px); editPeerUsername: setupChannelLink; editPeerUsernameSkip: 8px; editPeerInviteLink: FlatLabel(defaultFlatLabel) {