mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Added ability to choose subscription option for Premium in Settings.
This commit is contained in:
parent
6f3d19914d
commit
149d92d224
8 changed files with 232 additions and 57 deletions
|
@ -1702,6 +1702,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_premium_unlock_stickers" = "Unlock Premium Stickers";
|
||||
"lng_premium_unlock_emoji" = "Unlock Animated Emoji";
|
||||
|
||||
"lng_premium_subscribe_months_12" = "Annual";
|
||||
"lng_premium_subscribe_months_6" = "Semiannual";
|
||||
"lng_premium_subscribe_months_1" = "Monthly";
|
||||
"lng_premium_subscribe_total" = "{cost} per year";
|
||||
"lng_premium_subscribe_button" = "Subscribe for {cost} per month";
|
||||
|
||||
"lng_premium_emoji_status_title" = "{user} set this emoji from {link} as their current status.";
|
||||
"lng_premium_emoji_status_about" = "Emoji status is a premium feature. Other features included in **Telegram Premium**:";
|
||||
"lng_premium_emoji_status_button" = "Unlock Emoji Status";
|
||||
|
|
|
@ -10,8 +10,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "api/api_premium_option.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "core/click_handler_types.h" // ClickHandlerContext.
|
||||
#include "core/local_url_handlers.h" // TryConvertUrlToLocal.
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_peer_values.h" // Data::PeerPremiumValue.
|
||||
#include "data/data_session.h"
|
||||
|
@ -167,7 +165,11 @@ void GiftBox(
|
|||
options[value].total);
|
||||
state->buttonText.fire(std::move(text));
|
||||
});
|
||||
Ui::Premium::AddGiftOptions(buttonsParent, group, options);
|
||||
Ui::Premium::AddGiftOptions(
|
||||
buttonsParent,
|
||||
group,
|
||||
options,
|
||||
st::premiumGiftOption);
|
||||
|
||||
// Footer.
|
||||
auto terms = object_ptr<Ui::FlatLabel>(
|
||||
|
@ -198,26 +200,17 @@ void GiftBox(
|
|||
[] { return QString("gift"); },
|
||||
state->buttonText.events(),
|
||||
Ui::Premium::GiftGradientStops(),
|
||||
[=] {
|
||||
const auto value = group->value();
|
||||
return (value < options.size() && value >= 0)
|
||||
? options[value].botUrl
|
||||
: QString();
|
||||
},
|
||||
});
|
||||
auto button = object_ptr<Ui::GradientButton>::fromRaw(raw);
|
||||
button->resizeToWidth(boxWidth
|
||||
- stButton.buttonPadding.left()
|
||||
- stButton.buttonPadding.right());
|
||||
button->setClickedCallback([=] {
|
||||
const auto value = group->value();
|
||||
Assert(value < options.size() && value >= 0);
|
||||
|
||||
const auto local = Core::TryConvertUrlToLocal(options[value].botUrl);
|
||||
if (local.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
UrlClickHandler::Open(
|
||||
local,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller.get()),
|
||||
.botStartAutoSubmit = true,
|
||||
}));
|
||||
});
|
||||
box->setShowFinishedCallback([raw = button.data()]{
|
||||
raw->startGlareAnimation();
|
||||
});
|
||||
|
|
|
@ -489,6 +489,7 @@ settingsPremiumArrow: icon{{ "fast_to_original", menuIconFg }};
|
|||
settingsPremiumArrowOver: icon{{ "fast_to_original", menuIconFgOver }};
|
||||
settingsPremiumStatusPadding: margins(22px, 8px, 22px, 2px);
|
||||
|
||||
settingsPremiumOptionsPadding: margins(0px, 9px, 0px, 2px);
|
||||
settingsPremiumTopHeight: 220px;
|
||||
settingsPremiumUserHeight: 223px;
|
||||
settingsPremiumUserTitlePadding: margins(0px, 16px, 0px, 6px);
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "chat_helpers/stickers_lottie.h" // LottiePlayerFromDocument.
|
||||
#include "core/application.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/local_url_handlers.h" // Core::TryConvertUrlToLocal.
|
||||
#include "core/ui_integration.h" // MarkedTextContext.
|
||||
#include "data/data_document.h"
|
||||
#include "data/data_document_media.h"
|
||||
|
@ -39,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/checkbox.h" // Ui::RadiobuttonGroup.
|
||||
#include "ui/widgets/gradient_round_button.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
|
@ -69,6 +71,33 @@ constexpr auto kTitleAdditionalScale = 0.15;
|
|||
return u":/gui/icons/settings/star.svg"_q;
|
||||
}
|
||||
|
||||
[[nodiscard]] Data::SubscriptionOptions SubscriptionOptionsForRows(
|
||||
Data::SubscriptionOptions result) {
|
||||
for (auto &option : result) {
|
||||
const auto total = option.costTotal;
|
||||
const auto perMonth = option.costPerMonth;
|
||||
|
||||
option.costTotal = tr::lng_premium_gift_per(
|
||||
tr::now,
|
||||
lt_cost,
|
||||
perMonth);
|
||||
option.costPerMonth = tr::lng_premium_subscribe_total(
|
||||
tr::now,
|
||||
lt_cost,
|
||||
total);
|
||||
|
||||
if (option.duration == tr::lng_months(tr::now, lt_count, 1)) {
|
||||
option.costPerMonth = QString();
|
||||
option.duration = tr::lng_premium_subscribe_months_1(tr::now);
|
||||
} else if (option.duration == tr::lng_months(tr::now, lt_count, 6)) {
|
||||
option.duration = tr::lng_premium_subscribe_months_6(tr::now);
|
||||
} else if (option.duration == tr::lng_years(tr::now, lt_count, 1)) {
|
||||
option.duration = tr::lng_premium_subscribe_months_12(tr::now);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
namespace Ref {
|
||||
namespace Gift {
|
||||
|
||||
|
@ -968,6 +997,9 @@ public:
|
|||
|
||||
private:
|
||||
void setupContent();
|
||||
void setupSubscriptionOptions(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
int lastSkip);
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
const QString _ref;
|
||||
|
@ -979,8 +1011,11 @@ private:
|
|||
rpl::variable<Info::Wrap> _wrap;
|
||||
Fn<void(bool)> _setPaused;
|
||||
|
||||
std::shared_ptr<Ui::RadiobuttonGroup> _radioGroup;
|
||||
|
||||
rpl::event_stream<> _showBack;
|
||||
rpl::event_stream<> _showFinished;
|
||||
rpl::event_stream<QString> _buttonText;
|
||||
|
||||
};
|
||||
|
||||
|
@ -989,7 +1024,8 @@ Premium::Premium(
|
|||
not_null<Window::SessionController*> controller)
|
||||
: Section(parent)
|
||||
, _controller(controller)
|
||||
, _ref(ResolveRef(controller->premiumRef())) {
|
||||
, _ref(ResolveRef(controller->premiumRef()))
|
||||
, _radioGroup(std::make_shared<Ui::RadiobuttonGroup>()) {
|
||||
setupContent();
|
||||
_controller->session().api().premium().reload();
|
||||
}
|
||||
|
@ -1016,6 +1052,47 @@ void Premium::setStepDataReference(std::any &data) {
|
|||
}
|
||||
}
|
||||
|
||||
void Premium::setupSubscriptionOptions(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
int lastSkip) {
|
||||
const auto options = container->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
object_ptr<Ui::VerticalLayout>(container)));
|
||||
const auto skip = container->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
object_ptr<Ui::VerticalLayout>(container)));
|
||||
const auto content = options->entity();
|
||||
|
||||
AddSkip(content, st::settingsPremiumOptionsPadding.top());
|
||||
|
||||
Ui::Premium::AddGiftOptions(
|
||||
content,
|
||||
_radioGroup,
|
||||
SubscriptionOptionsForRows(
|
||||
_controller->session().api().premium().subscriptionOptions()),
|
||||
st::premiumSubscriptionOption,
|
||||
true);
|
||||
|
||||
AddSkip(content, st::settingsPremiumOptionsPadding.bottom());
|
||||
AddDivider(content);
|
||||
|
||||
AddSkip(content, lastSkip - st::settingsSectionSkip);
|
||||
AddSkip(skip->entity(), lastSkip);
|
||||
|
||||
auto toggleOn = rpl::combine(
|
||||
Data::AmPremiumValue(&_controller->session()),
|
||||
rpl::single(!!(Ref::EmojiStatus::Parse(_ref)))
|
||||
) | rpl::map([=](bool premium, bool isEmojiStatus) {
|
||||
return !premium && !isEmojiStatus;
|
||||
});
|
||||
options->toggleOn(rpl::duplicate(toggleOn), anim::type::instant);
|
||||
skip->toggleOn(std::move(
|
||||
toggleOn
|
||||
) | rpl::map([](bool value) { return !value; }), anim::type::instant);
|
||||
}
|
||||
|
||||
void Premium::setupContent() {
|
||||
const auto content = Ui::CreateChild<Ui::VerticalLayout>(this);
|
||||
|
||||
|
@ -1025,7 +1102,9 @@ void Premium::setupContent() {
|
|||
const auto &titlePadding = st::settingsPremiumRowTitlePadding;
|
||||
const auto &descriptionPadding = st::settingsPremiumRowAboutPadding;
|
||||
|
||||
AddSkip(content, stDefault.padding.top() + titlePadding.top());
|
||||
setupSubscriptionOptions(
|
||||
content,
|
||||
stDefault.padding.top() + titlePadding.top());
|
||||
|
||||
auto entryMap = EntryMap();
|
||||
auto iconContainers = std::vector<Ui::AbstractButton*>();
|
||||
|
@ -1385,10 +1464,11 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
|||
}
|
||||
|
||||
const auto emojiStatusData = Ref::EmojiStatus::Parse(_ref);
|
||||
const auto session = &_controller->session();
|
||||
|
||||
auto buttonText = [&]() -> std::optional<rpl::producer<QString>> {
|
||||
if (emojiStatusData) {
|
||||
auto &data = _controller->session().data();
|
||||
auto &data = session->data();
|
||||
if (const auto peer = data.peer(emojiStatusData.peerId)) {
|
||||
return Info::Profile::EmojiStatusIdValue(
|
||||
peer
|
||||
|
@ -1399,7 +1479,7 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
|||
}) | rpl::flatten_latest();
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
return _buttonText.events();
|
||||
}();
|
||||
|
||||
_subscribe = CreateSubscribeButton({
|
||||
|
@ -1407,6 +1487,13 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
|||
content,
|
||||
[ref = _ref] { return ref; },
|
||||
std::move(buttonText),
|
||||
std::nullopt,
|
||||
[=, options = session->api().premium().subscriptionOptions()] {
|
||||
const auto value = _radioGroup->value();
|
||||
return (value < options.size() && value >= 0)
|
||||
? options[value].botUrl
|
||||
: QString();
|
||||
},
|
||||
});
|
||||
if (emojiStatusData) {
|
||||
// "Learn More" should open the general Premium Settings
|
||||
|
@ -1419,6 +1506,18 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
|||
ShowPremium(controller, QString());
|
||||
controller->setPremiumRef(ref);
|
||||
});
|
||||
} else {
|
||||
_radioGroup->setChangedCallback([=](int value) {
|
||||
const auto options =
|
||||
_controller->session().api().premium().subscriptionOptions();
|
||||
Expects(value < options.size() && value >= 0);
|
||||
auto text = tr::lng_premium_subscribe_button(
|
||||
tr::now,
|
||||
lt_cost,
|
||||
options[value].costPerMonth);
|
||||
_buttonText.fire(std::move(text));
|
||||
});
|
||||
_radioGroup->setValue(0);
|
||||
}
|
||||
|
||||
_showFinished.events(
|
||||
|
@ -1432,7 +1531,6 @@ QPointer<Ui::RpWidget> Premium::createPinnedToBottom(
|
|||
_subscribe->resizeToWidth(width - padding.left() - padding.right());
|
||||
}, _subscribe->lifetime());
|
||||
|
||||
const auto session = &_controller->session();
|
||||
rpl::combine(
|
||||
_subscribe->heightValue(),
|
||||
Data::AmPremiumValue(session),
|
||||
|
@ -1543,9 +1641,24 @@ not_null<Ui::GradientButton*> CreateSubscribeButton(
|
|||
|
||||
result->setClickedCallback([
|
||||
controller = args.controller,
|
||||
computeRef = args.computeRef] {
|
||||
SendScreenAccept(controller);
|
||||
StartPremiumPayment(controller, computeRef());
|
||||
computeRef = args.computeRef,
|
||||
computeBotUrl = args.computeBotUrl] {
|
||||
const auto url = computeBotUrl ? QString() : computeBotUrl();
|
||||
if (!url.isEmpty()) {
|
||||
const auto local = Core::TryConvertUrlToLocal(url);
|
||||
if (local.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
UrlClickHandler::Open(
|
||||
local,
|
||||
QVariant::fromValue(ClickHandlerContext{
|
||||
.sessionWindow = base::make_weak(controller.get()),
|
||||
.botStartAutoSubmit = true,
|
||||
}));
|
||||
} else {
|
||||
SendScreenAccept(controller);
|
||||
StartPremiumPayment(controller, computeRef());
|
||||
}
|
||||
});
|
||||
|
||||
const auto &st = st::premiumPreviewBox.button;
|
||||
|
|
|
@ -53,6 +53,7 @@ struct SubscribeButtonArgs final {
|
|||
Fn<QString()> computeRef;
|
||||
std::optional<rpl::producer<QString>> text;
|
||||
std::optional<QGradientStops> gradientStops;
|
||||
Fn<QString()> computeBotUrl; // nullable
|
||||
};
|
||||
|
||||
[[nodiscard]] not_null<Ui::GradientButton*> CreateSubscribeButton(
|
||||
|
|
|
@ -97,17 +97,56 @@ premiumAccountsNameTop: 13px;
|
|||
premiumAccountsPadding: margins(0px, 20px, 0px, 14px);
|
||||
premiumAccountsHeight: 105px;
|
||||
|
||||
PremiumOption {
|
||||
rowPadding: margins;
|
||||
rowMargins: margins;
|
||||
rowHeight: pixels;
|
||||
|
||||
borderWidth: pixels;
|
||||
borderRadius: pixels;
|
||||
|
||||
subtitleTop: pixels;
|
||||
textLeft: pixels;
|
||||
|
||||
badgeHeight: pixels;
|
||||
badgeRadius: pixels;
|
||||
badgeMargins: margins;
|
||||
badgeShift: point;
|
||||
}
|
||||
|
||||
premiumSubscriptionOption: PremiumOption {
|
||||
rowPadding: margins(9px, 2px, 17px, 3px);
|
||||
rowMargins: margins(14px, 0px, 5px, 0px);
|
||||
rowHeight: 39px;
|
||||
|
||||
borderWidth: 0px;
|
||||
borderRadius: 0px;
|
||||
|
||||
subtitleTop: 1px;
|
||||
textLeft: 51px;
|
||||
|
||||
badgeHeight: 15px;
|
||||
badgeRadius: 4px;
|
||||
badgeMargins: margins(3px, 1px, 3px, 0px);
|
||||
badgeShift: point(9px, 0px);
|
||||
}
|
||||
|
||||
// Gift.
|
||||
premiumGiftRowHeight: 56px;
|
||||
premiumGiftRowBorderWidth: 2px;
|
||||
premiumGiftRowBorderRadius: 9px;
|
||||
premiumGiftRowPaddings: margins(19px, 2px, 17px, 2px);
|
||||
premiumGiftRowMargins: margins(14px, 0px, 15px, 0px);
|
||||
premiumGiftRowSubtitleTop: 7px;
|
||||
premiumGiftRowTextLeft: 53px;
|
||||
premiumGiftRowBadgeHeight: 18px;
|
||||
premiumGiftRowBadgeRadius: 4px;
|
||||
premiumGiftRowBadgeMargins: margins(5px, 1px, 5px, 0px);
|
||||
premiumGiftOption: PremiumOption {
|
||||
rowPadding: margins(19px, 2px, 17px, 2px);
|
||||
rowMargins: margins(14px, 0px, 15px, 0px);
|
||||
rowHeight: 56px;
|
||||
|
||||
borderWidth: 2px;
|
||||
borderRadius: 9px;
|
||||
|
||||
subtitleTop: 7px;
|
||||
textLeft: 53px;
|
||||
|
||||
badgeHeight: 18px;
|
||||
badgeRadius: 4px;
|
||||
badgeMargins: margins(5px, 1px, 5px, 0px);
|
||||
}
|
||||
|
||||
premiumGiftUserpicPadding: margins(10px, 27px, 18px, 13px);
|
||||
premiumGiftTitlePadding: margins(18px, 0px, 18px, 0px);
|
||||
|
|
|
@ -938,7 +938,9 @@ void ShowListBox(
|
|||
void AddGiftOptions(
|
||||
not_null<Ui::VerticalLayout*> parent,
|
||||
std::shared_ptr<Ui::RadiobuttonGroup> group,
|
||||
std::vector<Data::SubscriptionOption> gifts) {
|
||||
std::vector<Data::SubscriptionOption> gifts,
|
||||
const style::PremiumOption &st,
|
||||
bool topBadges) {
|
||||
|
||||
struct Edges {
|
||||
Ui::RpWidget *top = nullptr;
|
||||
|
@ -956,8 +958,8 @@ void AddGiftOptions(
|
|||
const auto addRow = [&](const Data::SubscriptionOption &info, int index) {
|
||||
const auto row = parent->add(
|
||||
object_ptr<Ui::AbstractButton>(parent),
|
||||
st::premiumGiftRowPaddings);
|
||||
row->resize(row->width(), st::premiumGiftRowHeight);
|
||||
st.rowPadding);
|
||||
row->resize(row->width(), st.rowHeight);
|
||||
{
|
||||
if (!index) {
|
||||
edges->top = row;
|
||||
|
@ -981,7 +983,7 @@ void AddGiftOptions(
|
|||
- margins.top()
|
||||
- margins.bottom();
|
||||
radio->moveToLeft(
|
||||
st::premiumGiftRowMargins.left(),
|
||||
st.rowMargins.left(),
|
||||
(s.height() - radioHeight) / 2);
|
||||
}, radio->lifetime());
|
||||
|
||||
|
@ -992,30 +994,45 @@ void AddGiftOptions(
|
|||
|
||||
p.fillRect(r, Qt::transparent);
|
||||
|
||||
const auto left = st::premiumGiftRowTextLeft;
|
||||
const auto borderWidth = st::premiumGiftRowBorderWidth;
|
||||
const auto left = st.textLeft;
|
||||
const auto halfHeight = row->height() / 2;
|
||||
|
||||
const auto titleFont = st::semiboldFont;
|
||||
p.setFont(titleFont);
|
||||
p.setPen(st::boxTextFg);
|
||||
p.drawText(
|
||||
left,
|
||||
st::premiumGiftRowSubtitleTop + titleFont->ascent,
|
||||
info.duration);
|
||||
if (info.costPerMonth.isEmpty() && info.discount.isEmpty()) {
|
||||
const auto r = row->rect().translated(
|
||||
-row->rect().left() + left,
|
||||
0);
|
||||
p.drawText(r, info.duration, style::al_left);
|
||||
} else {
|
||||
p.drawText(
|
||||
left,
|
||||
st.subtitleTop + titleFont->ascent,
|
||||
info.duration);
|
||||
}
|
||||
|
||||
const auto discountFont = st::windowFiltersButton.badgeStyle.font;
|
||||
const auto discountWidth = discountFont->width(info.discount);
|
||||
const auto &discountMargins = discountWidth
|
||||
? st::premiumGiftRowBadgeMargins
|
||||
? st.badgeMargins
|
||||
: style::margins();
|
||||
const auto discountRect = QRect(
|
||||
|
||||
const auto bottomLeftRect = QRect(
|
||||
left,
|
||||
halfHeight + discountMargins.top(),
|
||||
discountWidth
|
||||
+ discountMargins.left()
|
||||
+ discountMargins.right(),
|
||||
st::premiumGiftRowBadgeHeight);
|
||||
st.badgeHeight);
|
||||
const auto discountRect = topBadges
|
||||
? bottomLeftRect.translated(
|
||||
titleFont->width(info.duration) + st.badgeShift.x(),
|
||||
-bottomLeftRect.top()
|
||||
+ st.badgeShift.y()
|
||||
+ st.subtitleTop
|
||||
+ (titleFont->height - bottomLeftRect.height()) / 2)
|
||||
: bottomLeftRect;
|
||||
{
|
||||
const auto from = edges->top->y();
|
||||
const auto to = edges->bottom->y() + edges->bottom->height();
|
||||
|
@ -1023,17 +1040,17 @@ void AddGiftOptions(
|
|||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(partialGradient.compute(row->y(), row->height()));
|
||||
const auto round = st::premiumGiftRowBadgeRadius;
|
||||
const auto round = st.badgeRadius;
|
||||
p.drawRoundedRect(discountRect, round, round);
|
||||
}
|
||||
|
||||
if (animation->nowIndex == index) {
|
||||
if (st.borderWidth && (animation->nowIndex == index)) {
|
||||
const auto progress = animation->animation.value(1.);
|
||||
const auto w = row->width();
|
||||
auto gradient = QLinearGradient(w - w * progress, 0, w * 2, 0);
|
||||
gradient.setSpread(QGradient::Spread::RepeatSpread);
|
||||
gradient.setStops(stops);
|
||||
const auto pen = QPen(QBrush(gradient), borderWidth);
|
||||
const auto pen = QPen(QBrush(gradient), st.borderWidth);
|
||||
p.setPen(pen);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
const auto borderRect = row->rect()
|
||||
|
@ -1042,7 +1059,7 @@ void AddGiftOptions(
|
|||
pen.width() / 2,
|
||||
pen.width() / 2,
|
||||
pen.width() / 2);
|
||||
const auto round = st::premiumGiftRowBorderRadius;
|
||||
const auto round = st.borderRadius;
|
||||
p.drawRoundedRect(borderRect, round, round);
|
||||
}
|
||||
|
||||
|
@ -1051,15 +1068,17 @@ void AddGiftOptions(
|
|||
p.drawText(discountRect, info.discount, style::al_center);
|
||||
|
||||
const auto perRect = QMargins(0, 0, row->width(), 0)
|
||||
+ discountRect.translated(
|
||||
discountRect.width() + discountMargins.left(),
|
||||
+ bottomLeftRect.translated(
|
||||
topBadges
|
||||
? 0
|
||||
: bottomLeftRect.width() + discountMargins.left(),
|
||||
0);
|
||||
p.setPen(st::windowSubTextFg);
|
||||
p.setFont(st::shareBoxListItem.nameStyle.font);
|
||||
p.drawText(perRect, info.costPerMonth, style::al_left);
|
||||
|
||||
const auto totalRect = row->rect()
|
||||
- QMargins(0, 0, st::premiumGiftRowMargins.right(), 0);
|
||||
- QMargins(0, 0, st.rowMargins.right(), 0);
|
||||
p.setFont(st::normalFont);
|
||||
p.drawText(totalRect, info.costTotal, style::al_right);
|
||||
}, row->lifetime());
|
||||
|
|
|
@ -22,6 +22,7 @@ struct SubscriptionOption;
|
|||
|
||||
namespace style {
|
||||
struct RoundImageCheckbox;
|
||||
struct PremiumOption;
|
||||
struct TextStyle;
|
||||
} // namespace style
|
||||
|
||||
|
@ -90,7 +91,9 @@ void ShowListBox(
|
|||
void AddGiftOptions(
|
||||
not_null<Ui::VerticalLayout*> parent,
|
||||
std::shared_ptr<Ui::RadiobuttonGroup> group,
|
||||
std::vector<Data::SubscriptionOption> gifts);
|
||||
std::vector<Data::SubscriptionOption> gifts,
|
||||
const style::PremiumOption &st,
|
||||
bool topBadges = false);
|
||||
|
||||
} // namespace Premium
|
||||
} // namespace Ui
|
||||
|
|
Loading…
Add table
Reference in a new issue