edit_invite_link_session.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "ui/boxes/edit_invite_link_session.h"
  8. #include "core/ui_integration.h" // TextContext
  9. #include "data/components/credits.h"
  10. #include "data/data_peer.h"
  11. #include "data/data_session.h"
  12. #include "data/stickers/data_custom_emoji.h"
  13. #include "lang/lang_keys.h"
  14. #include "main/main_app_config.h"
  15. #include "main/main_session.h"
  16. #include "ui/boxes/edit_invite_link.h" // InviteLinkSubscriptionToggle
  17. #include "ui/effects/credits_graphics.h"
  18. #include "ui/layers/generic_box.h"
  19. #include "ui/rect.h"
  20. #include "ui/text/format_values.h"
  21. #include "ui/text/text_utilities.h"
  22. #include "ui/vertical_list.h"
  23. #include "ui/widgets/buttons.h"
  24. #include "ui/widgets/fields/number_input.h"
  25. #include "ui/widgets/label_with_custom_emoji.h"
  26. #include "ui/widgets/labels.h"
  27. #include "ui/wrap/slide_wrap.h"
  28. #include "ui/wrap/vertical_layout.h"
  29. #include "styles/style_channel_earn.h"
  30. #include "styles/style_chat.h"
  31. #include "styles/style_settings.h"
  32. #include "styles/style_layers.h"
  33. #include "styles/style_info.h"
  34. namespace Ui {
  35. InviteLinkSubscriptionToggle FillCreateInviteLinkSubscriptionToggle(
  36. not_null<Ui::GenericBox*> box,
  37. not_null<PeerData*> peer) {
  38. struct State final {
  39. rpl::variable<float64> usdRate = 0;
  40. };
  41. const auto state = box->lifetime().make_state<State>();
  42. const auto currency = u"USD"_q;
  43. const auto container = box->verticalLayout();
  44. const auto toggle = container->add(
  45. object_ptr<SettingsButton>(
  46. container,
  47. tr::lng_group_invite_subscription(),
  48. st::settingsButtonNoIconLocked),
  49. style::margins{ 0, 0, 0, st::defaultVerticalListSkip });
  50. const auto maxCredits = peer->session().appConfig().get<int>(
  51. u"stars_subscription_amount_max"_q,
  52. 2500);
  53. const auto &st = st::inviteLinkCreditsField;
  54. const auto skip = st.textMargins.top() / 2;
  55. const auto wrap = container->add(
  56. object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
  57. container,
  58. object_ptr<Ui::VerticalLayout>(container)));
  59. box->setShowFinishedCallback([=] {
  60. wrap->toggleOn(toggle->toggledValue());
  61. wrap->finishAnimating();
  62. });
  63. const auto inputContainer = wrap->entity()->add(
  64. CreateSkipWidget(container, st.heightMin - skip));
  65. const auto input = CreateChild<NumberInput>(
  66. inputContainer,
  67. st,
  68. tr::lng_group_invite_subscription_ph(),
  69. QString(),
  70. std::pow(QString::number(maxCredits).size(), 10));
  71. wrap->toggledValue() | rpl::start_with_next([=](bool shown) {
  72. if (shown) {
  73. input->setFocus();
  74. }
  75. }, input->lifetime());
  76. const auto icon = CreateSingleStarWidget(
  77. inputContainer,
  78. st.style.font->height);
  79. const auto priceOverlay = Ui::CreateChild<Ui::RpWidget>(inputContainer);
  80. priceOverlay->setAttribute(Qt::WA_TransparentForMouseEvents);
  81. inputContainer->sizeValue(
  82. ) | rpl::start_with_next([=](const QSize &size) {
  83. input->resize(
  84. size.width() - rect::m::sum::h(st::boxRowPadding),
  85. st.heightMin);
  86. input->moveToLeft(st::boxRowPadding.left(), -skip);
  87. icon->moveToLeft(
  88. st::boxRowPadding.left(),
  89. input->pos().y() + st.textMargins.top());
  90. priceOverlay->resize(size);
  91. }, input->lifetime());
  92. ToggleChildrenVisibility(inputContainer, true);
  93. QObject::connect(input, &Ui::MaskedInputField::changed, [=] {
  94. const auto amount = input->getLastText().toDouble();
  95. if (amount > maxCredits) {
  96. input->setText(QString::number(maxCredits));
  97. }
  98. priceOverlay->update();
  99. });
  100. priceOverlay->paintRequest(
  101. ) | rpl::start_with_next([=, right = st::boxRowPadding.right()] {
  102. if (state->usdRate.current() <= 0) {
  103. return;
  104. }
  105. const auto amount = input->getLastText().toDouble();
  106. if (amount <= 0) {
  107. return;
  108. }
  109. const auto text = tr::lng_group_invite_subscription_price(
  110. tr::now,
  111. lt_cost,
  112. Ui::FillAmountAndCurrency(
  113. amount * state->usdRate.current(),
  114. currency));
  115. auto p = QPainter(priceOverlay);
  116. p.setFont(st.placeholderFont);
  117. p.setPen(st.placeholderFg);
  118. p.setBrush(Qt::NoBrush);
  119. const auto m = QMargins(0, skip, right, 0);
  120. p.drawText(priceOverlay->rect() - m, text, style::al_right);
  121. }, priceOverlay->lifetime());
  122. state->usdRate = peer->session().credits().rateValue(peer);
  123. auto about = Ui::CreateLabelWithCustomEmoji(
  124. container,
  125. tr::lng_group_invite_subscription_about(
  126. lt_link,
  127. tr::lng_group_invite_subscription_about_link(
  128. lt_emoji,
  129. rpl::single(Ui::Text::IconEmoji(&st::textMoreIconEmoji)),
  130. Ui::Text::RichLangValue
  131. ) | rpl::map([](TextWithEntities text) {
  132. return Ui::Text::Link(
  133. std::move(text),
  134. tr::lng_group_invite_subscription_about_url(tr::now));
  135. }),
  136. Ui::Text::RichLangValue),
  137. Core::TextContext({ .session = &peer->session() }),
  138. st::boxDividerLabel);
  139. Ui::AddSkip(wrap->entity());
  140. Ui::AddSkip(wrap->entity());
  141. container->add(object_ptr<Ui::DividerLabel>(
  142. container,
  143. std::move(about),
  144. st::defaultBoxDividerLabelPadding,
  145. RectPart::Top | RectPart::Bottom));
  146. return { toggle, input };
  147. }
  148. } // namespace Ui