diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 78097555e..03fea8b0b 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1704,6 +1704,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_star_ref_link_copied_title" = "Link copied to clipboard"; "lng_star_ref_link_copied_text" = "Share this link and earn {amount} of what people who use it spend in {app}!"; "lng_star_ref_stopped" = "This link was part of an affiliate program that has been terminated by the app owner."; +"lng_star_ref_revoke_title" = "Revoke Link"; +"lng_star_ref_revoke_text" = "Are you sure you want to revoke the link of {bot}?"; +"lng_star_ref_revoked_title" = "Link removed"; +"lng_star_ref_revoked_text" = "It will no longer work."; "lng_manage_discussion_group" = "Discussion"; "lng_manage_discussion_group_add" = "Add a group"; diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp index ac76363e1..b680f72e7 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/generic_box.h" #include "ui/widgets/buttons.h" #include "ui/widgets/labels.h" +#include "ui/wrap/padding_wrap.h" #include "ui/wrap/vertical_layout.h" #include "ui/text/text_utilities.h" #include "ui/painter.h" @@ -398,6 +399,52 @@ object_ptr StarRefLinkBox( }); } +object_ptr ConfirmEndBox(Fn finish) { + return Box([=](not_null box) { + box->setTitle(tr::lng_star_ref_warning_title()); + const auto skip = st::defaultVerticalListSkip; + const auto margins = st::boxRowPadding + QMargins(0, 0, 0, skip); + box->addRow( + object_ptr( + box, + tr::lng_star_ref_warning_if_end(Ui::Text::RichLangValue), + st::boxLabel), + margins); + const auto addPoint = [&](tr::phrase<> text) { + const auto padded = box->addRow( + object_ptr>( + box, + object_ptr( + box, + text(Ui::Text::RichLangValue), + st::boxLabel), + QMargins(st::boxTextFont->height, 0, 0, 0)), + margins); + padded->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(padded); + auto hq = PainterHighQualityEnabler(p); + const auto size = st::boxTextFont->spacew; + const auto top = (st::boxTextFont->height - size) / 2; + p.setBrush(st::windowFg); + p.setPen(Qt::NoPen); + p.drawEllipse(0, top, size, size); + }, padded->lifetime()); + }; + addPoint(tr::lng_star_ref_warning_if_end1); + addPoint(tr::lng_star_ref_warning_if_end2); + addPoint(tr::lng_star_ref_warning_if_end3); + const auto done = [=] { + box->closeBox(); + finish(); + }; + box->addButton( + tr::lng_star_ref_warning_end(), + done, + st::attentionBoxButton); + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + }); +} + std::unique_ptr MakePeerBubbleButton( not_null parent, not_null peer, @@ -471,6 +518,24 @@ std::unique_ptr MakePeerBubbleButton( return result; } + +void FinishProgram( + std::shared_ptr show, + not_null bot, + Fn finished) { + bot->session().api().request(MTPbots_UpdateStarRefProgram( + MTP_flags(0), + bot->inputUser, + MTP_int(0), + MTP_int(0) + )).done([=](const MTPStarRefProgram &result) { + bot->setStarRefProgram(Data::ParseStarRefProgram(&result)); + finished(); + }).fail([=](const MTP::Error &error) { + show->showToast(u"Failed: "_q + error.type()); + }).send(); +} + ConnectedBots Parse( not_null session, const MTPpayments_ConnectedStarRefBots &bots) { diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h index 00e056c09..f051b1042 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.h @@ -16,6 +16,7 @@ class RoundButton; class VerticalLayout; class BoxContent; class RpWidget; +class Show; } // namespace Ui namespace style { @@ -65,12 +66,18 @@ void AddFullWidthButtonFooter( ConnectedBot row, not_null peer, Fn done); +[[nodiscard]] object_ptr ConfirmEndBox(Fn finish); std::unique_ptr MakePeerBubbleButton( not_null parent, not_null peer, Ui::RpWidget *right = nullptr); +void FinishProgram( + std::shared_ptr show, + not_null bot, + Fn removed); + [[nodiscard]] ConnectedBots Parse( not_null session, const MTPpayments_ConnectedStarRefBots &bots); 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 e637afe91..fa7035644 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 @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/premium_top_bar.h" #include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" #include "ui/widgets/menu/menu_add_action_callback.h" #include "ui/widgets/menu/menu_add_action_callback_factory.h" #include "ui/widgets/buttons.h" @@ -295,6 +296,24 @@ void ListController::open(not_null bot, ConnectedBotState state) { } } +void RevokeLink( + not_null controller, + not_null peer, + const QString &link) { + peer->session().api().request(MTPpayments_EditConnectedStarRefBot( + MTP_flags(MTPpayments_EditConnectedStarRefBot::Flag::f_revoked), + peer->input, + MTP_string(link) + )).done([=] { + controller->showToast({ + .title = tr::lng_star_ref_revoked_title(tr::now), + .text = tr::lng_star_ref_revoked_text(tr::now), + }); + }).fail([=](const MTP::Error &error) { + controller->showToast(u"Failed: "_q + error.type()); + }).send(); +} + base::unique_qptr ListController::rowContextMenu( QWidget *parent, not_null row) { @@ -316,15 +335,19 @@ base::unique_qptr ListController::rowContextMenu( _controller->showToast(tr::lng_username_copied(tr::now)); }, &st::menuIconLinks); const auto revoke = [=] { - session().api().request(MTPpayments_EditConnectedStarRefBot( - MTP_flags(MTPpayments_EditConnectedStarRefBot::Flag::f_revoked), - _peer->input, - MTP_string(state.link) - )).done([=] { - _controller->showToast(u"Revoked!"_q); - }).fail([=](const MTP::Error &error) { - _controller->showToast(u"Failed: "_q + error.type()); - }).send(); + const auto link = state.link; + const auto sure = [=](Fn close) { + RevokeLink(_controller, _peer, link); + close(); + }; + _controller->show(Ui::MakeConfirmBox({ + .text = tr::lng_star_ref_revoke_text( + lt_bot, + rpl::single(Ui::Text::Bold(bot->name())), + Ui::Text::RichLangValue), + .confirmed = sure, + .title = tr::lng_star_ref_revoke_title(), + })); }; addAction({ .text = tr::lng_star_ref_list_my_leave(tr::now), diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp index b750273a4..d2b3e6a6a 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_setup_widget.cpp @@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "settings/settings_common.h" #include "ui/effects/premium_top_bar.h" #include "ui/text/text_utilities.h" +#include "ui/toast/toast.h" #include "ui/widgets/buttons.h" #include "ui/widgets/continuous_sliders.h" #include "ui/widgets/labels.h" @@ -619,15 +620,31 @@ void InnerWidget::setupCommission() { Ui::AddSkip(_container); Ui::AddSubsectionTitle(_container, tr::lng_star_ref_commission_title()); - const auto commission = ValueForCommission(_state); + const auto appConfig = &_controller->session().appConfig(); + const auto commissionMin = std::clamp( + appConfig->starrefCommissionMin(), + 1, + 998); + const auto commissionMax = std::clamp( + appConfig->starrefCommissionMax(), + commissionMin + 1, + 999); + const auto commission = std::clamp( + ValueForCommission(_state), + commissionMin, + commissionMax); + + auto valueMin = (commissionMin + 9) / 10; + auto valueMax = commissionMax / 10; auto values = std::vector(); - if (commission > 0 && commission < 10) { + if (commission < valueMin * 10) { values.push_back(commission); } - for (auto i = 1; i != 91; ++i) { + for (auto i = valueMin; i != valueMax + 1; ++i) { values.push_back(i * 10); - if (i * 10 < commission && (i == 90 || (i + 1) * 10 > commission)) { + if (i * 10 < commission + && (i == valueMax || (i + 1) * 10 > commission)) { values.push_back(commission); } } @@ -721,24 +738,21 @@ void InnerWidget::setupEnd() { tr::lng_star_ref_end(), st::settingsAttentionButton)); end->setClickedCallback([=] { - using Flag = MTPbots_UpdateStarRefProgram::Flag; - const auto user = _state.user; const auto weak = Ui::MakeWeak(this); - user->session().api().request(MTPbots_UpdateStarRefProgram( - MTP_flags(0), - user->inputUser, - MTP_int(0), - MTP_int(0) - )).done([=](const MTPStarRefProgram &result) { - user->setStarRefProgram(Data::ParseStarRefProgram(&result)); - if (const auto controller = weak ? _controller.get() : nullptr) { - const auto window = controller->parentController(); - controller->showBackFromStack(); - window->showToast("Removed!"); - } - }).fail(crl::guard(weak, [=](const MTP::Error &error) { - _controller->showToast(u"Failed: "_q + error.type()); - })).send(); + const auto window = _controller->parentController(); + window->show(ConfirmEndBox([=] { + FinishProgram(_controller->uiShow(), _state.user, [=] { + if (const auto strong = weak.data()) { + _controller->showBackFromStack(); + window->showToast({ + .title = tr::lng_star_ref_ended_title(tr::now), + .text = tr::lng_star_ref_ended_text( + tr::now, + Ui::Text::RichLangValue), + }); + } + }); + })); }); Ui::AddSkip(_container); Ui::AddDivider(_container); diff --git a/Telegram/SourceFiles/main/main_app_config.cpp b/Telegram/SourceFiles/main/main_app_config.cpp index 8d9797a32..c26d57126 100644 --- a/Telegram/SourceFiles/main/main_app_config.cpp +++ b/Telegram/SourceFiles/main/main_app_config.cpp @@ -65,6 +65,14 @@ bool AppConfig::starrefJoinAllowed() const { return get(u"starref_connect_allowed"_q, false); } +int AppConfig::starrefCommissionMin() const { + return get(u"starref_min_commission_permille"_q, 1); +} + +int AppConfig::starrefCommissionMax() const { + return get(u"starref_max_commission_permille"_q, 900); +} + void AppConfig::refresh(bool force) { if (_requestId || !_api) { if (force) { diff --git a/Telegram/SourceFiles/main/main_app_config.h b/Telegram/SourceFiles/main/main_app_config.h index 55817f26e..3092aa567 100644 --- a/Telegram/SourceFiles/main/main_app_config.h +++ b/Telegram/SourceFiles/main/main_app_config.h @@ -69,6 +69,8 @@ public: [[nodiscard]] const std::vector &startRefPrefixes(); [[nodiscard]] bool starrefSetupAllowed() const; [[nodiscard]] bool starrefJoinAllowed() const; + [[nodiscard]] int starrefCommissionMin() const; + [[nodiscard]] int starrefCommissionMax() const; void refresh(bool force = false);