/* 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 "dialogs/dialogs_community_requestable_list.h" #include "boxes/peer_list_box.h" #include "data/data_channel.h" #include "data/data_community.h" #include "lang/lang_keys.h" #include "main/session/session_show.h" #include "main/main_session.h" #include "ui/qt_object_factory.h" #include "window/window_session_controller.h" #include "styles/style_dialogs.h" namespace Dialogs { namespace { [[nodiscard]] std::unique_ptr MakeCommunityChatRow( not_null peer) { auto row = std::make_unique(peer); const auto channel = peer->asChannel(); if (channel && channel->membersCountKnown()) { row->setCustomStatus(tr::lng_chat_status_members( tr::now, lt_count_decimal, channel->membersCount())); } return row; } class ChatsController final : public PeerListController { public: ChatsController( not_null session, rpl::producer>> chats, Fn)> callback); Main::Session &session() const override; void prepare() override; void rowClicked(not_null row) override; [[nodiscard]] rpl::producer countValue() const { return _count.value(); } private: const not_null _session; rpl::producer>> _chats; Fn)> _callback; rpl::variable _count = 0; }; ChatsController::ChatsController( not_null session, rpl::producer>> chats, Fn)> callback) : _session(session) , _chats(std::move(chats)) , _callback(std::move(callback)) { setStyleOverrides(&st::communityRequestableList); } Main::Session &ChatsController::session() const { return *_session; } void ChatsController::prepare() { std::move( _chats ) | rpl::on_next([=](const std::vector> &list) { while (delegate()->peerListFullRowsCount() > 0) { delegate()->peerListRemoveRow( delegate()->peerListRowAt( delegate()->peerListFullRowsCount() - 1)); } for (const auto &peer : list) { delegate()->peerListAppendRow(MakeCommunityChatRow(peer)); } delegate()->peerListRefreshRows(); _count = int(list.size()); }, lifetime()); } void ChatsController::rowClicked(not_null row) { _callback(row->peer()); } } // namespace CommunityRequestableList::CommunityRequestableList( QWidget *parent, not_null controller, not_null community) : RpWidget(parent) , _controller(controller) { auto requestable = community->linkedPeersValue( ) | rpl::map([=] { auto result = std::vector>(); for (const auto &linked : community->linkedPeers()) { const auto channel = linked.peer->asChannel(); if (channel && channel->amIn()) { continue; } else if (Data::IsCommunityChatViewable(linked)) { continue; } result.push_back(linked.peer); } return result; }) | rpl::start_spawning(lifetime()); const auto openChat = [=](not_null peer) { _controller->showPeerHistory( peer, Window::SectionShow::Way::ClearStack, ShowAtUnreadMsgId); }; const auto delegate = lifetime().make_state< PeerListContentDelegateShow >(controller->uiShow()); const auto chatsController = lifetime().make_state( &controller->session(), rpl::duplicate(requestable), openChat); _content = Ui::CreateChild(this, chatsController); delegate->setContent(_content); chatsController->setDelegate(delegate); _count = chatsController->countValue(); _count.value( ) | rpl::on_next([=](int count) { setVisible(count > 0); resizeToWidth(width()); }, lifetime()); _content->heightValue( ) | rpl::on_next([=] { resizeToWidth(width()); }, lifetime()); } CommunityRequestableList::~CommunityRequestableList() = default; int CommunityRequestableList::resizeGetHeight(int newWidth) { _content->resizeToWidth(newWidth); _content->moveToLeft(0, 0); return _content->height(); } rpl::producer CommunityRequestableList::countValue() const { return _count.value(); } } // namespace Dialogs