From e4d920b1480f8c0b5f7be941bf79a7f25f26a7e5 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 9 Nov 2023 10:21:59 +0400 Subject: [PATCH] Show multiboost "x5" badge in boost box. --- Telegram/SourceFiles/ui/boxes/boost_box.cpp | 73 ++++++++++++++++++- Telegram/SourceFiles/ui/effects/premium.style | 6 ++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.cpp b/Telegram/SourceFiles/ui/boxes/boost_box.cpp index 68010c530..633cb3e1f 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/boost_box.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/layers/generic_box.h" #include "ui/text/text_utilities.h" #include "ui/widgets/buttons.h" +#include "ui/painter.h" #include "styles/style_giveaway.h" #include "styles/style_layers.h" #include "styles/style_premium.h" @@ -45,6 +46,69 @@ namespace { return data; } +[[nodiscard]] object_ptr MakeTitle( + not_null box, + rpl::producer title, + rpl::producer repeated) { + auto result = object_ptr(box); + + struct State { + not_null title; + not_null repeated; + }; + const auto notEmpty = [](const QString &text) { + return !text.isEmpty(); + }; + const auto state = box->lifetime().make_state(State{ + .title = Ui::CreateChild( + result.data(), + rpl::duplicate(title), + st::boostTitle), + .repeated = Ui::CreateChild( + result.data(), + rpl::duplicate(repeated) | rpl::filter(notEmpty), + st::boostTitleBadge), + }); + state->title->show(); + state->repeated->showOn(std::move(repeated) | rpl::map(notEmpty)); + + result->resize(result->width(), st::boostTitle.style.font->height); + + rpl::combine( + result->widthValue(), + rpl::duplicate(title), + state->repeated->shownValue(), + state->repeated->widthValue() + ) | rpl::start_with_next([=](int outer, auto&&, bool shown, int badge) { + const auto repeated = shown ? badge : 0; + const auto skip = st::boostTitleBadgeSkip; + const auto available = outer - repeated - skip; + const auto use = std::min(state->title->textMaxWidth(), available); + state->title->resizeToWidth(use); + const auto left = (outer - use - skip - repeated) / 2; + state->title->moveToLeft(left, 0); + const auto mleft = st::boostTitleBadge.margin.left(); + const auto mtop = st::boostTitleBadge.margin.top(); + state->repeated->moveToLeft(left + use + skip + mleft, mtop); + }, result->lifetime()); + + const auto badge = state->repeated; + badge->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(badge); + auto hq = PainterHighQualityEnabler(p); + const auto radius = std::min(badge->width(), badge->height()) / 2; + p.setPen(Qt::NoPen); + auto brush = QLinearGradient( + QPointF(badge->width(), badge->height()), + QPointF()); + brush.setStops(Ui::Premium::ButtonGradientStops()); + p.setBrush(brush); + p.drawRoundedRect(badge->rect(), radius, radius); + }, badge->lifetime()); + + return result; +} + } // namespace void StartFireworks(not_null parent) { @@ -111,6 +175,10 @@ void BoostBox( ? tr::lng_boost_channel_title_first() : tr::lng_boost_channel_title_more(); }) | rpl::flatten_latest(); + auto repeated = state->data.value( + ) | rpl::map([=](BoostCounters counters) { + return (counters.mine > 1) ? u"x%1"_q.arg(counters.mine) : u""_q; + }); auto text = state->data.value( ) | rpl::map([=](BoostCounters counters) { @@ -164,10 +232,7 @@ void BoostBox( }) | rpl::flatten_latest(); box->addRow( - object_ptr( - box, - std::move(title), - st::boostTitle), + MakeTitle(box, std::move(title), std::move(repeated)), st::boxRowPadding + QMargins(0, st::boostTitleSkip, 0, 0)); box->addRow( diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index 9c49a6c15..69c356610 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -252,6 +252,12 @@ boostTitle: FlatLabel(defaultFlatLabel) { font: font(17px semibold); } } +boostTitleBadge: FlatLabel(defaultFlatLabel) { + margin: margins(4px, 2px, 4px, 2px); + style: semiboldTextStyle; + textFg: premiumButtonFg; +} +boostTitleBadgeSkip: 6px; boostTextSkip: 5px; boostText: FlatLabel(defaultFlatLabel) { minWidth: 40px;