Added api support for premium bot peer type for credits history entries.

This commit is contained in:
23rd 2024-05-24 16:02:05 +03:00 committed by John Preston
parent 97a5e0c6ea
commit 7194781bb8
6 changed files with 80 additions and 15 deletions

View file

@ -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<not_null<PeerData*>> PremiumPeerBot(
not_null<Main::Session*> session) {
const auto username = session->appConfig().get<QString>(
u"premium_bot_username"_q,
QString());
if (username.isEmpty()) {
return rpl::never<not_null<PeerData*>>();
}
if (const auto p = session->data().peerByUsername(username)) {
return rpl::single<not_null<PeerData*>>(p);
}
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
const auto api = lifetime.make_state<MTP::Sender>(&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

View file

@ -68,4 +68,7 @@ private:
};
[[nodiscard]] rpl::producer<not_null<PeerData*>> PremiumPeerBot(
not_null<Main::Session*> session);
} // namespace Api

View file

@ -121,7 +121,7 @@ struct BoostsDescriptor final {
struct CreditsDescriptor final {
Data::CreditsStatusSlice firstSlice;
Fn<void(const Data::CreditsHistoryEntry &)> entryClickedCallback;
not_null<PeerData*> peer;
not_null<PeerData*> premiumBot;
not_null<QImage*> 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<Main::Session*> _session;
const not_null<PeerData*> _premiumBot;
Fn<void(const Data::CreditsHistoryEntry &)> _entryClickedCallback;
not_null<QImage*> 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<CreditsRow>(peer, descriptor);
} else if (item.peerType == Type::PremiumBot) {
return std::make_unique<CreditsRow>(_premiumBot, descriptor);
} else {
return std::make_unique<CreditsRow>(descriptor);
}
@ -1084,7 +1089,7 @@ void AddCreditsHistoryList(
const Data::CreditsStatusSlice &firstSlice,
not_null<Ui::VerticalLayout*> container,
Fn<void(const Data::CreditsHistoryEntry &)> callback,
not_null<PeerData*> self,
not_null<PeerData*> bot,
not_null<QImage*> 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<State>(std::move(d));
state->delegate.setContent(container->add(

View file

@ -50,7 +50,7 @@ void AddCreditsHistoryList(
const Data::CreditsStatusSlice &firstSlice,
not_null<Ui::VerticalLayout*> container,
Fn<void(const Data::CreditsHistoryEntry &)> entryClickedCallback,
not_null<PeerData*> self,
not_null<PeerData*> premiumBot,
not_null<QImage*> creditIcon,
bool in,
bool out);

View file

@ -366,6 +366,7 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> container) {
Ui::AddSkip(content, st::settingsPremiumOptionsPadding.top());
const auto fill = [=](
not_null<PeerData*> premiumBot,
const Data::CreditsStatusSlice &fullSlice,
const Data::CreditsStatusSlice &inSlice,
const Data::CreditsStatusSlice &outSlice) {
@ -475,8 +476,12 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> 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<Ui::VerticalLayout*> container) {
fullSlice,
fullWrap->entity(),
entryClicked,
_controller->session().user(),
premiumBot,
&_star,
true,
true);
@ -588,7 +593,7 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> container) {
inSlice,
inWrap->entity(),
entryClicked,
_controller->session().user(),
premiumBot,
&_star,
true,
false);
@ -596,7 +601,7 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> container) {
outSlice,
outWrap->entity(),
std::move(entryClicked),
_controller->session().user(),
premiumBot,
&_star,
false,
true);
@ -617,8 +622,12 @@ void Credits::setupHistory(not_null<Ui::VerticalLayout*> 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<PeerData*> bot) {
fill(bot, fullSlice, inSlice, outSlice);
apiLifetime->destroy();
}, *apiLifetime);
});
});
});

View file

@ -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);
};
}