Fixed build with layer 206.

This commit is contained in:
23rd 2025-06-27 23:45:20 +03:00
parent 140862ce5a
commit 50d74fcf25
14 changed files with 180 additions and 125 deletions

View file

@ -80,7 +80,7 @@ constexpr auto kTransactionsLimit = 100;
}, [](const auto &) { return (const MTPDstarGift*)nullptr; })
: nullptr;
const auto reaction = tl.data().is_reaction();
const auto amount = CreditsAmountFromTL(tl.data().vstars());
const auto amount = CreditsAmountFromTL(tl.data().vamount());
const auto starrefAmount = CreditsAmountFromTL(
tl.data().vstarref_amount());
const auto starrefCommission
@ -107,7 +107,7 @@ constexpr auto kTransactionsLimit = 100;
.date = base::unixtime::parse(tl.data().vdate().v),
.photoId = photo ? photo->id : 0,
.extended = std::move(extended),
.credits = CreditsAmountFromTL(tl.data().vstars()),
.credits = CreditsAmountFromTL(tl.data().vamount()),
.bareMsgId = uint64(tl.data().vmsg_id().value_or_empty()),
.barePeerId = saveActorId ? peer->id.value : barePeerId,
.bareGiveawayMsgId = uint64(

View file

@ -56,7 +56,6 @@ void HandleWithdrawalButton(
? &currencyReceiver->session()
: &creditsReceiver->session());
using ChannelOutUrl = MTPstats_BroadcastRevenueWithdrawalUrl;
using CreditsOutUrl = MTPpayments_StarsRevenueWithdrawalUrl;
session->api().cloudPassword().reload();
@ -98,19 +97,19 @@ void HandleWithdrawalButton(
show->showToast(message);
}
};
if (currencyReceiver) {
session->api().request(
MTPstats_GetBroadcastRevenueWithdrawalUrl(
currencyReceiver->input,
result.result
)).done([=](const ChannelOutUrl &r) {
done(qs(r.data().vurl()));
}).fail(fail).send();
} else if (creditsReceiver) {
if (currencyReceiver || creditsReceiver) {
using F = MTPpayments_getStarsRevenueWithdrawalUrl::Flag;
session->api().request(
MTPpayments_GetStarsRevenueWithdrawalUrl(
creditsReceiver->input,
MTP_long(receiver.creditsAmount()),
MTP_flags(currencyReceiver
? F::f_ton
: F::f_amount),
currencyReceiver
? currencyReceiver->input
: creditsReceiver->input,
MTP_long(creditsReceiver
? receiver.creditsAmount()
: 0),
result.result
)).done([=](const CreditsOutUrl &r) {
done(qs(r.data().vurl()));
@ -138,17 +137,19 @@ void HandleWithdrawalButton(
processOut();
}
};
if (currencyReceiver) {
session->api().request(
MTPstats_GetBroadcastRevenueWithdrawalUrl(
currencyReceiver->input,
MTP_inputCheckPasswordEmpty()
)).fail(fail).send();
} else if (creditsReceiver) {
if (currencyReceiver || creditsReceiver) {
using F = MTPpayments_getStarsRevenueWithdrawalUrl::Flag;
session->api().request(
MTPpayments_GetStarsRevenueWithdrawalUrl(
creditsReceiver->input,
MTP_long(receiver.creditsAmount()),
MTP_flags(currencyReceiver
? F::f_ton
: F::f_amount),
currencyReceiver
? currencyReceiver->input
: creditsReceiver->input,
MTP_long(creditsReceiver
? receiver.creditsAmount()
: 0),
MTP_inputCheckPasswordEmpty()
)).fail(fail).send();
}

View file

@ -695,19 +695,23 @@ rpl::producer<rpl::no_value, QString> EarnStatistics::request() {
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
makeRequest(MTPstats_GetBroadcastRevenueStats(
MTP_flags(0),
makeRequest(MTPpayments_GetStarsRevenueStats(
MTP_flags(MTPpayments_getStarsRevenueStats::Flag::f_ton),
(_isUser ? user()->input : channel()->input)
)).done([=](const MTPstats_BroadcastRevenueStats &result) {
)).done([=](const MTPpayments_StarsRevenueStats &result) {
const auto &data = result.data();
const auto &balances = data.vbalances().data();
const auto &balances = data.vstatus().data();
const auto amount = [](const auto &a) {
return CreditsAmountFromTL(a);
};
_data = Data::EarnStatistics{
.topHoursGraph = StatisticalGraphFromTL(
data.vtop_hours_graph()),
.topHoursGraph = data.vtop_hours_graph()
? StatisticalGraphFromTL(*data.vtop_hours_graph())
: Data::StatisticalGraph(),
.revenueGraph = StatisticalGraphFromTL(data.vrevenue_graph()),
.currentBalance = balances.vcurrent_balance().v,
.availableBalance = balances.vavailable_balance().v,
.overallRevenue = balances.voverall_revenue().v,
.currentBalance = amount(balances.vcurrent_balance()),
.availableBalance = amount(balances.vavailable_balance()),
.overallRevenue = amount(balances.voverall_revenue()),
.usdRate = data.vusd_rate().v,
};
@ -745,39 +749,60 @@ void EarnStatistics::requestHistory(
if (_requestId) {
return;
}
constexpr auto kTlFirstSlice = tl::make_int(kFirstSlice);
constexpr auto kTlLimit = tl::make_int(kLimit);
_requestId = api().request(MTPstats_GetBroadcastRevenueTransactions(
_requestId = api().request(MTPpayments_GetStarsTransactions(
MTP_flags(MTPpayments_getStarsTransactions::Flag::f_ton
| MTPpayments_getStarsTransactions::Flag::f_inbound
| MTPpayments_getStarsTransactions::Flag::f_outbound),
MTP_string(), // Subscription ID.
(_isUser ? user()->input : channel()->input),
MTP_int(token),
(!token) ? kTlFirstSlice : kTlLimit
)).done([=](const MTPstats_BroadcastRevenueTransactions &result) {
MTP_string(token),
token.isEmpty() ? kTlFirstSlice : kTlLimit
)).done([=](const MTPpayments_StarsStatus &result) {
_requestId = 0;
const auto &tlTransactions = result.data().vtransactions().v;
const auto nextToken = result.data().vnext_offset().value_or_empty();
qDebug() << "next" << nextToken;
const auto &tlTransactions
= result.data().vhistory().value_or_empty();
auto list = std::vector<Data::EarnHistoryEntry>();
list.reserve(tlTransactions.size());
for (const auto &tlTransaction : tlTransactions) {
list.push_back(tlTransaction.match([&](
const MTPDbroadcastRevenueTransactionProceeds &d) {
return Data::EarnHistoryEntry{
const auto &d = tlTransaction.data();
const auto isProceed = d.vads_proceeds_from_date()
|| d.vads_proceeds_to_date();
const auto isRefund = d.is_refund();
const auto amount = CreditsAmountFromTL(d.vamount());
if (isProceed) {
list.push_back(Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::In,
.amount = d.vamount().v,
.date = base::unixtime::parse(d.vfrom_date().v),
.dateTo = base::unixtime::parse(d.vto_date().v),
};
}, [&](const MTPDbroadcastRevenueTransactionWithdrawal &d) {
return Data::EarnHistoryEntry{
.amount = amount,
.date = base::unixtime::parse(
d.vads_proceeds_from_date()->v),
.dateTo = base::unixtime::parse(
d.vads_proceeds_to_date()->v),
});
} else if (isRefund) {
list.push_back(Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::Return,
.amount = amount,
.date = base::unixtime::parse(d.vdate().v),
// .provider = qs(d.vprovider()),
});
} else {
list.push_back(Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::Out,
.status = d.is_pending()
? Data::EarnHistoryEntry::Status::Pending
: d.is_failed()
? Data::EarnHistoryEntry::Status::Failed
: Data::EarnHistoryEntry::Status::Success,
.amount = (std::numeric_limits<Data::EarnInt>::max()
- d.vamount().v
+ 1),
.amount = amount,
.date = base::unixtime::parse(d.vdate().v),
// .provider = qs(d.vprovider()),
.successDate = d.vtransaction_date()
@ -786,21 +811,14 @@ void EarnStatistics::requestHistory(
.successLink = d.vtransaction_url()
? qs(*d.vtransaction_url())
: QString(),
};
}, [&](const MTPDbroadcastRevenueTransactionRefund &d) {
return Data::EarnHistoryEntry{
.type = Data::EarnHistoryEntry::Type::Return,
.amount = d.vamount().v,
.date = base::unixtime::parse(d.vdate().v),
// .provider = qs(d.vprovider()),
};
}));
});
}
}
const auto nextToken = token + tlTransactions.size();
done(Data::EarnHistorySlice{
.list = std::move(list),
.total = result.data().vcount().v,
.allLoaded = (result.data().vcount().v == nextToken),
.total = int(tlTransactions.size()),
// .total = result.data().vcount().v,
.allLoaded = nextToken.isEmpty(),
.token = Data::EarnHistorySlice::OffsetToken(nextToken),
});
}).fail([=] {

View file

@ -1841,9 +1841,8 @@ void Controller::fillBotCurrencyButton() {
auto &lifetime = _controls.buttonsLayout->lifetime();
const auto state = lifetime.make_state<State>();
const auto format = [=](uint64 balance) {
return Info::ChannelEarn::MajorPart(balance)
+ Info::ChannelEarn::MinorPart(balance);
const auto format = [=](const CreditsAmount &balance) {
return Lang::FormatCreditsAmountDecimal(balance);
};
const auto was = _peer->session().credits().balanceCurrency(
_peer->id);

View file

@ -85,9 +85,11 @@ CreditsAmount Credits::balance(PeerId peerId) const {
return (it != _cachedPeerBalances.end()) ? it->second : CreditsAmount();
}
uint64 Credits::balanceCurrency(PeerId peerId) const {
CreditsAmount Credits::balanceCurrency(PeerId peerId) const {
const auto it = _cachedPeerCurrencyBalances.find(peerId);
return (it != _cachedPeerCurrencyBalances.end()) ? it->second : 0;
return (it != _cachedPeerCurrencyBalances.end())
? it->second
: CreditsAmount();
}
rpl::producer<CreditsAmount> Credits::balanceValue() const {
@ -204,7 +206,7 @@ void Credits::apply(PeerId peerId, CreditsAmount balance) {
_refreshedByPeerId.fire_copy(peerId);
}
void Credits::applyCurrency(PeerId peerId, uint64 balance) {
void Credits::applyCurrency(PeerId peerId, CreditsAmount balance) {
_cachedPeerCurrencyBalances[peerId] = balance;
_refreshedByPeerId.fire_copy(peerId);
}
@ -227,10 +229,17 @@ CreditsAmount CreditsAmountFromTL(const MTPStarsAmount &amount) {
data.vnanos().v,
CreditsType::Stars);
}, [&](const MTPDstarsTonAmount &data) {
return CreditsAmount(
data.vamount().v / uint64(1'000'000'000),
data.vamount().v % uint64(1'000'000'000),
const auto isNegative = (static_cast<int64_t>(data.vamount().v) < 0);
const auto absValue = isNegative
? uint64(~data.vamount().v + 1)
: data.vamount().v;
const auto result = CreditsAmount(
int64(absValue / 1'000'000'000),
absValue % 1'000'000'000,
CreditsType::Ton);
return isNegative
? CreditsAmount(0, CreditsType::Ton) - result
: result;
});
}

View file

@ -40,8 +40,8 @@ public:
[[nodiscard]] bool statsEnabled() const;
void applyCurrency(PeerId peerId, uint64 balance);
[[nodiscard]] uint64 balanceCurrency(PeerId peerId) const;
void applyCurrency(PeerId peerId, CreditsAmount balance);
[[nodiscard]] CreditsAmount balanceCurrency(PeerId peerId) const;
void lock(CreditsAmount count);
void unlock(CreditsAmount count);
@ -58,7 +58,7 @@ private:
std::unique_ptr<rpl::lifetime> _loader;
base::flat_map<PeerId, CreditsAmount> _cachedPeerBalances;
base::flat_map<PeerId, uint64> _cachedPeerCurrencyBalances;
base::flat_map<PeerId, CreditsAmount> _cachedPeerCurrencyBalances;
CreditsAmount _balance;
CreditsAmount _locked;

View file

@ -1468,14 +1468,14 @@ void ApplyChannelUpdate(
const auto currencyLoadLifetime = std::make_shared<rpl::lifetime>();
const auto currencyLoad
= currencyLoadLifetime->make_state<Api::EarnStatistics>(channel);
const auto apply = [=](Data::EarnInt balance) {
const auto apply = [=](const CreditsAmount &balance) {
if (const auto strong = weak.get()) {
strong->credits().applyCurrency(id, balance);
}
currencyLoadLifetime->destroy();
};
currencyLoad->request() | rpl::start_with_error_done(
[=](const QString &error) { apply(0); },
[=](const QString &error) { apply({}); },
[=] { apply(currencyLoad->data().currentBalance); },
*currencyLoadLifetime);
base::timer_once(kTimeout) | rpl::start_with_next([=] {

View file

@ -33,7 +33,7 @@ struct EarnHistoryEntry final {
Type type;
Status status;
EarnInt amount = 0;
CreditsAmount amount;
QDateTime date;
QDateTime dateTo;
@ -45,7 +45,7 @@ struct EarnHistoryEntry final {
};
struct EarnHistorySlice final {
using OffsetToken = int;
using OffsetToken = QString;
std::vector<EarnHistoryEntry> list;
int total = 0;
bool allLoaded = false;
@ -58,9 +58,9 @@ struct EarnStatistics final {
}
Data::StatisticalGraph topHoursGraph;
Data::StatisticalGraph revenueGraph;
EarnInt currentBalance = 0;
EarnInt availableBalance = 0;
EarnInt overallRevenue = 0;
CreditsAmount currentBalance;
CreditsAmount availableBalance;
CreditsAmount overallRevenue;
float64 usdRate = 0.;
bool switchedOff = false;

View file

@ -790,14 +790,14 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
= std::make_shared<rpl::lifetime>();
const auto currencyLoad
= currencyLoadLifetime->make_state<Api::EarnStatistics>(user);
const auto apply = [=](Data::EarnInt balance) {
const auto apply = [=](const CreditsAmount &balance) {
if (const auto strong = weak.get()) {
strong->credits().applyCurrency(id, balance);
}
currencyLoadLifetime->destroy();
};
currencyLoad->request() | rpl::start_with_error_done(
[=](const QString &error) { apply(0); },
[=](const QString &error) { apply({}); },
[=] { apply(currencyLoad->data().currentBalance); },
*currencyLoadLifetime);
base::timer_once(kTimeout) | rpl::start_with_next([=] {

View file

@ -22,6 +22,10 @@ QString MajorPart(EarnInt value) {
return (diff <= 0) ? QString(kZero) : string.mid(0, diff);
}
QString MajorPart(CreditsAmount value) {
return QString::number(int64(value.value()));
}
QString MinorPart(EarnInt value) {
if (!value) {
return QString(kDot) + kZero + kZero;
@ -46,6 +50,10 @@ QString MinorPart(EarnInt value) {
return result.chopped(zeroCount);
}
QString MinorPart(CreditsAmount value) {
return QString::number(value.value(), 'f', 2).right(3);
}
QString ToUsd(
Data::EarnInt value,
float64 rate,

View file

@ -12,7 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Info::ChannelEarn {
[[nodiscard]] QString MajorPart(Data::EarnInt value);
[[nodiscard]] QString MajorPart(CreditsAmount value);
[[nodiscard]] QString MinorPart(Data::EarnInt value);
[[nodiscard]] QString MinorPart(CreditsAmount value);
[[nodiscard]] QString ToUsd(
Data::EarnInt value,
float64 rate,

View file

@ -249,7 +249,6 @@ void InnerWidget::load() {
) | rpl::start_with_next([=, peerId = _peer->id](
const MTPUpdates &updates) {
using TLCreditsUpdate = MTPDupdateStarsRevenueStatus;
using TLCurrencyUpdate = MTPDupdateBroadcastRevenueTransactions;
using TLNotificationUpdate = MTPDupdateServiceNotification;
Api::PerformForUpdate<TLCreditsUpdate>(updates, [&](
const TLCreditsUpdate &d) {
@ -257,29 +256,39 @@ void InnerWidget::load() {
return;
}
const auto &data = d.vstatus().data();
auto &e = _state.creditsEarn;
e.currentBalance = CreditsAmountFromTL(data.vcurrent_balance());
e.availableBalance = CreditsAmountFromTL(data.vavailable_balance());
e.overallRevenue = CreditsAmountFromTL(data.voverall_revenue());
e.isWithdrawalEnabled = data.is_withdrawal_enabled();
e.nextWithdrawalAt = data.vnext_withdrawal_at()
? base::unixtime::parse(
data.vnext_withdrawal_at()->v)
: QDateTime();
state->apiCreditsHistory.request({}, [=](
const Data::CreditsStatusSlice &data) {
_state.creditsStatusSlice = data;
_stateUpdated.fire({});
const auto isCredits = data.vcurrent_balance().match([](
const MTPDstarsAmount &) {
return true;
}, [](const MTPDstarsTonAmount &) {
return false;
});
});
Api::PerformForUpdate<TLCurrencyUpdate>(updates, [&](
const TLCurrencyUpdate &d) {
if (peerId == peerFromMTP(d.vpeer())) {
const auto &data = d.vbalances().data();
auto &e = _state.currencyEarn;
e.currentBalance = data.vcurrent_balance().v;
e.availableBalance = data.vavailable_balance().v;
e.overallRevenue = data.voverall_revenue().v;
if (isCredits) {
auto &credits = _state.creditsEarn;
credits.currentBalance = CreditsAmountFromTL(
data.vcurrent_balance());
credits.availableBalance = CreditsAmountFromTL(
data.vavailable_balance());
credits.overallRevenue = CreditsAmountFromTL(
data.voverall_revenue());
credits.isWithdrawalEnabled
= data.is_withdrawal_enabled();
credits.nextWithdrawalAt = data.vnext_withdrawal_at()
? base::unixtime::parse(
data.vnext_withdrawal_at()->v)
: QDateTime();
state->apiCreditsHistory.request({}, [=](
const Data::CreditsStatusSlice &data) {
_state.creditsStatusSlice = data;
_stateUpdated.fire({});
});
} else {
auto &currency = _state.currencyEarn;
currency.currentBalance = CreditsAmountFromTL(
data.vcurrent_balance());
currency.availableBalance = CreditsAmountFromTL(
data.vavailable_balance());
currency.overallRevenue = CreditsAmountFromTL(
data.voverall_revenue());
_stateUpdated.fire({});
}
});
@ -405,7 +414,7 @@ void InnerWidget::fill() {
const auto withdrawalEnabled = WithdrawalEnabled(session);
const auto addEmojiToMajor = [=](
not_null<Ui::FlatLabel*> label,
rpl::producer<EarnInt> value,
rpl::producer<CreditsAmount> value,
std::optional<bool> isIn,
std::optional<QMargins> margins) {
const auto &st = label->st();
@ -425,9 +434,11 @@ void InnerWidget::fill() {
: TextWithEntities::Simple((*isIn) ? QChar('+') : kMinus);
std::move(
value
) | rpl::start_with_next([=](EarnInt v) {
) | rpl::start_with_next([=](CreditsAmount v) {
label->setMarkedText(
base::duplicate(prepended).append(icon).append(MajorPart(v)),
base::duplicate(prepended)
.append(icon)
.append(QString::number(v.whole())),
Core::TextContext({ .session = session }));
}, label->lifetime());
};
@ -706,7 +717,7 @@ void InnerWidget::fill() {
Ui::AddSkip(container, st::channelEarnOverviewTitleSkip);
const auto addOverview = [&](
rpl::producer<EarnInt> currencyValue,
rpl::producer<CreditsAmount> currencyValue,
rpl::producer<CreditsAmount> creditsValue,
const tr::phrase<> &text,
bool showCurrency,
@ -724,15 +735,17 @@ void InnerWidget::fill() {
{});
const auto minorLabel = Ui::CreateChild<Ui::FlatLabel>(
line,
rpl::duplicate(currencyValue) | rpl::map([=](EarnInt v) {
return MinorPart(v).left(kMinorLength);
rpl::duplicate(
currencyValue
) | rpl::map([](CreditsAmount v) {
return MinorPart(v);
}),
st::channelEarnOverviewMinorLabel);
const auto secondMinorLabel = Ui::CreateChild<Ui::FlatLabel>(
line,
std::move(
currencyValue
) | rpl::map([=](EarnInt value) {
) | rpl::map([=](CreditsAmount value) {
return value
? ToUsd(value, multiplier, kMinorLength)
: QString();

View file

@ -849,19 +849,20 @@ template <typename Text, typename ToggleOn, typename Callback>
st));
}
rpl::producer<uint64> AddCurrencyAction(
rpl::producer<CreditsAmount> AddCurrencyAction(
not_null<UserData*> user,
not_null<Ui::VerticalLayout*> wrap,
not_null<Controller*> controller) {
struct State final {
rpl::variable<uint64> balance;
rpl::variable<CreditsAmount> balance;
};
const auto state = wrap->lifetime().make_state<State>();
const auto parentController = controller->parentController();
const auto wrapButton = AddActionButton(
wrap,
tr::lng_manage_peer_bot_balance_currency(),
state->balance.value() | rpl::map(rpl::mappers::_1 > 0),
state->balance.value(
) | rpl::map(rpl::mappers::_1 > CreditsAmount(0)),
[=] { parentController->showSection(Info::ChannelEarn::Make(user)); },
nullptr);
{
@ -889,14 +890,14 @@ rpl::producer<uint64> AddCurrencyAction(
= std::make_shared<rpl::lifetime>();
const auto currencyLoad
= currencyLoadLifetime->make_state<Api::EarnStatistics>(user);
const auto done = [=](Data::EarnInt balance) {
const auto done = [=](CreditsAmount balance) {
if ([[maybe_unused]] const auto strong = weak.data()) {
state->balance = balance;
currencyLoadLifetime->destroy();
}
};
currencyLoad->request() | rpl::start_with_error_done(
[=](const QString &error) { done(0); },
[=](const QString &error) { done({}); },
[=] { done(currencyLoad->data().currentBalance); },
*currencyLoadLifetime);
}
@ -918,7 +919,7 @@ rpl::producer<uint64> AddCurrencyAction(
) | rpl::start_with_next([=, &st](
int width,
const QString &button,
Data::EarnInt balance) {
CreditsAmount balance) {
const auto available = width
- rect::m::sum::h(st.padding)
- st.style.font->width(button)
@ -2404,7 +2405,7 @@ void ActionsFiller::addBalanceActions(not_null<UserData*> user) {
rpl::combine(
std::move(currencyBalance),
std::move(creditsBalance)
) | rpl::map((rpl::mappers::_1 > 0)
) | rpl::map((rpl::mappers::_1 > CreditsAmount(0))
|| (rpl::mappers::_2 > CreditsAmount(0))));
}
@ -2915,18 +2916,20 @@ object_ptr<Ui::RpWidget> SetupChannelMembersAndManage(
auto creditsValue = rpl::single(
rpl::empty_value()
) | rpl::then(rpl::duplicate(refreshed)) | rpl::map([=] {
return channel->session().credits().balance(channel->id).whole();
return channel->session().credits().balance(channel->id);
});
auto currencyValue = rpl::single(
rpl::empty_value()
) | rpl::then(rpl::duplicate(refreshed)) | rpl::map([=] {
return channel->session().credits().balanceCurrency(channel->id);
});
const auto emptyAmount = CreditsAmount(0);
balanceWrap->toggleOn(
rpl::combine(
rpl::duplicate(creditsValue),
rpl::duplicate(currencyValue)
) | rpl::map(rpl::mappers::_1 > 0 || rpl::mappers::_2 > 0),
) | rpl::map(rpl::mappers::_1 > emptyAmount
|| rpl::mappers::_2 > emptyAmount),
anim::type::normal);
balanceWrap->finishAnimating();
@ -2961,13 +2964,14 @@ object_ptr<Ui::RpWidget> SetupChannelMembersAndManage(
rpl::combine(
std::move(creditsValue),
std::move(currencyValue)
) | rpl::map([](uint64 credits, uint64 currency) {
auto creditsText = (credits > 0)
) | rpl::map([](CreditsAmount credits, CreditsAmount currency) {
auto creditsText = (credits > CreditsAmount(0))
? Ui::Text::SingleCustomEmoji(Ui::kCreditsCurrency)
.append(QChar(' '))
.append(QString::number(credits))
.append(Info::ChannelEarn::MajorPart(credits))
.append(Info::ChannelEarn::MinorPart(credits))
: TextWithEntities();
auto currencyText = (currency > 0)
auto currencyText = (currency > CreditsAmount(0))
? Ui::Text::SingleCustomEmoji("_")
.append(QChar(' '))
.append(Info::ChannelEarn::MajorPart(currency))

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_statistics.h"
#include "boxes/peer_list_controllers.h"
#include "boxes/peer_list_widgets.h"
#include "info/channel_statistics/earn/earn_format.h"
#include "chat_helpers/stickers_gift_box_pack.h"
#include "core/ui_integration.h" // TextContext
#include "data/data_channel.h"