Added ability to moderate non-users to moderation box.
This commit is contained in:
parent
ab85d18cc8
commit
d40951f068
|
@ -46,12 +46,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
using Users = std::vector<not_null<UserData*>>;
|
using Participants = std::vector<not_null<PeerData*>>;
|
||||||
|
|
||||||
struct ModerateOptions final {
|
struct ModerateOptions final {
|
||||||
bool allCanBan = false;
|
bool allCanBan = false;
|
||||||
bool allCanDelete = false;
|
bool allCanDelete = false;
|
||||||
Users users;
|
Participants participants;
|
||||||
};
|
};
|
||||||
|
|
||||||
ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) {
|
ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) {
|
||||||
|
@ -76,9 +76,9 @@ ModerateOptions CalculateModerateOptions(const HistoryItemsList &items) {
|
||||||
if (!item->suggestDeleteAllReport()) {
|
if (!item->suggestDeleteAllReport()) {
|
||||||
result.allCanDelete = false;
|
result.allCanDelete = false;
|
||||||
}
|
}
|
||||||
if (const auto user = item->from()->asUser()) {
|
if (const auto p = item->from()) {
|
||||||
if (!ranges::contains(result.users, not_null{ user })) {
|
if (!ranges::contains(result.participants, not_null{ p })) {
|
||||||
result.users.push_back(user);
|
result.participants.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,42 +212,45 @@ void CreateModerateMessagesBox(
|
||||||
rpl::event_stream<bool> toggleRequestsFromTop;
|
rpl::event_stream<bool> toggleRequestsFromTop;
|
||||||
rpl::event_stream<bool> toggleRequestsFromInner;
|
rpl::event_stream<bool> toggleRequestsFromInner;
|
||||||
rpl::event_stream<bool> checkAllRequests;
|
rpl::event_stream<bool> checkAllRequests;
|
||||||
Fn<Users()> collectRequests;
|
Fn<Participants()> collectRequests;
|
||||||
};
|
};
|
||||||
const auto [allCanBan, allCanDelete, users] = CalculateModerateOptions(
|
const auto [allCanBan, allCanDelete, participants]
|
||||||
items);
|
= CalculateModerateOptions(items);
|
||||||
const auto inner = box->verticalLayout();
|
const auto inner = box->verticalLayout();
|
||||||
|
|
||||||
Assert(!users.empty());
|
Assert(!participants.empty());
|
||||||
|
|
||||||
const auto confirms = inner->lifetime().make_state<rpl::event_stream<>>();
|
const auto confirms = inner->lifetime().make_state<rpl::event_stream<>>();
|
||||||
|
|
||||||
const auto isSingle = users.size() == 1;
|
const auto isSingle = participants.size() == 1;
|
||||||
const auto buttonPadding = isSingle
|
const auto buttonPadding = isSingle
|
||||||
? QMargins()
|
? QMargins()
|
||||||
: QMargins(0, 0, Button::ComputeSize(users.size()).width(), 0);
|
: QMargins(0, 0, Button::ComputeSize(participants.size()).width(), 0);
|
||||||
|
|
||||||
const auto session = &items.front()->history()->session();
|
const auto session = &items.front()->history()->session();
|
||||||
const auto historyPeerId = items.front()->history()->peer->id;
|
const auto historyPeerId = items.front()->history()->peer->id;
|
||||||
|
|
||||||
using Request = Fn<void(not_null<UserData*>, not_null<ChannelData*>)>;
|
using Request = Fn<void(not_null<PeerData*>, not_null<ChannelData*>)>;
|
||||||
const auto sequentiallyRequest = [=](Request request, Users users) {
|
const auto sequentiallyRequest = [=](
|
||||||
|
Request request,
|
||||||
|
Participants participants) {
|
||||||
constexpr auto kSmallDelayMs = 5;
|
constexpr auto kSmallDelayMs = 5;
|
||||||
const auto userIds = ranges::views::all(
|
const auto participantIds = ranges::views::all(
|
||||||
users
|
participants
|
||||||
) | ranges::views::transform([](not_null<UserData*> user) {
|
) | ranges::views::transform([](not_null<PeerData*> peer) {
|
||||||
return user->id;
|
return peer->id;
|
||||||
}) | ranges::to_vector;
|
}) | ranges::to_vector;
|
||||||
const auto lifetime = std::make_shared<rpl::lifetime>();
|
const auto lifetime = std::make_shared<rpl::lifetime>();
|
||||||
const auto counter = lifetime->make_state<int>(0);
|
const auto counter = lifetime->make_state<int>(0);
|
||||||
const auto timer = lifetime->make_state<base::Timer>();
|
const auto timer = lifetime->make_state<base::Timer>();
|
||||||
timer->setCallback(crl::guard(session, [=] {
|
timer->setCallback(crl::guard(session, [=] {
|
||||||
if ((*counter) < userIds.size()) {
|
if ((*counter) < participantIds.size()) {
|
||||||
const auto peer = session->data().peer(historyPeerId);
|
const auto peer = session->data().peer(historyPeerId);
|
||||||
const auto channel = peer ? peer->asChannel() : nullptr;
|
const auto channel = peer ? peer->asChannel() : nullptr;
|
||||||
const auto from = session->data().peer(userIds[*counter]);
|
const auto from = session->data().peer(
|
||||||
if (const auto user = from->asUser(); channel && user) {
|
participantIds[*counter]);
|
||||||
request(user, channel);
|
if (channel && from) {
|
||||||
|
request(from, channel);
|
||||||
}
|
}
|
||||||
(*counter)++;
|
(*counter)++;
|
||||||
} else {
|
} else {
|
||||||
|
@ -304,7 +307,8 @@ void CreateModerateMessagesBox(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto createUsersList = [&](not_null<Controller*> controller) {
|
const auto createParticipantsList = [&](
|
||||||
|
not_null<Controller*> controller) {
|
||||||
const auto wrap = inner->add(
|
const auto wrap = inner->add(
|
||||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
inner,
|
inner,
|
||||||
|
@ -322,8 +326,8 @@ void CreateModerateMessagesBox(
|
||||||
auto &lifetime = wrap->lifetime();
|
auto &lifetime = wrap->lifetime();
|
||||||
const auto clicks = lifetime.make_state<rpl::event_stream<>>();
|
const auto clicks = lifetime.make_state<rpl::event_stream<>>();
|
||||||
const auto checkboxes = ranges::views::all(
|
const auto checkboxes = ranges::views::all(
|
||||||
users
|
participants
|
||||||
) | ranges::views::transform([&](not_null<UserData*> user) {
|
) | ranges::views::transform([&](not_null<PeerData*> peer) {
|
||||||
const auto line = container->add(
|
const auto line = container->add(
|
||||||
object_ptr<Ui::AbstractButton>(container));
|
object_ptr<Ui::AbstractButton>(container));
|
||||||
const auto &st = st::moderateBoxUserpic;
|
const auto &st = st::moderateBoxUserpic;
|
||||||
|
@ -331,11 +335,11 @@ void CreateModerateMessagesBox(
|
||||||
|
|
||||||
const auto userpic = Ui::CreateChild<Ui::UserpicButton>(
|
const auto userpic = Ui::CreateChild<Ui::UserpicButton>(
|
||||||
line,
|
line,
|
||||||
user,
|
peer,
|
||||||
st);
|
st);
|
||||||
const auto checkbox = Ui::CreateChild<Ui::Checkbox>(
|
const auto checkbox = Ui::CreateChild<Ui::Checkbox>(
|
||||||
line,
|
line,
|
||||||
user->name(),
|
peer->name(),
|
||||||
false,
|
false,
|
||||||
st::defaultBoxCheckbox);
|
st::defaultBoxCheckbox);
|
||||||
line->widthValue(
|
line->widthValue(
|
||||||
|
@ -381,10 +385,10 @@ void CreateModerateMessagesBox(
|
||||||
}, container->lifetime());
|
}, container->lifetime());
|
||||||
|
|
||||||
controller->collectRequests = [=] {
|
controller->collectRequests = [=] {
|
||||||
auto result = Users();
|
auto result = Participants();
|
||||||
for (auto i = 0; i < checkboxes.size(); i++) {
|
for (auto i = 0; i < checkboxes.size(); i++) {
|
||||||
if (checkboxes[i]->checked()) {
|
if (checkboxes[i]->checked()) {
|
||||||
result.push_back(users[i]);
|
result.push_back(participants[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -395,12 +399,13 @@ void CreateModerateMessagesBox(
|
||||||
not_null<Ui::Checkbox*> checkbox,
|
not_null<Ui::Checkbox*> checkbox,
|
||||||
not_null<Controller*> controller) {
|
not_null<Controller*> controller) {
|
||||||
if (isSingle) {
|
if (isSingle) {
|
||||||
const auto user = users.front();
|
const auto p = participants.front();
|
||||||
controller->collectRequests = [=] { return Users{ user }; };
|
controller->collectRequests = [=] { return Participants{ p }; };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto button = Ui::CreateChild<Button>(inner, users.size());
|
const auto count = int(participants.size());
|
||||||
button->resize(Button::ComputeSize(users.size()));
|
const auto button = Ui::CreateChild<Button>(inner, count);
|
||||||
|
button->resize(Button::ComputeSize(count));
|
||||||
|
|
||||||
const auto overlay = Ui::CreateChild<Ui::AbstractButton>(inner);
|
const auto overlay = Ui::CreateChild<Ui::AbstractButton>(inner);
|
||||||
|
|
||||||
|
@ -428,7 +433,7 @@ void CreateModerateMessagesBox(
|
||||||
checkbox->setChecked(!checkbox->checked());
|
checkbox->setChecked(!checkbox->checked());
|
||||||
controller->checkAllRequests.fire_copy(checkbox->checked());
|
controller->checkAllRequests.fire_copy(checkbox->checked());
|
||||||
});
|
});
|
||||||
createUsersList(controller);
|
createParticipantsList(controller);
|
||||||
};
|
};
|
||||||
|
|
||||||
Ui::AddSkip(inner);
|
Ui::AddSkip(inner);
|
||||||
|
@ -458,20 +463,20 @@ void CreateModerateMessagesBox(
|
||||||
|
|
||||||
const auto ids = items.front()->from()->owner().itemsToIds(items);
|
const auto ids = items.front()->from()->owner().itemsToIds(items);
|
||||||
handleConfirmation(report, controller, [=](
|
handleConfirmation(report, controller, [=](
|
||||||
not_null<UserData*> u,
|
not_null<PeerData*> p,
|
||||||
not_null<ChannelData*> c) {
|
not_null<ChannelData*> c) {
|
||||||
auto filtered = QVector<MTPint>();
|
auto filtered = QVector<MTPint>();
|
||||||
for (const auto &id : ids) {
|
for (const auto &id : ids) {
|
||||||
if (const auto item = u->session().data().message(id)) {
|
if (const auto item = p->session().data().message(id)) {
|
||||||
if (item->from()->asUser() == u) {
|
if (item->from() == p) {
|
||||||
filtered.push_back(MTP_int(item->fullId().msg));
|
filtered.push_back(MTP_int(item->fullId().msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
u->session().api().request(
|
c->session().api().request(
|
||||||
MTPchannels_ReportSpam(
|
MTPchannels_ReportSpam(
|
||||||
c->inputChannel,
|
c->inputChannel,
|
||||||
u->input,
|
p->input,
|
||||||
MTP_vector<MTPint>(std::move(filtered)))
|
MTP_vector<MTPint>(std::move(filtered)))
|
||||||
).send();
|
).send();
|
||||||
});
|
});
|
||||||
|
@ -501,7 +506,7 @@ void CreateModerateMessagesBox(
|
||||||
tr::lng_selected_delete_sure(
|
tr::lng_selected_delete_sure(
|
||||||
lt_count,
|
lt_count,
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
MessagesCountValue(history, users.front()),
|
MessagesCountValue(history, participants.front()),
|
||||||
deleteAll->checkedValue()
|
deleteAll->checkedValue()
|
||||||
) | rpl::map([s = items.size()](int all, bool checked) {
|
) | rpl::map([s = items.size()](int all, bool checked) {
|
||||||
return float64((checked && all) ? all : s);
|
return float64((checked && all) ? all : s);
|
||||||
|
@ -518,9 +523,9 @@ void CreateModerateMessagesBox(
|
||||||
handleSubmition(deleteAll);
|
handleSubmition(deleteAll);
|
||||||
|
|
||||||
handleConfirmation(deleteAll, controller, [=](
|
handleConfirmation(deleteAll, controller, [=](
|
||||||
not_null<UserData*> u,
|
not_null<PeerData*> p,
|
||||||
not_null<ChannelData*> c) {
|
not_null<ChannelData*> c) {
|
||||||
u->session().api().deleteAllFromParticipant(c, u);
|
p->session().api().deleteAllFromParticipant(c, p);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (allCanBan) {
|
if (allCanBan) {
|
||||||
|
@ -554,7 +559,7 @@ void CreateModerateMessagesBox(
|
||||||
const auto container = wrap->entity();
|
const auto container = wrap->entity();
|
||||||
wrap->toggle(false, anim::type::instant);
|
wrap->toggle(false, anim::type::instant);
|
||||||
|
|
||||||
const auto session = &users.front()->session();
|
const auto session = &participants.front()->session();
|
||||||
const auto emojiMargin = QMargins(
|
const auto emojiMargin = QMargins(
|
||||||
-st::moderateBoxExpandInnerSkip,
|
-st::moderateBoxExpandInnerSkip,
|
||||||
-st::moderateBoxExpandInnerSkip / 2,
|
-st::moderateBoxExpandInnerSkip / 2,
|
||||||
|
@ -664,7 +669,7 @@ void CreateModerateMessagesBox(
|
||||||
tr::lng_restrict_users_part_single_header(),
|
tr::lng_restrict_users_part_single_header(),
|
||||||
tr::lng_restrict_users_part_header(
|
tr::lng_restrict_users_part_header(
|
||||||
lt_count,
|
lt_count,
|
||||||
rpl::single(users.size()) | tr::to_count())),
|
rpl::single(participants.size()) | tr::to_count())),
|
||||||
prepareFlags,
|
prepareFlags,
|
||||||
disabledMessages,
|
disabledMessages,
|
||||||
{ .isForum = peer->isForum() });
|
{ .isForum = peer->isForum() });
|
||||||
|
@ -677,12 +682,12 @@ void CreateModerateMessagesBox(
|
||||||
container->add(std::move(checkboxes));
|
container->add(std::move(checkboxes));
|
||||||
|
|
||||||
handleConfirmation(ban, controller, [=](
|
handleConfirmation(ban, controller, [=](
|
||||||
not_null<UserData*> user,
|
not_null<PeerData*> peer,
|
||||||
not_null<ChannelData*> channel) {
|
not_null<ChannelData*> channel) {
|
||||||
if (wrap->toggled()) {
|
if (wrap->toggled()) {
|
||||||
Api::ChatParticipants::Restrict(
|
Api::ChatParticipants::Restrict(
|
||||||
channel,
|
channel,
|
||||||
user,
|
peer,
|
||||||
ChatRestrictionsInfo(), // Unused.
|
ChatRestrictionsInfo(), // Unused.
|
||||||
ChatRestrictionsInfo(getRestrictions(), 0),
|
ChatRestrictionsInfo(getRestrictions(), 0),
|
||||||
nullptr,
|
nullptr,
|
||||||
|
@ -690,7 +695,7 @@ void CreateModerateMessagesBox(
|
||||||
} else {
|
} else {
|
||||||
channel->session().api().chatParticipants().kick(
|
channel->session().api().chatParticipants().kick(
|
||||||
channel,
|
channel,
|
||||||
user,
|
peer,
|
||||||
{ channel->restrictions(), 0 });
|
{ channel->restrictions(), 0 });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -698,8 +703,8 @@ void CreateModerateMessagesBox(
|
||||||
|
|
||||||
const auto close = crl::guard(box, [=] { box->closeBox(); });
|
const auto close = crl::guard(box, [=] { box->closeBox(); });
|
||||||
{
|
{
|
||||||
const auto data = &users.front()->session().data();
|
const auto data = &participants.front()->session().data();
|
||||||
const auto ids = users.front()->session().data().itemsToIds(items);
|
const auto ids = data->itemsToIds(items);
|
||||||
box->addButton(tr::lng_box_delete(), [=] {
|
box->addButton(tr::lng_box_delete(), [=] {
|
||||||
confirms->fire({});
|
confirms->fire({});
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
|
@ -716,7 +721,7 @@ void CreateModerateMessagesBox(
|
||||||
bool CanCreateModerateMessagesBox(const HistoryItemsList &items) {
|
bool CanCreateModerateMessagesBox(const HistoryItemsList &items) {
|
||||||
const auto options = CalculateModerateOptions(items);
|
const auto options = CalculateModerateOptions(items);
|
||||||
return (options.allCanBan || options.allCanDelete)
|
return (options.allCanBan || options.allCanDelete)
|
||||||
&& !options.users.empty();
|
&& !options.participants.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeleteChatBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
|
void DeleteChatBox(not_null<Ui::GenericBox*> box, not_null<PeerData*> peer) {
|
||||||
|
|
Loading…
Reference in New Issue