mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-07 04:05:17 +00:00
Add pending requests box for chats to be added.
This commit is contained in:
@@ -232,6 +232,8 @@ PRIVATE
|
||||
boxes/peers/choose_peer_box.h
|
||||
boxes/peers/community_box.cpp
|
||||
boxes/peers/community_box.h
|
||||
boxes/peers/community_pending_requests_box.cpp
|
||||
boxes/peers/community_pending_requests_box.h
|
||||
boxes/peers/create_managed_bot_box.cpp
|
||||
boxes/peers/create_managed_bot_box.h
|
||||
boxes/peers/edit_contact_box.cpp
|
||||
|
||||
@@ -2240,6 +2240,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_community_chats_viewable" = "Chats you can view";
|
||||
"lng_community_chats_requestable" = "Chats you can request to join";
|
||||
"lng_community_add_chat" = "Add a Chat to Community";
|
||||
"lng_community_requests_title" = "Pending Requests";
|
||||
"lng_community_requests_about" = "Chats require admin approval before they're added to the community.";
|
||||
"lng_community_requests_count#one" = "{count} chat suggested for this community";
|
||||
"lng_community_requests_count#other" = "{count} chats suggested for this community";
|
||||
"lng_community_requests_button#one" = "{count} Pending Request";
|
||||
"lng_community_requests_button#other" = "{count} Pending Requests";
|
||||
"lng_community_request_suggested_group" = "{user} suggested this group";
|
||||
"lng_community_request_suggested_channel" = "{user} suggested this channel";
|
||||
"lng_community_request_only_members" = "Only visible to its members";
|
||||
"lng_community_request_add" = "Add";
|
||||
"lng_community_request_decline" = "Decline";
|
||||
"lng_community_requests_add_all" = "Add All";
|
||||
"lng_community_requests_decline_all" = "Decline All";
|
||||
"lng_community_requests_add_all_title" = "Add All Chats";
|
||||
"lng_community_requests_add_all_sure#one" = "Do you want to add {count} chat to the community?";
|
||||
"lng_community_requests_add_all_sure#other" = "Do you want to add {count} chats to the community?";
|
||||
"lng_community_requests_decline_all_title" = "Decline All";
|
||||
"lng_community_requests_decline_all_sure#one" = "Do you want to decline {count} request to join the community?";
|
||||
"lng_community_requests_decline_all_sure#other" = "Do you want to decline all {count} requests to join the community?";
|
||||
|
||||
"lng_manage_monoforum" = "Direct Messages";
|
||||
"lng_manage_monoforum_off" = "Off";
|
||||
|
||||
@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "boxes/peers/add_to_community_box.h"
|
||||
#include "boxes/peers/community_pending_requests_box.h"
|
||||
#include "boxes/peers/manage_community_box.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
@@ -163,6 +164,32 @@ void CommunityBox(
|
||||
Ui::AddSkip(container);
|
||||
Ui::AddDividerText(container, tr::lng_community_show_as_one_about());
|
||||
|
||||
if (community->canManageLinkedPeers()) {
|
||||
const auto wrap = container->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
object_ptr<Ui::VerticalLayout>(container)));
|
||||
const auto inner = wrap->entity();
|
||||
Ui::AddSkip(inner);
|
||||
auto count = Info::Profile::PendingRequestsCountValue(
|
||||
community
|
||||
) | rpl::start_spawning(wrap->lifetime());
|
||||
Settings::AddButtonWithIcon(
|
||||
inner,
|
||||
tr::lng_community_requests_button(
|
||||
lt_count,
|
||||
rpl::duplicate(count) | tr::to_count()),
|
||||
st::settingsButton,
|
||||
{ &st::menuIconInvite }
|
||||
)->addClickHandler([=] {
|
||||
ShowCommunityPendingRequestsBox(navigation, community);
|
||||
});
|
||||
wrap->toggleOn(
|
||||
std::move(count) | rpl::map(rpl::mappers::_1 > 0),
|
||||
anim::type::instant);
|
||||
wrap->finishAnimating();
|
||||
}
|
||||
|
||||
auto chats = info->linkedPeersValue(
|
||||
) | rpl::map([=] {
|
||||
return PartitionChats(info);
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
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/community_pending_requests_box.h"
|
||||
|
||||
#include "api/api_communities.h"
|
||||
#include "apiwrap.h"
|
||||
#include "boxes/peer_list_box.h"
|
||||
#include "boxes/peers/manage_community_box.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_session.h"
|
||||
#include "ui/boxes/confirm_box.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_layers.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr auto kPerPage = 100;
|
||||
constexpr auto kAcceptButton = 1;
|
||||
constexpr auto kRejectButton = 2;
|
||||
|
||||
class RowDelegate {
|
||||
public:
|
||||
[[nodiscard]] virtual QSize rowAcceptButtonSize() = 0;
|
||||
[[nodiscard]] virtual QSize rowRejectButtonSize() = 0;
|
||||
virtual void rowPaintAccept(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) = 0;
|
||||
virtual void rowPaintReject(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) = 0;
|
||||
};
|
||||
|
||||
class Row final : public PeerListRow {
|
||||
public:
|
||||
Row(
|
||||
not_null<RowDelegate*> delegate,
|
||||
const Api::CommunityPeerRequest &request);
|
||||
|
||||
int elementsCount() const override;
|
||||
QRect elementGeometry(int element, int outerWidth) const override;
|
||||
bool elementDisabled(int element) const override;
|
||||
bool elementOnlySelect(int element) const override;
|
||||
void elementAddRipple(
|
||||
int element,
|
||||
QPoint point,
|
||||
Fn<void()> updateCallback) override;
|
||||
void elementsStopLastRipple() override;
|
||||
void elementsPaint(
|
||||
Painter &p,
|
||||
int outerWidth,
|
||||
bool selected,
|
||||
int selectedElement) override;
|
||||
|
||||
private:
|
||||
const not_null<RowDelegate*> _delegate;
|
||||
std::unique_ptr<Ui::RippleAnimation> _acceptRipple;
|
||||
std::unique_ptr<Ui::RippleAnimation> _rejectRipple;
|
||||
|
||||
};
|
||||
|
||||
Row::Row(
|
||||
not_null<RowDelegate*> delegate,
|
||||
const Api::CommunityPeerRequest &request)
|
||||
: PeerListRow(request.peer)
|
||||
, _delegate(delegate) {
|
||||
const auto suggestedBy = request.requestedBy
|
||||
? request.requestedBy->shortName()
|
||||
: QString();
|
||||
auto status = request.peer->isBroadcast()
|
||||
? tr::lng_community_request_suggested_channel(
|
||||
tr::now,
|
||||
lt_user,
|
||||
suggestedBy)
|
||||
: tr::lng_community_request_suggested_group(
|
||||
tr::now,
|
||||
lt_user,
|
||||
suggestedBy);
|
||||
if (!request.visible) {
|
||||
status += QString::fromUtf8(" \xE2\x80\xA2 ")
|
||||
+ tr::lng_community_request_only_members(tr::now);
|
||||
}
|
||||
setCustomStatus(status);
|
||||
}
|
||||
|
||||
int Row::elementsCount() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
QRect Row::elementGeometry(int element, int outerWidth) const {
|
||||
switch (element) {
|
||||
case kAcceptButton: {
|
||||
const auto size = _delegate->rowAcceptButtonSize();
|
||||
return QRect(st::requestAcceptPosition, size);
|
||||
} break;
|
||||
case kRejectButton: {
|
||||
const auto accept = _delegate->rowAcceptButtonSize();
|
||||
const auto size = _delegate->rowRejectButtonSize();
|
||||
return QRect(
|
||||
(st::requestAcceptPosition
|
||||
+ QPoint(accept.width() + st::requestButtonsSkip, 0)),
|
||||
size);
|
||||
} break;
|
||||
}
|
||||
return QRect();
|
||||
}
|
||||
|
||||
bool Row::elementDisabled(int element) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Row::elementOnlySelect(int element) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Row::elementAddRipple(
|
||||
int element,
|
||||
QPoint point,
|
||||
Fn<void()> updateCallback) {
|
||||
const auto pointer = (element == kAcceptButton)
|
||||
? &_acceptRipple
|
||||
: (element == kRejectButton)
|
||||
? &_rejectRipple
|
||||
: nullptr;
|
||||
if (!pointer) {
|
||||
return;
|
||||
}
|
||||
auto &ripple = *pointer;
|
||||
if (!ripple) {
|
||||
auto mask = Ui::RippleAnimation::RoundRectMask(
|
||||
(element == kAcceptButton
|
||||
? _delegate->rowAcceptButtonSize()
|
||||
: _delegate->rowRejectButtonSize()),
|
||||
st::buttonRadius);
|
||||
ripple = std::make_unique<Ui::RippleAnimation>(
|
||||
(element == kAcceptButton
|
||||
? st::requestsAcceptButton.ripple
|
||||
: st::requestsRejectButton.ripple),
|
||||
std::move(mask),
|
||||
std::move(updateCallback));
|
||||
}
|
||||
ripple->add(point);
|
||||
}
|
||||
|
||||
void Row::elementsStopLastRipple() {
|
||||
if (_acceptRipple) {
|
||||
_acceptRipple->lastStop();
|
||||
}
|
||||
if (_rejectRipple) {
|
||||
_rejectRipple->lastStop();
|
||||
}
|
||||
}
|
||||
|
||||
void Row::elementsPaint(
|
||||
Painter &p,
|
||||
int outerWidth,
|
||||
bool selected,
|
||||
int selectedElement) {
|
||||
const auto accept = elementGeometry(kAcceptButton, outerWidth);
|
||||
const auto reject = elementGeometry(kRejectButton, outerWidth);
|
||||
|
||||
const auto over = [&](int element) {
|
||||
return (selectedElement == element);
|
||||
};
|
||||
_delegate->rowPaintAccept(
|
||||
p,
|
||||
accept,
|
||||
_acceptRipple,
|
||||
outerWidth,
|
||||
over(kAcceptButton));
|
||||
_delegate->rowPaintReject(
|
||||
p,
|
||||
reject,
|
||||
_rejectRipple,
|
||||
outerWidth,
|
||||
over(kRejectButton));
|
||||
}
|
||||
|
||||
class Controller final
|
||||
: public PeerListController
|
||||
, public RowDelegate
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
Controller(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void prepare() override;
|
||||
void loadMoreRows() override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
void rowElementClicked(
|
||||
not_null<PeerListRow*> row,
|
||||
int element) override;
|
||||
|
||||
QSize rowAcceptButtonSize() override;
|
||||
QSize rowRejectButtonSize() override;
|
||||
void rowPaintAccept(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) override;
|
||||
void rowPaintReject(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) override;
|
||||
|
||||
private:
|
||||
void paintButton(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
const style::RoundButton &st,
|
||||
const Ui::RoundRect &rect,
|
||||
const Ui::RoundRect &rectOver,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
const QString &text,
|
||||
int textWidth,
|
||||
int outerWidth,
|
||||
bool over);
|
||||
void process(not_null<PeerListRow*> row, bool reject);
|
||||
|
||||
const not_null<Window::SessionNavigation*> _navigation;
|
||||
const not_null<ChannelData*> _community;
|
||||
|
||||
QString _offset;
|
||||
bool _allLoaded = false;
|
||||
bool _loading = false;
|
||||
|
||||
Ui::RoundRect _acceptRect;
|
||||
Ui::RoundRect _acceptRectOver;
|
||||
Ui::RoundRect _rejectRect;
|
||||
Ui::RoundRect _rejectRectOver;
|
||||
QString _acceptText;
|
||||
QString _rejectText;
|
||||
int _acceptTextWidth = 0;
|
||||
int _rejectTextWidth = 0;
|
||||
|
||||
};
|
||||
|
||||
Controller::Controller(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community)
|
||||
: _navigation(navigation)
|
||||
, _community(community)
|
||||
, _acceptRect(st::buttonRadius, st::requestsAcceptButton.textBg)
|
||||
, _acceptRectOver(st::buttonRadius, st::requestsAcceptButton.textBgOver)
|
||||
, _rejectRect(st::buttonRadius, st::requestsRejectButton.textBg)
|
||||
, _rejectRectOver(st::buttonRadius, st::requestsRejectButton.textBgOver)
|
||||
, _acceptText(tr::lng_community_request_add(tr::now))
|
||||
, _rejectText(tr::lng_community_request_decline(tr::now))
|
||||
, _acceptTextWidth(st::requestsAcceptButton.style.font->width(_acceptText))
|
||||
, _rejectTextWidth(st::requestsRejectButton.style.font->width(_rejectText)) {
|
||||
setStyleOverrides(&st::requestsBoxList);
|
||||
}
|
||||
|
||||
Main::Session &Controller::session() const {
|
||||
return _community->session();
|
||||
}
|
||||
|
||||
void Controller::prepare() {
|
||||
delegate()->peerListSetTitle(tr::lng_community_requests_title());
|
||||
loadMoreRows();
|
||||
}
|
||||
|
||||
void Controller::loadMoreRows() {
|
||||
if (_allLoaded || _loading) {
|
||||
return;
|
||||
}
|
||||
_loading = true;
|
||||
session().api().communities().requestPeerLinkRequests(
|
||||
_community,
|
||||
_offset,
|
||||
kPerPage,
|
||||
crl::guard(this, [=](Api::CommunityPeerRequestsSlice slice) {
|
||||
_loading = false;
|
||||
for (const auto &request : slice.list) {
|
||||
if (!delegate()->peerListFindRow(request.peer->id.value)) {
|
||||
delegate()->peerListAppendRow(
|
||||
std::make_unique<Row>(this, request));
|
||||
}
|
||||
}
|
||||
delegate()->peerListRefreshRows();
|
||||
_offset = slice.nextOffset;
|
||||
if (_offset.isEmpty()) {
|
||||
_allLoaded = true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
void Controller::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto peer = row->peer();
|
||||
if (const auto window = _navigation->parentController()) {
|
||||
window->showPeer(peer);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::rowElementClicked(
|
||||
not_null<PeerListRow*> row,
|
||||
int element) {
|
||||
if (element == kAcceptButton) {
|
||||
process(row, false);
|
||||
} else if (element == kRejectButton) {
|
||||
process(row, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::process(not_null<PeerListRow*> row, bool reject) {
|
||||
const auto peer = row->peer();
|
||||
const auto id = peer->id.value;
|
||||
session().api().communities().togglePeerLinkRequestApproval(
|
||||
_community,
|
||||
peer,
|
||||
reject,
|
||||
crl::guard(this, [=] {
|
||||
if (const auto row = delegate()->peerListFindRow(id)) {
|
||||
delegate()->peerListRemoveRow(row);
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
}),
|
||||
crl::guard(this, [=](const QString &error) {
|
||||
delegate()->peerListUiShow()->showToast(error);
|
||||
}));
|
||||
}
|
||||
|
||||
QSize Controller::rowAcceptButtonSize() {
|
||||
return QSize(
|
||||
_acceptTextWidth + st::requestsAcceptButton.width,
|
||||
st::requestsAcceptButton.height);
|
||||
}
|
||||
|
||||
QSize Controller::rowRejectButtonSize() {
|
||||
return QSize(
|
||||
_rejectTextWidth + st::requestsRejectButton.width,
|
||||
st::requestsRejectButton.height);
|
||||
}
|
||||
|
||||
void Controller::rowPaintAccept(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) {
|
||||
paintButton(
|
||||
p,
|
||||
geometry,
|
||||
st::requestsAcceptButton,
|
||||
_acceptRect,
|
||||
_acceptRectOver,
|
||||
ripple,
|
||||
_acceptText,
|
||||
_acceptTextWidth,
|
||||
outerWidth,
|
||||
over);
|
||||
}
|
||||
|
||||
void Controller::rowPaintReject(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
int outerWidth,
|
||||
bool over) {
|
||||
paintButton(
|
||||
p,
|
||||
geometry,
|
||||
st::requestsRejectButton,
|
||||
_rejectRect,
|
||||
_rejectRectOver,
|
||||
ripple,
|
||||
_rejectText,
|
||||
_rejectTextWidth,
|
||||
outerWidth,
|
||||
over);
|
||||
}
|
||||
|
||||
void Controller::paintButton(
|
||||
Painter &p,
|
||||
QRect geometry,
|
||||
const style::RoundButton &st,
|
||||
const Ui::RoundRect &rect,
|
||||
const Ui::RoundRect &rectOver,
|
||||
std::unique_ptr<Ui::RippleAnimation> &ripple,
|
||||
const QString &text,
|
||||
int textWidth,
|
||||
int outerWidth,
|
||||
bool over) {
|
||||
rect.paint(p, geometry);
|
||||
if (over) {
|
||||
rectOver.paint(p, geometry);
|
||||
}
|
||||
if (ripple) {
|
||||
ripple->paint(p, geometry.x(), geometry.y(), outerWidth);
|
||||
if (ripple->empty()) {
|
||||
ripple = nullptr;
|
||||
}
|
||||
}
|
||||
p.setFont(st.style.font);
|
||||
p.setPen(over ? st.textFgOver : st.textFg);
|
||||
p.drawTextLeft(
|
||||
geometry.x() + (geometry.width() - textWidth) / 2,
|
||||
geometry.y() + st.textTop,
|
||||
outerWidth,
|
||||
text);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void ShowCommunityPendingRequestsBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community) {
|
||||
auto controller = std::make_unique<Controller>(navigation, community);
|
||||
const auto init = [=](not_null<PeerListBox*> box) {
|
||||
const auto count = std::max(community->pendingRequestsCount(), 1);
|
||||
const auto processAll = [=](bool reject) {
|
||||
const auto sure = [=](Fn<void()> &&close) {
|
||||
close();
|
||||
community->session().api().communities(
|
||||
).toggleAllPeerLinkRequestApproval(
|
||||
community,
|
||||
reject,
|
||||
crl::guard(box, [=] { box->closeBox(); }),
|
||||
crl::guard(box, [=](const QString &error) {
|
||||
box->uiShow()->showToast(error);
|
||||
}));
|
||||
};
|
||||
box->uiShow()->showBox(Ui::MakeConfirmBox({
|
||||
.text = (reject
|
||||
? tr::lng_community_requests_decline_all_sure(
|
||||
tr::now,
|
||||
lt_count,
|
||||
count)
|
||||
: tr::lng_community_requests_add_all_sure(
|
||||
tr::now,
|
||||
lt_count,
|
||||
count)),
|
||||
.confirmed = sure,
|
||||
.confirmText = (reject
|
||||
? tr::lng_community_request_decline()
|
||||
: tr::lng_community_request_add()),
|
||||
.title = (reject
|
||||
? tr::lng_community_requests_decline_all_title()
|
||||
: tr::lng_community_requests_add_all_title()),
|
||||
}));
|
||||
};
|
||||
box->addButton(
|
||||
tr::lng_community_requests_add_all(),
|
||||
[=] { processAll(false); });
|
||||
box->addLeftButton(
|
||||
tr::lng_community_requests_decline_all(),
|
||||
[=] { processAll(true); });
|
||||
|
||||
auto above = object_ptr<Ui::VerticalLayout>(box);
|
||||
Ui::AddDividerText(above, tr::lng_community_requests_about());
|
||||
Ui::AddSkip(above);
|
||||
Ui::AddSubsectionTitle(
|
||||
above,
|
||||
tr::lng_community_requests_count(
|
||||
lt_count,
|
||||
rpl::single(float64(count))));
|
||||
box->peerListSetAboveWidget(std::move(above));
|
||||
};
|
||||
navigation->uiShow()->showBox(Box<PeerListBox>(
|
||||
std::move(controller),
|
||||
init));
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
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
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
class ChannelData;
|
||||
|
||||
namespace Window {
|
||||
class SessionNavigation;
|
||||
} // namespace Window
|
||||
|
||||
void ShowCommunityPendingRequestsBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community);
|
||||
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/peers/manage_community_box.h"
|
||||
|
||||
#include "apiwrap.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"
|
||||
@@ -23,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/widgets/fields/input_field.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/slide_wrap.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
@@ -179,6 +181,28 @@ void ManageCommunityBox(
|
||||
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::menuIconInvite }
|
||||
)->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(),
|
||||
|
||||
Reference in New Issue
Block a user