mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-07 04:05:17 +00:00
352 lines
10 KiB
C++
352 lines
10 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
the official desktop application for the Telegram messaging service.
|
|
|
|
For license and copyright information please follow this link:
|
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|
*/
|
|
#include "boxes/peers/manage_community_box.h"
|
|
|
|
#include "api/api_peer_photo.h"
|
|
#include "apiwrap.h"
|
|
#include "boxes/peers/community_box.h"
|
|
#include "boxes/peers/community_pending_requests_box.h"
|
|
#include "boxes/peers/edit_participants_box.h"
|
|
#include "data/data_changes.h"
|
|
#include "data/data_channel.h"
|
|
#include "data/data_session.h"
|
|
#include "info/profile/info_profile_values.h"
|
|
#include "lang/lang_keys.h"
|
|
#include "main/main_session.h"
|
|
#include "main/session/session_show.h"
|
|
#include "settings/settings_common.h"
|
|
#include "ui/boxes/confirm_box.h"
|
|
#include "ui/controls/userpic_button.h"
|
|
#include "ui/layers/generic_box.h"
|
|
#include "ui/painter.h"
|
|
#include "ui/rp_widget.h"
|
|
#include "ui/ui_utility.h"
|
|
#include "ui/userpic_view.h"
|
|
#include "ui/vertical_list.h"
|
|
#include "ui/widgets/buttons.h"
|
|
#include "ui/widgets/checkbox.h"
|
|
#include "ui/widgets/fields/input_field.h"
|
|
#include "ui/widgets/labels.h"
|
|
#include "ui/wrap/padding_wrap.h"
|
|
#include "ui/wrap/slide_wrap.h"
|
|
#include "ui/wrap/vertical_layout.h"
|
|
#include "window/window_session_controller.h"
|
|
#include "styles/style_boxes.h"
|
|
#include "styles/style_info.h"
|
|
#include "styles/style_layers.h"
|
|
#include "styles/style_menu_icons.h"
|
|
#include "styles/style_settings.h"
|
|
|
|
namespace {
|
|
|
|
[[nodiscard]] rpl::producer<QString> PositiveNumberString(
|
|
rpl::producer<int> value) {
|
|
return std::move(value) | rpl::map([](int count) {
|
|
return count ? QString::number(count) : QString();
|
|
});
|
|
}
|
|
|
|
void SaveCommunityTitle(
|
|
not_null<ChannelData*> community,
|
|
const QString &title) {
|
|
const auto api = &community->session().api();
|
|
api->request(MTPchannels_EditTitle(
|
|
community->inputChannel(),
|
|
MTP_string(title)
|
|
)).done([=](const MTPUpdates &result) {
|
|
api->applyUpdates(result);
|
|
}).fail([=](const MTP::Error &error) {
|
|
if (error.type() == u"CHAT_NOT_MODIFIED"_q) {
|
|
community->setName(title, QString());
|
|
}
|
|
}).send();
|
|
}
|
|
|
|
void SaveCommunityWhoCanAddChats(
|
|
not_null<ChannelData*> community,
|
|
bool onlyAdmins) {
|
|
const auto rights = onlyAdmins
|
|
? ChatRestrictions(ChatRestriction::ManageLinkedPeers)
|
|
: ChatRestrictions();
|
|
const auto api = &community->session().api();
|
|
api->request(MTPmessages_EditChatDefaultBannedRights(
|
|
community->input(),
|
|
RestrictionsToMTP({ rights, 0 })
|
|
)).done([=](const MTPUpdates &result) {
|
|
api->applyUpdates(result);
|
|
}).fail([=](const MTP::Error &error) {
|
|
if (error.type() == u"CHAT_NOT_MODIFIED"_q) {
|
|
community->setDefaultRestrictions(rights);
|
|
}
|
|
}).send();
|
|
}
|
|
|
|
void DeleteCommunityWithConfirmation(
|
|
not_null<Window::SessionNavigation*> navigation,
|
|
not_null<ChannelData*> community) {
|
|
const auto show = navigation->uiShow();
|
|
const auto sure = [=](Fn<void()> &&close) {
|
|
close();
|
|
const auto session = &community->session();
|
|
session->api().request(MTPchannels_DeleteChannel(
|
|
community->inputChannel()
|
|
)).done([=](const MTPUpdates &result) {
|
|
session->api().applyUpdates(result);
|
|
}).fail([=](const MTP::Error &error) {
|
|
if (error.type() != u"CHANNEL_NOT_MODIFIED"_q) {
|
|
show->showToast(error.type());
|
|
}
|
|
}).send();
|
|
show->hideLayer();
|
|
};
|
|
show->showBox(Ui::MakeConfirmBox({
|
|
.text = tr::lng_community_delete_sure(),
|
|
.confirmed = sure,
|
|
.confirmText = tr::lng_box_delete(),
|
|
.confirmStyle = &st::attentionBoxButton,
|
|
.title = tr::lng_community_delete(),
|
|
}));
|
|
}
|
|
|
|
void ManageCommunityBox(
|
|
not_null<Ui::GenericBox*> box,
|
|
not_null<Window::SessionNavigation*> navigation,
|
|
not_null<ChannelData*> community) {
|
|
box->setTitle(tr::lng_community_title());
|
|
|
|
const auto canEdit = community->canEditInformation();
|
|
|
|
const auto container = box->verticalLayout();
|
|
|
|
auto photo = (Ui::UserpicButton*)nullptr;
|
|
auto field = (Ui::InputField*)nullptr;
|
|
if (canEdit) {
|
|
const auto row = container->add(
|
|
object_ptr<Ui::RpWidget>(container));
|
|
const auto photoWrap = Ui::AttachParentChild(
|
|
row,
|
|
object_ptr<Ui::PaddingWrap<Ui::UserpicButton>>(
|
|
row,
|
|
object_ptr<Ui::UserpicButton>(
|
|
row,
|
|
navigation->parentController(),
|
|
community,
|
|
Ui::UserpicButton::Role::ChangePhoto,
|
|
Ui::UserpicButton::Source::PeerPhoto,
|
|
st::defaultUserpicButton,
|
|
Ui::PeerUserpicShape::Forum),
|
|
st::editPeerPhotoMargins));
|
|
photo = photoWrap->entity();
|
|
photo->showCustomOnChosen();
|
|
const auto cache = row->lifetime().make_state<
|
|
Ui::CommunityUserpicEffect>();
|
|
row->paintRequest(
|
|
) | rpl::on_next([=] {
|
|
const auto size = photo->width();
|
|
const auto origin = photo->mapTo(row, QPoint());
|
|
auto p = QPainter(row);
|
|
Ui::PaintCommunityUserpicEffect(
|
|
p,
|
|
*cache,
|
|
origin.x(),
|
|
origin.y(),
|
|
size,
|
|
st::windowSubTextFg->c);
|
|
}, row->lifetime());
|
|
const auto titleWrap = Ui::AttachParentChild(
|
|
row,
|
|
object_ptr<Ui::PaddingWrap<Ui::InputField>>(
|
|
row,
|
|
object_ptr<Ui::InputField>(
|
|
row,
|
|
st::editPeerTitleField,
|
|
tr::lng_community_create_name(),
|
|
community->name()),
|
|
st::editPeerTitleMargins));
|
|
field = titleWrap->entity();
|
|
photoWrap->heightValue(
|
|
) | rpl::on_next([=](int height) {
|
|
row->resize(row->width(), height);
|
|
}, photoWrap->lifetime());
|
|
row->widthValue(
|
|
) | rpl::on_next([=](int width) {
|
|
const auto left = st::editPeerPhotoMargins.left()
|
|
+ st::defaultUserpicButton.size.width();
|
|
titleWrap->resizeToWidth(width - left);
|
|
titleWrap->moveToLeft(left, 0, width);
|
|
}, titleWrap->lifetime());
|
|
} else {
|
|
field = container->add(
|
|
object_ptr<Ui::InputField>(
|
|
container,
|
|
st::defaultInputField,
|
|
tr::lng_community_create_name(),
|
|
community->name()),
|
|
st::boxRowPadding);
|
|
field->setEnabled(false);
|
|
}
|
|
|
|
Ui::AddSkip(container, st::defaultVerticalListSkip * 2);
|
|
Ui::AddDivider(container);
|
|
Ui::AddSkip(container);
|
|
|
|
Ui::AddSubsectionTitle(container, tr::lng_community_manage_who_add());
|
|
const auto whoCanAdd = std::make_shared<Ui::RadiobuttonGroup>(
|
|
community->communityAnyoneCanAddPeers() ? 0 : 1);
|
|
const auto addOption = [&](
|
|
int value,
|
|
const QString &label,
|
|
rpl::producer<QString> about) {
|
|
const auto wrap = container->add(
|
|
object_ptr<Ui::VerticalLayout>(container),
|
|
st::boxRowPadding);
|
|
const auto radio = wrap->add(object_ptr<Ui::Radiobutton>(
|
|
wrap,
|
|
whoCanAdd,
|
|
value,
|
|
label,
|
|
st::defaultBoxCheckbox));
|
|
wrap->add(
|
|
object_ptr<Ui::FlatLabel>(
|
|
wrap,
|
|
std::move(about),
|
|
st::editPeerPrivacyLabel),
|
|
st::editPeerPreHistoryLabelMargins);
|
|
if (!canEdit) {
|
|
radio->setDisabled(true);
|
|
}
|
|
};
|
|
Ui::AddSkip(container, st::defaultVerticalListSkip * 2);
|
|
addOption(
|
|
0,
|
|
tr::lng_community_manage_all_members(tr::now),
|
|
tr::lng_community_manage_all_members_about());
|
|
Ui::AddSkip(container, st::defaultVerticalListSkip * 2);
|
|
addOption(
|
|
1,
|
|
tr::lng_community_manage_only_admins(tr::now),
|
|
tr::lng_community_manage_only_admins_about());
|
|
Ui::AddSkip(container, st::defaultVerticalListSkip * 2);
|
|
|
|
Ui::AddDivider(container);
|
|
Ui::AddSkip(container);
|
|
|
|
Settings::AddButtonWithLabel(
|
|
container,
|
|
tr::lng_manage_peer_administrators(),
|
|
PositiveNumberString(Info::Profile::AdminsCountValue(community)),
|
|
st::settingsButton,
|
|
{ &st::menuIconAdmin }
|
|
)->addClickHandler([=] {
|
|
ParticipantsBoxController::Start(
|
|
navigation,
|
|
community,
|
|
ParticipantsBoxController::Role::Admins);
|
|
});
|
|
if (community->canManageLinkedPeers()) {
|
|
const auto wrap = container->add(
|
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
|
container,
|
|
object_ptr<Ui::VerticalLayout>(container)));
|
|
auto count = Info::Profile::PendingRequestsCountValue(
|
|
community
|
|
) | rpl::start_spawning(wrap->lifetime());
|
|
Settings::AddButtonWithLabel(
|
|
wrap->entity(),
|
|
tr::lng_community_requests_title(),
|
|
PositiveNumberString(rpl::duplicate(count)),
|
|
st::settingsButton,
|
|
{ &st::menuIconPendingRequests }
|
|
)->addClickHandler([=] {
|
|
ShowCommunityPendingRequestsBox(navigation, community);
|
|
});
|
|
wrap->toggleOn(
|
|
std::move(count) | rpl::map(rpl::mappers::_1 > 0),
|
|
anim::type::instant);
|
|
wrap->finishAnimating();
|
|
}
|
|
Settings::AddButtonWithLabel(
|
|
container,
|
|
tr::lng_manage_peer_removed_users(),
|
|
PositiveNumberString(Info::Profile::KickedCountValue(community)),
|
|
st::settingsButton,
|
|
{ &st::menuIconRemovedUsers }
|
|
)->addClickHandler([=] {
|
|
ParticipantsBoxController::Start(
|
|
navigation,
|
|
community,
|
|
ParticipantsBoxController::Role::Kicked);
|
|
});
|
|
|
|
if (community->communityInfo() && community->canManageLinkedPeers()) {
|
|
Ui::AddSkip(container);
|
|
Ui::AddDivider(container);
|
|
Ui::AddSkip(container);
|
|
SetupCommunityEditChatsList(
|
|
container,
|
|
Main::MakeSessionShow(box->uiShow(), &community->session()),
|
|
navigation,
|
|
community);
|
|
}
|
|
|
|
if (community->canDelete()) {
|
|
Ui::AddSkip(container);
|
|
Ui::AddDivider(container);
|
|
Ui::AddSkip(container);
|
|
Settings::AddButtonWithIcon(
|
|
container,
|
|
tr::lng_community_delete(),
|
|
st::settingsAttentionButtonWithIcon,
|
|
{ &st::menuIconDeleteAttention }
|
|
)->addClickHandler([=] {
|
|
DeleteCommunityWithConfirmation(navigation, community);
|
|
});
|
|
}
|
|
|
|
if (canEdit) {
|
|
box->addButton(tr::lng_settings_save(), [=] {
|
|
const auto title = field->getLastText().trimmed();
|
|
if (title.isEmpty()) {
|
|
field->showError();
|
|
return;
|
|
}
|
|
if (title != community->name()) {
|
|
SaveCommunityTitle(community, title);
|
|
}
|
|
const auto onlyAdmins = (whoCanAdd->current() == 1);
|
|
const auto wasOnlyAdmins
|
|
= !community->communityAnyoneCanAddPeers();
|
|
if (onlyAdmins != wasOnlyAdmins) {
|
|
SaveCommunityWhoCanAddChats(community, onlyAdmins);
|
|
}
|
|
if (auto image = photo->takeResultImage(); !image.isNull()) {
|
|
community->session().api().peerPhoto().upload(
|
|
community,
|
|
{ std::move(image) });
|
|
}
|
|
box->closeBox();
|
|
});
|
|
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
|
} else {
|
|
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
|
}
|
|
|
|
if (!community->wasFullUpdated()) {
|
|
community->session().api().requestFullPeer(community);
|
|
}
|
|
}
|
|
|
|
} // namespace
|
|
|
|
void ShowManageCommunityBox(
|
|
not_null<Window::SessionNavigation*> navigation,
|
|
not_null<ChannelData*> community) {
|
|
navigation->uiShow()->showBox(
|
|
Box(ManageCommunityBox, navigation, community));
|
|
}
|