diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp index 7f82a41eb..0cce8689d 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_permissions_box.cpp @@ -434,24 +434,25 @@ not_null AddDefaultCheckbox( template < typename Flags, typename DisabledMessagePairs, - typename FlagLabelPairs, - typename CheckboxFactory> + typename FlagLabelPairs> [[nodiscard]] EditFlagsControl CreateEditFlags( not_null container, rpl::producer header, Flags checked, const DisabledMessagePairs &disabledMessagePairs, - const FlagLabelPairs &flagLabelPairs, - CheckboxFactory checkboxFactory) { + const FlagLabelPairs &flagLabelPairs) { struct FlagCheck final { QPointer widget; rpl::event_stream checkChanges; }; struct State final { + Ui::SlideWrap *inner = nullptr; std::map checkboxes; rpl::event_stream<> anyChanges; + std::vector> mediaToggleCallbacks; }; const auto state = container->lifetime().make_state(); + const auto mediaRestrictions = MediaRestrictions(); const auto value = [=] { auto result = Flags(0); @@ -532,13 +533,54 @@ template < : std::nullopt; const auto toggled = ((checked & flags) != 0); auto flagCheck = state->checkboxes.emplace(flags, FlagCheck()).first; - const auto control = checkboxFactory( - container, - flags, - text, - toggled, - locked, - [=](bool v) { flagCheck->second.checkChanges.fire_copy(v); }); + + const auto control = [&] { + const auto isMedia = ranges::any_of( + mediaRestrictions, + [&](auto f) { return (flags & f); }); + if (isMedia) { + state->mediaToggleCallbacks.push_back([=](bool v) { + flagCheck->second.checkChanges.fire_copy(v); + }); + if (!state->inner) { + auto wrap = object_ptr>( + container, + object_ptr(container)); + wrap->hide(anim::type::instant); + SendMediaToggle( + container, + rpl::single( + ChatRestrictions(0) + ) | rpl::then( + state->anyChanges.events( + ) | rpl::map(value) | rpl::map(NegateRestrictions) + ) | rpl::map([=](ChatRestrictions r) -> int { + return (r == ChatRestrictions(0)) + ? 0 + : ranges::count_if( + mediaRestrictions, + [&](auto f) { return !(r & f); }); + }), + mediaRestrictions.size(), + wrap.data(), + [=](bool toggled) { + for (auto &c : state->mediaToggleCallbacks) { + c(toggled); + } + }, + locked); + state->inner = container->add(std::move(wrap)); + } + const auto checkbox = AddInnerCheckbox( + state->inner->entity(), + text, + toggled, + state->anyChanges.events()); + return checkbox; + } else { + return AddDefaultCheckbox(container, text, toggled); + } + }(); flagCheck->second.widget = Ui::MakeWeak(control); control->toggleOn(flagCheck->second.checkChanges.events()); control->setToggleLocked(locked.has_value()); @@ -570,6 +612,13 @@ template < checkbox.widget->finishAnimating(); } + // + container->widthValue( + ) | rpl::start_with_next([=](int w) { + state->inner->resizeToWidth(w); + }, state->inner->lifetime()); + // + return { nullptr, value, @@ -1108,68 +1157,12 @@ EditFlagsControl CreateEditRestrictions( std::map disabledMessages, Data::RestrictionsSetOptions options) { auto widget = object_ptr(parent); - struct State { - Ui::SlideWrap *inner = nullptr; - rpl::event_stream restrictions; - std::vector> mediaToggleCallbacks; - }; - const auto state = widget->lifetime().make_state(); - const auto mediaRestrictions = MediaRestrictions(); - const auto checkboxFactory = [&]( - not_null container, - ChatRestrictions flags, - const QString &text, - bool toggled, - std::optional locked, - Fn toggleCallback) { - const auto isMedia = ranges::any_of( - mediaRestrictions, - [&](auto f) { return (flags & f); }); - if (isMedia) { - state->mediaToggleCallbacks.push_back(toggleCallback); - if (!state->inner) { - auto wrap = object_ptr>( - container, - object_ptr(container)); - wrap->hide(anim::type::instant); - SendMediaToggle( - container, - state->restrictions.events_starting_with( - ChatRestrictions(0) - ) | rpl::map([=](ChatRestrictions r) -> int { - return (r == ChatRestrictions(0)) - ? 0 - : ranges::count_if( - mediaRestrictions, - [&](auto f) { return !(r & f); }); - }), - mediaRestrictions.size(), - wrap.data(), - [=](bool toggled) { - for (auto &callback : state->mediaToggleCallbacks) { - callback(toggled); - } - }, - locked); - state->inner = container->add(std::move(wrap)); - } - const auto checkbox = AddInnerCheckbox( - state->inner->entity(), - text, - toggled, - state->restrictions.events() | rpl::to_empty); - return checkbox; - } else { - return AddDefaultCheckbox(container, text, toggled); - } - }; auto result = CreateEditFlags( widget.data(), header, NegateRestrictions(restrictions), disabledMessages, - RestrictionLabels(options), - checkboxFactory); + RestrictionLabels(options)); result.widget = std::move(widget); result.value = [original = std::move(result.value)]{ return NegateRestrictions(original()); @@ -1177,13 +1170,6 @@ EditFlagsControl CreateEditRestrictions( result.changes = std::move( result.changes ) | rpl::map(NegateRestrictions); - rpl::duplicate( - result.changes - ) | rpl::start_to_stream(state->restrictions, state->inner->lifetime()); - result.widget->widthValue( - ) | rpl::start_with_next([=](int w) { - state->inner->resizeToWidth(w); - }, state->inner->lifetime()); return result; }