Added message counter to each peer in moderate box.

This commit is contained in:
23rd 2024-11-26 06:08:17 +03:00
parent 489c86dad8
commit 743c3c54a7
3 changed files with 96 additions and 31 deletions

View file

@ -87,19 +87,35 @@ ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) {
return result;
}
[[nodiscard]] rpl::producer<int> MessagesCountValue(
[[nodiscard]] rpl::producer<base::flat_map<PeerId, int>> MessagesCountValue(
not_null<History*> history,
not_null<PeerData*> from) {
std::vector<not_null<PeerData*>> from) {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
auto search = lifetime.make_state<Api::MessagesSearch>(history);
consumer.put_next(0);
search->messagesFounds(
) | rpl::start_with_next([=](const Api::FoundMessages &found) {
consumer.put_next_copy(found.total);
}, lifetime);
search->searchMessages({ .from = from });
struct State final {
base::flat_map<PeerId, int> messagesCounts;
int index = 0;
rpl::lifetime apiLifetime;
};
const auto search = lifetime.make_state<Api::MessagesSearch>(history);
const auto state = lifetime.make_state<State>();
const auto send = [=](auto repeat) -> void {
if (state->index >= from.size()) {
consumer.put_next_copy(state->messagesCounts);
return;
}
const auto peer = from[state->index];
const auto peerId = peer->id;
state->apiLifetime = search->messagesFounds(
) | rpl::start_with_next([=](const Api::FoundMessages &found) {
state->messagesCounts[peerId] = found.total;
state->index++;
repeat(repeat);
});
search->searchMessages({ .from = peer });
};
consumer.put_next({});
send(send);
return lifetime;
};
@ -274,15 +290,50 @@ void CreateModerateMessagesBox(
false,
st::defaultBoxCheckbox),
st::boxRowPadding + buttonPadding);
if (isSingle) {
const auto history = items.front()->history();
const auto history = items.front()->history();
auto messagesCounts = MessagesCountValue(history, participants);
const auto controller = box->lifetime().make_state<Controller>(
Controller::Data{
.messagesCounts = rpl::duplicate(messagesCounts),
.participants = participants,
});
Ui::AddExpandablePeerList(deleteAll, controller, inner);
{
tr::lng_selected_delete_sure(
lt_count,
rpl::combine(
MessagesCountValue(history, participants.front()),
deleteAll->checkedValue()
) | rpl::map([s = items.size()](int all, bool checked) {
return float64((checked && all) ? all : s);
std::move(messagesCounts),
isSingle
? deleteAll->checkedValue()
: rpl::merge(
controller->toggleRequestsFromInner.events(),
controller->checkAllRequests.events())
) | rpl::map([=, s = items.size()](const auto &map, bool c) {
const auto checked = (isSingle && !c)
? Participants()
: controller->collectRequests
? controller->collectRequests()
: Participants();
auto result = 0;
for (const auto &[peerId, count] : map) {
for (const auto &peer : checked) {
if (peer->id == peerId) {
result += count;
break;
}
}
}
for (const auto &item : items) {
for (const auto &peer : checked) {
if (peer->id == item->from()->id) {
result--;
break;
}
}
result++;
}
return float64(result);
})
) | rpl::start_with_next([=](const QString &text) {
title->setText(text);
@ -290,10 +341,6 @@ void CreateModerateMessagesBox(
- rect::m::sum::h(st::boxRowPadding));
}, title->lifetime());
}
const auto controller = box->lifetime().make_state<Controller>(
Controller::Data{ .participants = participants });
Ui::AddExpandablePeerList(deleteAll, controller, inner);
handleSubmition(deleteAll);
handleConfirmation(deleteAll, controller, [=](

View file

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/expandable_peer_list.h"
#include "data/data_peer.h"
#include "info/profile/info_profile_values.h"
#include "ui/controls/userpic_button.h"
#include "ui/rect.h"
#include "ui/text/text_utilities.h"
@ -148,19 +149,35 @@ void AddExpandablePeerList(
const auto &st = st::moderateBoxUserpic;
line->resize(line->width(), st.size.height());
const auto userpic = Ui::CreateChild<Ui::UserpicButton>(
line,
peer,
st);
using namespace Info::Profile;
auto name = controller->data.bold
? NameValue(peer) | rpl::map(Ui::Text::Bold)
: NameValue(peer) | rpl::map(Ui::Text::WithEntities);
const auto userpic
= Ui::CreateChild<Ui::UserpicButton>(line, peer, st);
const auto checkbox = Ui::CreateChild<Ui::Checkbox>(
line,
controller->data.bold
? Ui::Text::Bold(peer->name())
: TextWithEntities{ .text = peer->name() },
ranges::contains(controller->data.checked, peer->id),
st::defaultBoxCheckbox);
line->widthValue(
) | rpl::start_with_next([=](int width) {
controller->data.messagesCounts
? rpl::combine(
std::move(name),
rpl::duplicate(controller->data.messagesCounts)
) | rpl::map([=](const auto &richName, const auto &map) {
const auto it = map.find(peer->id);
return (it == map.end() || !it->second)
? richName
: TextWithEntities(
(u"(%1) "_q).arg(it->second)).append(richName);
})
: std::move(name),
st::defaultBoxCheckbox,
std::make_unique<Ui::CheckView>(
st::defaultCheck,
ranges::contains(controller->data.checked, peer->id)));
checkbox->setCheckAlignment(style::al_left);
rpl::combine(
line->widthValue(),
checkbox->widthValue()
) | rpl::start_with_next([=](int width, int) {
userpic->moveToLeft(
st::boxRowPadding.left()
+ checkbox->checkRect().width()

View file

@ -18,6 +18,7 @@ class VerticalLayout;
struct ExpandablePeerListController final {
struct Data final {
rpl::producer<base::flat_map<PeerId, int>> messagesCounts = nullptr;
Participants participants;
std::vector<PeerId> checked;
bool skipSingle = false;