Support bots as community linked peers

This commit is contained in:
John Preston
2026-07-07 11:57:16 +04:00
parent 3e003fb090
commit 7ad96f25df
15 changed files with 256 additions and 165 deletions

View File

@@ -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";

View File

@@ -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()) {

View File

@@ -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

View File

@@ -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>>(

View File

@@ -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);

View File

@@ -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 = [&](

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(

View File

@@ -27,6 +27,7 @@ struct CommunityLinkedPeer {
};
[[nodiscard]] bool IsCommunityChatViewable(const CommunityLinkedPeer &linked);
[[nodiscard]] ChannelId PeerLinkedCommunityId(not_null<PeerData*> peer);
class CommunityInfo final {
public:

View File

@@ -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<

View File

@@ -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);
}

View File

@@ -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()) {

View File

@@ -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(

View File

@@ -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();
}