mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/telegramdesktop/tdesktop
synced 2026-09-20 08:03:45 +08:00
Support bots as community linked peers
This commit is contained in:
@@ -2203,11 +2203,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_community_manage" = "Manage Community";
|
||||
"lng_community_add_button" = "Add Group to a Community";
|
||||
"lng_community_add_button_channel" = "Add Channel to a Community";
|
||||
"lng_community_add_button_bot" = "Add Bot to a Community";
|
||||
"lng_community_remove_button" = "Remove Group from Community";
|
||||
"lng_community_remove_button_channel" = "Remove Channel from Community";
|
||||
"lng_community_remove_button_bot" = "Remove Bot from Community";
|
||||
"lng_community_remove_done" = "Removed from the community.";
|
||||
"lng_community_remove_sure" = "Remove {group} from the community?";
|
||||
"lng_community_add_about" = "Make your group part of a community with multiple related chats.";
|
||||
"lng_community_add_about_bot" = "Make your bot part of a community with multiple related chats.";
|
||||
"lng_community_create" = "Create Community";
|
||||
"lng_community_existing" = "Add to an existing community";
|
||||
"lng_community_status" = "community";
|
||||
@@ -2225,9 +2228,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_community_visibility_note" = "You won't be able to change this later.";
|
||||
"lng_community_add_to" = "Add to Community";
|
||||
"lng_community_add_confirm" = "If this group is approved by a community admin, its members will be able to join or request to join other chats in the community.";
|
||||
"lng_community_add_confirm_bot" = "If this bot is approved by a community admin, community members will be able to see and use it.";
|
||||
"lng_community_add_confirm_add" = "Add";
|
||||
"lng_community_add_done" = "Group added to the community.";
|
||||
"lng_community_add_done_channel" = "Channel added to the community.";
|
||||
"lng_community_add_done_bot" = "Bot added to the community.";
|
||||
"lng_community_request_sent" = "Your request was sent to the community admins.";
|
||||
"lng_community_manage_name" = "Community name";
|
||||
"lng_community_manage_who_add" = "Who can add chats";
|
||||
@@ -2261,11 +2266,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"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_suggested_bot" = "{user} suggested this bot";
|
||||
"lng_community_request_only_members" = "Only visible to its members";
|
||||
"lng_community_request_add" = "Add";
|
||||
"lng_community_request_decline" = "Decline";
|
||||
"lng_community_request_invite_only" = "This group is invite-only. Only its members can view it.";
|
||||
"lng_community_request_invite_only_bot" = "This bot is invite-only. Only invited members can use it.";
|
||||
"lng_community_request_message_owner" = "Message Group Owner";
|
||||
"lng_community_request_message_owner_bot" = "Message Bot Owner";
|
||||
"lng_community_requests_add_all" = "Add All";
|
||||
"lng_community_requests_decline_all" = "Decline All";
|
||||
"lng_community_requests_add_all_title" = "Add All Chats";
|
||||
@@ -2304,11 +2312,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_community_removed_list_about" = "Users removed from the community will be shown here.";
|
||||
"lng_community_chat_view_channel" = "View Channel";
|
||||
"lng_community_chat_view_group" = "View Group";
|
||||
"lng_community_chat_view_bot" = "View Bot";
|
||||
"lng_community_chat_remove_channel" = "Remove Channel";
|
||||
"lng_community_chat_remove_group" = "Remove Group";
|
||||
"lng_community_chat_remove_bot" = "Remove Bot";
|
||||
"lng_community_chat_loading" = "Loading...";
|
||||
"lng_community_peers_limit#one" = "Limit of {count} chat reached.";
|
||||
"lng_community_peers_limit#other" = "Limit of {count} chats reached.";
|
||||
"lng_community_bot_peers_limit#one" = "Limit of {count} bot reached.";
|
||||
"lng_community_bot_peers_limit#other" = "Limit of {count} bots reached.";
|
||||
|
||||
"lng_manage_monoforum" = "Direct Messages";
|
||||
"lng_manage_monoforum_off" = "Off";
|
||||
|
||||
@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "history/history.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
@@ -54,6 +55,25 @@ int CommunityPeersLimit(not_null<Main::Session*> session) {
|
||||
session->isTestMode() ? 10 : 100);
|
||||
}
|
||||
|
||||
int CommunityBotPeersLimit(not_null<Main::Session*> session) {
|
||||
return session->appConfig().get<int>(
|
||||
u"community_bot_peers_limit"_q,
|
||||
session->isTestMode() ? 10 : 100);
|
||||
}
|
||||
|
||||
QString CommunityPeersLimitToast(not_null<PeerData*> peer) {
|
||||
const auto session = &peer->session();
|
||||
return peer->isUser()
|
||||
? tr::lng_community_bot_peers_limit(
|
||||
tr::now,
|
||||
lt_count,
|
||||
CommunityBotPeersLimit(session))
|
||||
: tr::lng_community_peers_limit(
|
||||
tr::now,
|
||||
lt_count,
|
||||
CommunityPeersLimit(session));
|
||||
}
|
||||
|
||||
Communities::Communities(not_null<ApiWrap*> api)
|
||||
: _session(&api->session())
|
||||
, _api(&api->instance()) {
|
||||
|
||||
@@ -130,5 +130,7 @@ private:
|
||||
};
|
||||
|
||||
[[nodiscard]] int CommunityPeersLimit(not_null<Main::Session*> session);
|
||||
[[nodiscard]] int CommunityBotPeersLimit(not_null<Main::Session*> session);
|
||||
[[nodiscard]] QString CommunityPeersLimitToast(not_null<PeerData*> peer);
|
||||
|
||||
} // namespace Api
|
||||
|
||||
@@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_community.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "lang/lang_hardcoded.h"
|
||||
#include "lang/lang_keys.h"
|
||||
@@ -41,7 +42,7 @@ class Controller final
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
Controller(
|
||||
not_null<ChannelData*> group,
|
||||
not_null<PeerData*> peer,
|
||||
Fn<void(not_null<ChannelData*>)> callback);
|
||||
|
||||
Main::Session &session() const override;
|
||||
@@ -56,21 +57,21 @@ private:
|
||||
void appendRow(not_null<ChannelData*> community);
|
||||
void updateStatus(not_null<PeerListRow*> row);
|
||||
|
||||
const not_null<ChannelData*> _group;
|
||||
const not_null<PeerData*> _peer;
|
||||
const Fn<void(not_null<ChannelData*>)> _callback;
|
||||
rpl::variable<int> _count = 0;
|
||||
|
||||
};
|
||||
|
||||
Controller::Controller(
|
||||
not_null<ChannelData*> group,
|
||||
not_null<PeerData*> peer,
|
||||
Fn<void(not_null<ChannelData*>)> callback)
|
||||
: _group(group)
|
||||
: _peer(peer)
|
||||
, _callback(std::move(callback)) {
|
||||
}
|
||||
|
||||
Main::Session &Controller::session() const {
|
||||
return _group->session();
|
||||
return _peer->session();
|
||||
}
|
||||
|
||||
void Controller::prepare() {
|
||||
@@ -125,7 +126,7 @@ void Controller::updateStatus(not_null<PeerListRow*> row) {
|
||||
void CreateCommunityBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> group) {
|
||||
not_null<PeerData*> peer) {
|
||||
box->setTitle(tr::lng_community_create_title());
|
||||
|
||||
const auto field = box->addRow(object_ptr<Ui::InputField>(
|
||||
@@ -154,7 +155,7 @@ void CreateCommunityBox(
|
||||
navigation->session().api().communities().create(
|
||||
title,
|
||||
QString(),
|
||||
group,
|
||||
peer,
|
||||
hidden->checked(),
|
||||
crl::guard(box, [=](not_null<ChannelData*> community) {
|
||||
show->hideLayer();
|
||||
@@ -234,18 +235,20 @@ void ChooseVisibilityBox(
|
||||
void ShowAddPeerToCommunity(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community,
|
||||
not_null<ChannelData*> group) {
|
||||
not_null<PeerData*> peer) {
|
||||
const auto show = navigation->uiShow();
|
||||
const auto add = [=](bool visible) {
|
||||
const auto sure = [=](Fn<void()> &&close) {
|
||||
close();
|
||||
group->session().api().communities().addPeerLink(
|
||||
peer->session().api().communities().addPeerLink(
|
||||
community,
|
||||
group,
|
||||
peer,
|
||||
visible,
|
||||
[=] {
|
||||
show->hideLayer();
|
||||
show->showToast(group->isBroadcast()
|
||||
show->showToast(peer->isUser()
|
||||
? tr::lng_community_add_done_bot(tr::now)
|
||||
: peer->isBroadcast()
|
||||
? tr::lng_community_add_done_channel(tr::now)
|
||||
: tr::lng_community_add_done(tr::now));
|
||||
},
|
||||
@@ -255,10 +258,8 @@ void ShowAddPeerToCommunity(
|
||||
show->showToast(
|
||||
tr::lng_community_request_sent(tr::now));
|
||||
} else if (error == Api::kCommunityPeersTooMuch.utf16()) {
|
||||
show->showToast(tr::lng_community_peers_limit(
|
||||
tr::now,
|
||||
lt_count,
|
||||
Api::CommunityPeersLimit(&community->session())));
|
||||
show->showToast(
|
||||
Api::CommunityPeersLimitToast(peer));
|
||||
} else {
|
||||
show->showToast(error.isEmpty()
|
||||
? Lang::Hard::ServerError()
|
||||
@@ -272,7 +273,9 @@ void ShowAddPeerToCommunity(
|
||||
sure([] {});
|
||||
} else {
|
||||
show->showBox(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_community_add_confirm(),
|
||||
.text = (peer->isUser()
|
||||
? tr::lng_community_add_confirm_bot()
|
||||
: tr::lng_community_add_confirm()),
|
||||
.confirmed = sure,
|
||||
.confirmText = tr::lng_community_add_confirm_add(),
|
||||
.title = tr::lng_community_add_to(),
|
||||
@@ -284,18 +287,20 @@ void ShowAddPeerToCommunity(
|
||||
|
||||
void ShowAddToCommunityBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> group) {
|
||||
not_null<PeerData*> peer) {
|
||||
const auto choose = [=](not_null<ChannelData*> community) {
|
||||
ShowAddPeerToCommunity(navigation, community, group);
|
||||
ShowAddPeerToCommunity(navigation, community, peer);
|
||||
};
|
||||
auto controller = std::make_unique<Controller>(group, choose);
|
||||
auto controller = std::make_unique<Controller>(peer, choose);
|
||||
const auto raw = controller.get();
|
||||
const auto init = [=](not_null<PeerListBox*> box) {
|
||||
box->setTitle(tr::lng_community_title());
|
||||
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
||||
|
||||
auto above = object_ptr<Ui::VerticalLayout>(box);
|
||||
Ui::AddDividerText(above, tr::lng_community_add_about());
|
||||
Ui::AddDividerText(above, peer->isUser()
|
||||
? tr::lng_community_add_about_bot()
|
||||
: tr::lng_community_add_about());
|
||||
Ui::AddSkip(above);
|
||||
Settings::AddButtonWithIcon(
|
||||
above,
|
||||
@@ -304,7 +309,7 @@ void ShowAddToCommunityBox(
|
||||
{ &st::menuBlueIconGroupCreate }
|
||||
)->addClickHandler([=] {
|
||||
navigation->uiShow()->showBox(
|
||||
Box(CreateCommunityBox, navigation, group));
|
||||
Box(CreateCommunityBox, navigation, peer));
|
||||
});
|
||||
const auto wrap = above->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
|
||||
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
class ChannelData;
|
||||
class PeerData;
|
||||
|
||||
namespace Window {
|
||||
class SessionNavigation;
|
||||
@@ -15,9 +16,9 @@ class SessionNavigation;
|
||||
|
||||
void ShowAddToCommunityBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> group);
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
void ShowAddPeerToCommunity(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community,
|
||||
not_null<ChannelData*> group);
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
@@ -138,19 +138,24 @@ base::unique_qptr<Ui::PopupMenu> ChatsController::rowContextMenu(
|
||||
const auto peer = row->peer();
|
||||
const auto channel = peer->asChannel();
|
||||
const auto broadcast = channel && channel->isBroadcast();
|
||||
const auto user = peer->asUser();
|
||||
auto result = base::make_unique_q<Ui::PopupMenu>(
|
||||
parent,
|
||||
st::popupMenuWithIcons);
|
||||
const auto addAction = Ui::Menu::CreateAddActionCallback(result);
|
||||
addAction({
|
||||
.text = (broadcast
|
||||
.text = (user
|
||||
? tr::lng_community_chat_view_bot
|
||||
: broadcast
|
||||
? tr::lng_community_chat_view_channel
|
||||
: tr::lng_community_chat_view_group)(tr::now),
|
||||
.handler = [=] { _callback(peer); },
|
||||
.icon = &st::menuIconShowInChat,
|
||||
});
|
||||
addAction({
|
||||
.text = (broadcast
|
||||
.text = (user
|
||||
? tr::lng_community_chat_remove_bot
|
||||
: broadcast
|
||||
? tr::lng_community_chat_remove_channel
|
||||
: tr::lng_community_chat_remove_group)(tr::now),
|
||||
.handler = [=] { _remove(row); },
|
||||
@@ -190,6 +195,20 @@ void ShowCommunityChatJoinConfirm(
|
||||
}));
|
||||
}
|
||||
|
||||
void OpenCommunityLinkedPeer(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Data::CommunityInfo*> community,
|
||||
not_null<PeerData*> peer) {
|
||||
if (peer->isUser() && !community->isHidden(peer)) {
|
||||
controller->showPeerHistory(
|
||||
peer,
|
||||
Window::SectionShow::Way::ClearStack,
|
||||
ShowAtUnreadMsgId);
|
||||
} else {
|
||||
ShowCommunityChatJoinConfirm(controller->uiShow(), community, peer);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupCommunityContent(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Window::SessionController*> controller,
|
||||
@@ -301,7 +320,7 @@ void SetupCommunityContent(
|
||||
}) | rpl::start_spawning(container->lifetime());
|
||||
|
||||
const auto openChat = [=](not_null<PeerData*> peer) {
|
||||
ShowCommunityChatJoinConfirm(show, info, peer);
|
||||
OpenCommunityLinkedPeer(controller, info, peer);
|
||||
};
|
||||
|
||||
const auto addPeerListSection = [&](
|
||||
|
||||
@@ -46,6 +46,11 @@ void ShowCommunityChatJoinConfirm(
|
||||
not_null<Data::CommunityInfo*> community,
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
void OpenCommunityLinkedPeer(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<Data::CommunityInfo*> community,
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
void ShowChooseChatToAddBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<ChannelData*> community);
|
||||
|
||||
@@ -42,6 +42,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/components/credits.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_community.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
@@ -485,6 +486,7 @@ private:
|
||||
void fillSignaturesButton();
|
||||
void fillHistoryVisibilityButton();
|
||||
void fillManageSection();
|
||||
void fillCommunitySection();
|
||||
void fillPendingRequestsButton();
|
||||
|
||||
void fillBotUsernamesButton();
|
||||
@@ -1488,6 +1490,9 @@ void Controller::fillManageSection() {
|
||||
st::boxDividerLabel),
|
||||
st::defaultBoxDividerLabelPadding));
|
||||
fillBotVerifyAccounts();
|
||||
if (_peer->asUser()->botInfo->canEditInformation) {
|
||||
fillCommunitySection();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1545,10 +1550,6 @@ void Controller::fillManageSection() {
|
||||
&& (channel->isMegagroup() || channel->isBroadcast())
|
||||
&& !channel->isMonoforum()
|
||||
&& channel->amCreator();
|
||||
const auto canAddToCommunity = communityEligible
|
||||
&& !channel->linkedCommunityId();
|
||||
const auto linkedToCommunity = communityEligible
|
||||
&& channel->linkedCommunityId();
|
||||
|
||||
::AddSkip(_controls.buttonsLayout, 0);
|
||||
|
||||
@@ -1749,74 +1750,11 @@ void Controller::fillManageSection() {
|
||||
{ .icon = &st::menuIconStarRefShare });
|
||||
}
|
||||
|
||||
if (canAddToCommunity) {
|
||||
::AddSkip(_controls.buttonsLayout);
|
||||
AddButtonWithCount(
|
||||
_controls.buttonsLayout,
|
||||
(_isGroup
|
||||
? tr::lng_community_add_button()
|
||||
: tr::lng_community_add_button_channel()),
|
||||
rpl::single(QString()),
|
||||
[=] { ShowAddToCommunityBox(_navigation, channel); },
|
||||
{ &st::menuIconCommunity });
|
||||
::AddSkip(_controls.buttonsLayout);
|
||||
Ui::AddDividerText(
|
||||
_controls.buttonsLayout,
|
||||
tr::lng_community_add_about());
|
||||
} else if (linkedToCommunity) {
|
||||
const auto community = channel->owner().channel(
|
||||
channel->linkedCommunityId());
|
||||
::AddSkip(_controls.buttonsLayout);
|
||||
AddCommunityRow(
|
||||
_controls.buttonsLayout,
|
||||
community,
|
||||
[=] {
|
||||
_navigation->parentController()->showPeerInfo(community);
|
||||
});
|
||||
AddButtonWithCount(
|
||||
_controls.buttonsLayout,
|
||||
(_isGroup
|
||||
? tr::lng_community_remove_button()
|
||||
: tr::lng_community_remove_button_channel()),
|
||||
rpl::single(QString()),
|
||||
[=] {
|
||||
const auto show = _navigation->uiShow();
|
||||
const auto done = [=] {
|
||||
show->showToast(
|
||||
tr::lng_community_remove_done(tr::now));
|
||||
};
|
||||
const auto fail = [=](const QString &error) {
|
||||
show->showToast(error.isEmpty()
|
||||
? Lang::Hard::ServerError()
|
||||
: error);
|
||||
};
|
||||
const auto remove = [=](Fn<void()> close) {
|
||||
community->session().api().communities().removePeerLink(
|
||||
community,
|
||||
channel,
|
||||
done,
|
||||
fail);
|
||||
close();
|
||||
};
|
||||
show->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_community_remove_sure(
|
||||
tr::now,
|
||||
lt_group,
|
||||
tr::bold(channel->name()),
|
||||
tr::marked),
|
||||
.confirmed = remove,
|
||||
.confirmText = tr::lng_box_remove(),
|
||||
.confirmStyle = &st::attentionBoxButton,
|
||||
}));
|
||||
},
|
||||
{ &st::menuIconLeaveAttention },
|
||||
st::manageGroupAttentionButton);
|
||||
::AddSkip(_controls.buttonsLayout);
|
||||
if (communityEligible) {
|
||||
fillCommunitySection();
|
||||
}
|
||||
|
||||
if ((canEditStickers || canDeleteChannel)
|
||||
&& !canAddToCommunity
|
||||
&& !linkedToCommunity) {
|
||||
if ((canEditStickers || canDeleteChannel) && !communityEligible) {
|
||||
::AddSkip(_controls.buttonsLayout);
|
||||
}
|
||||
|
||||
@@ -1839,6 +1777,79 @@ void Controller::fillManageSection() {
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::fillCommunitySection() {
|
||||
const auto container = _controls.buttonsLayout;
|
||||
const auto peer = _peer;
|
||||
const auto isBot = peer->isUser();
|
||||
if (const auto communityId = Data::PeerLinkedCommunityId(peer)) {
|
||||
const auto community = peer->owner().channel(communityId);
|
||||
::AddSkip(container);
|
||||
AddCommunityRow(
|
||||
container,
|
||||
community,
|
||||
[=] {
|
||||
_navigation->parentController()->showPeerInfo(community);
|
||||
});
|
||||
AddButtonWithCount(
|
||||
container,
|
||||
(isBot
|
||||
? tr::lng_community_remove_button_bot()
|
||||
: _isGroup
|
||||
? tr::lng_community_remove_button()
|
||||
: tr::lng_community_remove_button_channel()),
|
||||
rpl::single(QString()),
|
||||
[=] {
|
||||
const auto show = _navigation->uiShow();
|
||||
const auto done = [=] {
|
||||
show->showToast(
|
||||
tr::lng_community_remove_done(tr::now));
|
||||
};
|
||||
const auto fail = [=](const QString &error) {
|
||||
show->showToast(error.isEmpty()
|
||||
? Lang::Hard::ServerError()
|
||||
: error);
|
||||
};
|
||||
const auto remove = [=](Fn<void()> close) {
|
||||
community->session().api().communities().removePeerLink(
|
||||
community,
|
||||
peer,
|
||||
done,
|
||||
fail);
|
||||
close();
|
||||
};
|
||||
show->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_community_remove_sure(
|
||||
tr::now,
|
||||
lt_group,
|
||||
tr::bold(peer->name()),
|
||||
tr::marked),
|
||||
.confirmed = remove,
|
||||
.confirmText = tr::lng_box_remove(),
|
||||
.confirmStyle = &st::attentionBoxButton,
|
||||
}));
|
||||
},
|
||||
{ &st::menuIconLeaveAttention },
|
||||
st::manageGroupAttentionButton);
|
||||
::AddSkip(container);
|
||||
} else {
|
||||
::AddSkip(container);
|
||||
AddButtonWithCount(
|
||||
container,
|
||||
(isBot
|
||||
? tr::lng_community_add_button_bot()
|
||||
: _isGroup
|
||||
? tr::lng_community_add_button()
|
||||
: tr::lng_community_add_button_channel()),
|
||||
rpl::single(QString()),
|
||||
[=] { ShowAddToCommunityBox(_navigation, peer); },
|
||||
{ &st::menuIconCommunity });
|
||||
::AddSkip(container);
|
||||
Ui::AddDividerText(container, isBot
|
||||
? tr::lng_community_add_about_bot()
|
||||
: tr::lng_community_add_about());
|
||||
}
|
||||
}
|
||||
|
||||
void Controller::editReactions() {
|
||||
const auto done = [=](const Data::AllowedReactions &chosen) {
|
||||
SaveAllowedReactions(_peer, chosen);
|
||||
|
||||
@@ -96,6 +96,15 @@ bool IsCommunityChatViewable(const CommunityLinkedPeer &linked) {
|
||||
return linked.canViewHistory;
|
||||
}
|
||||
|
||||
ChannelId PeerLinkedCommunityId(not_null<PeerData*> peer) {
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
return channel->linkedCommunityId();
|
||||
} else if (const auto user = peer->asUser()) {
|
||||
return user->linkedCommunityId();
|
||||
}
|
||||
return ChannelId();
|
||||
}
|
||||
|
||||
CommunityInfo::CommunityInfo(not_null<ChannelData*> channel)
|
||||
: _channel(channel)
|
||||
, _chatsList(
|
||||
|
||||
@@ -27,6 +27,7 @@ struct CommunityLinkedPeer {
|
||||
};
|
||||
|
||||
[[nodiscard]] bool IsCommunityChatViewable(const CommunityLinkedPeer &linked);
|
||||
[[nodiscard]] ChannelId PeerLinkedCommunityId(not_null<PeerData*> peer);
|
||||
|
||||
class CommunityInfo final {
|
||||
public:
|
||||
|
||||
@@ -119,7 +119,7 @@ CommunityRequestableList::CommunityRequestableList(
|
||||
}) | rpl::start_spawning(lifetime());
|
||||
|
||||
const auto openChat = [=](not_null<PeerData*> peer) {
|
||||
ShowCommunityChatJoinConfirm(_controller->uiShow(), community, peer);
|
||||
OpenCommunityLinkedPeer(_controller, community, peer);
|
||||
};
|
||||
|
||||
const auto delegate = lifetime().make_state<
|
||||
|
||||
@@ -233,23 +233,28 @@ void MessageGroupOwnerBox(
|
||||
st::boxRowPadding,
|
||||
style::al_top);
|
||||
|
||||
Ui::AddSkip(content, st::boostTextSkip);
|
||||
const auto channel = chat->asChannel();
|
||||
const auto count = (channel && channel->membersCountKnown())
|
||||
? channel->membersCount()
|
||||
: 0;
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_chat_status_members(tr::now, lt_count, count),
|
||||
st::showOrLabel),
|
||||
st::boxRowPadding,
|
||||
style::al_top);
|
||||
const auto bot = chat->isUser();
|
||||
if (!bot) {
|
||||
Ui::AddSkip(content, st::boostTextSkip);
|
||||
const auto channel = chat->asChannel();
|
||||
const auto count = (channel && channel->membersCountKnown())
|
||||
? channel->membersCount()
|
||||
: 0;
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
tr::lng_chat_status_members(tr::now, lt_count, count),
|
||||
st::showOrLabel),
|
||||
st::boxRowPadding,
|
||||
style::al_top);
|
||||
}
|
||||
|
||||
Ui::AddSkip(content, st::boostTextSkip);
|
||||
auto info = Ui::Text::IconEmoji(&st::requestHiddenIcon)
|
||||
.append(' ')
|
||||
.append(tr::lng_community_request_invite_only(tr::now));
|
||||
.append((bot
|
||||
? tr::lng_community_request_invite_only_bot
|
||||
: tr::lng_community_request_invite_only)(tr::now));
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
@@ -263,7 +268,9 @@ void MessageGroupOwnerBox(
|
||||
const auto message = content->add(
|
||||
object_ptr<Ui::RoundButton>(
|
||||
content,
|
||||
tr::lng_community_request_message_owner(),
|
||||
(bot
|
||||
? tr::lng_community_request_message_owner_bot()
|
||||
: tr::lng_community_request_message_owner()),
|
||||
st::defaultActiveButton),
|
||||
st::boxRowPadding,
|
||||
style::al_justify);
|
||||
@@ -382,7 +389,13 @@ Row::Row(
|
||||
? request.requestedBy->shortName()
|
||||
: QString();
|
||||
_userWidth = st::requestSuggestStyle.font->width(user);
|
||||
auto suggest = request.peer->isBroadcast()
|
||||
auto suggest = request.peer->isUser()
|
||||
? tr::lng_community_request_suggested_bot(
|
||||
tr::now,
|
||||
lt_user,
|
||||
tr::link(user),
|
||||
tr::marked)
|
||||
: request.peer->isBroadcast()
|
||||
? tr::lng_community_request_suggested_channel(
|
||||
tr::now,
|
||||
lt_user,
|
||||
@@ -398,16 +411,18 @@ Row::Row(
|
||||
suggest,
|
||||
Ui::NameTextOptions());
|
||||
|
||||
const auto channel = request.peer->asChannel();
|
||||
const auto count = (channel && channel->membersCountKnown())
|
||||
? channel->membersCount()
|
||||
: 0;
|
||||
auto members = Ui::Text::IconEmoji(&st::requestMembersIcon)
|
||||
.append(Lang::FormatCountToShort(count).string);
|
||||
_members.setMarkedText(
|
||||
st::requestMembersStyle,
|
||||
members,
|
||||
Ui::NameTextOptions());
|
||||
if (!request.peer->isUser()) {
|
||||
const auto channel = request.peer->asChannel();
|
||||
const auto count = (channel && channel->membersCountKnown())
|
||||
? channel->membersCount()
|
||||
: 0;
|
||||
auto members = Ui::Text::IconEmoji(&st::requestMembersIcon)
|
||||
.append(Lang::FormatCountToShort(count).string);
|
||||
_members.setMarkedText(
|
||||
st::requestMembersStyle,
|
||||
members,
|
||||
Ui::NameTextOptions());
|
||||
}
|
||||
|
||||
_hiddenChat = !request.visible;
|
||||
if (!request.visible) {
|
||||
@@ -1089,10 +1104,7 @@ void Controller::performNow(const std::shared_ptr<PendingAction> &action) {
|
||||
crl::guard(this, [=](const QString &error) {
|
||||
const auto show = delegate()->peerListUiShow();
|
||||
if (error == Api::kCommunityPeersTooMuch.utf16()) {
|
||||
show->showToast(tr::lng_community_peers_limit(
|
||||
tr::now,
|
||||
lt_count,
|
||||
Api::CommunityPeersLimit(&session())));
|
||||
show->showToast(Api::CommunityPeersLimitToast(peer));
|
||||
} else {
|
||||
show->showToast(error);
|
||||
}
|
||||
|
||||
@@ -1262,7 +1262,7 @@ private:
|
||||
void addManagedBotFooter(not_null<UserData*> managerUser);
|
||||
[[nodiscard]] Section makeReportOrDeleteReaction();
|
||||
[[nodiscard]] Section makeViewChannel(not_null<ChannelData*> channel);
|
||||
[[nodiscard]] Section makeCommunityLink(not_null<ChannelData*> channel);
|
||||
[[nodiscard]] Section makeCommunityLink(not_null<PeerData*> peer);
|
||||
[[nodiscard]] Section makeTopicsList(not_null<Data::Forum*> forum);
|
||||
|
||||
[[nodiscard]] Section makeDeleteReactionSection(GroupReactionOrigin data);
|
||||
@@ -2540,7 +2540,7 @@ Section DetailsFiller::makeViewChannel(not_null<ChannelData*> channel) {
|
||||
};
|
||||
}
|
||||
|
||||
Section DetailsFiller::makeCommunityLink(not_null<ChannelData*> channel) {
|
||||
Section DetailsFiller::makeCommunityLink(not_null<PeerData*> peer) {
|
||||
const auto parent = _stack->layout();
|
||||
auto wrap = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
parent,
|
||||
@@ -2548,8 +2548,8 @@ Section DetailsFiller::makeCommunityLink(not_null<ChannelData*> channel) {
|
||||
const auto raw = wrap.data();
|
||||
const auto container = raw->entity();
|
||||
const auto window = _controller->parentController();
|
||||
const auto community = channel->owner().channel(
|
||||
channel->linkedCommunityId());
|
||||
const auto community = peer->owner().channel(
|
||||
Data::PeerLinkedCommunityId(peer));
|
||||
|
||||
class Controller final : public PeerListController {
|
||||
public:
|
||||
@@ -2611,7 +2611,7 @@ Section DetailsFiller::makeCommunityLink(not_null<ChannelData*> channel) {
|
||||
delegate->setContent(content);
|
||||
controller->setDelegate(delegate);
|
||||
|
||||
auto hidden = channel->session().changes().peerFlagsValue(
|
||||
auto hidden = peer->session().changes().peerFlagsValue(
|
||||
community,
|
||||
Data::PeerUpdate::Flag::FullInfo
|
||||
) | rpl::map([=] {
|
||||
@@ -2621,7 +2621,7 @@ Section DetailsFiller::makeCommunityLink(not_null<ChannelData*> channel) {
|
||||
return rpl::single(false);
|
||||
}
|
||||
return info->linkedPeersValue() | rpl::map([=] {
|
||||
return info->isHidden(channel);
|
||||
return info->isHidden(peer);
|
||||
});
|
||||
}) | rpl::flatten_latest() | rpl::start_spawning(container->lifetime());
|
||||
|
||||
@@ -2702,10 +2702,8 @@ void DetailsFiller::buildSections() {
|
||||
_stack->add(makePersonalChannel(user));
|
||||
_stack->addPlainSeparator();
|
||||
}
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
if (channel->linkedCommunityId()) {
|
||||
_stack->add(makeCommunityLink(channel));
|
||||
}
|
||||
if (Data::PeerLinkedCommunityId(_peer)) {
|
||||
_stack->add(makeCommunityLink(_peer));
|
||||
}
|
||||
_stack->add(makeInfo());
|
||||
if (const auto user = _peer->asUser()) {
|
||||
|
||||
@@ -75,17 +75,13 @@ namespace {
|
||||
};
|
||||
|
||||
[[nodiscard]] bool PeerHiddenInCommunity(not_null<PeerData*> peer) {
|
||||
const auto channel = peer->asChannel();
|
||||
if (!channel) {
|
||||
return false;
|
||||
}
|
||||
const auto communityId = channel->linkedCommunityId();
|
||||
const auto communityId = Data::PeerLinkedCommunityId(peer);
|
||||
if (!communityId) {
|
||||
return false;
|
||||
}
|
||||
const auto community = channel->owner().channel(communityId);
|
||||
const auto community = peer->owner().channel(communityId);
|
||||
const auto info = community->communityInfo();
|
||||
return info && info->isHidden(channel);
|
||||
return info && info->isHidden(peer);
|
||||
}
|
||||
|
||||
[[nodiscard]] TextWithEntities MaybeHiddenPrefixed(
|
||||
@@ -110,16 +106,14 @@ StatusLabel::StatusLabel(
|
||||
: _label(label)
|
||||
, _peer(peer)
|
||||
, _refreshTimer([=] { refresh(); }) {
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
if (const auto communityId = channel->linkedCommunityId()) {
|
||||
const auto community = channel->owner().channel(communityId);
|
||||
community->session().changes().peerFlagsValue(
|
||||
community,
|
||||
Data::PeerUpdate::Flag::FullInfo
|
||||
) | rpl::on_next([=] {
|
||||
refresh();
|
||||
}, _lifetime);
|
||||
}
|
||||
if (const auto communityId = Data::PeerLinkedCommunityId(_peer)) {
|
||||
const auto community = _peer->owner().channel(communityId);
|
||||
community->session().changes().peerFlagsValue(
|
||||
community,
|
||||
Data::PeerUpdate::Flag::FullInfo
|
||||
) | rpl::on_next([=] {
|
||||
refresh();
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,9 +144,11 @@ void StatusLabel::refresh() {
|
||||
if (showOnline) {
|
||||
_refreshTimer.callOnce(updateIn);
|
||||
}
|
||||
return (showOnline && _colorized)
|
||||
? Ui::Text::Colorized(result)
|
||||
: TextWithEntities{ .text = result };
|
||||
return MaybeHiddenPrefixed(
|
||||
(showOnline && _colorized)
|
||||
? Ui::Text::Colorized(result)
|
||||
: TextWithEntities{ .text = result },
|
||||
hidden);
|
||||
} else if (auto chat = _peer->asChat()) {
|
||||
if (!chat->amIn()) {
|
||||
return tr::lng_chat_status_unaccessible(
|
||||
|
||||
@@ -391,16 +391,16 @@ TopBar::TopBar(
|
||||
? std::make_shared<Info::Memento>(topic, section)
|
||||
: std::make_shared<Info::Memento>(shown, section));
|
||||
});
|
||||
_statusLabel->setHiddenLinkCallback([=] {
|
||||
controller->showToast(Ui::Toast::Config{
|
||||
.title = tr::lng_community_hidden_chat_title(tr::now),
|
||||
.text = tr::lng_community_hidden_chat_about(
|
||||
tr::now,
|
||||
tr::marked),
|
||||
.icon = &st::infoStatusHiddenToastIcon,
|
||||
});
|
||||
});
|
||||
}
|
||||
_statusLabel->setHiddenLinkCallback([=] {
|
||||
controller->showToast(Ui::Toast::Config{
|
||||
.title = tr::lng_community_hidden_chat_title(tr::now),
|
||||
.text = tr::lng_community_hidden_chat_about(
|
||||
tr::now,
|
||||
tr::marked),
|
||||
.icon = &st::infoStatusHiddenToastIcon,
|
||||
});
|
||||
});
|
||||
if (!_peer->isMegagroup() && !_topic) {
|
||||
setupStatusWithRating();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user