mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Add top reactors to paid reaction details.
This commit is contained in:
parent
9bb1fa8782
commit
afe30da9f4
14 changed files with 301 additions and 58 deletions
|
@ -2042,6 +2042,11 @@ auto MessageReactions::recent() const
|
|||
return _recent;
|
||||
}
|
||||
|
||||
auto MessageReactions::topPaid() const -> const std::vector<TopPaid> & {
|
||||
static const auto kEmpty = std::vector<TopPaid>();
|
||||
return _paid ? _paid->top : kEmpty;
|
||||
}
|
||||
|
||||
bool MessageReactions::empty() const {
|
||||
return _list.empty();
|
||||
}
|
||||
|
|
|
@ -379,6 +379,7 @@ public:
|
|||
[[nodiscard]] const std::vector<MessageReaction> &list() const;
|
||||
[[nodiscard]] auto recent() const
|
||||
-> const base::flat_map<ReactionId, std::vector<RecentReaction>> &;
|
||||
[[nodiscard]] const std::vector<TopPaid> &topPaid() const;
|
||||
[[nodiscard]] std::vector<ReactionId> chosen() const;
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
|
|
|
@ -2573,11 +2573,11 @@ const std::vector<Data::MessageReaction> &HistoryItem::reactions() const {
|
|||
|
||||
std::vector<Data::MessageReaction> HistoryItem::reactionsWithLocal() const {
|
||||
auto result = reactions();
|
||||
const auto i = ranges::find(
|
||||
result,
|
||||
Data::ReactionId::Paid(),
|
||||
&Data::MessageReaction::id);
|
||||
if (const auto local = _reactions ? _reactions->localPaidCount() : 0) {
|
||||
const auto i = ranges::find(
|
||||
result,
|
||||
Data::ReactionId::Paid(),
|
||||
&Data::MessageReaction::id);
|
||||
if (i != end(result)) {
|
||||
i->my = true;
|
||||
i->count += local;
|
||||
|
@ -2591,10 +2591,16 @@ std::vector<Data::MessageReaction> HistoryItem::reactionsWithLocal() const {
|
|||
.my = true,
|
||||
});
|
||||
}
|
||||
} else if (i != end(result) && i != begin(result)) {
|
||||
std::rotate(begin(result), i, i + 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int HistoryItem::reactionsPaidScheduled() const {
|
||||
return _reactions ? _reactions->scheduledPaid() : 0;
|
||||
}
|
||||
|
||||
bool HistoryItem::reactionsAreTags() const {
|
||||
return _flags & MessageFlag::ReactionsAreTags;
|
||||
}
|
||||
|
@ -2609,6 +2615,12 @@ auto HistoryItem::recentReactions() const
|
|||
return _reactions ? _reactions->recent() : kEmpty;
|
||||
}
|
||||
|
||||
auto HistoryItem::topPaidReactions() const
|
||||
-> const std::vector<Data::MessageReactionsTopPaid> & {
|
||||
static const auto kEmpty = std::vector<Data::MessageReactionsTopPaid>();
|
||||
return _reactions ? _reactions->topPaid() : kEmpty;
|
||||
}
|
||||
|
||||
bool HistoryItem::canViewReactions() const {
|
||||
return (_flags & MessageFlag::CanViewReactions)
|
||||
&& _reactions
|
||||
|
|
|
@ -57,6 +57,7 @@ struct RippleAnimation;
|
|||
namespace Data {
|
||||
struct MessagePosition;
|
||||
struct RecentReaction;
|
||||
struct MessageReactionsTopPaid;
|
||||
struct ReactionId;
|
||||
class Media;
|
||||
struct MessageReaction;
|
||||
|
@ -456,6 +457,9 @@ public:
|
|||
-> const base::flat_map<
|
||||
Data::ReactionId,
|
||||
std::vector<Data::RecentReaction>> &;
|
||||
[[nodiscard]] auto topPaidReactions() const
|
||||
-> const std::vector<Data::MessageReactionsTopPaid> &;
|
||||
[[nodiscard]] int reactionsPaidScheduled() const;
|
||||
[[nodiscard]] bool canViewReactions() const;
|
||||
[[nodiscard]] std::vector<Data::ReactionId> chosenReactions() const;
|
||||
[[nodiscard]] Data::ReactionId lookupUnreadReaction(
|
||||
|
|
|
@ -55,6 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "base/unixtime.h"
|
||||
#include "base/call_delayed.h"
|
||||
#include "data/business/data_shortcut_messages.h"
|
||||
#include "data/components/credits.h"
|
||||
#include "data/components/scheduled_messages.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
#include "data/notify/data_notify_settings.h"
|
||||
|
@ -869,6 +870,11 @@ HistoryWidget::HistoryWidget(
|
|||
}
|
||||
if (flags & PeerUpdateFlag::FullInfo) {
|
||||
fullInfoUpdated();
|
||||
if (const auto channel = _peer ? _peer->asChannel() : nullptr) {
|
||||
if (channel->allowedReactions().paidEnabled) {
|
||||
session().credits().load();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ struct InlineList::Button {
|
|||
int textWidth = 0;
|
||||
int count = 0;
|
||||
bool chosen = false;
|
||||
bool paid = false;
|
||||
bool tag = false;
|
||||
};
|
||||
|
||||
|
@ -180,7 +181,7 @@ void InlineList::layoutButtons() {
|
|||
}
|
||||
|
||||
InlineList::Button InlineList::prepareButtonWithId(const ReactionId &id) {
|
||||
auto result = Button{ .id = id };
|
||||
auto result = Button{ .id = id, .paid = id.paid()};
|
||||
if (const auto customId = id.custom()) {
|
||||
result.custom = _owner->owner().customEmojiManager().create(
|
||||
customId,
|
||||
|
@ -421,14 +422,18 @@ void InlineList::paint(
|
|||
} else if (!bubbleReady) {
|
||||
opacity = bubbleProgress;
|
||||
}
|
||||
color = stm->msgFileBg->c;
|
||||
color = button.paid
|
||||
? st->creditsBg3()->c
|
||||
: stm->msgFileBg->c;
|
||||
} else {
|
||||
if (!bubbleReady) {
|
||||
opacity = bubbleProgress;
|
||||
}
|
||||
color = (chosen
|
||||
? st->msgServiceFg()
|
||||
: st->msgServiceBg())->c;
|
||||
color = (!chosen
|
||||
? st->msgServiceBg()
|
||||
: button.paid
|
||||
? st->creditsBg2()
|
||||
: st->msgServiceFg())->c;
|
||||
}
|
||||
|
||||
const auto fill = geometry.marginsAdded({
|
||||
|
@ -451,7 +456,7 @@ void InlineList::paint(
|
|||
? QPen(AdaptChosenServiceFg(st->msgServiceBg()->c))
|
||||
: st->msgServiceFg())
|
||||
: !chosen
|
||||
? stm->msgServiceFg
|
||||
? (button.paid ? st->creditsFg() : stm->msgServiceFg)
|
||||
: context.outbg
|
||||
? (context.selected()
|
||||
? st->historyFileOutIconFgSelected()
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/send_credits_box.h" // CreditsEmojiSmall.
|
||||
#include "core/ui_integration.h" // MarkedTextContext.
|
||||
#include "data/components/credits.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
|
@ -27,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/layers/show.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/dynamic_thumbnails.h"
|
||||
|
||||
namespace Payments {
|
||||
namespace {
|
||||
|
@ -167,10 +169,26 @@ void ShowPaidReactionDetails(
|
|||
};
|
||||
});
|
||||
};
|
||||
auto top = std::vector<Ui::PaidReactionTop>();
|
||||
const auto &topPaid = item->topPaidReactions();
|
||||
top.reserve(topPaid.size());
|
||||
for (const auto &entry : topPaid) {
|
||||
if (!entry.top) {
|
||||
continue;
|
||||
}
|
||||
top.push_back({
|
||||
.name = entry.peer->shortName(),
|
||||
.photo = Ui::MakeUserpicThumbnail(entry.peer),
|
||||
.count = int(entry.count),
|
||||
});
|
||||
}
|
||||
ranges::sort(top, ranges::greater(), &Ui::PaidReactionTop::count);
|
||||
|
||||
state->selectBox = show->show(Ui::MakePaidReactionBox({
|
||||
.min = min,
|
||||
.max = max,
|
||||
.chosen = chosen,
|
||||
.top = std::move(top),
|
||||
.channel = item->history()->peer->name(),
|
||||
.submit = std::move(submitText),
|
||||
.balanceValue = session->credits().balanceValue(),
|
||||
|
|
|
@ -8,10 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "payments/ui/payments_reaction_box.h"
|
||||
|
||||
#include "lang/lang_keys.h"
|
||||
#include "ui/boxes/boost_box.h" // MakeBoostFeaturesBadge.
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/continuous_sliders.h"
|
||||
#include "ui/dynamic_image.h"
|
||||
#include "ui/painter.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_credits.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_premium.h"
|
||||
|
@ -27,6 +31,8 @@ namespace Settings {
|
|||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMaxTopPaidShown = 3;
|
||||
|
||||
void PaidReactionSlider(
|
||||
not_null<VerticalLayout*> container,
|
||||
int min,
|
||||
|
@ -35,9 +41,9 @@ void PaidReactionSlider(
|
|||
Fn<void(int)> changed) {
|
||||
const auto top = st::boxTitleClose.height + st::creditsHistoryRightSkip;
|
||||
const auto slider = container->add(
|
||||
object_ptr<MediaSlider>(container, st::settingsScale),
|
||||
object_ptr<MediaSlider>(container, st::paidReactSlider),
|
||||
st::boxRowPadding + QMargins(0, top, 0, 0));
|
||||
slider->resize(slider->width(), st::settingsScale.seekSize.height());
|
||||
slider->resize(slider->width(), st::paidReactSlider.seekSize.height());
|
||||
slider->setPseudoDiscrete(
|
||||
max + 1 - min,
|
||||
[=](int index) { return min + index; },
|
||||
|
@ -46,13 +52,145 @@ void PaidReactionSlider(
|
|||
changed);
|
||||
}
|
||||
|
||||
[[nodiscard]] QImage GenerateBadgeImage(int count) {
|
||||
const auto text = Lang::FormatCountDecimal(count);
|
||||
const auto length = st::chatSimilarBadgeFont->width(text);
|
||||
const auto contents = length
|
||||
+ st::chatSimilarLockedIcon.width();
|
||||
const auto badge = QRect(
|
||||
st::chatSimilarBadgePadding.left(),
|
||||
st::chatSimilarBadgePadding.top(),
|
||||
contents,
|
||||
st::chatSimilarBadgeFont->height);
|
||||
const auto rect = badge.marginsAdded(st::chatSimilarBadgePadding);
|
||||
|
||||
auto result = QImage(
|
||||
rect.size() * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
result.fill(Qt::transparent);
|
||||
auto q = QPainter(&result);
|
||||
|
||||
const auto &font = st::chatSimilarBadgeFont;
|
||||
const auto textTop = badge.y() + font->ascent;
|
||||
const auto icon = &st::chatSimilarLockedIcon;
|
||||
const auto position = st::chatSimilarLockedIconPosition;
|
||||
|
||||
auto hq = PainterHighQualityEnabler(q);
|
||||
q.setBrush(st::creditsBg3);
|
||||
q.setPen(Qt::NoPen);
|
||||
const auto radius = rect.height() / 2.;
|
||||
q.drawRoundedRect(rect, radius, radius);
|
||||
|
||||
auto textLeft = 0;
|
||||
if (icon) {
|
||||
icon->paint(
|
||||
q,
|
||||
badge.x() + position.x(),
|
||||
badge.y() + position.y(),
|
||||
rect.width());
|
||||
textLeft += position.x() + icon->width();
|
||||
}
|
||||
|
||||
q.setFont(font);
|
||||
q.setPen(st::premiumButtonFg);
|
||||
q.drawText(textLeft, textTop, text);
|
||||
q.end();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> MakeTopReactor(
|
||||
not_null<QWidget*> parent,
|
||||
const PaidReactionTop &data) {
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(parent);
|
||||
result->show();
|
||||
|
||||
struct State {
|
||||
QImage badge;
|
||||
Ui::Text::String name;
|
||||
};
|
||||
const auto state = result->lifetime().make_state<State>();
|
||||
state->name.setText(st::defaultTextStyle, data.name);
|
||||
|
||||
const auto count = data.count;
|
||||
const auto photo = data.photo;
|
||||
photo->subscribeToUpdates([=] {
|
||||
result->update();
|
||||
});
|
||||
style::PaletteChanged(
|
||||
) | rpl::start_with_next([=] {
|
||||
state->badge = QImage();
|
||||
}, result->lifetime());
|
||||
result->paintRequest() | rpl::start_with_next([=] {
|
||||
auto p = Painter(result);
|
||||
const auto left = (result->width() - st::paidReactTopUserpic) / 2;
|
||||
p.drawImage(left, 0, photo->image(st::paidReactTopUserpic));
|
||||
|
||||
if (state->badge.isNull()) {
|
||||
state->badge = GenerateBadgeImage(count);
|
||||
}
|
||||
const auto bwidth = state->badge.width()
|
||||
/ state->badge.devicePixelRatio();
|
||||
p.drawImage(
|
||||
(result->width() - bwidth) / 2,
|
||||
st::paidReactTopBadgeSkip,
|
||||
state->badge);
|
||||
|
||||
p.setPen(st::windowFg);
|
||||
const auto skip = st::normalFont->spacew;
|
||||
const auto nameTop = st::paidReactTopNameSkip;
|
||||
const auto available = result->width() - skip * 2;
|
||||
state->name.draw(p, skip, nameTop, available, style::al_top);
|
||||
}, result->lifetime());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FillTopReactors(
|
||||
not_null<VerticalLayout*> container,
|
||||
std::vector<PaidReactionTop> top) {
|
||||
container->add(
|
||||
MakeBoostFeaturesBadge(
|
||||
container,
|
||||
tr::lng_paid_react_top_title(),
|
||||
[](QRect) { return st::creditsBg3->b; }),
|
||||
st::boxRowPadding + st::paidReactTopTitleMargin);
|
||||
|
||||
const auto height = st::paidReactTopNameSkip + st::normalFont->height;
|
||||
const auto wrap = container->add(
|
||||
object_ptr<Ui::FixedHeightWidget>(container, height),
|
||||
st::paidReactTopMargin);
|
||||
struct State {
|
||||
std::vector<not_null<Ui::RpWidget*>> widgets;
|
||||
};
|
||||
const auto state = wrap->lifetime().make_state<State>();
|
||||
|
||||
const auto topCount = std::min(int(top.size()), kMaxTopPaidShown);
|
||||
for (auto i = 0; i != topCount; ++i) {
|
||||
state->widgets.push_back(MakeTopReactor(wrap, top[i]));
|
||||
}
|
||||
|
||||
wrap->widthValue() | rpl::start_with_next([=](int width) {
|
||||
const auto single = width / 4;
|
||||
if (single <= st::paidReactTopUserpic) {
|
||||
return;
|
||||
}
|
||||
auto left = (width - single * topCount) / 2;
|
||||
for (const auto widget : state->widgets) {
|
||||
widget->setGeometry(left, 0, single, height);
|
||||
left += single;
|
||||
}
|
||||
}, wrap->lifetime());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void PaidReactionsBox(
|
||||
not_null<GenericBox*> box,
|
||||
PaidReactionBoxArgs &&args) {
|
||||
box->setWidth(st::boxWideWidth);
|
||||
box->setStyle(st::boostBox);
|
||||
box->setStyle(st::paidReactBox);
|
||||
box->setNoContentMargin(true);
|
||||
|
||||
struct State {
|
||||
|
@ -77,7 +215,7 @@ void PaidReactionsBox(
|
|||
box,
|
||||
tr::lng_paid_react_title(),
|
||||
st::boostCenteredTitle),
|
||||
st::boxRowPadding + QMargins(0, st::boostTitleSkip, 0, 0));
|
||||
st::boxRowPadding + QMargins(0, st::paidReactTitleSkip, 0, 0));
|
||||
box->addRow(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
box,
|
||||
|
@ -87,7 +225,11 @@ void PaidReactionsBox(
|
|||
Text::RichLangValue),
|
||||
st::boostText),
|
||||
(st::boxRowPadding
|
||||
+ QMargins(0, st::boostTextSkip, 0, st::boostBottomSkip)));
|
||||
+ QMargins(0, st::lineWidth, 0, st::boostBottomSkip)));
|
||||
|
||||
if (!args.top.empty()) {
|
||||
FillTopReactors(box->verticalLayout(), std::move(args.top));
|
||||
}
|
||||
|
||||
const auto button = box->addButton(rpl::single(QString()), [=] {
|
||||
args.send(state->chosen.current());
|
||||
|
@ -117,7 +259,7 @@ void PaidReactionsBox(
|
|||
|
||||
box->widthValue(
|
||||
) | rpl::start_with_next([=](int width) {
|
||||
const auto &padding = st::boostBox.buttonPadding;
|
||||
const auto &padding = st::paidReactBox.buttonPadding;
|
||||
button->resizeToWidth(width
|
||||
- padding.left()
|
||||
- padding.right());
|
||||
|
|
|
@ -13,17 +13,26 @@ namespace Ui {
|
|||
|
||||
class BoxContent;
|
||||
class GenericBox;
|
||||
class DynamicImage;
|
||||
|
||||
struct TextWithContext {
|
||||
TextWithEntities text;
|
||||
std::any context;
|
||||
};
|
||||
|
||||
struct PaidReactionTop {
|
||||
QString name;
|
||||
std::shared_ptr<DynamicImage> photo;
|
||||
int count = 0;
|
||||
};
|
||||
|
||||
struct PaidReactionBoxArgs {
|
||||
int min = 0;
|
||||
int max = 0;
|
||||
int chosen = 0;
|
||||
|
||||
std::vector<PaidReactionTop> top;
|
||||
|
||||
QString channel;
|
||||
Fn<rpl::producer<TextWithContext>(rpl::producer<int> amount)> submit;
|
||||
rpl::producer<uint64> balanceValue;
|
||||
|
|
|
@ -111,48 +111,13 @@ namespace {
|
|||
[[nodiscard]] object_ptr<Ui::FlatLabel> MakeFeaturesBadge(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QString> text) {
|
||||
auto result = object_ptr<Ui::FlatLabel>(
|
||||
parent,
|
||||
std::move(text),
|
||||
st::boostLevelBadge);
|
||||
const auto label = result.data();
|
||||
|
||||
label->show();
|
||||
label->paintRequest() | rpl::start_with_next([=] {
|
||||
const auto size = label->textMaxWidth();
|
||||
const auto rect = QRect(
|
||||
(label->width() - size) / 2,
|
||||
st::boostLevelBadge.margin.top(),
|
||||
size,
|
||||
st::boostLevelBadge.style.font->height
|
||||
).marginsAdded(st::boostLevelBadge.margin);
|
||||
auto p = QPainter(label);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
return MakeBoostFeaturesBadge(parent, std::move(text), [](QRect rect) {
|
||||
auto gradient = QLinearGradient(
|
||||
rect.topLeft(),
|
||||
rect.topRight());
|
||||
gradient.setStops(Ui::Premium::GiftGradientStops());
|
||||
p.setBrush(gradient);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(rect, rect.height() / 2., rect.height() / 2.);
|
||||
|
||||
const auto &lineFg = st::windowBgRipple;
|
||||
const auto line = st::boostLevelBadgeLine;
|
||||
const auto top = st::boostLevelBadge.margin.top()
|
||||
+ ((st::boostLevelBadge.style.font->height - line) / 2);
|
||||
const auto left = 0;
|
||||
const auto skip = st::boostLevelBadgeSkip;
|
||||
if (const auto right = rect.x() - skip; right > left) {
|
||||
p.fillRect(left, top, right - left, line, lineFg);
|
||||
}
|
||||
const auto right = label->width();
|
||||
if (const auto left = rect.x() + rect.width() + skip
|
||||
; left < right) {
|
||||
p.fillRect(left, top, right - left, line, lineFg);
|
||||
}
|
||||
}, label->lifetime());
|
||||
|
||||
return result;
|
||||
return QBrush(gradient);
|
||||
});
|
||||
}
|
||||
|
||||
void AddFeaturesList(
|
||||
|
@ -885,4 +850,48 @@ void FillBoostLimit(
|
|||
limitLinePadding);
|
||||
}
|
||||
|
||||
object_ptr<Ui::FlatLabel> MakeBoostFeaturesBadge(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QString> text,
|
||||
Fn<QBrush(QRect)> bg) {
|
||||
auto result = object_ptr<Ui::FlatLabel>(
|
||||
parent,
|
||||
std::move(text),
|
||||
st::boostLevelBadge);
|
||||
const auto label = result.data();
|
||||
|
||||
label->show();
|
||||
label->paintRequest() | rpl::start_with_next([=] {
|
||||
const auto size = label->textMaxWidth();
|
||||
const auto rect = QRect(
|
||||
(label->width() - size) / 2,
|
||||
st::boostLevelBadge.margin.top(),
|
||||
size,
|
||||
st::boostLevelBadge.style.font->height
|
||||
).marginsAdded(st::boostLevelBadge.margin);
|
||||
auto p = QPainter(label);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setBrush(bg(rect));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(rect, rect.height() / 2., rect.height() / 2.);
|
||||
|
||||
const auto &lineFg = st::windowBgRipple;
|
||||
const auto line = st::boostLevelBadgeLine;
|
||||
const auto top = st::boostLevelBadge.margin.top()
|
||||
+ ((st::boostLevelBadge.style.font->height - line) / 2);
|
||||
const auto left = 0;
|
||||
const auto skip = st::boostLevelBadgeSkip;
|
||||
if (const auto right = rect.x() - skip; right > left) {
|
||||
p.fillRect(left, top, right - left, line, lineFg);
|
||||
}
|
||||
const auto right = label->width();
|
||||
if (const auto left = rect.x() + rect.width() + skip
|
||||
; left < right) {
|
||||
p.fillRect(left, top, right - left, line, lineFg);
|
||||
}
|
||||
}, label->lifetime());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -17,6 +17,7 @@ class Show;
|
|||
class RpWidget;
|
||||
class GenericBox;
|
||||
class VerticalLayout;
|
||||
class FlatLabel;
|
||||
|
||||
struct BoostCounters {
|
||||
int level = 0;
|
||||
|
@ -129,4 +130,9 @@ void FillBoostLimit(
|
|||
rpl::producer<BoostCounters> data,
|
||||
style::margins limitLinePadding);
|
||||
|
||||
[[nodiscard]] object_ptr<Ui::FlatLabel> MakeBoostFeaturesBadge(
|
||||
not_null<QWidget*> parent,
|
||||
rpl::producer<QString> text,
|
||||
Fn<QBrush(QRect)> bg);
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
@ -46,7 +46,7 @@ creditsBoxButtonLabel: FlatLabel(defaultFlatLabel) {
|
|||
}
|
||||
|
||||
starIconSmall: icon{{ "payments/small_star", windowFg }};
|
||||
starIconSmallPadding: margins(0px, -2px, 0px, 0px);
|
||||
starIconSmallPadding: margins(0px, -3px, 0px, 0px);
|
||||
|
||||
creditsHistoryEntryTypeAds: icon {{ "folders/folders_channels", premiumButtonFg }};
|
||||
|
||||
|
|
|
@ -340,13 +340,13 @@ showOrBox: Box(boostBox) {
|
|||
|
||||
boostBoxMaxHeight: 512px;
|
||||
boostLevelBadge: FlatLabel(defaultFlatLabel) {
|
||||
margin: margins(12px, 4px, 12px, 4px);
|
||||
margin: margins(12px, 4px, 12px, 5px);
|
||||
style: semiboldTextStyle;
|
||||
textFg: premiumButtonFg;
|
||||
align: align(top);
|
||||
}
|
||||
boostLevelBadgePadding: margins(30px, 12px, 32px, 12px);
|
||||
boostLevelBadgeSkip: 8px;
|
||||
boostLevelBadgeSkip: 12px;
|
||||
boostLevelBadgeLine: 1px;
|
||||
|
||||
boostFeatureLabel: FlatLabel(defaultFlatLabel) {
|
||||
|
@ -365,3 +365,29 @@ boostFeatureName: icon{{ "settings/premium/features/feature_color_names", window
|
|||
boostFeatureStories: icon{{ "settings/premium/features/feature_stories", windowBgActive }};
|
||||
boostFeatureTranscribe: icon{{ "settings/premium/features/feature_voice", windowBgActive }};
|
||||
boostFeatureOffSponsored: icon{{ "settings/premium/features/feature_off_sponsored", windowBgActive }};
|
||||
|
||||
paidReactTitleSkip: 23px;
|
||||
paidReactTopTitleMargin: margins(10px, 26px, 10px, 12px);
|
||||
paidReactTopMargin: margins(0px, 12px, 0px, 11px);
|
||||
paidReactTopUserpic: 42px;
|
||||
paidReactTopNameSkip: 47px;
|
||||
paidReactTopBadgeSkip: 32px;
|
||||
paidReactSlider: MediaSlider(defaultContinuousSlider) {
|
||||
activeFg: creditsBg3;
|
||||
inactiveFg: creditsBg2;
|
||||
activeFgOver: creditsBg3;
|
||||
inactiveFgOver: creditsBg2;
|
||||
activeFgDisabled: creditsBg3;
|
||||
inactiveFgDisabled: creditsBg2;
|
||||
width: 6px;
|
||||
seekSize: size(16px, 16px);
|
||||
}
|
||||
paidReactBox: Box(boostBox) {
|
||||
buttonPadding: margins(22px, 22px, 22px, 22px);
|
||||
buttonHeight: 42px;
|
||||
button: RoundButton(defaultActiveButton) {
|
||||
height: 42px;
|
||||
textTop: 12px;
|
||||
font: font(13px semibold);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 8db5d1aa533334c75ed2598ecf3607768ae9b418
|
||||
Subproject commit a5b1266a8c340ed916466a83cbbc5793471c2438
|
Loading…
Add table
Reference in a new issue