diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 08a8edd13..b1dff0aa6 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1647,6 +1647,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_star_ref_update" = "Update Affiliate Program"; "lng_star_ref_update_info" = "By updating an affiliate program, you agree to the {terms} of Affiliate Programs."; "lng_star_ref_button_link" = "terms and conditions"; +"lng_star_ref_tos_url" = "https://telegram.org/tos/mini-apps"; "lng_star_ref_warning_title" = "Warning"; "lng_star_ref_warning_text" = "Once you start the affiliate program, you won't be able to decrease its commission or duration. You can only increase these parameters or end the program, which will disable all previously distributed referral links."; "lng_star_ref_warning_change" = "This change is irreversible. You won't be able to reduce commission or duration. You can only increase these parameters or end the program, which will disable all previously shared referral links."; diff --git a/Telegram/SourceFiles/boxes/peers/replace_boost_box.cpp b/Telegram/SourceFiles/boxes/peers/replace_boost_box.cpp index a3bc8b69b..634e4a248 100644 --- a/Telegram/SourceFiles/boxes/peers/replace_boost_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/replace_boost_box.cpp @@ -202,10 +202,11 @@ void Controller::prepare() { const auto session = &_to->session(); auto above = object_ptr((QWidget*)nullptr); above->add( - CreateBoostReplaceUserpics( + CreateUserpicsTransfer( above.data(), _selectedPeers.value(), - _to), + _to, + UserpicsTransferType::BoostReplace), st::boxRowPadding + st::boostReplaceUserpicsPadding); above->add( object_ptr( @@ -366,10 +367,11 @@ object_ptr ReassignBoostSingleBox( }); box->verticalLayout()->insert( 0, - CreateBoostReplaceUserpics( + CreateUserpicsTransfer( box, rpl::single(std::vector{ peer }), - to), + to, + UserpicsTransferType::BoostReplace), st::boxRowPadding + st::boostReplaceUserpicsPadding); }); @@ -536,10 +538,11 @@ object_ptr ReassignBoostsBox( return Box(std::move(controller), std::move(initBox)); } -object_ptr CreateBoostReplaceUserpics( +object_ptr CreateUserpicsTransfer( not_null parent, rpl::producer>> from, - not_null to) { + not_null to, + UserpicsTransferType type) { struct State { std::vector> from; std::vector> buttons; @@ -640,13 +643,18 @@ object_ptr CreateBoostReplaceUserpics( button->render(&q, position, QRegion(), QWidget::DrawChildren); } state->painting = false; + const auto boosting = (type == UserpicsTransferType::BoostReplace); const auto last = state->buttons.back().get(); + const auto back = boosting ? last : right; const auto add = st::boostReplaceIconAdd; - const auto skip = st::boostReplaceIconSkip; - const auto w = st::boostReplaceIcon.width() + 2 * skip; - const auto h = st::boostReplaceIcon.height() + 2 * skip; - const auto x = last->x() + last->width() - w + add.x(); - const auto y = last->y() + last->height() - h + add.y(); + const auto &icon = boosting + ? st::boostReplaceIcon + : st::starrefJoinIcon; + const auto skip = boosting ? st::boostReplaceIconSkip : 0; + const auto w = icon.width() + 2 * skip; + const auto h = icon.height() + 2 * skip; + const auto x = back->x() + back->width() - w + add.x(); + const auto y = back->y() + back->height() - h + add.y(); auto brush = QLinearGradient(QPointF(x + w, y + h), QPointF(x, y)); brush.setStops(Ui::Premium::ButtonGradientStops()); @@ -654,7 +662,7 @@ object_ptr CreateBoostReplaceUserpics( pen.setWidthF(stroke); q.setPen(pen); q.drawEllipse(x - half, y - half, w + stroke, h + stroke); - st::boostReplaceIcon.paint(q, x + skip, y + skip, outerw); + icon.paint(q, x + skip, y + skip, outerw); const auto size = st::boostReplaceArrow.size(); st::boostReplaceArrow.paint( diff --git a/Telegram/SourceFiles/boxes/peers/replace_boost_box.h b/Telegram/SourceFiles/boxes/peers/replace_boost_box.h index c84b0d306..6e622479d 100644 --- a/Telegram/SourceFiles/boxes/peers/replace_boost_box.h +++ b/Telegram/SourceFiles/boxes/peers/replace_boost_box.h @@ -53,10 +53,15 @@ object_ptr ReassignBoostsBox( Fn slots, int groups, int channels)> reassign, Fn cancel); -[[nodiscard]] object_ptr CreateBoostReplaceUserpics( +enum class UserpicsTransferType { + BoostReplace, + StarRefJoin, +}; +[[nodiscard]] object_ptr CreateUserpicsTransfer( not_null parent, rpl::producer>> from, - not_null to); + not_null to, + UserpicsTransferType type); [[nodiscard]] object_ptr CreateUserpicsWithMoreBadge( not_null parent, 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 be5834f29..cf61d9af0 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 @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "base/timer_rpl.h" #include "base/unixtime.h" +#include "boxes/peers/replace_boost_box.h" // CreateUserpicsTransfer. #include "boxes/peer_list_box.h" #include "core/click_handler_types.h" #include "data/data_session.h" @@ -31,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/labels.h" #include "ui/widgets/popup_menu.h" #include "ui/wrap/fade_wrap.h" +#include "ui/wrap/padding_wrap.h" #include "ui/wrap/slide_wrap.h" #include "ui/wrap/vertical_layout.h" #include "ui/ui_utility.h" @@ -53,6 +55,19 @@ enum class JoinType { Suggested, }; +struct ConnectedBotState { + StarRefProgram program; + QString link; + TimeId date = 0; + int users = 0; + bool revoked = false; +}; +struct ConnectedBot { + not_null bot; + ConnectedBotState state; +}; +using ConnectedBots = std::vector; + class ListController final : public PeerListController { public: ListController( @@ -71,36 +86,17 @@ public: [[nodiscard]] rpl::producer rowCountValue() const; - //std::unique_ptr createRestoredRow( - // not_null peer) override { - // return createRow(peer); - //} - - //std::unique_ptr saveState() const override; - //void restoreState(std::unique_ptr state) override; - void setContentWidget(not_null widget); [[nodiscard]] rpl::producer unlockHeightValue() const; private: - struct RowState { - StarRefProgram program; - QString link; - int users = 0; - }; + [[nodiscard]] std::unique_ptr createRow(ConnectedBot bot); - [[nodiscard]] std::unique_ptr createRow( - not_null peer, - RowState state); - void showLink(not_null peer, RowState state); - - struct SavedState : SavedStateBase { - }; const not_null _controller; const not_null _peer; const JoinType _type = {}; - base::flat_map, RowState> _states; + base::flat_map, ConnectedBotState> _states; mtpRequestId _requestId = 0; TimeId _offsetDate = 0; @@ -111,6 +107,246 @@ private: }; +[[nodiscard]] ConnectedBots Parse( + not_null session, + const MTPpayments_ConnectedStarRefBots &bots) { + const auto &data = bots.data(); + session->data().processUsers(data.vusers()); + const auto &list = data.vconnected_bots().v; + auto result = ConnectedBots(); + for (const auto &bot : list) { + const auto &data = bot.data(); + const auto botId = UserId(data.vbot_id()); + const auto link = qs(data.vurl()); + const auto date = data.vdate().v; + const auto commission = data.vcommission_permille().v; + const auto durationMonths + = data.vduration_months().value_or_empty(); + const auto users = int(data.vparticipants().v); + const auto revoked = data.is_revoked(); + result.push_back({ + .bot = session->data().user(botId), + .state = { + .program = { + .commission = ushort(commission), + .durationMonths = uchar(durationMonths), + }, + .link = link, + .date = date, + .users = users, + .revoked = revoked, + }, + }); + } + return result; +} + +[[nodiscard]] rpl::producer FormatProgramDuration( + StarRefProgram program) { + return !program.durationMonths + ? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue) + : (program.durationMonths < 12) + ? tr::lng_star_ref_one_about_for_months( + lt_count, + rpl::single(program.durationMonths * 1.), + Ui::Text::RichLangValue) + : tr::lng_star_ref_one_about_for_years( + lt_count, + rpl::single((program.durationMonths / 12) * 1.), + Ui::Text::RichLangValue); +} + +[[nodiscard]] not_null AddFullWidthButton( + not_null box, + rpl::producer text, + Fn callback = nullptr) { + const auto &boxSt = box->getDelegate()->style(); + const auto result = box->addButton(std::move(text), std::move(callback)); + rpl::combine( + box->widthValue(), + result->widthValue() + ) | rpl::start_with_next([=](int width, int buttonWidth) { + const auto correct = width + - boxSt.buttonPadding.left() + - boxSt.buttonPadding.right(); + if (correct > 0 && buttonWidth != correct) { + result->resizeToWidth(correct); + result->moveToLeft( + boxSt.buttonPadding.left(), + boxSt.buttonPadding.top(), + width); + } + }, result->lifetime()); + return result; +} + +[[nodiscard]] object_ptr StarRefLinkBox( + ConnectedBot row, + not_null peer) { + return Box([=](not_null box) { + box->setTitle(tr::lng_star_ref_link_title()); + + const auto bot = row.bot; + const auto program = row.state.program; + auto duration = !program.durationMonths + ? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue) + : (program.durationMonths < 12) + ? tr::lng_star_ref_one_about_for_months( + lt_count, + rpl::single(program.durationMonths * 1.), + Ui::Text::RichLangValue) + : tr::lng_star_ref_one_about_for_years( + lt_count, + rpl::single((program.durationMonths / 12) * 1.), + Ui::Text::RichLangValue); + auto text = tr::lng_star_ref_link_about_channel( + lt_amount, + rpl::single(Ui::Text::Bold(FormatStarRefCommission(program.commission))), + lt_app, + rpl::single(Ui::Text::Bold(bot->name())), + lt_duration, + std::move(duration), + Ui::Text::WithEntities); + box->addRow( + object_ptr(box, std::move(text), st::boxLabel)); + Ui::AddSkip(box->verticalLayout()); + box->addRow( + object_ptr( + box, + rpl::single(row.state.link) | Ui::Text::ToLink(), + st::boxLabel)); + Ui::AddSkip(box->verticalLayout()); + if (row.state.users > 0) { + box->addRow( + object_ptr( + box, + tr::lng_star_ref_link_copy_users( + lt_count, + rpl::single(row.state.users * 1.), + lt_app, + rpl::single(bot->name())), + st::boxLabel)); + } else { + box->addRow( + object_ptr( + box, + tr::lng_star_ref_link_copy_none( + lt_app, + rpl::single(bot->name())), + st::boxLabel)); + } + + box->addButton(tr::lng_star_ref_link_copy(), [=] { + QApplication::clipboard()->setText(row.state.link); + box->uiShow()->showToast(tr::lng_username_copied(tr::now)); + }); + box->addButton(tr::lng_cancel(), [=] { + box->closeBox(); + }); + }); +} + +[[nodiscard]] object_ptr JoinStarRefBox( + ConnectedBot row, + not_null peer) { + Expects(row.bot->isUser()); + + return Box([=](not_null box) { + const auto show = box->uiShow(); + + const auto bot = row.bot; + const auto program = row.state.program; + + box->setStyle(st::starrefFooterBox); + box->setNoContentMargin(true); + box->addTopButton(st::boxTitleClose, [=] { + box->closeBox(); + }); + + box->addRow( + CreateUserpicsTransfer( + box, + rpl::single(std::vector{ not_null(bot) }), + peer, + UserpicsTransferType::StarRefJoin), + st::boxRowPadding + st::starrefJoinUserpicsPadding); + box->addRow( + object_ptr>( + box, + object_ptr( + box, + tr::lng_star_ref_title(), + st::boxTitle)), + st::boxRowPadding + st::starrefJoinTitlePadding); + box->addRow( + object_ptr( + box, + tr::lng_star_ref_one_about( + lt_app, + rpl::single(Ui::Text::Bold(bot->name())), + lt_amount, + rpl::single(Ui::Text::Bold( + FormatStarRefCommission(program.commission))), + lt_duration, + FormatProgramDuration(program), + Ui::Text::WithEntities), + st::boxLabel), + st::boxRowPadding); + struct State { + QPointer weak; + bool sent = false; + }; + const auto state = std::make_shared(); + state->weak = box; + + const auto send = [=] { + if (state->sent) { + return; + } + state->sent = true; + bot->session().api().request(MTPpayments_ConnectStarRefBot( + peer->input, + bot->asUser()->inputUser + )).done([=](const MTPpayments_ConnectedStarRefBots &result) { + const auto parsed = Parse(&bot->session(), result); + if (parsed.empty()) { + state->sent = false; + show->showToast(u"Failed."_q); + } else { + show->show(StarRefLinkBox(parsed.front(), peer)); + if (const auto strong = state->weak.data()) { + strong->closeBox(); + } + } + }).fail([=](const MTP::Error &error) { + state->sent = false; + show->showToast(u"Failed: "_q + error.type()); + }).send(); + }; + const auto button = AddFullWidthButton( + box, + tr::lng_star_ref_one_join(), + send); + const auto footer = Ui::CreateChild( + button->parentWidget(), + tr::lng_star_ref_one_join_text( + lt_terms, + tr::lng_star_ref_button_link( + ) | Ui::Text::ToLink(tr::lng_star_ref_tos_url(tr::now)), + Ui::Text::WithEntities), + st::starrefJoinFooter); + button->geometryValue() | rpl::start_with_next([=](QRect geometry) { + footer->resizeToWidth(geometry.width()); + const auto &st = box->getDelegate()->style(); + const auto top = geometry.y() + geometry.height(); + const auto available = st.buttonPadding.bottom(); + footer->moveToLeft( + geometry.left(), + top + (available - footer->height()) / 2); + }, footer->lifetime()); + }); +} + ListController::ListController( not_null controller, not_null peer, @@ -131,20 +367,22 @@ Main::Session &ListController::session() const { return _peer->session(); } -std::unique_ptr ListController::createRow( - not_null peer, - RowState state) { - _states.emplace(peer, state); - auto result = std::make_unique(peer); - const auto program = state.program; +std::unique_ptr ListController::createRow(ConnectedBot bot) { + _states.emplace(bot.bot, bot.state); + auto result = std::make_unique(bot.bot); + const auto program = bot.state.program; const auto duration = !program.durationMonths ? tr::lng_star_ref_duration_forever(tr::now) : (program.durationMonths < 12) ? tr::lng_months(tr::now, lt_count, program.durationMonths) : tr::lng_years(tr::now, lt_count, program.durationMonths / 12); - result->setCustomStatus(u"+%1%, %2"_q.arg( - QString::number(program.commission / 10.), - duration)); + if (bot.state.revoked) { + result->setCustomStatus(u"Revoked"_q); + } else { + result->setCustomStatus(u"+%1%, %2"_q.arg( + QString::number(program.commission / 10.), + duration)); + } return result; } @@ -170,32 +408,12 @@ void ListController::loadMoreRows() { MTP_string(_offsetThing), MTP_int(kPerPage) )).done([=](const MTPpayments_ConnectedStarRefBots &result) { - const auto &data = result.data(); - session().data().processUsers(data.vusers()); - const auto &list = data.vconnected_bots().v; - if (list.empty()) { + const auto parsed = Parse(&session(), result); + if (parsed.empty()) { _allLoaded = true; } else { - for (const auto &bot : list) { - const auto &data = bot.data(); - const auto botId = UserId(data.vbot_id()); - _offsetThing = qs(data.vurl()); - _offsetDate = data.vdate().v; - const auto commission = data.vcommission_permille().v; - const auto durationMonths - = data.vduration_months().value_or_empty(); - const auto user = session().data().user(botId); - if (data.is_revoked()) { - continue; - } - delegate()->peerListAppendRow(createRow(user, { - .program = { - .commission = ushort(commission), - .durationMonths = uchar(durationMonths), - }, - .link = _offsetThing, - .users = int(data.vparticipants().v), - })); + for (const auto &bot : parsed) { + delegate()->peerListAppendRow(createRow(bot)); } delegate()->peerListRefreshRows(); _rowCount = delegate()->peerListFullRowsCount(); @@ -226,10 +444,13 @@ void ListController::loadMoreRows() { const auto durationMonths = data.vduration_months().value_or_empty(); const auto user = session().data().user(botId); - delegate()->peerListAppendRow(createRow(user, { - .program = { - .commission = ushort(commission), - .durationMonths = uchar(durationMonths), + delegate()->peerListAppendRow(createRow({ + .bot = user, + .state = { + .program = { + .commission = ushort(commission), + .durationMonths = uchar(durationMonths), + }, }, })); } @@ -246,152 +467,25 @@ void ListController::loadMoreRows() { rpl::producer ListController::rowCountValue() const { return _rowCount.value(); } -// -//std::unique_ptr ListController::saveState() const { -// auto result = PeerListController::saveState(); -// auto my = std::make_unique(); -// result->controllerState = std::move(my); -// return result; -//} -// -//void ListController::restoreState( -// std::unique_ptr state) { -// auto typeErasedState = state -// ? state->controllerState.get() -// : nullptr; -// if (dynamic_cast(typeErasedState)) { -// PeerListController::restoreState(std::move(state)); -// } -//} - -void ListController::showLink(not_null peer, RowState state) { - const auto window = _controller->parentController(); - window->show(Box([=](not_null box) { - box->setTitle(tr::lng_star_ref_link_title()); - - const auto program = state.program; - auto duration = !program.durationMonths - ? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue) - : (program.durationMonths < 12) - ? tr::lng_star_ref_one_about_for_months( - lt_count, - rpl::single(program.durationMonths * 1.), - Ui::Text::RichLangValue) - : tr::lng_star_ref_one_about_for_years( - lt_count, - rpl::single((program.durationMonths / 12) * 1.), - Ui::Text::RichLangValue); - auto text = tr::lng_star_ref_link_about_channel( - lt_amount, - rpl::single(Ui::Text::Bold(QString::number(program.commission / 10.) + '%')), - lt_app, - rpl::single(Ui::Text::Bold(peer->name())), - lt_duration, - std::move(duration), - Ui::Text::WithEntities); - box->addRow( - object_ptr(box, std::move(text), st::boxLabel)); - Ui::AddSkip(box->verticalLayout()); - box->addRow( - object_ptr( - box, - rpl::single(state.link) | Ui::Text::ToLink(), - st::boxLabel)); - Ui::AddSkip(box->verticalLayout()); - if (state.users > 0) { - box->addRow( - object_ptr( - box, - tr::lng_star_ref_link_copy_users( - lt_count, - rpl::single(state.users * 1.), - lt_app, - rpl::single(peer->name())), - st::boxLabel)); - } else { - box->addRow( - object_ptr( - box, - tr::lng_star_ref_link_copy_none( - lt_app, - rpl::single(peer->name())), - st::boxLabel)); - } - - box->addButton(tr::lng_star_ref_link_copy(), [=] { - QApplication::clipboard()->setText(state.link); - window->showToast(tr::lng_username_copied(tr::now)); - }); - box->addButton(tr::lng_cancel(), [=] { - box->closeBox(); - }); - })); -} void ListController::rowClicked(not_null row) { - const auto peer = row->peer(); - const auto i = _states.find(peer); + const auto bot = row->peer()->asUser(); + const auto i = _states.find(bot); Assert(i != end(_states)); const auto state = i->second; - const auto program = state.program; const auto window = _controller->parentController(); if (_type == JoinType::Joined || !state.link.isEmpty()) { - showLink(row->peer(), state); + window->show(StarRefLinkBox({ bot, state }, _peer)); } else { - const auto join = [=](Fn close) { - session().api().request(MTPpayments_ConnectStarRefBot( - _peer->input, - peer->asUser()->inputUser - )).done([=](const MTPpayments_ConnectedStarRefBots &result) { - window->showToast(u"Connected!"_q); - close(); - }).fail([=](const MTP::Error &error) { - window->showToast(u"Failed: "_q + error.type()); - }).send(); - }; - auto duration = !program.durationMonths - ? tr::lng_star_ref_one_about_for_forever(Ui::Text::RichLangValue) - : (program.durationMonths < 12) - ? tr::lng_star_ref_one_about_for_months( - lt_count, - rpl::single(program.durationMonths * 1.), - Ui::Text::RichLangValue) - : tr::lng_star_ref_one_about_for_years( - lt_count, - rpl::single((program.durationMonths / 12) * 1.), - Ui::Text::RichLangValue); - auto text = tr::lng_star_ref_one_about( - lt_app, - rpl::single(Ui::Text::Bold(peer->name())), - lt_amount, - rpl::single(Ui::Text::Bold(QString::number(program.commission / 10.) + '%')), - lt_duration, - std::move(duration), - Ui::Text::WithEntities); - auto added = tr::lng_star_ref_one_join_text( - lt_terms, - tr::lng_star_ref_button_link() | Ui::Text::ToLink(), - Ui::Text::WithEntities); - auto joined = rpl::combine( - std::move(text), - std::move(added) - ) | rpl::map([=](TextWithEntities a, TextWithEntities b) { - return a.append("\n\n").append(b); - }); - window->show(Ui::MakeConfirmBox({ - .text = std::move(joined), - .confirmed = join, - .confirmText = tr::lng_star_ref_one_join(), - .title = tr::lng_star_ref_title(), - })); + window->show(JoinStarRefBox({ bot, state }, _peer)); } } base::unique_qptr ListController::rowContextMenu( QWidget *parent, not_null row) { - const auto peer = row->peer(); - const auto i = _states.find(peer); + const auto bot = row->peer()->asUser(); + const auto i = _states.find(bot); Assert(i != end(_states)); const auto state = i->second; if (state.link.isEmpty()) { @@ -403,7 +497,7 @@ base::unique_qptr ListController::rowContextMenu( const auto addAction = Ui::Menu::CreateAddActionCallback(result.get()); addAction(tr::lng_star_ref_list_my_open(tr::now), [=] { - _controller->parentController()->showPeerHistory(peer); + _controller->parentController()->showPeerHistory(bot); }, &st::menuIconBot); addAction(tr::lng_star_ref_list_my_copy(tr::now), [=] { QApplication::clipboard()->setText(state.link); @@ -774,5 +868,9 @@ std::shared_ptr Make(not_null peer) { std::make_shared(peer))); } +QString FormatStarRefCommission(ushort commission) { + return QString::number(commission / 10.) + '%'; +} + } // namespace Info::BotStarRef::Join diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h index 129caed9f..05dd393ae 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_join_widget.h @@ -76,4 +76,6 @@ private: [[nodiscard]] std::shared_ptr Make(not_null peer); +[[nodiscard]] QString FormatStarRefCommission(ushort commission); + } // namespace Info::BotStarRef::Join 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 88a09f7bf..c508bf3ef 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 @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "core/click_handler_types.h" #include "data/data_user.h" +#include "info/bot/starref/info_bot_starref_join_widget.h" #include "info/profile/info_profile_icon.h" #include "info/info_controller.h" #include "info/info_memento.h" @@ -495,7 +496,7 @@ void InnerWidget::setupCommission() { commission, setCommission, setCommission, - [=](int value) { return QString::number(value / 10.) + '%'; }, + [=](int value) { return Join::FormatStarRefCommission(value); }, _state.exists), st::boxRowPadding); @@ -852,7 +853,8 @@ std::unique_ptr Widget::setupBottom() { ? tr::lng_star_ref_update_info : tr::lng_star_ref_start_info)( lt_terms, - tr::lng_star_ref_button_link() | Ui::Text::ToLink(), + tr::lng_star_ref_button_link( + ) | Ui::Text::ToLink(tr::lng_star_ref_tos_url(tr::now)), Ui::Text::WithEntities), st::boxDividerLabel), QMargins(margins.left(), 0, margins.right(), 0)); diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index a4f57331f..5946ac357 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -81,6 +81,24 @@ starrefCover: PremiumCover(userPremiumCover) { titlePadding: margins(0px, 12px, 0px, 11px); } starrefCoverHeight: 180px; +starrefFooterBox: Box(defaultBox) { + buttonPadding: margins(22px, 11px, 22px, 54px); + buttonHeight: 42px; + button: RoundButton(defaultActiveButton) { + height: 42px; + textTop: 12px; + style: semiboldTextStyle; + } + shadowIgnoreTopSkip: true; +} +starrefJoinIcon: icon{{ "payments/small_star", premiumButtonFg }}; +starrefJoinUserpicsPadding: margins(0px, 32px, 0px, 10px); +starrefJoinTitlePadding: margins(0px, 0px, 0px, 12px); +starrefJoinFooter: FlatLabel(defaultFlatLabel) { + textFg: windowSubTextFg; + align: align(top); + minWidth: 240px; +} defaultPremiumBoxLabel: FlatLabel(defaultFlatLabel) { minWidth: 220px;