diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f27bc5471..e269cc572 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1675,9 +1675,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_star_ref_list_my_leave" = "Leave"; "lng_star_ref_list_subtitle" = "Programs"; "lng_star_ref_sort_text" = "Sort by {sort}"; +"lng_star_ref_sort_profitability" = "Profitability"; "lng_star_ref_sort_date" = "Date"; "lng_star_ref_sort_revenue" = "Revenue"; -"lng_star_ref_sort_commission" = "Commission"; "lng_star_ref_reliable_title" = "Reliable"; "lng_star_ref_reliable_about" = "Receive guaranteed commissions for spending by users you refer."; "lng_star_ref_transparent_title" = "Transparent"; diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp index 0cb99104c..5aab0da6e 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.cpp @@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/vertical_list.h" #include "styles/style_info.h" #include "styles/style_layers.h" +#include "styles/style_media_player.h" #include "styles/style_menu_icons.h" #include "styles/style_premium.h" #include "styles/style_settings.h" @@ -60,6 +61,12 @@ enum class JoinType { Existing, }; +enum class SuggestedSort { + Profitability, + Revenue, + Date +}; + class ListController final : public PeerListController , public base::has_weak_ptr { @@ -83,6 +90,8 @@ public: [[nodiscard]] rpl::producer revoked() const; [[nodiscard]] rpl::producer<> addForBotRequests() const; + void setSort(SuggestedSort sort); + void process(ConnectedBot row); private: @@ -111,6 +120,7 @@ private: QString _offsetThing; bool _allLoaded = false; bool _recipientsRequested = false; + SuggestedSort _sort = SuggestedSort::Profitability; rpl::variable _rowCount = 0; @@ -214,7 +224,11 @@ void ListController::loadMoreRows() { using Flag = MTPpayments_GetSuggestedStarRefBots::Flag; _requestId = session().api().request( MTPpayments_GetSuggestedStarRefBots( - MTP_flags(Flag::f_order_by_revenue), + MTP_flags((_sort == SuggestedSort::Revenue) + ? Flag::f_order_by_revenue + : (_sort == SuggestedSort::Date) + ? Flag::f_order_by_date + : Flag()), _peer->input, MTP_string(_offsetThing), MTP_int(kPerPage)) @@ -222,6 +236,13 @@ void ListController::loadMoreRows() { setDescriptionText(QString()); setupAddForBot(); + if (_offsetThing.isEmpty()) { + while (delegate()->peerListFullRowsCount() > 0) { + delegate()->peerListRemoveRow( + delegate()->peerListRowAt(0)); + } + } + const auto &data = result.data(); if (data.vnext_offset()) { _offsetThing = qs(*data.vnext_offset()); @@ -306,6 +327,19 @@ rpl::producer<> ListController::addForBotRequests() const { return _addForBot.events(); } +void ListController::setSort(SuggestedSort sort) { + if (_sort == sort) { + return; + } + _sort = sort; + if (const auto requestId = base::take(_requestId)) { + session().api().request(requestId).cancel(); + } + _allLoaded = false; + _offsetThing = QString(); + loadMoreRows(); +} + void ListController::process(ConnectedBot row) { if (_type != JoinType::Joined) { _states[row.bot] = { .program = row.state.program }; @@ -485,6 +519,7 @@ private: void setupInfo(); not_null setupMy(); not_null setupSuggested(); + void setupSort(not_null label); [[nodiscard]] object_ptr infoRow( rpl::producer title, @@ -493,6 +528,7 @@ private: const not_null _controller; const not_null _container; + rpl::variable _sort = SuggestedSort::Profitability; ListController *_my = nullptr; ListController *_suggested = nullptr; @@ -572,6 +608,49 @@ not_null InnerWidget::setupMy() { return controller; } +void InnerWidget::setupSort(not_null label) { + constexpr auto phrase = [](SuggestedSort sort) { + return (sort == SuggestedSort::Profitability) + ? tr::lng_star_ref_sort_profitability(tr::now) + : (sort == SuggestedSort::Revenue) + ? tr::lng_star_ref_sort_revenue(tr::now) + : tr::lng_star_ref_sort_date(tr::now); + }; + const auto sort = Ui::CreateChild( + label->parentWidget(), + tr::lng_star_ref_sort_text( + lt_sort, + _sort.value() | rpl::map(phrase) | Ui::Text::ToLink(), + Ui::Text::WithEntities), + st::defaultFlatLabel); + rpl::combine( + label->geometryValue(), + widthValue(), + sort->widthValue() + ) | rpl::start_with_next([=](QRect geometry, int outer, int sortWidth) { + const auto skip = st::boxRowPadding.right(); + sort->moveToLeft(outer - sortWidth - skip, geometry.y(), outer); + }, sort->lifetime()); + sort->setClickHandlerFilter([=](const auto &...) { + const auto menu = Ui::CreateChild( + sort, + st::popupMenuWithIcons); + const auto orders = { + SuggestedSort::Profitability, + SuggestedSort::Revenue, + SuggestedSort::Date + }; + for (const auto order : orders) { + const auto chosen = (order == _sort.current()); + menu->addAction(phrase(order), crl::guard(this, [=] { + _sort = order; + }), chosen ? &st::mediaPlayerMenuCheck : nullptr); + } + menu->popup(sort->mapToGlobal(QPoint(0, 0))); + return false; + }); +} + not_null InnerWidget::setupSuggested() { const auto wrap = _container->add( object_ptr>( @@ -580,7 +659,10 @@ not_null InnerWidget::setupSuggested() { const auto inner = wrap->entity(); Ui::AddSkip(inner); - Ui::AddSubsectionTitle(inner, tr::lng_star_ref_list_subtitle()); + const auto subtitle = Ui::AddSubsectionTitle( + inner, + tr::lng_star_ref_list_subtitle()); + setupSort(subtitle); const auto delegate = lifetime().make_state< PeerListContentDelegateSimple @@ -604,6 +686,10 @@ not_null InnerWidget::setupSuggested() { _my->process(row); }, content->lifetime()); + _sort.value() | rpl::start_with_next([=](SuggestedSort sort) { + controller->setSort(sort); + }, content->lifetime()); + return controller; }