From 496247c1d8e0980a766a7507994df9998b5b3dfc Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Thu, 28 Mar 2024 03:55:35 +0300 Subject: [PATCH] Added ability to load chunked history transactions in earn info section. --- Telegram/Resources/langs/lang.strings | 2 + Telegram/SourceFiles/api/api_statistics.cpp | 12 +-- Telegram/SourceFiles/api/api_statistics.h | 6 +- .../earn/info_earn_inner_widget.cpp | 99 ++++++++++++++++--- 4 files changed, 95 insertions(+), 24 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 47f5d390b..32888bec3 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -4995,6 +4995,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_channel_earn_history_return" = "Refund"; "lng_channel_earn_history_return_about" = "Refunded back"; "lng_channel_earn_history_pending" = "Pending"; +"lng_channel_earn_history_show_more#one" = "Show {count} More Transaction"; +"lng_channel_earn_history_show_more#other" = "Show {count} More Transactions"; "lng_channel_earn_off" = "Switch Off Ads"; "lng_channel_earn_off_about" = "You will not be eligible for any rewards if you switch off ads."; "lng_channel_earn_cpm_min" = "No Ads"; diff --git a/Telegram/SourceFiles/api/api_statistics.cpp b/Telegram/SourceFiles/api/api_statistics.cpp index 2779c7900..9bc31c483 100644 --- a/Telegram/SourceFiles/api/api_statistics.cpp +++ b/Telegram/SourceFiles/api/api_statistics.cpp @@ -771,7 +771,7 @@ rpl::producer EarnStatistics::request() { .usdRate = data.vusd_rate().v, }; - requestBoosts({}, [=](Data::EarnHistorySlice &&slice) { + requestHistory({}, [=](Data::EarnHistorySlice &&slice) { _data.firstHistorySlice = std::move(slice); api().request( @@ -795,7 +795,7 @@ rpl::producer EarnStatistics::request() { }; } -void EarnStatistics::requestBoosts( +void EarnStatistics::requestHistory( const Data::EarnHistorySlice::OffsetToken &token, Fn done) { if (_requestId) { @@ -831,11 +831,9 @@ void EarnStatistics::requestBoosts( : d.is_failed() ? Data::EarnHistoryEntry::Status::Failed : Data::EarnHistoryEntry::Status::Success, - .amount = d.is_failed() - ? (std::numeric_limits::max() - - d.vamount().v - + 1) - : d.vamount().v, + .amount = (std::numeric_limits::max() + - d.vamount().v + + 1), .date = base::unixtime::parse(d.vdate().v), // .provider = qs(d.vprovider()), .successDate = d.vtransaction_date() diff --git a/Telegram/SourceFiles/api/api_statistics.h b/Telegram/SourceFiles/api/api_statistics.h index cf48d3cf2..f18cba71d 100644 --- a/Telegram/SourceFiles/api/api_statistics.h +++ b/Telegram/SourceFiles/api/api_statistics.h @@ -113,14 +113,14 @@ public: explicit EarnStatistics(not_null channel); [[nodiscard]] rpl::producer request(); - void requestBoosts( + void requestHistory( const Data::EarnHistorySlice::OffsetToken &token, Fn done); [[nodiscard]] Data::EarnStatistics data() const; - static constexpr auto kFirstSlice = int(10); - static constexpr auto kLimit = int(40); + static constexpr auto kFirstSlice = int(5); + static constexpr auto kLimit = int(10); private: Data::EarnStatistics _data; diff --git a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp index 5a961819a..b21b13a6d 100644 --- a/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/earn/info_earn_inner_widget.cpp @@ -31,14 +31,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/controls/userpic_button.h" #include "ui/effects/animation_value_f.h" #include "ui/effects/fade_animation.h" +#include "ui/effects/toggle_arrow.h" #include "ui/layers/generic_box.h" #include "ui/painter.h" #include "ui/rect.h" #include "ui/text/text_utilities.h" #include "ui/vertical_list.h" #include "ui/widgets/continuous_sliders.h" -#include "main/main_account.h" -#include "main/main_app_config.h" #include "ui/widgets/fields/input_field.h" #include "ui/wrap/slide_wrap.h" #include "styles/style_boxes.h" @@ -48,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_layers.h" #include "styles/style_settings.h" #include "styles/style_statistics.h" +#include "styles/style_window.h" // mainMenuToggleFourStrokes. #include @@ -105,6 +105,27 @@ constexpr auto kDot = QChar('.'); return session->appConfig().get(key, false); } +void AddArrow(not_null parent) { + const auto arrow = Ui::CreateChild(parent.get()); + arrow->paintRequest( + ) | rpl::start_with_next([=](const QRect &r) { + auto p = QPainter(arrow); + + const auto path = Ui::ToggleUpDownArrowPath( + st::statisticsShowMoreButtonArrowSize, + st::statisticsShowMoreButtonArrowSize, + st::statisticsShowMoreButtonArrowSize, + st::mainMenuToggleFourStrokes, + 0.); + + auto hq = PainterHighQualityEnabler(p); + p.fillPath(path, st::lightButtonFg); + }, arrow->lifetime()); + arrow->resize(Size(st::statisticsShowMoreButtonArrowSize * 2)); + arrow->move(st::statisticsShowMoreButtonArrowPosition); + arrow->show(); +} + void AddHeader( not_null content, tr::phrase<> text) { @@ -625,13 +646,15 @@ void InnerWidget::fill() { AddHeader(container, tr::lng_channel_earn_history_title); Ui::AddSkip(container); - const auto addHistoryEntry = [&]( + const auto historyList = container->add( + object_ptr(container)); + const auto addHistoryEntry = [=]( const Data::EarnHistoryEntry &entry, const tr::phrase<> &text) { - const auto wrap = container->add( + const auto wrap = historyList->add( object_ptr>( - container, - object_ptr(container), + historyList, + object_ptr(historyList), QMargins())); const auto inner = wrap->entity(); inner->setAttribute(Qt::WA_TransparentForMouseEvents); @@ -847,14 +870,62 @@ void InnerWidget::fill() { button->lower(); }, wrap->lifetime()); }; - for (const auto &entry : data.firstHistorySlice.list) { - addHistoryEntry( - entry, - (entry.type == Data::EarnHistoryEntry::Type::In) - ? tr::lng_channel_earn_history_in - : (entry.type == Data::EarnHistoryEntry::Type::Return) - ? tr::lng_channel_earn_history_return - : tr::lng_channel_earn_history_out); + const auto handleSlice = [=](const Data::EarnHistorySlice &slice) { + for (const auto &entry : slice.list) { + addHistoryEntry( + entry, + (entry.type == Data::EarnHistoryEntry::Type::In) + ? tr::lng_channel_earn_history_in + : (entry.type == Data::EarnHistoryEntry::Type::Return) + ? tr::lng_channel_earn_history_return + : tr::lng_channel_earn_history_out); + } + historyList->resizeToWidth(container->width()); + }; + handleSlice(data.firstHistorySlice); + if (!data.firstHistorySlice.allLoaded) { + struct ShowMoreState final { + ShowMoreState(not_null channel) + : api(channel) { + } + Api::EarnStatistics api; + bool loading = false; + Data::EarnHistorySlice::OffsetToken token; + rpl::variable showed = 0; + }; + const auto state = lifetime().make_state(channel); + state->token = data.firstHistorySlice.token; + state->showed = data.firstHistorySlice.list.size(); + const auto max = data.firstHistorySlice.total; + const auto wrap = container->add( + object_ptr>( + container, + object_ptr( + container, + tr::lng_channel_earn_history_show_more( + lt_count, + state->showed.value( + ) | rpl::map( + max - rpl::mappers::_1 + ) | tr::to_count()), + st::statisticsShowMoreButton))); + const auto button = wrap->entity(); + AddArrow(button); + + wrap->toggle(true, anim::type::instant); + const auto handleReceived = [=](Data::EarnHistorySlice slice) { + state->loading = false; + handleSlice(slice); + wrap->toggle(!slice.allLoaded, anim::type::instant); + state->token = slice.token; + state->showed = state->showed.current() + slice.list.size(); + }; + button->setClickedCallback([=] { + if (!state->loading) { + state->loading = true; + state->api.requestHistory(state->token, handleReceived); + } + }); } } Ui::AddSkip(container);