From ce40ecc7f92f87ed29263cfb1f58cb9ac43566b4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 23 Dec 2022 17:13:32 +0400 Subject: [PATCH] Show admins in participants_hidden group info. --- .../SourceFiles/api/api_chat_participants.cpp | 2 + Telegram/SourceFiles/api/api_updates.cpp | 3 +- Telegram/SourceFiles/boxes/peer_list_box.cpp | 4 - Telegram/SourceFiles/boxes/peer_list_box.h | 2 - .../boxes/peers/add_participants_box.cpp | 3 +- .../boxes/peers/edit_participants_box.cpp | 94 ++++++++++++++----- .../boxes/peers/edit_participants_box.h | 8 +- .../chat_helpers/field_autocomplete.cpp | 4 +- Telegram/SourceFiles/data/data_channel.cpp | 9 +- Telegram/SourceFiles/history/history.cpp | 7 +- .../view/history_view_top_bar_widget.cpp | 8 +- .../info/profile/info_profile_actions.cpp | 24 +---- .../profile/info_profile_inner_widget.cpp | 28 +++--- .../info/profile/info_profile_members.cpp | 34 +++++-- .../info/profile/info_profile_members.h | 9 +- .../info_profile_members_controllers.cpp | 2 +- .../info_profile_members_controllers.h | 4 +- 17 files changed, 154 insertions(+), 91 deletions(-) diff --git a/Telegram/SourceFiles/api/api_chat_participants.cpp b/Telegram/SourceFiles/api/api_chat_participants.cpp index b429dc4652..531ff17100 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.cpp +++ b/Telegram/SourceFiles/api/api_chat_participants.cpp @@ -365,6 +365,7 @@ void ChatParticipants::requestForAdd( void ChatParticipants::requestLast(not_null channel) { if (!channel->isMegagroup() + || !channel->canViewMembers() || _participantsRequests.contains(channel)) { return; } @@ -532,6 +533,7 @@ ChatParticipants::Parsed ChatParticipants::ParseRecent( const TLMembers &data) { const auto result = Parse(channel, data); const auto applyLast = channel->isMegagroup() + && channel->canViewMembers() && (channel->mgInfo->lastParticipants.size() <= result.list.size()); if (applyLast) { ApplyLastList(channel, result.availableCount, result.list); diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index c5fcf92c37..042d069580 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -1513,7 +1513,8 @@ void Updates::feedUpdate(const MTPUpdate &update) { // Request last active supergroup participants if the 'from' user was not loaded yet. // This will optimize similar getDifference() calls for almost all next messages. if (isDataLoaded == DataIsLoadedResult::FromNotLoaded && channel && channel->isMegagroup()) { - if (channel->mgInfo->lastParticipants.size() < _session->serverConfig().chatSizeMax + if (channel->canViewMembers() + && channel->mgInfo->lastParticipants.size() < _session->serverConfig().chatSizeMax && (channel->mgInfo->lastParticipants.empty() || channel->mgInfo->lastParticipants.size() < channel->membersCount())) { session().api().chatParticipants().requestLast(channel); diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index e6d8613e64..eda808ae6a 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -363,10 +363,6 @@ void PeerListController::peerListSearchRefreshRows() { delegate()->peerListRefreshRows(); } -rpl::producer PeerListController::onlineCountValue() const { - return rpl::single(0); -} - void PeerListController::setDescriptionText(const QString &text) { if (text.isEmpty()) { setDescription(nullptr); diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index c14541aa6a..3a09aebf9e 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -529,8 +529,6 @@ public: Unexpected("PeerListController::customRowRippleMaskGenerator."); } - [[nodiscard]] virtual rpl::producer onlineCountValue() const; - [[nodiscard]] rpl::lifetime &lifetime() { return _lifetime; } diff --git a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp index 27d1d15898..c34ab298df 100644 --- a/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_participants_box.cpp @@ -46,7 +46,7 @@ base::flat_set> GetAlreadyInFromPeer(PeerData *peer) { if (const auto chat = peer->asChat()) { return chat->participants; } else if (const auto channel = peer->asChannel()) { - if (channel->isMegagroup()) { + if (channel->isMegagroup() && channel->canViewMembers()) { const auto &participants = channel->mgInfo->lastParticipants; return { participants.cbegin(), participants.cend() }; } @@ -140,6 +140,7 @@ bool AddParticipantsBoxController::isAlreadyIn( } else if (const auto channel = _peer->asChannel()) { return _alreadyIn.contains(user) || (channel->isMegagroup() + && channel->canViewMembers() && base::contains(channel->mgInfo->lastParticipants, user)); } Unexpected("User in AddParticipantsBoxController::isAlreadyIn"); diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp index 81125811a7..c9d759cdd8 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.cpp @@ -501,7 +501,7 @@ void ParticipantsAdditionalData::fillFromChat(not_null chat) { void ParticipantsAdditionalData::fillFromChannel( not_null channel) { const auto information = channel->mgInfo.get(); - if (!information) { + if (!information || !channel->canViewMembers()) { return; } if (information->creator) { @@ -901,7 +901,7 @@ void ParticipantsBoxController::setupListChangeViewers() { }); } else if (auto row = createRow(user)) { delegate()->peerListPrependRow(std::move(row)); - delegate()->peerListRefreshRows(); + refreshRows(); if (_onlineSorter) { _onlineSorter->sort(); } @@ -914,7 +914,7 @@ void ParticipantsBoxController::setupListChangeViewers() { if (const auto row = delegate()->peerListFindRow(user->id.value)) { delegate()->peerListRemoveRow(row); } - delegate()->peerListRefreshRows(); + refreshRows(); }, lifetime()); } @@ -1170,9 +1170,11 @@ void ParticipantsBoxController::restoreState( } rpl::producer ParticipantsBoxController::onlineCountValue() const { - return _onlineSorter - ? _onlineSorter->onlineCountValue() - : rpl::single(0); + return _onlineCountValue.value(); +} + +rpl::producer ParticipantsBoxController::fullCountValue() const { + return _fullCountValue.value(); } void ParticipantsBoxController::prepare() { @@ -1205,17 +1207,48 @@ void ParticipantsBoxController::prepare() { setDescriptionText(tr::lng_contacts_loading(tr::now)); setSearchNoResultsText(tr::lng_blocked_list_not_found(tr::now)); + if (_role == Role::Profile) { + auto visible = _peer->isMegagroup() + ? Info::Profile::CanViewParticipantsValue(_peer->asMegagroup()) + : rpl::single(true); + std::move(visible) | rpl::start_with_next([=](bool visible) { + if (!visible) { + _onlineCountValue = 0; + _onlineSorter = nullptr; + } else if (!_onlineSorter) { + _onlineSorter = std::make_unique( + _peer, + delegate()); + _onlineCountValue = _onlineSorter->onlineCountValue(); + } + unload(); + rebuild(); + }, lifetime()); + } else { + rebuild(); + } +} + +void ParticipantsBoxController::unload() { + while (delegate()->peerListFullRowsCount() > 0) { + delegate()->peerListRemoveRow( + delegate()->peerListRowAt( + delegate()->peerListFullRowsCount() - 1)); + } + if (const auto requestId = base::take(_loadRequestId)) { + _api.request(requestId).cancel(); + } + _allLoaded = false; + _offset = 0; +} + +void ParticipantsBoxController::rebuild() { if (const auto chat = _peer->asChat()) { prepareChatRows(chat); } else { loadMoreRows(); } - if (_role == Role::Profile && !_onlineSorter) { - _onlineSorter = std::make_unique( - _peer, - delegate()); - } - delegate()->peerListRefreshRows(); + refreshRows(); } QPointer ParticipantsBoxController::showBox( @@ -1291,7 +1324,7 @@ void ParticipantsBoxController::rebuildChatParticipants( } _onlineSorter->sort(); - delegate()->peerListRefreshRows(); + refreshRows(); chatListReady(); } @@ -1344,7 +1377,7 @@ void ParticipantsBoxController::rebuildChatAdmins( } } - delegate()->peerListRefreshRows(); + refreshRows(); chatListReady(); } @@ -1366,7 +1399,7 @@ void ParticipantsBoxController::rebuildRowTypes() { delegate()->peerListRowAt(i).get()); row->setType(computeType(row->user())); } - delegate()->peerListRefreshRows(); + refreshRows(); } void ParticipantsBoxController::loadMoreRows() { @@ -1405,11 +1438,13 @@ void ParticipantsBoxController::loadMoreRows() { MTP_int(perPage), MTP_long(participantsHash) )).done([=](const MTPchannels_ChannelParticipants &result) { + auto added = false; const auto firstLoad = !_offset; _loadRequestId = 0; auto wasRecentRequest = firstLoad - && (_role == Role::Members || _role == Role::Profile); + && (_role == Role::Members || _role == Role::Profile) + && channel->canViewMembers(); result.match([&](const MTPDchannels_channelParticipants &data) { const auto &[availableCount, list] = wasRecentRequest @@ -1418,7 +1453,9 @@ void ParticipantsBoxController::loadMoreRows() { for (const auto &data : list) { if (const auto participant = _additional.applyParticipant( data)) { - appendRow(participant); + if (appendRow(participant)) { + added = true; + } } } if (const auto size = list.size()) { @@ -1431,7 +1468,9 @@ void ParticipantsBoxController::loadMoreRows() { LOG(("API Error: " "channels.channelParticipantsNotModified received!")); }); - + if (!firstLoad && !added) { + _allLoaded = true; + } if (_allLoaded || (firstLoad && delegate()->peerListFullRowsCount() > 0)) { refreshDescription(); @@ -1439,7 +1478,7 @@ void ParticipantsBoxController::loadMoreRows() { if (_onlineSorter) { _onlineSorter->sort(); } - delegate()->peerListRefreshRows(); + refreshRows(); }).fail([this] { _loadRequestId = 0; }).send(); @@ -1461,7 +1500,7 @@ bool ParticipantsBoxController::feedMegagroupLastParticipants() { return false; } const auto megagroup = _peer->asMegagroup(); - if (!megagroup) { + if (!megagroup || !megagroup->canViewMembers()) { return false; } const auto info = megagroup->mgInfo.get(); @@ -1663,7 +1702,7 @@ void ParticipantsBoxController::editAdminDone( } } recomputeTypeFor(user); - delegate()->peerListRefreshRows(); + refreshRows(); } void ParticipantsBoxController::showRestricted(not_null user) { @@ -1727,7 +1766,7 @@ void ParticipantsBoxController::editRestrictedDone( } } recomputeTypeFor(participant); - delegate()->peerListRefreshRows(); + refreshRows(); } void ParticipantsBoxController::kickParticipant(not_null participant) { @@ -1752,7 +1791,7 @@ void ParticipantsBoxController::unkickParticipant(not_null user) { _editBox = nullptr; if (const auto row = delegate()->peerListFindRow(user->id.value)) { delegate()->peerListRemoveRow(row); - delegate()->peerListRefreshRows(); + refreshRows(); } _peer->session().api().chatParticipants().add(_peer, { 1, user }); } @@ -1768,7 +1807,7 @@ void ParticipantsBoxController::kickParticipantSure( if (const auto row = delegate()->peerListFindRow(participant->id.value)) { delegate()->peerListRemoveRow(row); - delegate()->peerListRefreshRows(); + refreshRows(); } auto &session = _peer->session(); if (const auto chat = _peer->asChat()) { @@ -1842,7 +1881,7 @@ void ParticipantsBoxController::removeKicked( && !delegate()->peerListFullRowsCount()) { setDescriptionText(tr::lng_blocked_list_not_found(tr::now)); } - delegate()->peerListRefreshRows(); + refreshRows(); removeKicked(participant); } @@ -2059,6 +2098,11 @@ void ParticipantsBoxController::fullListRefresh() { delegate()->peerListRowAt(count - 1)); } loadMoreRows(); + refreshRows(); +} + +void ParticipantsBoxController::refreshRows() { + _fullCountValue = delegate()->peerListFullRowsCount(); delegate()->peerListRefreshRows(); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h index 3d3db377ae..30b4458130 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participants_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_participants_box.h @@ -184,7 +184,8 @@ public: std::unique_ptr saveState() const override; void restoreState(std::unique_ptr state) override; - rpl::producer onlineCountValue() const override; + [[nodiscard]] rpl::producer onlineCountValue() const; + [[nodiscard]] rpl::producer fullCountValue() const; protected: // Allow child controllers not providing navigation. @@ -229,6 +230,8 @@ private: void rebuildChatAdmins(not_null chat); void chatListReady(); void rebuildRowTypes(); + void rebuild(); + void unload(); void addNewItem(); void addNewParticipants(); @@ -266,6 +269,7 @@ private: void migrate(not_null chat, not_null channel); void subscribeToCreatorChange(not_null channel); void fullListRefresh(); + void refreshRows(); // It may be nullptr in subclasses of this controller. Window::SessionNavigation *_navigation = nullptr; @@ -278,6 +282,8 @@ private: bool _allLoaded = false; ParticipantsAdditionalData _additional; std::unique_ptr _onlineSorter; + rpl::variable _onlineCountValue; + rpl::variable _fullCountValue; Ui::BoxPointer _editBox; Ui::BoxPointer _addBox; QPointer _editParticipantBox; diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index 0f21d01211..0cb9d164d5 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -472,7 +472,9 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) { --i; mrows.push_back({ i->second }); } - } else if (_channel && _channel->isMegagroup()) { + } else if (_channel + && _channel->isMegagroup() + && _channel->canViewMembers()) { if (_channel->lastParticipantsRequestNeeded()) { _channel->session().api().chatParticipants().requestLast( _channel); diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 307801555d..5152b569e0 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -263,8 +263,11 @@ bool ChannelData::linkedChatKnown() const { void ChannelData::setMembersCount(int newMembersCount) { if (_membersCount != newMembersCount) { - if (isMegagroup() && !mgInfo->lastParticipants.empty()) { - mgInfo->lastParticipantsStatus |= MegagroupInfo::LastParticipantsCountOutdated; + if (isMegagroup() + && canViewMembers() + && !mgInfo->lastParticipants.empty()) { + mgInfo->lastParticipantsStatus + |= MegagroupInfo::LastParticipantsCountOutdated; mgInfo->lastParticipantsCount = membersCount(); } _membersCount = newMembersCount; @@ -485,7 +488,7 @@ bool ChannelData::isGroupAdmin(not_null user) const { } bool ChannelData::lastParticipantsRequestNeeded() const { - if (!mgInfo) { + if (!mgInfo || !canViewMembers()) { return false; } else if (mgInfo->lastParticipantsCount == membersCount()) { mgInfo->lastParticipantsStatus diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index df1bcbf87a..b2533c4fe4 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -879,7 +879,9 @@ not_null History::addNewToBack( if (auto chat = peer->asChat()) { return &chat->lastAuthors; } else if (auto channel = peer->asMegagroup()) { - return &channel->mgInfo->lastParticipants; + return channel->canViewMembers() + ? &channel->mgInfo->lastParticipants + : nullptr; } return nullptr; }; @@ -998,7 +1000,8 @@ void History::applyServiceChanges( not_null megagroup, not_null mgInfo, not_null user) { - if (!base::contains(mgInfo->lastParticipants, user)) { + if (!base::contains(mgInfo->lastParticipants, user) + && megagroup->canViewMembers()) { mgInfo->lastParticipants.push_front(user); session().changes().peerUpdated( peer, diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 6af8c0c152..529e1f19b0 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -1504,9 +1504,10 @@ bool TopBarWidget::trackOnlineOf(not_null user) const { } else if (const auto chat = peer->asChat()) { return chat->participants.contains(user->asUser()); } else if (const auto channel = peer->asMegagroup()) { - return ranges::contains( - channel->mgInfo->lastParticipants, - not_null{ user->asUser() }); + return channel->canViewMembers() + && ranges::contains( + channel->mgInfo->lastParticipants, + not_null{ user->asUser() }); } return false; } @@ -1562,6 +1563,7 @@ void TopBarWidget::updateOnlineDisplay() { } } else if (const auto channel = peer->asChannel()) { if (channel->isMegagroup() + && channel->canViewMembers() && (channel->membersCount() > 0) && (channel->membersCount() <= channel->session().serverConfig().chatSizeMax)) { diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 3a79c08b95..354042fa10 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -932,9 +932,7 @@ void ActionsFiller::addLeaveChannelAction(not_null channel) { AddActionButton( _wrap, - (channel->isMegagroup() - ? tr::lng_profile_leave_group() - : tr::lng_profile_leave_channel()), + tr::lng_profile_leave_channel(), AmInChannelValue(channel), Window::DeleteAndLeaveHandler( _controller->parentController(), @@ -950,9 +948,7 @@ void ActionsFiller::addJoinChannelAction( | rpl::start_spawning(_wrap->lifetime()); AddActionButton( _wrap, - (channel->isMegagroup() - ? tr::lng_profile_join_group() - : tr::lng_profile_join_channel()), + tr::lng_profile_join_channel(), rpl::duplicate(joinVisible), [=] { channel->session().api().joinChannel(channel); }, &st::infoIconAddMember); @@ -1003,14 +999,7 @@ void ActionsFiller::fillChannelActions( } object_ptr ActionsFiller::fill() { - const auto wrapToggled = [=]( - object_ptr content, - rpl::producer shown) { - auto result = object_ptr>(_parent, std::move(content)); - result->setDuration(0)->toggleOn(std::move(shown)); - return result; - }; - const auto wrapResult = [=](auto &&callback) { + auto wrapResult = [=](auto &&callback) { _wrap = object_ptr(_parent); _wrap->add(CreateSkipWidget(_wrap)); callback(); @@ -1022,11 +1011,8 @@ object_ptr ActionsFiller::fill() { fillUserActions(user); }); } else if (auto channel = _peer->asChannel()) { - if (const auto megagroup = channel->asMegagroup()) { - using namespace rpl::mappers; - return wrapToggled(wrapResult([=] { - fillChannelActions(megagroup); - }), CanViewParticipantsValue(megagroup) | rpl::map(!_1)); + if (channel->isMegagroup()) { + return { nullptr }; } return wrapResult([=] { fillChannelActions(channel); diff --git a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp index 35f2bd5185..855a0244cd 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp @@ -113,32 +113,23 @@ object_ptr InnerWidget::setupContent( if (auto members = SetupChannelMembers(_controller, result.data(), _peer)) { result->add(std::move(members)); } - result->add(object_ptr(result)); if (auto actions = SetupActions(_controller, result.data(), _peer)) { + result->add(object_ptr(result)); result->add(std::move(actions)); } - - if (_peer->isChat()) { + if (_peer->isChat() || _peer->isMegagroup()) { setupMembers(result.data()); - } else if (const auto megagroup = _peer->asMegagroup()) { - CanViewParticipantsValue( - megagroup - ) | rpl::start_with_next([=, raw = result.data()](bool can) { - if (can) { - setupMembers(raw); - } else { - _cover->setOnlineCount(rpl::single(0)); - delete base::take(_members); - } - }, lifetime()); } return result; } void InnerWidget::setupMembers(not_null container) { - _members = container->add(object_ptr( + auto wrap = container->add(object_ptr>( container, - _controller)); + object_ptr(container))); + const auto inner = wrap->entity(); + inner->add(object_ptr(inner)); + _members = inner->add(object_ptr(inner, _controller)); _members->scrollToRequests( ) | rpl::start_with_next([this](Ui::ScrollToRequest request) { auto min = (request.ymin < 0) @@ -152,6 +143,11 @@ void InnerWidget::setupMembers(not_null container) { _scrollToRequests.fire({ min, max }); }, _members->lifetime()); _cover->setOnlineCount(_members->onlineCountValue()); + + using namespace rpl::mappers; + wrap->toggleOn( + _members->fullCountValue() | rpl::map(_1 > 0), + anim::type::instant); } object_ptr InnerWidget::setupSharedMedia( diff --git a/Telegram/SourceFiles/info/profile/info_profile_members.cpp b/Telegram/SourceFiles/info/profile/info_profile_members.cpp index fc6fa187c5..88915b760b 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members.cpp @@ -87,6 +87,10 @@ rpl::producer Members::onlineCountValue() const { return _listController->onlineCountValue(); } +rpl::producer Members::fullCountValue() const { + return _listController->fullCountValue(); +} + rpl::producer Members::scrollToRequests() const { return _scrollToRequests.events(); } @@ -162,13 +166,18 @@ void Members::setupHeader() { } object_ptr Members::setupTitle() { + auto visible = _peer->isMegagroup() + ? CanViewParticipantsValue(_peer->asMegagroup()) + : rpl::single(true); auto result = object_ptr( _titleWrap, - tr::lng_chat_status_members( - lt_count_decimal, - MembersCountValue(_peer) | tr::to_count(), - Ui::Text::Upper - ), + rpl::conditional( + std::move(visible), + tr::lng_chat_status_members( + lt_count_decimal, + MembersCountValue(_peer) | tr::to_count(), + Ui::Text::Upper), + tr::lng_channel_admins(Ui::Text::Upper)), st::infoBlockHeaderLabel); result->setAttribute(Qt::WA_TransparentForMouseEvents); return result; @@ -184,8 +193,16 @@ void Members::setupButtons() { //_searchField->hide(); //_cancelSearch->setVisible(false); - auto addMemberShown = CanAddMemberValue(_peer) - | rpl::start_spawning(lifetime()); + auto visible = _peer->isMegagroup() + ? CanViewParticipantsValue(_peer->asMegagroup()) + : rpl::single(true); + rpl::duplicate(visible) | rpl::start_with_next([=](bool visible) { + _openMembers->setVisible(visible); + }, lifetime()); + + auto addMemberShown = CanAddMemberValue( + _peer + ) | rpl::start_spawning(lifetime()); _addMember->showOn(rpl::duplicate(addMemberShown)); _addMember->addClickHandler([this] { // TODO throttle(ripple duration) this->addMember(); @@ -205,7 +222,8 @@ void Members::setupButtons() { rpl::combine( std::move(addMemberShown), - std::move(searchShown) + std::move(searchShown), + std::move(visible) ) | rpl::start_with_next([this] { updateHeaderControlsGeometry(width()); }, lifetime()); diff --git a/Telegram/SourceFiles/info/profile/info_profile_members.h b/Telegram/SourceFiles/info/profile/info_profile_members.h index 46d048703c..99a6135d34 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members.h +++ b/Telegram/SourceFiles/info/profile/info_profile_members.h @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/rp_widget.h" #include "boxes/peer_list_box.h" +class ParticipantsBoxController; + namespace Ui { class InputField; class CrossButton; @@ -50,8 +52,9 @@ public: std::unique_ptr saveState(); void restoreState(std::unique_ptr state); - int desiredHeight() const; - rpl::producer onlineCountValue() const; + [[nodiscard]] int desiredHeight() const; + [[nodiscard]] rpl::producer onlineCountValue() const; + [[nodiscard]] rpl::producer fullCountValue() const; protected: void visibleTopBottomUpdated( @@ -116,7 +119,7 @@ private: //Wrap _wrap; not_null _controller; not_null _peer; - std::unique_ptr _listController; + std::unique_ptr _listController; object_ptr _header = { nullptr }; object_ptr _list = { nullptr }; diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp index b7eb2ad2cc..1987be5d49 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.cpp @@ -68,7 +68,7 @@ void MemberListRow::refreshStatus() { } } -std::unique_ptr CreateMembersController( +std::unique_ptr CreateMembersController( not_null navigation, not_null peer) { return std::make_unique( diff --git a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h index 4d462c02cc..37d04cb7c6 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h +++ b/Telegram/SourceFiles/info/profile/info_profile_members_controllers.h @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peer_list_controllers.h" #include "ui/unread_badge.h" +class ParticipantsBoxController; + namespace Window { class SessionNavigation; } // namespace Window @@ -43,7 +45,7 @@ private: }; -std::unique_ptr CreateMembersController( +std::unique_ptr CreateMembersController( not_null navigation, not_null peer);