Show community content on the channel info page instead of a box.

This commit is contained in:
John Preston
2026-06-15 22:17:26 +04:00
parent 271c9df754
commit c6d51dfeb9
10 changed files with 226 additions and 29 deletions
+2
View File
@@ -1142,6 +1142,8 @@ PRIVATE
info/common_groups/info_common_groups_inner_widget.h
info/common_groups/info_common_groups_widget.cpp
info/common_groups/info_common_groups_widget.h
info/community/info_community_widget.cpp
info/community/info_community_widget.h
info/downloads/info_downloads_inner_widget.cpp
info/downloads/info_downloads_inner_widget.h
info/downloads/info_downloads_provider.cpp
+1
View File
@@ -2199,6 +2199,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_manage_discussion_group_warning" = "\"Chat history for new members\" will be switched to **Visible**.";
"lng_community_title" = "Community";
"lng_community_manage" = "Manage Community";
"lng_community_add_button" = "Add Group to a Community";
"lng_community_add_about" = "Make your group part of a community with multiple related chats.";
"lng_community_create" = "Create Community";
@@ -129,23 +129,25 @@ void ChatsController::rowClicked(not_null<PeerListRow*> row) {
_callback(row->peer());
}
void CommunityBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionNavigation*> navigation,
not_null<ChannelData*> community) {
box->setTitle(Info::Profile::NameValue(community));
box->setWidth(st::boxWideWidth);
} // namespace
void SetupCommunityContent(
not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionNavigation*> navigation,
not_null<ChannelData*> community,
std::shared_ptr<Main::SessionShow> show) {
const auto info = community->communityInfo();
if (!info) {
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
return;
}
const auto container = box->verticalLayout();
box->addTopButton(st::boxTitleClose, [=] { box->closeBox(); });
if (community->canEditInformation()) {
box->addTopButton(st::communityBoxManage, [=] {
Settings::AddButtonWithIcon(
container,
tr::lng_community_manage(),
st::settingsButton,
{ &st::menuIconEdit }
)->addClickHandler([=] {
ShowManageCommunityBox(navigation, community);
});
}
@@ -199,7 +201,7 @@ void CommunityBox(
auto chats = info->linkedPeersValue(
) | rpl::map([=] {
return PartitionChats(info);
}) | rpl::start_spawning(box->lifetime());
}) | rpl::start_spawning(container->lifetime());
const auto openChat = [=](not_null<PeerData*> peer) {
navigation->showPeerHistory(
@@ -233,8 +235,7 @@ void CommunityBox(
const std::shared_ptr<Main::SessionShow> _show;
};
const auto delegate = inner->lifetime().make_state<Delegate>(
Main::MakeSessionShow(box->uiShow(), &community->session()));
const auto delegate = inner->lifetime().make_state<Delegate>(show);
const auto controller = inner->lifetime().make_state<
ChatsController
>(&community->session(), std::move(list), openChat);
@@ -266,16 +267,22 @@ void CommunityBox(
return c.requestable;
}));
box->addButton(tr::lng_community_add_chat(), [=] {
Settings::AddButtonWithIcon(
container,
tr::lng_community_add_chat(),
st::settingsButton,
{ &st::menuIconGroups }
)->addClickHandler([=] {
ShowChooseChatToAddBox(navigation, community);
});
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
if (!community->wasFullUpdated()) {
community->session().api().requestFullPeer(community);
}
}
namespace {
class ChooseChatController final : public PeerListController {
public:
ChooseChatController(
@@ -351,13 +358,6 @@ void ChooseChatController::rowClicked(not_null<PeerListRow*> row) {
} // namespace
void ShowCommunityBox(
not_null<Window::SessionNavigation*> navigation,
not_null<ChannelData*> community) {
navigation->uiShow()->showBox(
Box(CommunityBox, navigation, community));
}
void BanFromCommunityWithWarning(
std::shared_ptr<Ui::Show> show,
not_null<ChannelData*> community,
@@ -12,15 +12,22 @@ class PeerData;
namespace Ui {
class Show;
class VerticalLayout;
} // namespace Ui
namespace Main {
class SessionShow;
} // namespace Main
namespace Window {
class SessionNavigation;
} // namespace Window
void ShowCommunityBox(
void SetupCommunityContent(
not_null<Ui::VerticalLayout*> container,
not_null<Window::SessionNavigation*> navigation,
not_null<ChannelData*> community);
not_null<ChannelData*> community,
std::shared_ptr<Main::SessionShow> show);
void ShowChooseChatToAddBox(
not_null<Window::SessionNavigation*> navigation,
@@ -0,0 +1,117 @@
/*
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 "info/community/info_community_widget.h"
#include "boxes/peers/community_box.h"
#include "data/data_channel.h"
#include "info/profile/info_profile_values.h"
#include "info/info_controller.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/ui_utility.h"
#include "styles/style_info.h"
namespace Info::Community {
class InnerWidget final : public Ui::VerticalLayout {
public:
InnerWidget(
QWidget *parent,
not_null<Controller*> controller,
not_null<PeerData*> peer);
[[nodiscard]] not_null<PeerData*> peer() const {
return _peer;
}
private:
const not_null<PeerData*> _peer;
};
InnerWidget::InnerWidget(
QWidget *parent,
not_null<Controller*> controller,
not_null<PeerData*> peer)
: Ui::VerticalLayout(parent)
, _peer(peer) {
if (const auto community = peer->asChannel()) {
SetupCommunityContent(this, controller, community, controller->uiShow());
}
}
Memento::Memento(not_null<PeerData*> peer)
: ContentMemento(peer, nullptr, nullptr, PeerId()) {
}
Section Memento::section() const {
return Section(Section::Type::Community);
}
object_ptr<ContentWidget> Memento::createWidget(
QWidget *parent,
not_null<Controller*> controller,
const QRect &geometry) {
auto result = object_ptr<Widget>(parent, controller, peer());
result->setInternalState(geometry, this);
return result;
}
Memento::~Memento() = default;
Widget::Widget(
QWidget *parent,
not_null<Controller*> controller,
not_null<PeerData*> peer)
: ContentWidget(parent, controller) {
_inner = setInnerWidget(object_ptr<InnerWidget>(this, controller, peer));
}
rpl::producer<QString> Widget::title() {
return Info::Profile::NameValue(peer());
}
not_null<PeerData*> Widget::peer() const {
return _inner->peer();
}
bool Widget::showInternal(not_null<ContentMemento*> memento) {
if (!controller()->validateMementoPeer(memento)) {
return false;
}
if (auto communityMemento = dynamic_cast<Memento*>(memento.get())) {
if (communityMemento->peer() == peer()) {
restoreState(communityMemento);
return true;
}
}
return false;
}
void Widget::setInternalState(
const QRect &geometry,
not_null<Memento*> memento) {
setGeometry(geometry);
Ui::SendPendingMoveResizeEvents(this);
restoreState(memento);
}
std::shared_ptr<ContentMemento> Widget::doCreateMemento() {
auto result = std::make_shared<Memento>(peer());
saveState(result.get());
return result;
}
void Widget::saveState(not_null<Memento*> memento) {
memento->setScrollTop(scrollTopSave());
}
void Widget::restoreState(not_null<Memento*> memento) {
scrollTopRestore(memento->scrollTop());
}
} // namespace Info::Community
@@ -0,0 +1,62 @@
/*
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
#include "info/info_content_widget.h"
class PeerData;
class ChannelData;
namespace Info::Community {
class InnerWidget;
class Memento final : public ContentMemento {
public:
explicit Memento(not_null<PeerData*> peer);
object_ptr<ContentWidget> createWidget(
QWidget *parent,
not_null<Controller*> controller,
const QRect &geometry) override;
Section section() const override;
~Memento();
};
class Widget final : public ContentWidget {
public:
Widget(
QWidget *parent,
not_null<Controller*> controller,
not_null<PeerData*> peer);
[[nodiscard]] not_null<PeerData*> peer() const;
bool showInternal(
not_null<ContentMemento*> memento) override;
void setInternalState(
const QRect &geometry,
not_null<Memento*> memento);
rpl::producer<QString> title() override;
private:
void saveState(not_null<Memento*> memento);
void restoreState(not_null<Memento*> memento);
std::shared_ptr<ContentMemento> doCreateMemento() override;
InnerWidget *_inner = nullptr;
};
} // namespace Info::Community
@@ -157,6 +157,7 @@ public:
CommonGroups,
SimilarPeers,
RequestsList,
Community,
ReactionsList,
SavedSublists,
PeerGifts,
+9 -1
View File
@@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "info/similar_peers/info_similar_peers_widget.h"
#include "info/reactions_list/info_reactions_list_widget.h"
#include "info/requests_list/info_requests_list_widget.h"
#include "info/community/info_community_widget.h"
#include "info/peer_gifts/info_peer_gifts_widget.h"
#include "info/polls/info_polls_list_widget.h"
#include "info/polls/info_polls_results_widget.h"
@@ -35,7 +36,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Info {
Memento::Memento(not_null<PeerData*> peer)
: Memento(peer, Section::Type::Profile) {
: Memento(peer, [&] {
const auto channel = peer->asChannel();
return (channel && channel->isCommunity())
? Section::Type::Community
: Section::Type::Profile;
}()) {
}
Memento::Memento(not_null<PeerData*> peer, Section section)
@@ -217,6 +223,8 @@ std::shared_ptr<ContentMemento> Memento::DefaultContent(
return std::make_shared<SimilarPeers::Memento>(peer);
case Section::Type::RequestsList:
return std::make_shared<RequestsList::Memento>(peer);
case Section::Type::Community:
return std::make_shared<Community::Memento>(peer);
case Section::Type::SavedSublists:
return std::make_shared<Saved::SublistsMemento>(&peer->session());
case Section::Type::Members:
@@ -21,7 +21,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h"
#include "boxes/peer_list_box.h"
#include "boxes/peers/add_bot_to_chat_box.h"
#include "boxes/peers/community_box.h"
#include "boxes/peers/edit_contact_box.h"
#include "boxes/peers/edit_participants_box.h"
#include "boxes/peers/edit_peer_info_box.h"
@@ -2604,7 +2603,7 @@ Section DetailsFiller::makeCommunityLink(not_null<ChannelData*> channel) {
>();
const auto controller = container->lifetime().make_state<Controller>(
community,
[=] { ShowCommunityBox(window, community); });
[=] { window->showPeerInfo(community); });
const auto content = container->add(object_ptr<PeerListContent>(
container,
controller));
@@ -2757,7 +2757,7 @@ bool SessionController::canShowSeparateWindow(SeparateId id) const {
void SessionController::showPeer(not_null<PeerData*> peer, MsgId msgId) {
if (const auto channel = peer->asChannel()) {
if (channel->isCommunity()) {
ShowCommunityBox(this, channel);
showPeerInfo(channel, SectionShow());
return;
}
}
@@ -3089,7 +3089,7 @@ void SessionController::showPeerHistory(
if (const auto peer = session().data().peerLoaded(peerId)) {
if (const auto channel = peer->asChannel()) {
if (channel->isCommunity()) {
ShowCommunityBox(this, channel);
showPeerInfo(channel, SectionShow());
return;
}
}