diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index 453d9536f..84c3e646f 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -8,15 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_credits.h" #include "apiwrap.h" +#include "api/api_updates.h" #include "base/unixtime.h" #include "data/data_peer.h" #include "data/data_photo.h" #include "data/data_session.h" +#include "data/data_user.h" #include "main/main_app_config.h" #include "main/main_session.h" -#if _DEBUG -#include "base/random.h" -#endif namespace Api { namespace { @@ -199,4 +198,24 @@ rpl::producer> PremiumPeerBot( }; } +void CreditsRefund( + not_null peer, + const QString &entryId, + Fn done, + Fn fail) { + const auto user = peer->asUser(); + if (!user) { + return; + } + peer->session().api().request(MTPpayments_RefundStarsCharge( + user->inputUser, + MTP_string(entryId) + )).done([=](const MTPUpdates &result) { + peer->session().api().updates().applyUpdates(result); + done(); + }).fail([=](const MTP::Error &error) { + fail(error.type()); + }).send(); +} + } // namespace Api diff --git a/Telegram/SourceFiles/api/api_credits.h b/Telegram/SourceFiles/api/api_credits.h index 265e7b387..bd064a65b 100644 --- a/Telegram/SourceFiles/api/api_credits.h +++ b/Telegram/SourceFiles/api/api_credits.h @@ -68,6 +68,12 @@ private: }; +void CreditsRefund( + not_null peer, + const QString &entryId, + Fn done, + Fn fail); + [[nodiscard]] rpl::producer> PremiumPeerBot( not_null session); diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index b608b7218..0028e0fab 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/channel_statistics/boosts/giveaway/boost_badge.h" #include "lang/lang_keys.h" #include "main/main_session.h" +#include "main/session/session_show.h" #include "ui/effects/credits_graphics.h" #include "ui/effects/outline_segments.h" // Ui::UnreadStoryOutlineGradient. #include "ui/effects/toggle_arrow.h" @@ -841,6 +842,10 @@ public: void rowClicked(not_null row) override; void loadMoreRows() override; + base::unique_qptr rowContextMenu( + QWidget *parent, + not_null row) override; + [[nodiscard]] bool skipRequest() const; void requestNext(); @@ -930,6 +935,29 @@ void CreditsController::rowClicked(not_null row) { } } +base::unique_qptr CreditsController::rowContextMenu( + QWidget *parent, + not_null row) { + const auto entry = static_cast(row.get())->entry(); + if (!entry.bareId) { + return nullptr; + } + auto menu = base::make_unique_q( + parent, + st::defaultPopupMenu); + const auto peer = row->peer(); + const auto callback = crl::guard(parent, [=, id = entry.id] { + const auto show = delegate()->peerListUiShow(); + Api::CreditsRefund( + peer, + id, + [=] { show->showToast(tr::lng_report_spam_done(tr::now)); }, + [=](const QString &error) { show->showToast(error); }); + }); + menu->addAction(tr::lng_channel_earn_history_return(tr::now), callback); + return menu; +} + rpl::producer CreditsController::allLoadedValue() const { return _allLoaded.value(); } @@ -1086,6 +1114,7 @@ void AddBoostsList( } void AddCreditsHistoryList( + std::shared_ptr show, const Data::CreditsStatusSlice &firstSlice, not_null container, Fn callback, @@ -1094,13 +1123,18 @@ void AddCreditsHistoryList( bool in, bool out) { struct State final { - State(CreditsDescriptor d) : controller(std::move(d)) { + State( + CreditsDescriptor d, + std::shared_ptr show) + : delegate(std::move(show)) + , controller(std::move(d)) { } - PeerListContentDelegateSimple delegate; + PeerListContentDelegateShow delegate; CreditsController controller; }; - auto d = CreditsDescriptor{ firstSlice, callback, bot, icon, in, out }; - const auto state = container->lifetime().make_state(std::move(d)); + const auto state = container->lifetime().make_state( + CreditsDescriptor{ firstSlice, callback, bot, icon, in, out }, + show); state->delegate.setContent(container->add( object_ptr(container, &state->controller))); diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h index 09883090d..2d381cb7c 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.h @@ -23,6 +23,10 @@ struct RecentPostId; struct SupergroupStatistics; } // namespace Data +namespace Main { +class SessionShow; +} // namespace Main + namespace Info::Statistics { void AddPublicForwards( @@ -47,6 +51,7 @@ void AddBoostsList( rpl::producer title); void AddCreditsHistoryList( + std::shared_ptr show, const Data::CreditsStatusSlice &firstSlice, not_null container, Fn entryClickedCallback, diff --git a/Telegram/SourceFiles/settings/settings_credits.cpp b/Telegram/SourceFiles/settings/settings_credits.cpp index 48a3eb9ba..4cfeff843 100644 --- a/Telegram/SourceFiles/settings/settings_credits.cpp +++ b/Telegram/SourceFiles/settings/settings_credits.cpp @@ -239,6 +239,7 @@ void Credits::setupHistory(not_null container) { }; Info::Statistics::AddCreditsHistoryList( + controller->uiShow(), fullSlice, fullWrap->entity(), entryClicked, @@ -247,6 +248,7 @@ void Credits::setupHistory(not_null container) { true, true); Info::Statistics::AddCreditsHistoryList( + controller->uiShow(), inSlice, inWrap->entity(), entryClicked, @@ -255,6 +257,7 @@ void Credits::setupHistory(not_null container) { true, false); Info::Statistics::AddCreditsHistoryList( + controller->uiShow(), outSlice, outWrap->entity(), std::move(entryClicked),