mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Start UI of the gifts.
This commit is contained in:
parent
761617c1ce
commit
4cdd1fec95
2 changed files with 186 additions and 7 deletions
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "history/view/media/history_view_sticker_player.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "main/session/session_show.h"
|
||||
#include "main/main_session.h"
|
||||
|
@ -27,9 +28,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/painter.h"
|
||||
#include "ui/rect.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/widgets/label_with_custom_emoji.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_channel_earn.h"
|
||||
|
@ -47,6 +50,7 @@ namespace {
|
|||
|
||||
constexpr auto kPriceTabAll = 0;
|
||||
constexpr auto kPriceTabLimited = -1;
|
||||
constexpr auto kGiftsPerRow = 3;
|
||||
|
||||
struct GiftTypePremium {
|
||||
int64 cost = 0;
|
||||
|
@ -119,9 +123,9 @@ struct GiftDescriptor : std::variant<GiftTypePremium, GiftTypeStars> {
|
|||
for (auto &gift : list) {
|
||||
if (gift.months > minMonthsGift.months
|
||||
&& gift.currency == minMonthsGift.currency) {
|
||||
const auto costPerMonth = gift.cost / gift.months;
|
||||
const auto costPerMonth = gift.cost / (1. * gift.months);
|
||||
const auto maxCostPerMonth = minMonthsGift.cost
|
||||
/ minMonthsGift.months;
|
||||
/ (1. * minMonthsGift.months);
|
||||
const auto costRatio = costPerMonth / maxCostPerMonth;
|
||||
const auto discount = 1. - costRatio;
|
||||
const auto discountPercent = 100 * discount;
|
||||
|
@ -131,6 +135,7 @@ struct GiftDescriptor : std::variant<GiftTypePremium, GiftTypeStars> {
|
|||
}
|
||||
}
|
||||
}
|
||||
ranges::sort(list, ranges::less(), &GiftTypePremium::months);
|
||||
Map[session].last = list;
|
||||
consumer.put_next_copy(list);
|
||||
}, lifetime);
|
||||
|
@ -385,8 +390,174 @@ struct GiftPriceTabs {
|
|||
auto result = object_ptr<RpWidget>((QWidget*)nullptr);
|
||||
const auto raw = result.data();
|
||||
|
||||
raw->paintRequest() | rpl::start_with_next([=] {
|
||||
struct Button {
|
||||
GiftDescriptor descriptor;
|
||||
Text::String text;
|
||||
Text::String price;
|
||||
QRect geometry;
|
||||
QRect button;
|
||||
std::unique_ptr<HistoryView::StickerPlayer> player;
|
||||
};
|
||||
struct State {
|
||||
std::vector<Button> buttons;
|
||||
QPoint bgShift;
|
||||
QImage bg;
|
||||
};
|
||||
const auto state = raw->lifetime().make_state<State>();
|
||||
|
||||
const auto width = st::boxWideWidth;
|
||||
const auto padding = st::giftBoxPadding;
|
||||
const auto available = width - padding.left() - padding.right();
|
||||
const auto singlew = (available - 2 * st::giftBoxGiftSkip.x())
|
||||
/ kGiftsPerRow;
|
||||
const auto shadow = st::defaultDropdownMenu.wrap.shadow;
|
||||
const auto extend = shadow.extend;
|
||||
|
||||
state->bgShift = -QPoint(extend.left(), extend.top());
|
||||
const auto single = QSize(singlew, st::giftBoxGiftHeight);
|
||||
const auto bgSize = QRect(QPoint(), single ).marginsAdded(extend).size();
|
||||
state->bg = QImage(
|
||||
bgSize * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
state->bg.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
state->bg.fill(Qt::transparent);
|
||||
|
||||
auto p = QPainter(&state->bg);
|
||||
const auto rect = QRect(QPoint(), bgSize).marginsRemoved(extend);
|
||||
Shadow::paint(p, rect, bgSize.width(), shadow);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::windowBg);
|
||||
const auto radius = st::roundRadiusSmall;
|
||||
p.drawRoundedRect(rect, radius, radius);
|
||||
p.end();
|
||||
|
||||
std::move(
|
||||
gifts
|
||||
) | rpl::start_with_next([=](const std::vector<GiftDescriptor> &gifts) {
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &peer->session(),
|
||||
.customEmojiRepaint = [] {},
|
||||
};
|
||||
const auto star = [&] {
|
||||
return peer->owner().customEmojiManager().creditsEmoji();
|
||||
};
|
||||
auto x = padding.left();
|
||||
auto y = padding.top();
|
||||
state->buttons.resize(gifts.size());
|
||||
for (auto i = 0, count = int(gifts.size()); i != count; ++i) {
|
||||
auto &button = state->buttons[i];
|
||||
const auto &descriptor = gifts[i];
|
||||
if (button.descriptor != descriptor) {
|
||||
button.descriptor = descriptor;
|
||||
v::match(descriptor, [&](const GiftTypePremium &data) {
|
||||
const auto months = data.months;
|
||||
const auto years = (months % 12) ? 0 : months / 12;
|
||||
button.text = Text::String(singlew / 2);
|
||||
button.text.setMarkedText(
|
||||
st::defaultTextStyle,
|
||||
Text::Bold(years
|
||||
? tr::lng_years(tr::now, lt_count, years)
|
||||
: tr::lng_months(tr::now, lt_count, months)
|
||||
).append('\n').append(
|
||||
tr::lng_gift_premium_label(tr::now)
|
||||
));
|
||||
button.price.setText(
|
||||
st::semiboldTextStyle,
|
||||
FillAmountAndCurrency(
|
||||
data.cost,
|
||||
data.currency,
|
||||
true));
|
||||
}, [&](const GiftTypeStars &data) {
|
||||
button.price.setMarkedText(
|
||||
st::semiboldTextStyle,
|
||||
star().append(QString::number(data.stars)),
|
||||
kMarkupTextOptions,
|
||||
context);
|
||||
});
|
||||
const auto buttonw = button.price.maxWidth();
|
||||
const auto buttonh = st::semiboldFont->height;
|
||||
const auto inner = QRect(
|
||||
QPoint(),
|
||||
QSize(buttonw, buttonh)
|
||||
).marginsAdded(st::giftBoxButtonPadding);
|
||||
const auto skipx = (singlew - inner.width()) / 2;
|
||||
const auto skipy = single.height()
|
||||
- st::giftBoxButtonBottom
|
||||
- inner.height();
|
||||
const auto outer = (singlew - 2 * skipx);
|
||||
button.button = QRect(skipx, skipy, outer, inner.height());
|
||||
}
|
||||
const auto last = !((i + 1) % kGiftsPerRow);
|
||||
if (last) {
|
||||
x = padding.left() + available - single.width();
|
||||
}
|
||||
button.geometry = QRect(QPoint(x, y), single);
|
||||
if (last) {
|
||||
x = padding.left();
|
||||
y += single.height() + st::giftBoxGiftSkip.y();
|
||||
} else {
|
||||
x += single.width() + st::giftBoxGiftSkip.x();
|
||||
}
|
||||
}
|
||||
if (gifts.size() % kGiftsPerRow) {
|
||||
y += padding.bottom() + single.height();
|
||||
} else {
|
||||
y += padding.bottom() - st::giftBoxGiftSkip.y();
|
||||
}
|
||||
raw->resize(raw->width(), gifts.empty() ? 0 : y);
|
||||
}, raw->lifetime());
|
||||
|
||||
raw->paintRequest() | rpl::start_with_next([=] {
|
||||
auto p = QPainter(raw);
|
||||
for (const auto &button : state->buttons) {
|
||||
const auto position = button.geometry.topLeft();
|
||||
p.drawImage(position + state->bgShift, state->bg);
|
||||
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
const auto premium = v::is<GiftTypePremium>(button.descriptor);
|
||||
p.setFont(st::normalFont);
|
||||
v::match(button.descriptor, [&](const GiftTypePremium &data) {
|
||||
if (data.discountPercent > 0) {
|
||||
p.setPen(st::attentionBoxButton.textFg);
|
||||
p.drawText(QRect(position, QSize(singlew, st::normalFont->height * 2)), '-' + QString::number(data.discountPercent) + '%', style::al_center);
|
||||
}
|
||||
}, [&](const GiftTypeStars &data) {
|
||||
if (data.limited) {
|
||||
p.setPen(st::windowActiveTextFg);
|
||||
p.drawText(QRect(position, QSize(singlew, st::normalFont->height * 2)), u"limited"_q, style::al_center);
|
||||
}
|
||||
});
|
||||
p.setBrush(premium ? st::lightButtonBgOver : st::creditsBg3);
|
||||
p.setPen(Qt::NoPen);
|
||||
if (!premium) {
|
||||
p.setOpacity(0.12);
|
||||
}
|
||||
const auto geometry = button.button.translated(position);
|
||||
const auto radius = geometry.height() / 2.;
|
||||
p.drawRoundedRect(geometry, radius, radius);
|
||||
if (!premium) {
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
if (!button.text.isEmpty()) {
|
||||
p.setPen(st::windowFg);
|
||||
button.text.draw(p, {
|
||||
.position = (position
|
||||
+ QPoint(0, st::giftBoxPremiumTextTop)),
|
||||
.availableWidth = singlew,
|
||||
.align = style::al_top,
|
||||
});
|
||||
}
|
||||
|
||||
const auto padding = st::giftBoxButtonPadding;
|
||||
p.setPen(premium ? st::windowActiveTextFg : st::creditsFg);
|
||||
button.price.draw(p, {
|
||||
.position = (geometry.topLeft()
|
||||
+ QPoint(padding.left(), padding.top())),
|
||||
.availableWidth = button.price.maxWidth(),
|
||||
});
|
||||
}
|
||||
}, raw->lifetime());
|
||||
|
||||
return result;
|
||||
|
@ -437,19 +608,19 @@ void AddBlock(
|
|||
[[nodiscard]] object_ptr<RpWidget> MakePremiumGifts(
|
||||
not_null<Window::SessionController*> window,
|
||||
not_null<PeerData*> peer) {
|
||||
auto result = object_ptr<RpWidget>((QWidget*)nullptr);
|
||||
|
||||
struct State {
|
||||
rpl::variable<std::vector<GiftDescriptor>> gifts;
|
||||
};
|
||||
const auto state = std::make_unique<State>();
|
||||
auto state = std::make_unique<State>();
|
||||
|
||||
state->gifts = GiftsPremium(&window->session(), peer) | rpl::map([=](
|
||||
const std::vector<GiftTypePremium> &gifts) {
|
||||
return gifts | ranges::to<std::vector<GiftDescriptor>>;
|
||||
});
|
||||
|
||||
return MakeGiftsList(window, peer, state->gifts.value());
|
||||
auto result = MakeGiftsList(window, peer, state->gifts.value());
|
||||
result->lifetime().add([state = std::move(state)] {});
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] object_ptr<RpWidget> MakeStarsGifts(
|
||||
|
|
|
@ -79,3 +79,11 @@ giftBoxTabStyle: semiboldTextStyle;
|
|||
giftBoxTabFg: windowSubTextFg;
|
||||
giftBoxTabFgActive: windowBoldFg;
|
||||
giftBoxTabBgActive: windowBgRipple;
|
||||
giftBoxPadding: margins(20px, 4px, 20px, 24px);
|
||||
giftBoxGiftSkip: point(10px, 8px);
|
||||
giftBoxGiftHeight: 136px;
|
||||
giftBoxPremiumIconSize: 64px;
|
||||
giftBoxPremiumIconTop: 10px;
|
||||
giftBoxPremiumTextTop: 56px;
|
||||
giftBoxButtonBottom: 12px;
|
||||
giftBoxButtonPadding: margins(8px, 4px, 8px, 4px);
|
||||
|
|
Loading…
Add table
Reference in a new issue