tdesktop/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp

774 lines
21 KiB
C++
Raw Normal View History

2019-03-16 16:58:32 +00:00
/*
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 "boxes/peers/edit_peer_type_box.h"
2019-03-16 16:58:32 +00:00
#include "apiwrap.h"
#include "auth_session.h"
#include "boxes/add_contact_box.h"
#include "boxes/confirm_box.h"
#include "boxes/peer_list_controllers.h"
#include "boxes/peers/edit_participants_box.h"
#include "chat_helpers/emoji_suggestions_widget.h"
#include "core/application.h"
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_peer.h"
#include "data/data_session.h"
2019-03-16 16:58:32 +00:00
#include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h"
#include "mainwindow.h"
#include "mtproto/sender.h"
#include "observer_peer.h"
#include "styles/style_boxes.h"
#include "styles/style_info.h"
#include "ui/rp_widget.h"
#include "ui/special_buttons.h"
#include "ui/toast/toast.h"
#include "ui/widgets/buttons.h"
2019-03-16 16:58:32 +00:00
#include "ui/widgets/checkbox.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "window/window_controller.h"
#include <rpl/flatten_latest.h>
namespace {
constexpr auto kUsernameCheckTimeout = crl::time(200);
constexpr auto kMinUsernameLength = 5;
class Controller
: public base::has_weak_ptr
, private MTP::Sender {
public:
Controller(
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue);
2019-03-16 16:58:32 +00:00
void createContent();
QString getUsernameInput();
void setFocusUsername();
LangKey getTitle() {
return _isInviteLink
? lng_profile_invite_link_section
: _isGroup
? lng_manage_peer_group_type
: lng_manage_peer_channel_type;
}
bool isInviteLink() {
return _isInviteLink;
}
bool isAllowSave() {
return _isAllowSave;
}
Privacy getPrivacy() {
return _controls.privacy->value();
}
2019-03-16 16:58:32 +00:00
private:
struct Controls {
std::shared_ptr<Ui::RadioenumGroup<Privacy>> privacy;
Ui::SlideWrap<Ui::RpWidget> *usernameWrap = nullptr;
Ui::UsernameInput *usernameInput = nullptr;
base::unique_qptr<Ui::FlatLabel> usernameResult;
const style::FlatLabel *usernameResultStyle = nullptr;
Ui::SlideWrap<Ui::RpWidget> *createInviteLinkWrap = nullptr;
Ui::SlideWrap<Ui::RpWidget> *editInviteLinkWrap = nullptr;
Ui::FlatLabel *inviteLink = nullptr;
};
Controls _controls;
2019-03-16 16:58:32 +00:00
object_ptr<Ui::RpWidget> createPrivaciesEdit();
object_ptr<Ui::RpWidget> createUsernameEdit();
object_ptr<Ui::RpWidget> createInviteLinkCreate();
object_ptr<Ui::RpWidget> createInviteLinkEdit();
void observeInviteLink();
void privacyChanged(Privacy value);
void checkUsernameAvailability();
void askUsernameRevoke();
void usernameChanged();
void showUsernameError(rpl::producer<QString> &&error);
void showUsernameGood();
void showUsernameResult(
rpl::producer<QString> &&text,
not_null<const style::FlatLabel*> st);
bool canEditInviteLink() const;
void refreshEditInviteLink();
void refreshCreateInviteLink();
void createInviteLink();
void revokeInviteLink();
void exportInviteLink(const QString &confirmation);
void fillPrivaciesButtons(
not_null<Ui::VerticalLayout*> parent,
std::optional<Privacy> savedValue = std::nullopt);
void addRoundButton(
not_null<Ui::VerticalLayout*> container,
Privacy value,
LangKey groupTextKey,
LangKey channelTextKey,
LangKey groupAboutKey,
LangKey channelAboutKey);
bool inviteLinkShown();
QString inviteLinkText();
2019-03-16 16:58:32 +00:00
void subscribeToMigration();
void migrate(not_null<ChannelData*> channel);
not_null<PeerData*> _peer;
std::optional<Privacy> _privacySavedValue = std::nullopt;
std::optional<QString> _usernameSavedValue = std::nullopt;
2019-03-16 16:58:32 +00:00
bool _isGroup = false;
bool _isInviteLink = false;
bool _isAllowSave = false;
2019-03-16 16:58:32 +00:00
base::unique_qptr<Ui::VerticalLayout> _wrap;
base::Timer _checkUsernameTimer;
mtpRequestId _checkUsernameRequestId = 0;
UsernameState _usernameState = UsernameState::Normal;
rpl::event_stream<rpl::producer<QString>> _usernameResultTexts;
rpl::lifetime _lifetime;
};
Controller::Controller(
not_null<Ui::VerticalLayout*> container,
not_null<PeerData*> peer,
std::optional<Privacy> privacySavedValue,
std::optional<QString> usernameSavedValue)
2019-03-16 16:58:32 +00:00
: _peer(peer)
, _privacySavedValue(privacySavedValue)
, _usernameSavedValue(usernameSavedValue)
2019-03-16 16:58:32 +00:00
, _isGroup(_peer->isChat() || _peer->isMegagroup())
, _isInviteLink(!_privacySavedValue.has_value() && !_usernameSavedValue.has_value())
, _isAllowSave(!_usernameSavedValue.value_or(QString()).isEmpty())
2019-03-16 16:58:32 +00:00
, _wrap(container)
, _checkUsernameTimer([=] { checkUsernameAvailability(); }) {
subscribeToMigration();
_peer->updateFull();
}
void Controller::subscribeToMigration() {
SubscribeToMigration(
_peer,
_lifetime,
[=](not_null<ChannelData*> channel) { migrate(channel); });
}
void Controller::migrate(not_null<ChannelData*> channel) {
_peer = channel;
observeInviteLink();
_peer->updateFull();
}
void Controller::createContent() {
_controls = Controls();
if (_isInviteLink) {
_wrap->add(createInviteLinkCreate());
_wrap->add(createInviteLinkEdit());
return;
}
2019-03-16 16:58:32 +00:00
fillPrivaciesButtons(_wrap, _privacySavedValue);
// Skip.
_wrap->add(object_ptr<BoxContentDivider>(_wrap));
//
2019-03-16 16:58:32 +00:00
_wrap->add(createInviteLinkCreate());
_wrap->add(createInviteLinkEdit());
_wrap->add(createUsernameEdit());
if (_controls.privacy->value() == Privacy::Private) {
checkUsernameAvailability();
}
2019-03-16 16:58:32 +00:00
}
void Controller::addRoundButton(
not_null<Ui::VerticalLayout*> container,
Privacy value,
LangKey groupTextKey,
LangKey channelTextKey,
LangKey groupAboutKey,
LangKey channelAboutKey) {
container->add(object_ptr<Ui::Radioenum<Privacy>>(
container,
_controls.privacy,
value,
lang(_isGroup ? groupTextKey : channelTextKey),
st::editPeerPrivacyBoxCheckbox));
container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
container,
object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(_isGroup ? groupAboutKey : channelAboutKey),
st::editPeerPrivacyLabel),
st::editPeerPrivacyLabelMargins));
container->add(object_ptr<Ui::FixedHeightWidget>(
container,
st::editPeerPrivacyBottomSkip));
};
void Controller::fillPrivaciesButtons(
not_null<Ui::VerticalLayout*> parent,
std::optional<Privacy> savedValue) {
const auto canEditUsername = [&] {
if (const auto chat = _peer->asChat()) {
return chat->canEditUsername();
} else if (const auto channel = _peer->asChannel()) {
return channel->canEditUsername();
}
Unexpected("Peer type in Controller::createPrivaciesEdit.");
}();
if (!canEditUsername) {
return;
}
const auto result = parent->add(object_ptr<Ui::PaddingWrap<Ui::VerticalLayout>>(
parent,
object_ptr<Ui::VerticalLayout>(parent),
st::editPeerPrivaciesMargins));
auto container = result->entity();
const auto isPublic = _peer->isChannel()
&& _peer->asChannel()->isPublic();
_controls.privacy = std::make_shared<Ui::RadioenumGroup<Privacy>>(
savedValue.value_or(isPublic ? Privacy::Public : Privacy::Private));
addRoundButton(
container,
Privacy::Public,
lng_create_public_group_title,
lng_create_public_channel_title,
lng_create_public_group_about,
lng_create_public_channel_about);
addRoundButton(
container,
Privacy::Private,
lng_create_private_group_title,
lng_create_private_channel_title,
lng_create_private_group_about,
lng_create_private_channel_about);
_controls.privacy->setChangedCallback([=](Privacy value) {
privacyChanged(value);
});
if (!isPublic) {
// checkUsernameAvailability();
}
// return std::move(result);
}
void Controller::setFocusUsername() {
if (_controls.usernameInput) {
_controls.usernameInput->setFocus();
}
}
QString Controller::getUsernameInput() {
return _controls.usernameInput->getLastText().trimmed();
}
QString Controller::inviteLinkText() {
if (const auto channel = _peer->asChannel()) {
return channel->inviteLink();
} else if (const auto chat = _peer->asChat()) {
return chat->inviteLink();
}
return QString();
}
2019-03-16 16:58:32 +00:00
object_ptr<Ui::RpWidget> Controller::createUsernameEdit() {
Expects(_wrap != nullptr);
const auto channel = _peer->asChannel();
const auto username = _usernameSavedValue.value_or(channel ? channel->username : QString());
2019-03-16 16:58:32 +00:00
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap,
object_ptr<Ui::VerticalLayout>(_wrap),
st::editPeerUsernameMargins);
_controls.usernameWrap = result.data();
2019-03-16 16:58:32 +00:00
auto container = result->entity();
container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
2019-03-16 16:58:32 +00:00
container,
object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(lng_create_group_link),
st::editPeerSectionLabel),
st::editPeerUsernameTitleLabelMargins));
2019-03-16 16:58:32 +00:00
auto placeholder = container->add(object_ptr<Ui::RpWidget>(
container));
placeholder->setAttribute(Qt::WA_TransparentForMouseEvents);
_controls.usernameInput = Ui::AttachParentChild(
2019-03-16 16:58:32 +00:00
container,
object_ptr<Ui::UsernameInput>(
container,
st::setupChannelLink,
Fn<QString()>(),
username,
true));
_controls.usernameInput->heightValue(
2019-03-16 16:58:32 +00:00
) | rpl::start_with_next([placeholder](int height) {
placeholder->resize(placeholder->width(), height);
}, placeholder->lifetime());
placeholder->widthValue(
) | rpl::start_with_next([this](int width) {
_controls.usernameInput->resize(
2019-03-16 16:58:32 +00:00
width,
_controls.usernameInput->height());
2019-03-16 16:58:32 +00:00
}, placeholder->lifetime());
_controls.usernameInput->move(placeholder->pos());
container->add(object_ptr<Ui::PaddingWrap<Ui::FlatLabel>>(
container,
object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(lng_create_channel_link_about),
st::editPeerPrivacyLabel),
st::editPeerUsernameAboutLabelMargins));
2019-03-16 16:58:32 +00:00
QObject::connect(
_controls.usernameInput,
2019-03-16 16:58:32 +00:00
&Ui::UsernameInput::changed,
[this] { usernameChanged(); });
auto shown = (_controls.privacy->value() == Privacy::Public);
2019-03-16 16:58:32 +00:00
result->toggle(shown, anim::type::instant);
return std::move(result);
}
void Controller::privacyChanged(Privacy value) {
auto toggleEditUsername = [&] {
_controls.usernameWrap->toggle(
2019-03-16 16:58:32 +00:00
(value == Privacy::Public),
anim::type::instant);
};
auto refreshVisibilities = [&] {
// Now first we need to hide that was shown.
// Otherwise box will change own Y position.
if (value == Privacy::Public) {
refreshCreateInviteLink();
refreshEditInviteLink();
toggleEditUsername();
_controls.usernameResult = nullptr;
2019-03-16 16:58:32 +00:00
checkUsernameAvailability();
} else {
toggleEditUsername();
refreshCreateInviteLink();
refreshEditInviteLink();
}
};
if (value == Privacy::Public) {
if (_usernameState == UsernameState::TooMany) {
askUsernameRevoke();
return;
} else if (_usernameState == UsernameState::NotAvailable) {
_controls.privacy->setValue(Privacy::Private);
2019-03-16 16:58:32 +00:00
return;
}
refreshVisibilities();
_controls.usernameInput->setDisplayFocused(true);
setFocusUsername();
// _box->scrollToWidget(_controls.usernameInput);
2019-03-16 16:58:32 +00:00
} else {
request(base::take(_checkUsernameRequestId)).cancel();
_checkUsernameTimer.cancel();
refreshVisibilities();
setFocusUsername();
2019-03-16 16:58:32 +00:00
}
}
void Controller::checkUsernameAvailability() {
if (!_controls.usernameInput) {
2019-03-16 16:58:32 +00:00
return;
}
auto initial = (_controls.privacy->value() != Privacy::Public);
2019-03-16 16:58:32 +00:00
auto checking = initial
? qsl(".bad.")
: getUsernameInput();
2019-03-16 16:58:32 +00:00
if (checking.size() < kMinUsernameLength) {
return;
}
if (_checkUsernameRequestId) {
request(_checkUsernameRequestId).cancel();
}
const auto channel = _peer->migrateToOrMe()->asChannel();
const auto username = channel ? channel->username : QString();
_checkUsernameRequestId = request(MTPchannels_CheckUsername(
channel ? channel->inputChannel : MTP_inputChannelEmpty(),
MTP_string(checking)
)).done([=](const MTPBool &result) {
_checkUsernameRequestId = 0;
if (initial) {
return;
}
if (!mtpIsTrue(result) && checking != username) {
showUsernameError(
Lang::Viewer(lng_create_channel_link_occupied));
} else {
showUsernameGood();
}
}).fail([=](const RPCError &error) {
_checkUsernameRequestId = 0;
const auto &type = error.type();
_usernameState = UsernameState::Normal;
if (type == qstr("CHANNEL_PUBLIC_GROUP_NA")) {
_usernameState = UsernameState::NotAvailable;
_controls.privacy->setValue(Privacy::Private);
2019-03-16 16:58:32 +00:00
} else if (type == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) {
_usernameState = UsernameState::TooMany;
if (_controls.privacy->value() == Privacy::Public) {
2019-03-16 16:58:32 +00:00
askUsernameRevoke();
}
} else if (initial) {
if (_controls.privacy->value() == Privacy::Public) {
_controls.usernameResult = nullptr;
setFocusUsername();
// _box->scrollToWidget(_controls.usernameInput);
2019-03-16 16:58:32 +00:00
}
} else if (type == qstr("USERNAME_INVALID")) {
showUsernameError(
Lang::Viewer(lng_create_channel_link_invalid));
} else if (type == qstr("USERNAME_OCCUPIED")
&& checking != username) {
showUsernameError(
Lang::Viewer(lng_create_channel_link_occupied));
}
}).send();
}
void Controller::askUsernameRevoke() {
_controls.privacy->setValue(Privacy::Private);
2019-03-16 16:58:32 +00:00
auto revokeCallback = crl::guard(this, [this] {
_usernameState = UsernameState::Normal;
_controls.privacy->setValue(Privacy::Public);
2019-03-16 16:58:32 +00:00
checkUsernameAvailability();
});
Ui::show(
Box<RevokePublicLinkBox>(std::move(revokeCallback)),
LayerOption::KeepOther);
}
void Controller::usernameChanged() {
_isAllowSave = false;
auto username = getUsernameInput();
2019-03-16 16:58:32 +00:00
if (username.isEmpty()) {
_controls.usernameResult = nullptr;
2019-03-16 16:58:32 +00:00
_checkUsernameTimer.cancel();
return;
}
auto bad = ranges::find_if(username, [](QChar ch) {
return (ch < 'A' || ch > 'Z')
&& (ch < 'a' || ch > 'z')
&& (ch < '0' || ch > '9')
&& (ch != '_');
}) != username.end();
if (bad) {
showUsernameError(
Lang::Viewer(lng_create_channel_link_bad_symbols));
} else if (username.size() < kMinUsernameLength) {
showUsernameError(
Lang::Viewer(lng_create_channel_link_too_short));
} else {
_controls.usernameResult = nullptr;
2019-03-16 16:58:32 +00:00
_checkUsernameTimer.callOnce(kUsernameCheckTimeout);
}
}
void Controller::showUsernameError(rpl::producer<QString> &&error) {
showUsernameResult(std::move(error), &st::editPeerUsernameError);
}
void Controller::showUsernameGood() {
_isAllowSave = true;
2019-03-16 16:58:32 +00:00
showUsernameResult(
Lang::Viewer(lng_create_channel_link_available),
&st::editPeerUsernameGood);
}
void Controller::showUsernameResult(
rpl::producer<QString> &&text,
not_null<const style::FlatLabel*> st) {
if (!_controls.usernameResult
|| _controls.usernameResultStyle != st) {
_controls.usernameResultStyle = st;
_controls.usernameResult = base::make_unique_q<Ui::FlatLabel>(
_controls.usernameWrap,
2019-03-16 16:58:32 +00:00
_usernameResultTexts.events() | rpl::flatten_latest(),
*st);
auto label = _controls.usernameResult.get();
2019-03-16 16:58:32 +00:00
label->show();
label->widthValue(
) | rpl::start_with_next([label] {
label->moveToRight(
st::editPeerUsernamePosition.x(),
st::editPeerUsernamePosition.y());
}, label->lifetime());
}
_usernameResultTexts.fire(std::move(text));
}
void Controller::createInviteLink() {
exportInviteLink(lang(_isGroup
? lng_group_invite_about
: lng_group_invite_about_channel));
}
void Controller::revokeInviteLink() {
exportInviteLink(lang(lng_group_invite_about_new));
}
void Controller::exportInviteLink(const QString &confirmation) {
auto boxPointer = std::make_shared<QPointer<ConfirmBox>>();
auto callback = crl::guard(this, [=] {
if (const auto strong = *boxPointer) {
strong->closeBox();
}
_peer->session().api().exportInviteLink(_peer->migrateToOrMe());
});
auto box = Box<ConfirmBox>(
confirmation,
std::move(callback));
*boxPointer = Ui::show(std::move(box), LayerOption::KeepOther);
}
bool Controller::canEditInviteLink() const {
if (const auto channel = _peer->asChannel()) {
return channel->amCreator()
|| (channel->adminRights() & ChatAdminRight::f_invite_users);
} else if (const auto chat = _peer->asChat()) {
return chat->amCreator()
|| (chat->adminRights() & ChatAdminRight::f_invite_users);
}
return false;
}
void Controller::observeInviteLink() {
if (!_controls.editInviteLinkWrap) {
2019-03-16 16:58:32 +00:00
return;
}
// return; //
Notify::PeerUpdateValue(
_peer,
Notify::PeerUpdate::Flag::InviteLinkChanged
) | rpl::start_with_next([=] {
refreshCreateInviteLink();
refreshEditInviteLink();
}, _controls.editInviteLinkWrap->lifetime());
2019-03-16 16:58:32 +00:00
}
object_ptr<Ui::RpWidget> Controller::createInviteLinkEdit() {
Expects(_wrap != nullptr);
if (!canEditInviteLink()) {
return nullptr;
}
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap,
object_ptr<Ui::VerticalLayout>(_wrap),
st::editPeerInvitesMargins);
_controls.editInviteLinkWrap = result.data();
2019-03-16 16:58:32 +00:00
auto container = result->entity();
if (!_isInviteLink) {
container->add(object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(lng_profile_invite_link_section),
st::editPeerSectionLabel));
container->add(object_ptr<Ui::FixedHeightWidget>(
container,
st::editPeerInviteLinkBoxBottomSkip));
}
2019-03-16 16:58:32 +00:00
_controls.inviteLink = container->add(object_ptr<Ui::FlatLabel>(
2019-03-16 16:58:32 +00:00
container,
st::editPeerInviteLink));
_controls.inviteLink->setSelectable(true);
_controls.inviteLink->setContextCopyText(QString());
_controls.inviteLink->setBreakEverywhere(true);
_controls.inviteLink->setClickHandlerFilter([=](auto&&...) {
QApplication::clipboard()->setText(inviteLinkText());
2019-03-16 16:58:32 +00:00
Ui::Toast::Show(lang(lng_group_invite_copied));
return false;
});
container->add(object_ptr<Ui::FixedHeightWidget>(
container,
st::editPeerInviteLinkSkip));
container->add(object_ptr<Ui::LinkButton>(
container,
lang(lng_group_invite_create_new),
st::editPeerInviteLinkButton)
)->addClickHandler([=] { revokeInviteLink(); });
observeInviteLink();
return std::move(result);
}
void Controller::refreshEditInviteLink() {
auto link = inviteLinkText();
2019-03-16 16:58:32 +00:00
auto text = TextWithEntities();
if (!link.isEmpty()) {
text.text = link;
auto remove = qstr("https://");
if (text.text.startsWith(remove)) {
text.text.remove(0, remove.size());
}
text.entities.push_back(EntityInText(
EntityInTextCustomUrl,
0,
text.text.size(),
link));
}
_controls.inviteLink->setMarkedText(text);
2019-03-16 16:58:32 +00:00
// Hack to expand FlatLabel width to naturalWidth again.
_controls.editInviteLinkWrap->resizeToWidth(st::boxWideWidth);
2019-03-16 16:58:32 +00:00
_controls.editInviteLinkWrap->toggle(
inviteLinkShown() && !link.isEmpty(),
2019-03-16 16:58:32 +00:00
anim::type::instant);
}
object_ptr<Ui::RpWidget> Controller::createInviteLinkCreate() {
Expects(_wrap != nullptr);
if (!canEditInviteLink()) {
return nullptr;
}
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
_wrap,
object_ptr<Ui::VerticalLayout>(_wrap),
st::editPeerInvitesMargins);
2019-03-16 16:58:32 +00:00
auto container = result->entity();
if (!_isInviteLink) {
container->add(object_ptr<Ui::FlatLabel>(
container,
Lang::Viewer(lng_profile_invite_link_section),
st::editPeerSectionLabel));
container->add(object_ptr<Ui::FixedHeightWidget>(
container,
st::editPeerInviteLinkSkip));
}
2019-03-16 16:58:32 +00:00
container->add(object_ptr<Ui::LinkButton>(
_wrap,
lang(lng_group_invite_create),
st::editPeerInviteLinkButton)
)->addClickHandler([this] {
createInviteLink();
});
_controls.createInviteLinkWrap = result.data();
2019-03-16 16:58:32 +00:00
observeInviteLink();
return std::move(result);
}
void Controller::refreshCreateInviteLink() {
_controls.createInviteLinkWrap->toggle(
inviteLinkShown() && inviteLinkText().isEmpty(),
2019-03-16 16:58:32 +00:00
anim::type::instant);
}
bool Controller::inviteLinkShown() {
return !_controls.privacy
|| (_controls.privacy->value() == Privacy::Private)
|| _isInviteLink;
}
2019-03-16 16:58:32 +00:00
} // namespace
EditPeerTypeBox::EditPeerTypeBox(
2019-03-16 16:58:32 +00:00
QWidget*,
not_null<PeerData*> peer,
2019-03-16 16:58:32 +00:00
FnMut<void(Privacy, QString)> savedCallback,
std::optional<Privacy> privacySaved,
std::optional<QString> usernameSaved)
: _peer(peer)
, _savedCallback(std::move(savedCallback))
, _privacySavedValue(privacySaved)
, _usernameSavedValue(usernameSaved) {
2019-03-16 16:58:32 +00:00
}
void EditPeerTypeBox::prepare() {
2019-03-16 16:58:32 +00:00
_peer->updateFull();
2019-03-16 16:58:32 +00:00
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
auto controller = Ui::CreateChild<Controller>(
this,
content,
_peer,
_privacySavedValue,
_usernameSavedValue);
2019-03-16 16:58:32 +00:00
_focusRequests.events(
) | rpl::start_with_next(
[=] { controller->setFocusUsername(); },
2019-03-16 16:58:32 +00:00
lifetime());
controller->createContent();
setTitle(langFactory(controller->getTitle()));
if (!controller->isInviteLink()) {
addButton(langFactory(lng_settings_save), [=] {
const auto v = controller->getPrivacy();
if (!controller->isAllowSave() && (v == Privacy::Public)) {
controller->setFocusUsername();
return;
}
auto local = std::move(_savedCallback);
local(v,
(v == Privacy::Public)
? controller->getUsernameInput()
: QString()); // We dont need username with private type.
closeBox();
});
}
addButton(langFactory(controller->isInviteLink() ? lng_close : lng_cancel), [=] { closeBox(); });
2019-03-16 16:58:32 +00:00
setDimensionsToContent(st::boxWideWidth, content);
}
void EditPeerTypeBox::setupContent() {
}