diff --git a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp index ee579e9eb..3e1a8bea5 100644 --- a/Telegram/SourceFiles/boxes/moderate_messages_box.cpp +++ b/Telegram/SourceFiles/boxes/moderate_messages_box.cpp @@ -48,6 +48,13 @@ namespace { using Participants = std::vector>; +struct Controller final { + rpl::event_stream toggleRequestsFromTop; + rpl::event_stream toggleRequestsFromInner; + rpl::event_stream checkAllRequests; + Fn collectRequests; +}; + struct ModerateOptions final { bool allCanBan = false; bool allCanDelete = false; @@ -202,18 +209,147 @@ QPoint Button::prepareRippleStartPosition() const { return mapFromGlobal(QCursor::pos()); } +void CreateParticipantsList( + not_null controller, + not_null inner, + const Participants &participants) { + const auto wrap = inner->add( + object_ptr>( + inner, + object_ptr(inner))); + wrap->toggle(false, anim::type::instant); + + controller->toggleRequestsFromTop.events( + ) | rpl::start_with_next([=](bool toggled) { + wrap->toggle(toggled, anim::type::normal); + }, wrap->lifetime()); + + const auto container = wrap->entity(); + Ui::AddSkip(container); + + auto &lifetime = wrap->lifetime(); + const auto clicks = lifetime.make_state>(); + const auto checkboxes = ranges::views::all( + participants + ) | ranges::views::transform([&](not_null peer) { + const auto line = container->add( + object_ptr(container)); + const auto &st = st::moderateBoxUserpic; + line->resize(line->width(), st.size.height()); + + const auto userpic = Ui::CreateChild( + line, + peer, + st); + const auto checkbox = Ui::CreateChild( + line, + peer->name(), + false, + st::defaultBoxCheckbox); + line->widthValue( + ) | rpl::start_with_next([=](int width) { + userpic->moveToLeft( + st::boxRowPadding.left() + + checkbox->checkRect().width() + + st::defaultBoxCheckbox.textPosition.x(), + 0); + const auto skip = st::defaultBoxCheckbox.textPosition.x(); + checkbox->resizeToWidth(width + - rect::right(userpic) + - skip + - st::boxRowPadding.right()); + checkbox->moveToLeft( + rect::right(userpic) + skip, + ((userpic->height() - checkbox->height()) / 2) + + st::defaultBoxCheckbox.margin.top()); + }, checkbox->lifetime()); + + userpic->setAttribute(Qt::WA_TransparentForMouseEvents); + checkbox->setAttribute(Qt::WA_TransparentForMouseEvents); + + line->setClickedCallback([=] { + checkbox->setChecked(!checkbox->checked()); + clicks->fire({}); + }); + + return checkbox; + }) | ranges::to_vector; + + clicks->events( + ) | rpl::start_with_next([=] { + controller->toggleRequestsFromInner.fire_copy( + ranges::any_of(checkboxes, &Ui::Checkbox::checked)); + }, container->lifetime()); + + controller->checkAllRequests.events( + ) | rpl::start_with_next([=](bool checked) { + for (const auto &c : checkboxes) { + c->setChecked(checked); + } + }, container->lifetime()); + + controller->collectRequests = [=] { + auto result = Participants(); + for (auto i = 0; i < checkboxes.size(); i++) { + if (checkboxes[i]->checked()) { + result.push_back(participants[i]); + } + } + return result; + }; +} + +void AppendList( + not_null checkbox, + not_null controller, + not_null inner, + const Participants &participants, + bool handleSingle) { + const auto isSingle = handleSingle ? (participants.size() == 1) : false; + if (isSingle) { + const auto p = participants.front(); + controller->collectRequests = [=] { return Participants{ p }; }; + return; + } + const auto count = int(participants.size()); + const auto button = Ui::CreateChild