From 7194781bb836a34524de21c6246dbff51bc1daf3 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 24 May 2024 16:02:05 +0300 Subject: [PATCH] Added api support for premium bot peer type for credits history entries. --- Telegram/SourceFiles/api/api_credits.cpp | 34 +++++++++++++++++++ Telegram/SourceFiles/api/api_credits.h | 3 ++ .../info_statistics_list_controllers.cpp | 19 +++++++---- .../info_statistics_list_controllers.h | 2 +- .../SourceFiles/settings/settings_credits.cpp | 21 ++++++++---- .../ui/effects/credits_graphics.cpp | 16 ++++++++- 6 files changed, 80 insertions(+), 15 deletions(-) diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index 61ce79870..1604d6d5c 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "data/data_peer.h" #include "data/data_session.h" +#include "main/main_app_config.h" #include "main/main_session.h" #if _DEBUG #include "base/random.h" @@ -155,4 +156,37 @@ Data::CreditTopupOptions CreditsTopupOptions::options() const { return _options; } +rpl::producer> PremiumPeerBot( + not_null session) { + const auto username = session->appConfig().get( + u"premium_bot_username"_q, + QString()); + if (username.isEmpty()) { + return rpl::never>(); + } + if (const auto p = session->data().peerByUsername(username)) { + return rpl::single>(p); + } + return [=](auto consumer) { + auto lifetime = rpl::lifetime(); + + const auto api = lifetime.make_state(&session->mtp()); + + api->request(MTPcontacts_ResolveUsername( + MTP_string(username) + )).done([=](const MTPcontacts_ResolvedPeer &result) { + session->data().processUsers(result.data().vusers()); + session->data().processChats(result.data().vchats()); + const auto botPeer = session->data().peerLoaded( + peerFromMTP(result.data().vpeer())); + if (!botPeer) { + return consumer.put_done(); + } + consumer.put_next(not_null{ botPeer }); + }).send(); + + return lifetime; + }; +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_credits.h b/Telegram/SourceFiles/api/api_credits.h index 5807f34c7..265e7b387 100644 --- a/Telegram/SourceFiles/api/api_credits.h +++ b/Telegram/SourceFiles/api/api_credits.h @@ -68,4 +68,7 @@ private: }; +[[nodiscard]] rpl::producer> PremiumPeerBot( + not_null session); + } // namespace Api diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index 5154a3044..ecbcff3ec 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -121,7 +121,7 @@ struct BoostsDescriptor final { struct CreditsDescriptor final { Data::CreditsStatusSlice firstSlice; Fn entryClickedCallback; - not_null peer; + not_null premiumBot; not_null creditIcon; bool in = false; bool out = false; @@ -768,7 +768,7 @@ void CreditsRow::init() { constexpr auto kMinus = QChar(0x2212); _rightText.setText( st::semiboldTextStyle, - (PeerListRow::special() ? QChar('+') : kMinus) + (!_entry.bareId ? QChar('+') : kMinus) + Lang::FormatCountDecimal(_entry.credits)); } _paintUserpicCallback = !PeerListRow::special() @@ -816,7 +816,7 @@ void CreditsRow::rightActionPaint( bool actionSelected) { const auto &font = _rightText.style()->font; y += _rowHeight / 2; - p.setPen(PeerListRow::special() + p.setPen(!_entry.bareId ? st::boxTextFgGood : st::menuIconAttentionColor); x += st::creditsHistoryRightSkip; @@ -850,6 +850,7 @@ private: void applySlice(const Data::CreditsStatusSlice &slice); const not_null _session; + const not_null _premiumBot; Fn _entryClickedCallback; not_null const _creditIcon; @@ -863,10 +864,11 @@ private: }; CreditsController::CreditsController(CreditsDescriptor d) -: _session(&d.peer->session()) +: _session(&d.premiumBot->session()) +, _premiumBot(d.premiumBot) , _entryClickedCallback(std::move(d.entryClickedCallback)) , _creditIcon(d.creditIcon) -, _api(d.peer, d.in, d.out) +, _api(d.premiumBot, d.in, d.out) , _firstSlice(std::move(d.firstSlice)) { PeerListController::setStyleOverrides(&st::boostsListBox); } @@ -906,9 +908,12 @@ void CreditsController::applySlice(const Data::CreditsStatusSlice &slice) { .creditIcon = _creditIcon, .rowHeight = computeListSt().item.height, }; + using Type = Data::CreditsHistoryEntry::PeerType; if (item.bareId) { const auto peer = session().data().peer(PeerId(item.bareId)); return std::make_unique(peer, descriptor); + } else if (item.peerType == Type::PremiumBot) { + return std::make_unique(_premiumBot, descriptor); } else { return std::make_unique(descriptor); } @@ -1084,7 +1089,7 @@ void AddCreditsHistoryList( const Data::CreditsStatusSlice &firstSlice, not_null container, Fn callback, - not_null self, + not_null bot, not_null icon, bool in, bool out) { @@ -1094,7 +1099,7 @@ void AddCreditsHistoryList( PeerListContentDelegateSimple delegate; CreditsController controller; }; - auto d = CreditsDescriptor{ firstSlice, callback, self, icon, in, out }; + auto d = CreditsDescriptor{ firstSlice, callback, bot, icon, in, out }; const auto state = container->lifetime().make_state(std::move(d)); state->delegate.setContent(container->add( diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h index 0e3d00019..09883090d 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h @@ -50,7 +50,7 @@ void AddCreditsHistoryList( const Data::CreditsStatusSlice &firstSlice, not_null container, Fn entryClickedCallback, - not_null self, + not_null premiumBot, not_null creditIcon, bool in, bool out); diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index 127c5fd91..1b9efbe07 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -366,6 +366,7 @@ void Credits::setupHistory(not_null container) { Ui::AddSkip(content, st::settingsPremiumOptionsPadding.top()); const auto fill = [=]( + not_null premiumBot, const Data::CreditsStatusSlice &fullSlice, const Data::CreditsStatusSlice &inSlice, const Data::CreditsStatusSlice &outSlice) { @@ -475,8 +476,12 @@ void Credits::setupHistory(not_null container) { Ui::AddSkip(content); Ui::AddSkip(content); + using Type = Data::CreditsHistoryEntry::PeerType; + const auto &stUser = st::boostReplaceUserpic; - const auto peer = e.bareId + const auto peer = (e.peerType == Type::PremiumBot) + ? premiumBot.get() + : e.bareId ? _controller->session().data().peer(PeerId(e.bareId)).get() : nullptr; if (peer) { @@ -580,7 +585,7 @@ void Credits::setupHistory(not_null container) { fullSlice, fullWrap->entity(), entryClicked, - _controller->session().user(), + premiumBot, &_star, true, true); @@ -588,7 +593,7 @@ void Credits::setupHistory(not_null container) { inSlice, inWrap->entity(), entryClicked, - _controller->session().user(), + premiumBot, &_star, true, false); @@ -596,7 +601,7 @@ void Credits::setupHistory(not_null container) { outSlice, outWrap->entity(), std::move(entryClicked), - _controller->session().user(), + premiumBot, &_star, false, true); @@ -617,8 +622,12 @@ void Credits::setupHistory(not_null container) { apiFull->request({}, [=](Data::CreditsStatusSlice fullSlice) { apiIn->request({}, [=](Data::CreditsStatusSlice inSlice) { apiOut->request({}, [=](Data::CreditsStatusSlice outSlice) { - fill(fullSlice, inSlice, outSlice); - apiLifetime->destroy(); + ::Api::PremiumPeerBot( + &_controller->session() + ) | rpl::start_with_next([=](not_null bot) { + fill(bot, fullSlice, inSlice, outSlice); + apiLifetime->destroy(); + }, *apiLifetime); }); }); }); diff --git a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp index fd465f6b3..44e82195a 100644 --- a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp +++ b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_credits.h" #include "styles/style_intro.h" // introFragmentIcon. #include "styles/style_settings.h" +#include "styles/style_dialogs.h" namespace Ui { @@ -38,6 +39,13 @@ PaintRoundImageCallback GenerateCreditsPaintUserpicCallback( return { st::historyPeer2UserpicBg, st::historyPeer2UserpicBg2 }; case Data::CreditsHistoryEntry::PeerType::Fragment: return { st::historyPeer8UserpicBg, st::historyPeer8UserpicBg2 }; + case Data::CreditsHistoryEntry::PeerType::PremiumBot: + return { st::historyPeer8UserpicBg, st::historyPeer8UserpicBg2 }; + case Data::CreditsHistoryEntry::PeerType::Unsupported: + return { + st::historyPeerArchiveUserpicBg, + st::historyPeerArchiveUserpicBg, + }; } Unexpected("Unknown peer type."); }(); @@ -45,11 +53,17 @@ PaintRoundImageCallback GenerateCreditsPaintUserpicCallback( return [=](Painter &p, int x, int y, int outerWidth, int size) mutable { userpic->paintCircle(p, x, y, outerWidth, size); using PeerType = Data::CreditsHistoryEntry::PeerType; + if (entry.peerType == PeerType::PremiumBot) { + return; + } + const auto rect = QRect(x, y, size, size); ((entry.peerType == PeerType::AppStore) ? st::sessionIconiPhone : (entry.peerType == PeerType::PlayMarket) ? st::sessionIconAndroid - : st::introFragmentIcon).paintInCenter(p, { x, y, size, size }); + : (entry.peerType == PeerType::Fragment) + ? st::introFragmentIcon + : st::dialogsInaccessibleUserpic).paintInCenter(p, rect); }; }