From 6ff5e221ead1e3c5f52b80f54565ef521ccebe3d Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 10 Jan 2025 11:26:07 +0400 Subject: [PATCH] Support similar bots section. --- Telegram/CMakeLists.txt | 4 +- Telegram/Resources/langs/lang.strings | 7 ++ .../SourceFiles/api/api_chat_participants.cpp | 115 +++++++++++------- .../SourceFiles/api/api_chat_participants.h | 26 ++-- Telegram/SourceFiles/apiwrap.cpp | 2 +- Telegram/SourceFiles/data/data_peer.cpp | 17 +++ Telegram/SourceFiles/data/data_peer.h | 3 + .../media/history_view_similar_channels.cpp | 21 ++-- Telegram/SourceFiles/info/info.style | 1 + Telegram/SourceFiles/info/info_controller.h | 2 +- Telegram/SourceFiles/info/info_memento.cpp | 7 +- .../info/media/info_media_buttons.h | 19 ++- .../profile/info_profile_inner_widget.cpp | 16 +-- .../info/profile/info_profile_values.cpp | 14 +-- .../info/profile/info_profile_values.h | 4 +- .../info_similar_peers_widget.cpp} | 111 +++++++++-------- .../info_similar_peers_widget.h} | 14 +-- 17 files changed, 226 insertions(+), 157 deletions(-) rename Telegram/SourceFiles/info/{similar_channels/info_similar_channels_widget.cpp => similar_peers/info_similar_peers_widget.cpp} (85%) rename Telegram/SourceFiles/info/{similar_channels/info_similar_channels_widget.h => similar_peers/info_similar_peers_widget.h} (81%) diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 1071fbe7a..345f55b1b 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1014,8 +1014,8 @@ PRIVATE info/saved/info_saved_sublists_widget.h info/settings/info_settings_widget.cpp info/settings/info_settings_widget.h - info/similar_channels/info_similar_channels_widget.cpp - info/similar_channels/info_similar_channels_widget.h + info/similar_peers/info_similar_peers_widget.cpp + info/similar_peers/info_similar_peers_widget.h info/statistics/info_statistics_common.h info/statistics/info_statistics_inner_widget.cpp info/statistics/info_statistics_inner_widget.h diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 693cf00d8..7f316c55a 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1346,6 +1346,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_profile_common_groups#other" = "{count} groups in common"; "lng_profile_similar_channels#one" = "{count} similar channel"; "lng_profile_similar_channels#other" = "{count} similar channels"; +"lng_profile_similar_bots#one" = "{count} similar bot"; +"lng_profile_similar_bots#other" = "{count} similar bots"; "lng_profile_saved_messages#one" = "{count} saved message"; "lng_profile_saved_messages#other" = "{count} saved messages"; "lng_profile_peer_gifts#one" = "{count} gift"; @@ -2108,6 +2110,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_similar_channels_premium_all_link" = "Telegram Premium"; "lng_similar_channels_show_more" = "Show more channels"; +"lng_similar_bots_title" = "Similar bots"; +"lng_similar_bots_premium_all#one" = "Subscribe to {link} to unlock up to **{count}** similar bot."; +"lng_similar_bots_premium_all#other" = "Subscribe to {link} to unlock up to **{count}** similar bots."; +"lng_similar_bots_show_more" = "Show more bots"; + "lng_peer_gifts_title" = "Gifts"; "lng_peer_gifts_about" = "These gifts were sent to {user} by other users."; "lng_peer_gifts_about_mine" = "These gifts were sent to you by other users. Click on a gift to convert it to Stars or change its privacy settings."; diff --git a/Telegram/SourceFiles/api/api_chat_participants.cpp b/Telegram/SourceFiles/api/api_chat_participants.cpp index 10663d1de..478390798 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.cpp +++ b/Telegram/SourceFiles/api/api_chat_participants.cpp @@ -211,11 +211,10 @@ void ApplyBotsList( Data::PeerUpdate::Flag::FullInfo); } -[[nodiscard]] ChatParticipants::Channels ParseSimilar( +[[nodiscard]] ChatParticipants::Peers ParseSimilarChannels( not_null session, const MTPmessages_Chats &chats) { - auto result = ChatParticipants::Channels(); - std::vector>(); + auto result = ChatParticipants::Peers(); chats.match([&](const auto &data) { const auto &list = data.vchats().v; result.list.reserve(list.size()); @@ -234,10 +233,29 @@ void ApplyBotsList( return result; } -[[nodiscard]] ChatParticipants::Channels ParseSimilar( +[[nodiscard]] ChatParticipants::Peers ParseSimilarChannels( not_null channel, const MTPmessages_Chats &chats) { - return ParseSimilar(&channel->session(), chats); + return ParseSimilarChannels(&channel->session(), chats); +} + +[[nodiscard]] ChatParticipants::Peers ParseSimilarBots( + not_null session, + const MTPusers_Users &users) { + auto result = ChatParticipants::Peers(); + users.match([&](const auto &data) { + const auto &list = data.vusers().v; + result.list.reserve(list.size()); + for (const auto &user : list) { + result.list.push_back(session->data().processUser(user)); + } + if constexpr (MTPDusers_usersSlice::Is()) { + if (session->premiumPossible()) { + result.more = data.vcount().v - data.vusers().v.size(); + } + } + }); + return result; } } // namespace @@ -782,52 +800,65 @@ void ChatParticipants::unblock( _kickRequests.emplace(kick, requestId); } -void ChatParticipants::loadSimilarChannels(not_null channel) { - if (!channel->isBroadcast()) { - return; - } else if (const auto i = _similar.find(channel); i != end(_similar)) { +void ChatParticipants::loadSimilarPeers(not_null peer) { + if (const auto i = _similar.find(peer); i != end(_similar)) { if (i->second.requestId - || !i->second.channels.more - || !channel->session().premium()) { + || !i->second.peers.more + || !peer->session().premium()) { return; } } - using Flag = MTPchannels_GetChannelRecommendations::Flag; - _similar[channel].requestId = _api.request( - MTPchannels_GetChannelRecommendations( - MTP_flags(Flag::f_channel), - channel->inputChannel) - ).done([=](const MTPmessages_Chats &result) { - auto &similar = _similar[channel]; - similar.requestId = 0; - auto parsed = ParseSimilar(channel, result); - if (similar.channels == parsed) { - return; - } - similar.channels = std::move(parsed); - if (const auto history = channel->owner().historyLoaded(channel)) { - if (const auto item = history->joinedMessageInstance()) { - history->owner().requestItemResize(item); + if (const auto channel = peer->asBroadcast()) { + using Flag = MTPchannels_GetChannelRecommendations::Flag; + _similar[peer].requestId = _api.request( + MTPchannels_GetChannelRecommendations( + MTP_flags(Flag::f_channel), + channel->inputChannel) + ).done([=](const MTPmessages_Chats &result) { + auto &similar = _similar[channel]; + similar.requestId = 0; + auto parsed = ParseSimilarChannels(channel, result); + if (similar.peers == parsed) { + return; } - } - _similarLoaded.fire_copy(channel); - }).send(); + similar.peers = std::move(parsed); + if (const auto history = channel->owner().historyLoaded(channel)) { + if (const auto item = history->joinedMessageInstance()) { + history->owner().requestItemResize(item); + } + } + _similarLoaded.fire_copy(channel); + }).send(); + } else if (const auto bot = peer->asBot()) { + _similar[peer].requestId = _api.request( + MTPbots_GetBotRecommendations(bot->inputUser) + ).done([=](const MTPusers_Users &result) { + auto &similar = _similar[peer]; + similar.requestId = 0; + auto parsed = ParseSimilarBots(&peer->session(), result); + if (similar.peers == parsed) { + return; + } + similar.peers = std::move(parsed); + _similarLoaded.fire_copy(peer); + }).send(); + } } -auto ChatParticipants::similar(not_null channel) --> const Channels & { - const auto i = channel->isBroadcast() - ? _similar.find(channel) +auto ChatParticipants::similar(not_null peer) +-> const Peers & { + const auto i = (peer->isBroadcast() || peer->isBot()) + ? _similar.find(peer) : end(_similar); if (i != end(_similar)) { - return i->second.channels; + return i->second.peers; } - static const auto empty = Channels(); + static const auto empty = Peers(); return empty; } auto ChatParticipants::similarLoaded() const --> rpl::producer> { +-> rpl::producer> { return _similarLoaded.events(); } @@ -841,15 +872,15 @@ void ChatParticipants::loadRecommendations() { MTP_inputChannelEmpty()) ).done([=](const MTPmessages_Chats &result) { _recommendations.requestId = 0; - auto parsed = ParseSimilar(_session, result); - _recommendations.channels = std::move(parsed); - _recommendations.channels.more = 0; + auto parsed = ParseSimilarChannels(_session, result); + _recommendations.peers = std::move(parsed); + _recommendations.peers.more = 0; _recommendationsLoaded = true; }).send(); } -const ChatParticipants::Channels &ChatParticipants::recommendations() const { - return _recommendations.channels; +const ChatParticipants::Peers &ChatParticipants::recommendations() const { + return _recommendations.peers; } rpl::producer<> ChatParticipants::recommendationsLoaded() const { diff --git a/Telegram/SourceFiles/api/api_chat_participants.h b/Telegram/SourceFiles/api/api_chat_participants.h index df332522d..4f073eb8e 100644 --- a/Telegram/SourceFiles/api/api_chat_participants.h +++ b/Telegram/SourceFiles/api/api_chat_participants.h @@ -138,27 +138,27 @@ public: not_null channel, not_null participant); - void loadSimilarChannels(not_null channel); + void loadSimilarPeers(not_null peer); - struct Channels { - std::vector> list; + struct Peers { + std::vector> list; int more = 0; friend inline bool operator==( - const Channels &, - const Channels &) = default; + const Peers &, + const Peers &) = default; }; - [[nodiscard]] const Channels &similar(not_null channel); + [[nodiscard]] const Peers &similar(not_null peer); [[nodiscard]] auto similarLoaded() const - -> rpl::producer>; + -> rpl::producer>; void loadRecommendations(); - [[nodiscard]] const Channels &recommendations() const; + [[nodiscard]] const Peers &recommendations() const; [[nodiscard]] rpl::producer<> recommendationsLoaded() const; private: - struct SimilarChannels { - Channels channels; + struct SimilarPeers { + Peers peers; mtpRequestId requestId = 0; }; @@ -186,10 +186,10 @@ private: not_null>; base::flat_map _kickRequests; - base::flat_map, SimilarChannels> _similar; - rpl::event_stream> _similarLoaded; + base::flat_map, SimilarPeers> _similar; + rpl::event_stream> _similarLoaded; - SimilarChannels _recommendations; + SimilarPeers _recommendations; rpl::variable _recommendationsLoaded = false; }; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index fc9958c47..31a235a7a 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -1772,7 +1772,7 @@ void ApiWrap::joinChannel(not_null channel) { _channelAmInRequests.emplace(channel, requestId); using Flag = ChannelDataFlag; - chatParticipants().loadSimilarChannels(channel); + chatParticipants().loadSimilarPeers(channel); channel->setFlags(channel->flags() | Flag::SimilarExpanded); } } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 52673acb9..9da5b0f5f 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -911,6 +911,16 @@ void PeerData::fullUpdated() { setLoadedStatus(LoadedStatus::Full); } +UserData *PeerData::asBot() { + return isBot() ? static_cast(this) : nullptr; +} + +const UserData *PeerData::asBot() const { + return isBot() + ? static_cast(this) + : nullptr; +} + UserData *PeerData::asUser() { return isUser() ? static_cast(this) : nullptr; } @@ -1131,6 +1141,13 @@ EmojiStatusId PeerData::emojiStatusId() const { return _emojiStatusId; } +bool PeerData::isBot() const { + if (const auto user = asUser()) { + return user->isBot(); + } + return false; +} + bool PeerData::isSelf() const { if (const auto user = asUser()) { return (user->flags() & UserDataFlag::Self); diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 1c1cca3dc..9f7837412 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -218,6 +218,7 @@ public: [[nodiscard]] bool isChannel() const { return peerIsChannel(id); } + [[nodiscard]] bool isBot() const; [[nodiscard]] bool isSelf() const; [[nodiscard]] bool isVerified() const; [[nodiscard]] bool isPremium() const; @@ -267,6 +268,8 @@ public: [[nodiscard]] int slowmodeSecondsLeft() const; [[nodiscard]] bool canManageGroupCall() const; + [[nodiscard]] UserData *asBot(); + [[nodiscard]] const UserData *asBot() const; [[nodiscard]] UserData *asUser(); [[nodiscard]] const UserData *asUser() const; [[nodiscard]] ChatData *asChat(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_similar_channels.cpp b/Telegram/SourceFiles/history/view/media/history_view_similar_channels.cpp index aa14b12c1..93b99c481 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_similar_channels.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_similar_channels.cpp @@ -18,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/history_view_cursor_state.h" #include "history/history.h" #include "history/history_item.h" -#include "info/similar_channels/info_similar_channels_widget.h" +#include "info/similar_peers/info_similar_peers_widget.h" #include "info/info_controller.h" #include "info/info_memento.h" #include "lang/lang_keys.h" @@ -37,7 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace HistoryView { namespace { -using Channels = Api::ChatParticipants::Channels; +using Channels = Api::ChatParticipants::Peers; //void SimilarChannelsController::prepare() { // for (const auto &channel : _channels.list) { @@ -86,7 +86,7 @@ using Channels = Api::ChatParticipants::Channels; strong->showSection( std::make_shared( channel, - Info::Section::Type::SimilarChannels)); + Info::Section::Type::SimilarPeers)); } }); } @@ -519,7 +519,7 @@ QSize SimilarChannels::countOptimalSize() { _channels.clear(); _moreThumbnails = {}; const auto api = &channel->session().api(); - api->chatParticipants().loadSimilarChannels(channel); + api->chatParticipants().loadSimilarPeers(channel); const auto premium = channel->session().premium(); const auto &similar = api->chatParticipants().similar(channel); _empty = similar.list.empty() ? 1 : 0; @@ -543,9 +543,14 @@ QSize SimilarChannels::countOptimalSize() { ? limit : int(similar.list.size()); const auto more = similar.more + int(similar.list.size() - take); - auto &&channels = ranges::views::all(similar.list) + auto &&peers = ranges::views::all(similar.list) | ranges::views::take(limit); - for (const auto &channel : channels) { + for (const auto &peer : peers) { + const auto channel = peer->asBroadcast(); + if (!channel) { + continue; + } + const auto moreCounter = (_channels.size() + 1 == take) ? more : 0; _channels.push_back({ .geometry = QRect(QPoint(x, y), outer.size()), @@ -566,8 +571,8 @@ QSize SimilarChannels::countOptimalSize() { : channel->openLink(); const auto counter = moreCounter - ? moreCounter : - channel->membersCount(); + ? moreCounter + : channel->membersCount(); if (moreCounter || counter > 1) { last.counter = (moreCounter ? u"+"_q : QString()) + Lang::FormatCountToShort(counter).string; diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 96a0089fd..2483ae755 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -477,6 +477,7 @@ infoIconMediaAudio: icon {{ "info/info_media_audio", infoIconFg }}; infoIconMediaLink: icon {{ "info/info_media_link", infoIconFg }}; infoIconMediaGroup: icon {{ "info/info_common_groups", infoIconFg }}; infoIconMediaChannel: icon {{ "menu/channel", infoIconFg, point(4px, 4px) }}; +infoIconMediaBot: icon {{ "menu/bot", infoIconFg, point(4px, 4px) }}; infoIconMediaVoice: icon {{ "info/info_media_voice", infoIconFg }}; infoIconMediaStories: icon {{ "info/info_media_stories", infoIconFg }}; infoIconMediaSaved: icon {{ "info/info_media_saved", infoIconFg }}; diff --git a/Telegram/SourceFiles/info/info_controller.h b/Telegram/SourceFiles/info/info_controller.h index d6538ee93..e6e18d606 100644 --- a/Telegram/SourceFiles/info/info_controller.h +++ b/Telegram/SourceFiles/info/info_controller.h @@ -158,7 +158,7 @@ public: Media, GlobalMedia, CommonGroups, - SimilarChannels, + SimilarPeers, RequestsList, ReactionsList, SavedSublists, diff --git a/Telegram/SourceFiles/info/info_memento.cpp b/Telegram/SourceFiles/info/info_memento.cpp index 181083945..3e33e66fe 100644 --- a/Telegram/SourceFiles/info/info_memento.cpp +++ b/Telegram/SourceFiles/info/info_memento.cpp @@ -14,7 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/common_groups/info_common_groups_widget.h" #include "info/saved/info_saved_sublists_widget.h" #include "info/settings/info_settings_widget.h" -#include "info/similar_channels/info_similar_channels_widget.h" +#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/peer_gifts/info_peer_gifts_widget.h" @@ -172,9 +172,8 @@ std::shared_ptr Memento::DefaultContent( section.mediaType()); case Section::Type::CommonGroups: return std::make_shared(peer->asUser()); - case Section::Type::SimilarChannels: - return std::make_shared( - peer->asChannel()); + case Section::Type::SimilarPeers: + return std::make_shared(peer); case Section::Type::RequestsList: return std::make_shared(peer); case Section::Type::PeerGifts: diff --git a/Telegram/SourceFiles/info/media/info_media_buttons.h b/Telegram/SourceFiles/info/media/info_media_buttons.h index af97c6d27..b416221bf 100644 --- a/Telegram/SourceFiles/info/media/info_media_buttons.h +++ b/Telegram/SourceFiles/info/media/info_media_buttons.h @@ -131,26 +131,25 @@ inline auto AddCommonGroupsButton( return result; } -inline auto AddSimilarChannelsButton( +inline auto AddSimilarPeersButton( Ui::VerticalLayout *parent, not_null navigation, - not_null channel, + not_null peer, Ui::MultiSlideTracker &tracker) { auto result = AddCountedButton( parent, - Profile::SimilarChannelsCountValue(channel), - [](int count) { - return tr::lng_profile_similar_channels( - tr::now, - lt_count, - count); + Profile::SimilarPeersCountValue(peer), + [=](int count) { + return peer->isBroadcast() + ? tr::lng_profile_similar_channels(tr::now, lt_count, count) + : tr::lng_profile_similar_bots(tr::now, lt_count, count); }, tracker)->entity(); result->addClickHandler([=] { navigation->showSection( std::make_shared( - channel, - Section::Type::SimilarChannels)); + peer, + Section::Type::SimilarPeers)); }); return result; } diff --git a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp index e0e72cdca..03a6cbefa 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_inner_widget.cpp @@ -178,13 +178,13 @@ object_ptr InnerWidget::setupSharedMedia( icon, st::infoSharedMediaButtonIconPosition); }; - const auto addSimilarChannelsButton = [&]( - not_null channel, + const auto addSimilarPeersButton = [&]( + not_null peer, const style::icon &icon) { - auto result = Media::AddSimilarChannelsButton( + auto result = Media::AddSimilarPeersButton( content, _controller, - channel, + peer, tracker); object_ptr( result, @@ -248,10 +248,12 @@ object_ptr InnerWidget::setupSharedMedia( addMediaButton(MediaType::Link, st::infoIconMediaLink); addMediaButton(MediaType::RoundVoiceFile, st::infoIconMediaVoice); addMediaButton(MediaType::GIF, st::infoIconMediaGif); - if (const auto user = _peer->asUser()) { + if (const auto bot = _peer->asBot()) { + addSimilarPeersButton(bot, st::infoIconMediaBot); + } else if (const auto channel = _peer->asBroadcast()) { + addSimilarPeersButton(channel, st::infoIconMediaChannel); + } else if (const auto user = _peer->asUser()) { addCommonGroupsButton(user, st::infoIconMediaGroup); - } else if (const auto channel = _peer->asChannel()) { - addSimilarChannelsButton(channel, st::infoIconMediaChannel); } auto result = object_ptr>( diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.cpp b/Telegram/SourceFiles/info/profile/info_profile_values.cpp index 447f11320..79e54aceb 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_values.cpp @@ -570,16 +570,16 @@ rpl::producer CommonGroupsCountValue(not_null user) { }); } -rpl::producer SimilarChannelsCountValue( - not_null channel) { - const auto participants = &channel->session().api().chatParticipants(); - participants->loadSimilarChannels(channel); - return rpl::single(channel) | rpl::then( +rpl::producer SimilarPeersCountValue( + not_null peer) { + const auto participants = &peer->session().api().chatParticipants(); + participants->loadSimilarPeers(peer); + return rpl::single(peer) | rpl::then( participants->similarLoaded() ) | rpl::filter( - rpl::mappers::_1 == channel + rpl::mappers::_1 == peer ) | rpl::map([=] { - const auto &similar = participants->similar(channel); + const auto &similar = participants->similar(peer); return int(similar.list.size()) + similar.more; }); } diff --git a/Telegram/SourceFiles/info/profile/info_profile_values.h b/Telegram/SourceFiles/info/profile/info_profile_values.h index 4754ad705..64c6a901e 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_values.h +++ b/Telegram/SourceFiles/info/profile/info_profile_values.h @@ -117,8 +117,8 @@ struct LinkWithUrl { Storage::SharedMediaType type); [[nodiscard]] rpl::producer CommonGroupsCountValue( not_null user); -[[nodiscard]] rpl::producer SimilarChannelsCountValue( - not_null channel); +[[nodiscard]] rpl::producer SimilarPeersCountValue( + not_null peer); [[nodiscard]] rpl::producer SavedSublistCountValue( not_null peer); [[nodiscard]] rpl::producer PeerGiftsCountValue( diff --git a/Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.cpp b/Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.cpp similarity index 85% rename from Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.cpp rename to Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.cpp index ae77ec2e2..3646b5b68 100644 --- a/Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.cpp +++ b/Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.cpp @@ -5,7 +5,7 @@ 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/similar_channels/info_similar_channels_widget.h" +#include "info/similar_peers/info_similar_peers_widget.h" #include "api/api_chat_participants.h" #include "apiwrap.h" @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_peer_values.h" #include "data/data_premium_limits.h" #include "data/data_session.h" +#include "data/data_user.h" #include "info/info_controller.h" #include "main/main_session.h" #include "ui/text/text_utilities.h" @@ -27,14 +28,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_info.h" #include "styles/style_widgets.h" -namespace Info::SimilarChannels { +namespace Info::SimilarPeers { namespace { class ListController final : public PeerListController { public: ListController( not_null controller, - not_null channel); + not_null peer); Main::Session &session() const override; void prepare() override; @@ -60,7 +61,7 @@ private: struct SavedState : SavedStateBase { }; const not_null _controller; - const not_null _channel; + const not_null _peer; Ui::RpWidget *_content = nullptr; Ui::RpWidget *_unlock = nullptr; rpl::variable _unlockHeight; @@ -69,14 +70,14 @@ private: ListController::ListController( not_null controller, - not_null channel) + not_null peer) : PeerListController() , _controller(controller) -, _channel(channel) { +, _peer(peer) { } Main::Session &ListController::session() const { - return _channel->session(); + return _peer->session(); } std::unique_ptr ListController::createRow( @@ -95,20 +96,22 @@ std::unique_ptr ListController::createRow( } void ListController::prepare() { - delegate()->peerListSetTitle(tr::lng_similar_channels_title()); + delegate()->peerListSetTitle(_peer->isBroadcast() + ? tr::lng_similar_channels_title() + : tr::lng_similar_bots_title()); - const auto participants = &_channel->session().api().chatParticipants(); + const auto participants = &_peer->session().api().chatParticipants(); Data::AmPremiumValue( - &_channel->session() + &_peer->session() ) | rpl::start_with_next([=] { - participants->loadSimilarChannels(_channel); + participants->loadSimilarPeers(_peer); rebuild(); }, lifetime()); participants->similarLoaded( ) | rpl::filter( - rpl::mappers::_1 == _channel + rpl::mappers::_1 == _peer ) | rpl::start_with_next([=] { rebuild(); }, lifetime()); @@ -123,16 +126,16 @@ rpl::producer ListController::unlockHeightValue() const { } void ListController::rebuild() { - const auto participants = &_channel->session().api().chatParticipants(); - const auto &list = participants->similar(_channel); - for (const auto channel : list.list) { - if (!delegate()->peerListFindRow(channel->id.value)) { - delegate()->peerListAppendRow(createRow(channel)); + const auto participants = &_peer->session().api().chatParticipants(); + const auto &list = participants->similar(_peer); + for (const auto peer : list.list) { + if (!delegate()->peerListFindRow(peer->id.value)) { + delegate()->peerListAppendRow(createRow(peer)); } } if (!list.more - || _channel->session().premium() - || !_channel->session().premiumPossible()) { + || _peer->session().premium() + || !_peer->session().premiumPossible()) { delete base::take(_unlock); _unlockHeight = 0; } else if (!_unlock) { @@ -149,7 +152,9 @@ void ListController::setupUnlock() { const auto button = ::Settings::CreateLockedButton( _unlock, - tr::lng_similar_channels_show_more(), + (_peer->isBroadcast() + ? tr::lng_similar_channels_show_more() + : tr::lng_similar_bots_show_more()), st::similarChannelsLock, rpl::single(true)); button->setClickedCallback([=] { @@ -158,16 +163,18 @@ void ListController::setupUnlock() { }); const auto upto = Data::PremiumLimits( - &_channel->session()).similarChannelsPremium(); + &_peer->session()).similarChannelsPremium(); const auto about = Ui::CreateChild( _unlock, - tr::lng_similar_channels_premium_all( - lt_count, - rpl::single(upto * 1.), - lt_link, - tr::lng_similar_channels_premium_all_link( - ) | Ui::Text::ToBold() | Ui::Text::ToLink(), - Ui::Text::RichLangValue), + (_peer->isBroadcast() + ? tr::lng_similar_channels_premium_all + : tr::lng_similar_bots_premium_all)( + lt_count, + rpl::single(upto * 1.), + lt_link, + tr::lng_similar_channels_premium_all_link( + ) | Ui::Text::ToBold() | Ui::Text::ToLink(), + Ui::Text::RichLangValue), st::similarChannelsLockAbout); about->setClickHandlerFilter([=](const auto &...) { const auto window = _controller->parentController(); @@ -177,7 +184,9 @@ void ListController::setupUnlock() { rpl::combine( _content->sizeValue(), - tr::lng_similar_channels_show_more() + (_peer->isBroadcast() + ? tr::lng_similar_channels_show_more() + : tr::lng_similar_bots_show_more()) ) | rpl::start_with_next([=](QSize size, const auto &) { auto top = st::similarChannelsLockFade + st::similarChannelsLockPadding.top(); @@ -263,10 +272,10 @@ public: InnerWidget( QWidget *parent, not_null controller, - not_null channel); + not_null peer); - [[nodiscard]] not_null channel() const { - return _channel; + [[nodiscard]] not_null peer() const { + return _peer; } rpl::producer scrollToRequests() const; @@ -305,7 +314,7 @@ private: const std::shared_ptr _show; not_null _controller; - const not_null _channel; + const not_null _peer; std::unique_ptr _listController; object_ptr _list; @@ -316,12 +325,12 @@ private: InnerWidget::InnerWidget( QWidget *parent, not_null controller, - not_null channel) + not_null peer) : RpWidget(parent) , _show(controller->uiShow()) , _controller(controller) -, _channel(channel) -, _listController(std::make_unique(controller, _channel)) +, _peer(peer) +, _listController(std::make_unique(controller, _peer)) , _list(setupList(this, _listController.get())) { setContent(_list.data()); _listController->setDelegate(static_cast(this)); @@ -428,23 +437,19 @@ std::shared_ptr InnerWidget::peerListUiShow() { return _show; } -Memento::Memento(not_null channel) -: ContentMemento(channel, nullptr, PeerId()) { +Memento::Memento(not_null peer) +: ContentMemento(peer, nullptr, PeerId()) { } Section Memento::section() const { - return Section(Section::Type::SimilarChannels); -} - -not_null Memento::channel() const { - return peer()->asChannel(); + return Section(Section::Type::SimilarPeers); } object_ptr Memento::createWidget( QWidget *parent, not_null controller, const QRect &geometry) { - auto result = object_ptr(parent, controller, channel()); + auto result = object_ptr(parent, controller, peer()); result->setInternalState(geometry, this); return result; } @@ -462,20 +467,22 @@ Memento::~Memento() = default; Widget::Widget( QWidget *parent, not_null controller, - not_null channel) + not_null peer) : ContentWidget(parent, controller) { _inner = setInnerWidget(object_ptr( this, controller, - channel)); + peer)); } rpl::producer Widget::title() { - return tr::lng_similar_channels_title(); + return peer()->isBroadcast() + ? tr::lng_similar_channels_title() + : tr::lng_similar_bots_title(); } -not_null Widget::channel() const { - return _inner->channel(); +not_null Widget::peer() const { + return _inner->peer(); } bool Widget::showInternal(not_null memento) { @@ -483,7 +490,7 @@ bool Widget::showInternal(not_null memento) { return false; } if (auto similarMemento = dynamic_cast(memento.get())) { - if (similarMemento->channel() == channel()) { + if (similarMemento->peer() == peer()) { restoreState(similarMemento); return true; } @@ -500,7 +507,7 @@ void Widget::setInternalState( } std::shared_ptr Widget::doCreateMemento() { - auto result = std::make_shared(channel()); + auto result = std::make_shared(peer()); saveState(result.get()); return result; } @@ -515,4 +522,4 @@ void Widget::restoreState(not_null memento) { scrollTopRestore(memento->scrollTop()); } -} // namespace Info::SimilarChannels +} // namespace Info::SimilarPeers diff --git a/Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.h b/Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.h similarity index 81% rename from Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.h rename to Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.h index 74f15e64f..0f002aa4c 100644 --- a/Telegram/SourceFiles/info/similar_channels/info_similar_channels_widget.h +++ b/Telegram/SourceFiles/info/similar_peers/info_similar_peers_widget.h @@ -9,16 +9,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/info_content_widget.h" -class ChannelData; +class PeerData; struct PeerListState; -namespace Info::SimilarChannels { +namespace Info::SimilarPeers { class InnerWidget; class Memento final : public ContentMemento { public: - explicit Memento(not_null channel); + explicit Memento(not_null peer); object_ptr createWidget( QWidget *parent, @@ -27,8 +27,6 @@ public: Section section() const override; - [[nodiscard]] not_null channel() const; - void setListState(std::unique_ptr state); std::unique_ptr listState(); @@ -44,9 +42,9 @@ public: Widget( QWidget *parent, not_null controller, - not_null channel); + not_null peer); - [[nodiscard]] not_null channel() const; + [[nodiscard]] not_null peer() const; bool showInternal( not_null memento) override; @@ -67,4 +65,4 @@ private: }; -} // namespace Info::SimilarChannels +} // namespace Info::SimilarPeers