From 50d74fcf2599fee74dec5a4f771ba84079e56f44 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 27 Jun 2025 23:45:20 +0300 Subject: [PATCH] Fixed build with layer 206. --- Telegram/SourceFiles/api/api_credits.cpp | 4 +- Telegram/SourceFiles/api/api_earn.cpp | 43 ++++----- Telegram/SourceFiles/api/api_statistics.cpp | 94 +++++++++++-------- .../boxes/peers/edit_peer_info_box.cpp | 5 +- .../SourceFiles/data/components/credits.cpp | 21 +++-- .../SourceFiles/data/components/credits.h | 6 +- Telegram/SourceFiles/data/data_channel.cpp | 4 +- Telegram/SourceFiles/data/data_channel_earn.h | 10 +- Telegram/SourceFiles/data/data_user.cpp | 4 +- .../channel_statistics/earn/earn_format.cpp | 8 ++ .../channel_statistics/earn/earn_format.h | 2 + .../earn/info_channel_earn_list.cpp | 73 ++++++++------ .../info/profile/info_profile_actions.cpp | 30 +++--- .../info_statistics_list_controllers.cpp | 1 + 14 files changed, 180 insertions(+), 125 deletions(-) diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index cda8180343..6c9147e2b8 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -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( diff --git a/Telegram/SourceFiles/api/api_earn.cpp b/Telegram/SourceFiles/api/api_earn.cpp index d0b58b40fc..9df407aad2 100644 --- a/Telegram/SourceFiles/api/api_earn.cpp +++ b/Telegram/SourceFiles/api/api_earn.cpp @@ -56,7 +56,6 @@ void HandleWithdrawalButton( ? ¤cyReceiver->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(); } diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 400ad7fcae..010d55d725 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -695,19 +695,23 @@ rpl::producer 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(); 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::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([=] { diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 16c8cae875..41fba71ea2 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1841,9 +1841,8 @@ void Controller::fillBotCurrencyButton() { auto &lifetime = _controls.buttonsLayout->lifetime(); const auto state = lifetime.make_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); diff --git a/Telegram/SourceFiles/data/components/credits.cpp b/Telegram/SourceFiles/data/components/credits.cpp index bbd27a2ba2..c38c64ac85 100644 --- a/Telegram/SourceFiles/data/components/credits.cpp +++ b/Telegram/SourceFiles/data/components/credits.cpp @@ -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 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(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; }); } diff --git a/Telegram/SourceFiles/data/components/credits.h b/Telegram/SourceFiles/data/components/credits.h index 053b3f02a4..715c88c456 100644 --- a/Telegram/SourceFiles/data/components/credits.h +++ b/Telegram/SourceFiles/data/components/credits.h @@ -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 _loader; base::flat_map _cachedPeerBalances; - base::flat_map _cachedPeerCurrencyBalances; + base::flat_map _cachedPeerCurrencyBalances; CreditsAmount _balance; CreditsAmount _locked; diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 2f02a41d3f..b067d4a5a3 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1468,14 +1468,14 @@ void ApplyChannelUpdate( const auto currencyLoadLifetime = std::make_shared(); const auto currencyLoad = currencyLoadLifetime->make_state(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([=] { diff --git a/Telegram/SourceFiles/data/data_channel_earn.h b/Telegram/SourceFiles/data/data_channel_earn.h index c4db98f28b..cd7e5a75f6 100644 --- a/Telegram/SourceFiles/data/data_channel_earn.h +++ b/Telegram/SourceFiles/data/data_channel_earn.h @@ -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 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; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index c0cfae99b5..5706b1c519 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -790,14 +790,14 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { = std::make_shared(); const auto currencyLoad = currencyLoadLifetime->make_state(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([=] { diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp index 88c7744f73..6554a45c9e 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.cpp @@ -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, diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.h b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.h index 6750d05540..02ac4cee32 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.h +++ b/Telegram/SourceFiles/info/channel_statistics/earn/earn_format.h @@ -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, diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp index bda1ca5495..2a566a84d1 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_channel_earn_list.cpp @@ -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(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(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 ¤cy = _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 label, - rpl::producer value, + rpl::producer value, std::optional isIn, std::optional 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 currencyValue, + rpl::producer currencyValue, rpl::producer creditsValue, const tr::phrase<> &text, bool showCurrency, @@ -724,15 +735,17 @@ void InnerWidget::fill() { {}); const auto minorLabel = Ui::CreateChild( 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( line, std::move( currencyValue - ) | rpl::map([=](EarnInt value) { + ) | rpl::map([=](CreditsAmount value) { return value ? ToUsd(value, multiplier, kMinorLength) : QString(); diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index ba4ac5c49e..a4ec485ee5 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -849,19 +849,20 @@ template st)); } -rpl::producer AddCurrencyAction( +rpl::producer AddCurrencyAction( not_null user, not_null wrap, not_null controller) { struct State final { - rpl::variable balance; + rpl::variable balance; }; const auto state = wrap->lifetime().make_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 AddCurrencyAction( = std::make_shared(); const auto currencyLoad = currencyLoadLifetime->make_state(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 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 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 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 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)) diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index 59a66d8732..231d0010e1 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -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"