diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 22b7df6c9..b686d20d0 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1640,6 +1640,20 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_rights_user_restrictions" = "User restrictions"; "lng_rights_user_restrictions_header" = "What can this member do?"; "lng_rights_default_restrictions_header" = "What can members of this group do?"; +"lng_rights_slowmode_header" = "Slowmode"; +"lng_rights_slowmode_off" = "Off"; +"lng_rights_slowmode_seconds#one" = "{count}s"; +"lng_rights_slowmode_seconds#other" = "{count}s"; +"lng_rights_slowmode_minutes#one" = "{count}m"; +"lng_rights_slowmode_minutes#other" = "{count}m"; +"lng_rights_slowmode_hours#one" = "{count}h"; +"lng_rights_slowmode_hours#other" = "{count}h"; +"lng_rights_slowmode_about" = "Members will be able to send only one message per this interval."; +"lng_rights_slowmode_about_interval" = "Members will be able to send only one message {interval}."; +"lng_rights_slowmode_interval_seconds#one" = "every {count} second"; +"lng_rights_slowmode_interval_seconds#other" = "every {count} seconds"; +"lng_rights_slowmode_interval_minutes#one" = "every {count} minute"; +"lng_rights_slowmode_interval_minutes#other" = "every {count} minutes"; "lng_rights_channel_info" = "Change channel info"; "lng_rights_channel_post" = "Post messages"; diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 27278b8df..78a1c6ccc 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -988,3 +988,8 @@ blockUserConfirmation: FlatLabel(boxLabel) { } transferCheckWidth: 300px; + +slowmodeLabelsMargin: margins(0px, 5px, 0px, 0px); +slowmodeLabel: LabelSimple(defaultLabelSimple) { + textFg: windowSubTextFg; +} diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp index 754da311f..596cd71d5 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/vertical_layout.h" #include "ui/widgets/labels.h" #include "ui/widgets/checkbox.h" +#include "ui/widgets/continuous_sliders.h" #include "ui/toast/toast.h" #include "info/profile/info_profile_button.h" #include "info/profile/info_profile_icon.h" @@ -26,6 +27,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace { +constexpr auto kSlowmodeValues = 7; + +int SlowmodeDelayByIndex(int index) { + Expects(index >= 0 && index < kSlowmodeValues); + + switch (index) { + case 0: return 0; + case 1: return 30; + case 2: return 60; + case 3: return 5 * 60; + case 4: return 15 * 60; + case 5: return 30 * 60; + case 6: return 60 * 60; + } + Unexpected("Index in SlowmodeDelayByIndex."); +} + template void ApplyDependencies( const CheckboxesMap &checkboxes, @@ -342,6 +360,7 @@ void EditPeerPermissionsBox::prepare() { inner->add(std::move(checkboxes)); + addSlowmodeSlider(inner); addBannedButtons(inner); _value = getRestrictions; @@ -351,6 +370,143 @@ void EditPeerPermissionsBox::prepare() { setDimensionsToContent(st::boxWidth, inner); } +void EditPeerPermissionsBox::addSlowmodeSlider( + not_null container) { + using namespace rpl::mappers; + + if (const auto chat = _peer->asChat()) { + if (!chat->amCreator()) { + return; + } + } + const auto channel = _peer->asChannel(); + auto &lifetime = container->lifetime(); + const auto secondsCount = lifetime.make_state>(0); + + container->add( + object_ptr(container), + { 0, st::infoProfileSkip, 0, st::infoProfileSkip }); + + container->add( + object_ptr( + container, + tr::lng_rights_slowmode_header(), + st::rightsHeaderLabel), + st::rightsHeaderMargin); + + addSlowmodeLabels(container); + + const auto slider = container->add( + object_ptr(container, st::localStorageLimitSlider), + st::localStorageLimitMargin); + slider->resize(st::localStorageLimitSlider.seekSize); + slider->setPseudoDiscrete( + kSlowmodeValues, + SlowmodeDelayByIndex, + secondsCount->current(), + [=](int seconds) { + (*secondsCount) = seconds; + }); + + auto hasSlowMode = secondsCount->value( + ) | rpl::map( + _1 != 0 + ) | rpl::distinct_until_changed(); + + auto useSeconds = secondsCount->value( + ) | rpl::map( + _1 < 60 + ) | rpl::distinct_until_changed(); + + auto interval = rpl::combine( + std::move(useSeconds), + tr::lng_rights_slowmode_interval_seconds( + lt_count, + secondsCount->value() | tr::to_count()), + tr::lng_rights_slowmode_interval_minutes( + lt_count, + secondsCount->value() | rpl::map(_1 / 60.)) + ) | rpl::map([]( + bool use, + const QString &seconds, + const QString &minutes) { + return use ? seconds : minutes; + }); + + auto aboutText = rpl::combine( + std::move(hasSlowMode), + tr::lng_rights_slowmode_about(), + tr::lng_rights_slowmode_about_interval( + lt_interval, + std::move(interval)) + ) | rpl::map([]( + bool has, + const QString &about, + const QString &aboutInterval) { + return has ? aboutInterval : about; + }); + + const auto about = container->add( + object_ptr( + container, + object_ptr( + container, + std::move(aboutText), + st::boxDividerLabel), + st::proxyAboutPadding), + style::margins(0, st::infoProfileSkip, 0, st::infoProfileSkip)); +} + +void EditPeerPermissionsBox::addSlowmodeLabels( + not_null container) { + const auto labels = container->add( + object_ptr(container, st::normalFont->height), + st::slowmodeLabelsMargin); + for (auto i = 0; i != kSlowmodeValues; ++i) { + const auto seconds = SlowmodeDelayByIndex(i); + const auto label = Ui::CreateChild( + labels, + st::slowmodeLabel, + (!seconds + ? tr::lng_rights_slowmode_off(tr::now) + : (seconds < 60) + ? tr::lng_rights_slowmode_seconds( + tr::now, + lt_count, + seconds) + : (seconds < 3600) + ? tr::lng_rights_slowmode_minutes( + tr::now, + lt_count, + seconds / 60) + : tr::lng_rights_slowmode_hours( + tr::now, + lt_count, + seconds / 3600))); + rpl::combine( + labels->widthValue(), + label->widthValue() + ) | rpl::start_with_next([=](int outer, int inner) { + const auto skip = st::localStorageLimitMargin; + const auto size = st::localStorageLimitSlider.seekSize; + const auto available = outer + - skip.left() + - skip.right() + - size.width(); + const auto shift = (i == 0) + ? -(size.width() / 2) + : (i + 1 == kSlowmodeValues) + ? (size.width() - (size.width() / 2) - inner) + : (-inner / 2); + const auto left = skip.left() + + (size.width() / 2) + + (i * available) / (kSlowmodeValues - 1) + + shift; + label->moveToLeft(left, 0, outer); + }, label->lifetime()); + } +} + void EditPeerPermissionsBox::addBannedButtons( not_null container) { if (const auto chat = _peer->asChat()) { @@ -360,10 +516,6 @@ void EditPeerPermissionsBox::addBannedButtons( } const auto channel = _peer->asChannel(); - container->add( - object_ptr(container), - { 0, st::infoProfileSkip, 0, st::infoProfileSkip }); - const auto navigation = App::wnd()->sessionController(); container->add(EditPeerInfoBox::CreateButton( container, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h index 04e87308a..79fa3e017 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.h @@ -25,6 +25,8 @@ protected: void prepare() override; private: + void addSlowmodeSlider(not_null container); + void addSlowmodeLabels(not_null container); void addBannedButtons(not_null container); not_null _peer;