From cb272be805d7c674a78b4570162b9cf777841ff5 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Sun, 17 Mar 2019 10:00:58 +0300 Subject: [PATCH] Refactored code. Slightly improved animations and design. --- .../boxes/peers/edit_peer_group_type_box.cpp | 4 +- .../boxes/peers/edit_peer_info_box.cpp | 608 ++---------------- Telegram/SourceFiles/info/info.style | 3 +- 3 files changed, 61 insertions(+), 554 deletions(-) diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_group_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_group_type_box.cpp index 1f4ca4e68..fa12005fb 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_group_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_group_type_box.cpp @@ -764,7 +764,7 @@ EditPeerGroupTypeBox::EditPeerGroupTypeBox( peer = p; privacySavedValue = privacySaved; usernameSavedValue = usernameSaved; - allowSave = !usernameSaved->isEmpty(); + allowSave = !usernameSaved->isEmpty() && usernameSaved.has_value(); } void EditPeerGroupTypeBox::prepare() { @@ -773,7 +773,7 @@ void EditPeerGroupTypeBox::prepare() { setTitle(langFactory((peer->isChat() || peer->isMegagroup()) ? lng_manage_peer_group_type : lng_manage_peer_channel_type)); - + addButton(langFactory(lng_settings_save), [=] { const auto v = privacyButtons->value(); if (!allowSave && (v == Privacy::Public)) { diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 828a1d535..b6a3773ac 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -66,6 +66,13 @@ auto ToPositiveNumberStringRestrictions() { }); } +void AddSkip(not_null container) { + container->add(object_ptr( + container, + st::editPeerSkip)); + container->add(object_ptr(container)); +} + Info::Profile::Button *AddButton( not_null parent, rpl::producer &&text, @@ -317,7 +324,6 @@ private: object_ptr createTitleEdit(); object_ptr createPhotoEdit(); object_ptr createDescriptionEdit(); - object_ptr createPrivaciesEdit(); object_ptr createUsernameEdit(); object_ptr createInviteLinkCreate(); object_ptr createInviteLinkEdit(); @@ -334,25 +340,8 @@ private: void submitDescription(); void deleteWithConfirmation(); void deleteChannel(); - void privacyChanged(Privacy value); - void checkUsernameAvailability(); - void askUsernameRevoke(); - void usernameChanged(); - void showUsernameError(rpl::producer &&error); - void showUsernameGood(); - void showUsernameResult( - rpl::producer &&text, - not_null st); - - bool canEditInviteLink() const; - bool inviteLinkShown() const; - void refreshEditInviteLink(); - void refreshCreateInviteLink(); - void refreshHistoryVisibility(); - void createInviteLink(); - void revokeInviteLink(); - void exportInviteLink(const QString &confirmation); + void refreshHistoryVisibility(bool instant = false); std::optional validate() const; bool validateUsername(Saving &to) const; @@ -381,7 +370,6 @@ private: base::unique_qptr _wrap; Controls _controls; - base::Timer _checkUsernameTimer; mtpRequestId _checkUsernameRequestId = 0; UsernameState _usernameState = UsernameState::Normal; rpl::event_stream> _usernameResultTexts; @@ -398,8 +386,7 @@ Controller::Controller( not_null peer) : _box(box) , _peer(peer) -, _isGroup(_peer->isChat() || _peer->isMegagroup()) -, _checkUsernameTimer([=] { checkUsernameAvailability(); }) { +, _isGroup(_peer->isChat() || _peer->isMegagroup()) { _box->setTitle(computeTitle()); _box->addButton(langFactory(lng_settings_save), [this] { save(); @@ -420,7 +407,7 @@ void Controller::subscribeToMigration() { void Controller::migrate(not_null channel) { _peer = channel; - observeInviteLink(); + // observeInviteLink(); _peer->updateFull(); } @@ -435,28 +422,15 @@ object_ptr Controller::createContent() { _wrap.reset(result.data()); _controls = Controls(); - const auto addSkip = [](not_null container) { - container->add(object_ptr( - container, - 7 /*Create skip in style.*/)); - container->add(object_ptr(container)); - /*container->add(object_ptr( - container, - st::editPeerPrivacyTopSkip));*/ - }; - _wrap->add(createPhotoAndTitleEdit()); _wrap->add(createDescriptionEdit()); - addSkip(_wrap); // Divider. + AddSkip(_wrap); // Divider. _wrap->add(createPrivaciesButtons()); - addSkip(_wrap); // Divider. + AddSkip(_wrap); // Divider. _wrap->add(createManageGroupButtons()); - addSkip(_wrap); // Divider. + AddSkip(_wrap); // Divider. - _wrap->add(createPrivaciesEdit()); - _wrap->add(createInviteLinkCreate()); - _wrap->add(createInviteLinkEdit()); _wrap->add(createStickersEdit()); _wrap->add(createDeleteButton()); @@ -584,81 +558,6 @@ object_ptr Controller::createDescriptionEdit() { return std::move(result); } -object_ptr Controller::createPrivaciesEdit() { - Expects(_wrap != nullptr); - - 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 nullptr; - } - auto result = object_ptr>( - _wrap, - object_ptr(_wrap), - st::editPeerPrivaciesMargins); - auto container = result->entity(); - - const auto isPublic = _peer->isChannel() - && _peer->asChannel()->isPublic(); - _controls.privacy = std::make_shared>( - isPublic ? Privacy::Public : Privacy::Private); - auto addButton = [&]( - Privacy value, - LangKey groupTextKey, - LangKey channelTextKey, - LangKey groupAboutKey, - LangKey channelAboutKey) { - container->add(object_ptr( - container, - st::editPeerPrivacyTopSkip)); - container->add(object_ptr>( - container, - _controls.privacy, - value, - lang(_isGroup ? groupTextKey : channelTextKey), - st::defaultBoxCheckbox)); - container->add(object_ptr>( - container, - object_ptr( - container, - Lang::Viewer(_isGroup ? groupAboutKey : channelAboutKey), - st::editPeerPrivacyLabel), - st::editPeerHistoryVisibilityLabelMargins)); - container->add(object_ptr( - container, - st::editPeerPrivacyBottomSkip)); - }; - addButton( - Privacy::Public, - lng_create_public_group_title, - lng_create_public_channel_title, - lng_create_public_group_about, - lng_create_public_channel_about); - addButton( - Privacy::Private, - lng_create_private_group_title, - lng_create_private_channel_title, - lng_create_private_group_about, - lng_create_private_channel_about); - container->add(createUsernameEdit()); - - _controls.privacy->setChangedCallback([this](Privacy value) { - privacyChanged(value); - }); - if (!isPublic) { - checkUsernameAvailability(); - } - - return std::move(result); -} - - object_ptr Controller::createPrivaciesButtons() { Expects(_wrap != nullptr); @@ -674,18 +573,15 @@ object_ptr Controller::createPrivaciesButtons() { return nullptr; } - // Bug with defaultValue here. const auto channel = _peer->asChannel(); - auto defaultValue = (!channel || channel->hiddenPreHistory()) - ? HistoryVisibility::Hidden - : HistoryVisibility::Visible; + auto isRealChannel = !(!channel || !channel->canEditSignatures() || channel->isMegagroup()); - auto defaultValuePrivacy = (_peer->isChannel() + // Create Privacy Button. + _controls.privacySavedValue = (_peer->isChannel() && _peer->asChannel()->isPublic()) ? Privacy::Public : Privacy::Private; - const auto updateHistoryVisibility = std::make_shared>(); const auto updateType = std::make_shared>(); auto result = object_ptr>( @@ -722,7 +618,34 @@ object_ptr Controller::createPrivaciesButtons() { }), buttonCallback); + updateType->fire(std::move(_controls.privacySavedValue.value())); + + // Create Signatures Toggle Button. + if (isRealChannel) { + AddButtonWithText( + resultContainer, + std::move(Lang::Viewer(lng_edit_sign_messages)), + rpl::single(QString()), + [=] {} + )->toggleOn(rpl::single(channel->addsSignature()) + )->toggledValue( + ) | rpl::start_with_next([=](bool toggled) { + _controls.signaturesSavedValue = toggled; + }, resultContainer->lifetime()); + + return std::move(result); + } + + // Create History Visibility Button. + const auto addHistoryVisibilityButton = [=](LangKey privacyTextKey, Ui::VerticalLayout* container) { + // Bug with defaultValue here. + _controls.historyVisibilitySavedValue = (!channel || channel->hiddenPreHistory()) + ? HistoryVisibility::Hidden + : HistoryVisibility::Visible; + + const auto updateHistoryVisibility = std::make_shared>(); + const auto boxCallback = [=](HistoryVisibility checked) { updateHistoryVisibility->fire(std::move(checked)); _controls.historyVisibilitySavedValue = checked; @@ -744,6 +667,10 @@ object_ptr Controller::createPrivaciesButtons() { : lng_manage_history_visibility_hidden); }), buttonCallback); + + updateHistoryVisibility->fire( + std::move(_controls.historyVisibilitySavedValue.value()) + ); }; auto wrapLayout = resultContainer->add(object_ptr>( @@ -753,27 +680,9 @@ object_ptr Controller::createPrivaciesButtons() { _controls.historyVisibilityWrap = wrapLayout; addHistoryVisibilityButton(lng_manage_history_visibility_title, wrapLayout->entity()); - - updateHistoryVisibility->fire(std::move(defaultValue)); - updateType->fire(std::move(defaultValuePrivacy)); - refreshHistoryVisibility(); - // Draw Signatures toggle button. - if (!channel - || !channel->canEditSignatures() - || channel->isMegagroup()) { - return std::move(result); - } - AddButtonWithText( - resultContainer, - std::move(Lang::Viewer(lng_edit_sign_messages)), - rpl::single(QString()), - [=] {} - )->toggleOn(rpl::single(channel->addsSignature()) - )->toggledValue( - ) | rpl::start_with_next([=](bool toggled) { - _controls.signaturesSavedValue = toggled; - }, resultContainer->lifetime()); + //While appearing box we should use instant animation. + refreshHistoryVisibility(true); return std::move(result); } @@ -797,414 +706,13 @@ object_ptr Controller::createManageGroupButtons() { return std::move(result); } -object_ptr Controller::createUsernameEdit() { - Expects(_wrap != nullptr); - - const auto channel = _peer->asChannel(); - const auto username = channel ? channel->username : QString(); - - auto result = object_ptr>( - _wrap, - object_ptr(_wrap), - st::editPeerUsernameMargins); - _controls.usernameWrap = result.data(); - - auto container = result->entity(); - container->add(object_ptr( - container, - Lang::Viewer(lng_create_group_link), - st::editPeerSectionLabel)); - auto placeholder = container->add(object_ptr( - container)); - placeholder->setAttribute(Qt::WA_TransparentForMouseEvents); - _controls.username = Ui::AttachParentChild( - container, - object_ptr( - container, - st::setupChannelLink, - Fn(), - username, - true)); - _controls.username->heightValue( - ) | rpl::start_with_next([placeholder](int height) { - placeholder->resize(placeholder->width(), height); - }, placeholder->lifetime()); - placeholder->widthValue( - ) | rpl::start_with_next([this](int width) { - _controls.username->resize( - width, - _controls.username->height()); - }, placeholder->lifetime()); - _controls.username->move(placeholder->pos()); - - QObject::connect( - _controls.username, - &Ui::UsernameInput::changed, - [this] { usernameChanged(); }); - - auto shown = (_controls.privacy->value() == Privacy::Public); - result->toggle(shown, anim::type::instant); - - return std::move(result); -} - -void Controller::privacyChanged(Privacy value) { - auto toggleEditUsername = [&] { - _controls.usernameWrap->toggle( - (value == Privacy::Public), - anim::type::instant); - }; - auto refreshVisibilities = [&] { - // First we need to show everything, then hide anything. - // Otherwise the scroll position could jump up undesirably. - - if (value == Privacy::Public) { - toggleEditUsername(); - } - refreshCreateInviteLink(); - refreshEditInviteLink(); - refreshHistoryVisibility(); - if (value == Privacy::Public) { - _controls.usernameResult = nullptr; - checkUsernameAvailability(); - } else { - toggleEditUsername(); - } - }; - if (value == Privacy::Public) { - if (_usernameState == UsernameState::TooMany) { - askUsernameRevoke(); - return; - } else if (_usernameState == UsernameState::NotAvailable) { - _controls.privacy->setValue(Privacy::Private); - return; - } - refreshVisibilities(); - _controls.username->setDisplayFocused(true); - _controls.username->setFocus(); - _box->scrollToWidget(_controls.username); - } else { - request(base::take(_checkUsernameRequestId)).cancel(); - _checkUsernameTimer.cancel(); - refreshVisibilities(); - setFocus(); - } -} - -void Controller::checkUsernameAvailability() { - if (!_controls.username) { - return; - } - auto initial = (_controls.privacy->value() != Privacy::Public); - auto checking = initial - ? qsl(".bad.") - : _controls.username->getLastText().trimmed(); - 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); - } else if (type == qstr("CHANNELS_ADMIN_PUBLIC_TOO_MUCH")) { - _usernameState = UsernameState::TooMany; - if (_controls.privacy->value() == Privacy::Public) { - askUsernameRevoke(); - } - } else if (initial) { - if (_controls.privacy->value() == Privacy::Public) { - _controls.usernameResult = nullptr; - _controls.username->setFocus(); - _box->scrollToWidget(_controls.username); - } - } 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); - auto revokeCallback = crl::guard(this, [this] { - _usernameState = UsernameState::Normal; - _controls.privacy->setValue(Privacy::Public); - checkUsernameAvailability(); - }); - Ui::show( - Box(std::move(revokeCallback)), - LayerOption::KeepOther); -} - -void Controller::usernameChanged() { - auto username = _controls.username->getLastText().trimmed(); - if (username.isEmpty()) { - _controls.usernameResult = nullptr; - _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; - _checkUsernameTimer.callOnce(kUsernameCheckTimeout); - } -} - -void Controller::showUsernameError(rpl::producer &&error) { - showUsernameResult(std::move(error), &st::editPeerUsernameError); -} - -void Controller::showUsernameGood() { - showUsernameResult( - Lang::Viewer(lng_create_channel_link_available), - &st::editPeerUsernameGood); -} - -void Controller::showUsernameResult( - rpl::producer &&text, - not_null st) { - if (!_controls.usernameResult - || _controls.usernameResultStyle != st) { - _controls.usernameResultStyle = st; - _controls.usernameResult = base::make_unique_q( - _controls.usernameWrap, - _usernameResultTexts.events() | rpl::flatten_latest(), - *st); - auto label = _controls.usernameResult.get(); - 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>(); - auto callback = crl::guard(this, [=] { - if (const auto strong = *boxPointer) { - strong->closeBox(); - } - _peer->session().api().exportInviteLink(_peer->migrateToOrMe()); - }); - auto box = Box( - 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; -} - -bool Controller::inviteLinkShown() const { - return !_controls.privacy - || (_controls.privacy->value() == Privacy::Private); -} - -QString Controller::inviteLinkText() const { - if (const auto channel = _peer->asChannel()) { - return channel->inviteLink(); - } else if (const auto chat = _peer->asChat()) { - return chat->inviteLink(); - } - return QString(); -} - -void Controller::observeInviteLink() { - if (!_controls.editInviteLinkWrap) { - return; - } - Notify::PeerUpdateValue( - _peer, - Notify::PeerUpdate::Flag::InviteLinkChanged - ) | rpl::start_with_next([=] { - refreshCreateInviteLink(); - refreshEditInviteLink(); - }, _controls.editInviteLinkWrap->lifetime()); -} - -object_ptr Controller::createInviteLinkEdit() { - Expects(_wrap != nullptr); - - if (!canEditInviteLink()) { - return nullptr; - } - - auto result = object_ptr>( - _wrap, - object_ptr(_wrap), - st::editPeerInviteLinkMargins); - _controls.editInviteLinkWrap = result.data(); - - auto container = result->entity(); - container->add(object_ptr( - container, - Lang::Viewer(lng_profile_invite_link_section), - st::editPeerSectionLabel)); - container->add(object_ptr( - container, - st::editPeerInviteLinkSkip)); - - _controls.inviteLink = container->add(object_ptr( - container, - st::editPeerInviteLink)); - _controls.inviteLink->setSelectable(true); - _controls.inviteLink->setContextCopyText(QString()); - _controls.inviteLink->setBreakEverywhere(true); - _controls.inviteLink->setClickHandlerFilter([=](auto&&...) { - QApplication::clipboard()->setText(inviteLinkText()); - Ui::Toast::Show(lang(lng_group_invite_copied)); - return false; - }); - - container->add(object_ptr( - container, - st::editPeerInviteLinkSkip)); - container->add(object_ptr( - container, - lang(lng_group_invite_create_new), - st::editPeerInviteLinkButton) - )->addClickHandler([=] { revokeInviteLink(); }); - - observeInviteLink(); - - return std::move(result); -} - -void Controller::refreshEditInviteLink() { - auto link = inviteLinkText(); - 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); - - // Hack to expand FlatLabel width to naturalWidth again. - _controls.editInviteLinkWrap->resizeToWidth(st::boxWideWidth); - - _controls.editInviteLinkWrap->toggle( - inviteLinkShown() && !link.isEmpty(), - anim::type::instant); -} - -object_ptr Controller::createInviteLinkCreate() { - Expects(_wrap != nullptr); - - if (!canEditInviteLink()) { - return nullptr; - } - - auto result = object_ptr>( - _wrap, - object_ptr(_wrap), - st::editPeerInviteLinkMargins); - auto container = result->entity(); - - container->add(object_ptr( - container, - Lang::Viewer(lng_profile_invite_link_section), - st::editPeerSectionLabel)); - container->add(object_ptr( - container, - st::editPeerInviteLinkSkip)); - - container->add(object_ptr( - _wrap, - lang(lng_group_invite_create), - st::editPeerInviteLinkButton) - )->addClickHandler([this] { - createInviteLink(); - }); - _controls.createInviteLinkWrap = result.data(); - - observeInviteLink(); - - return std::move(result); -} - -void Controller::refreshCreateInviteLink() { - _controls.createInviteLinkWrap->toggle( - inviteLinkShown() && inviteLinkText().isEmpty(), - anim::type::instant); -} - -void Controller::refreshHistoryVisibility() { +void Controller::refreshHistoryVisibility(bool instant) { if (!_controls.historyVisibilityWrap) { return; } - auto historyVisibilityShown = !_controls.privacy - || (_controls.privacy->value() == Privacy::Private) - || (_controls.privacySavedValue == Privacy::Private); _controls.historyVisibilityWrap->toggle( - historyVisibilityShown, - anim::type::normal); + _controls.privacySavedValue == Privacy::Private, + instant ? anim::type::instant : anim::type::normal); } object_ptr Controller::createStickersEdit() { @@ -1308,9 +816,7 @@ std::optional Controller::validate() const { } bool Controller::validateUsername(Saving &to) const { - if (!_controls.privacy) { - return true; - } else if (_controls.privacySavedValue == Privacy::Private) { + if (_controls.privacySavedValue != Privacy::Public) { to.username = QString(); return true; } @@ -1320,8 +826,6 @@ bool Controller::validateUsername(Saving &to) const { : QString() ); if (username.isEmpty()) { - _controls.username->showError(); - _box->scrollToWidget(_controls.username); return false; } to.username = username; @@ -1351,8 +855,10 @@ bool Controller::validateDescription(Saving &to) const { } bool Controller::validateHistoryVisibility(Saving &to) const { + if (!_controls.historyVisibilityWrap) return true; + if (!_controls.historyVisibilityWrap->toggled() - || (_controls.privacy && _controls.privacy->value() == Privacy::Public)) { + || (_controls.privacySavedValue == Privacy::Public)) { return true; } to.hiddenPreHistory @@ -1449,7 +955,7 @@ void Controller::saveUsername() { }(); _controls.username->showError(); _box->scrollToWidget(_controls.username); - showUsernameError(Lang::Viewer(errorKey)); + // showUsernameError(Lang::Viewer(errorKey)); cancelSave(); }).send(); } diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index fdbb06c05..baecc0031 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -361,7 +361,7 @@ infoIconMediaVoice: icon {{ "info_media_voice", infoIconFg }}; infoIconMediaRound: icon {{ "info_media_round", infoIconFg }}; infoIconRecentActions: icon {{ "info_recent_actions", infoIconFg, point(-2px, 0px) }}; infoIconAdministrators: icon {{ "info_administrators", infoIconFg, point(-2px, -1px) }}; -infoIconBlacklist: icon {{ "info_blacklist", infoIconFg }}; +infoIconBlacklist: icon {{ "info_blacklist", infoIconFg, point(-2px, -2px) }}; infoIconPermissions: icon {{ "info_permissions", infoIconFg }}; infoInformationIconPosition: point(25px, 12px); infoNotificationsIconPosition: point(20px, 5px); @@ -617,6 +617,7 @@ manageGroupTopButtonWithText: InfoProfileCountButton(manageGroupButton) { iconPosition: point(0px, 0px); } +editPeerSkip: 7px; editPeerHistoryVisibilityMargins: margins(15px, 0px, 20px, 16px); terminateSessionsButton: InfoProfileButton(infoBlockButton) {