From 6ac13b7f8004ae06c7bff5907a47901bbd012a3c Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 27 Aug 2024 10:05:36 +0300 Subject: [PATCH] Added button for credits giveaway to box for giveaway creation. --- .../boosts/create_giveaway_box.cpp | 63 +++++++++++++- .../boosts/giveaway/giveaway_type_row.cpp | 83 +++++++++++++++++-- .../boosts/giveaway/giveaway_type_row.h | 4 + 3 files changed, 142 insertions(+), 8 deletions(-) diff --git a/Telegram/SourceFiles/info/channel_statistics/boosts/create_giveaway_box.cpp b/Telegram/SourceFiles/info/channel_statistics/boosts/create_giveaway_box.cpp index 58019ce84..cb93283ce 100644 --- a/Telegram/SourceFiles/info/channel_statistics/boosts/create_giveaway_box.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/boosts/create_giveaway_box.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "info/channel_statistics/boosts/create_giveaway_box.h" +#include "api/api_credits.h" #include "api/api_premium.h" #include "base/call_delayed.h" #include "base/unixtime.h" @@ -249,10 +250,11 @@ void CreateGiveawayBox( using GiveawayType = Giveaway::GiveawayTypeRow::Type; using GiveawayGroup = Ui::RadioenumGroup; struct State final { - State(not_null p) : apiOptions(p) { + State(not_null p) : apiOptions(p), apiCreditsOptions(p) { } Api::PremiumGiftCodeOptions apiOptions; + Api::CreditsGiveawayOptions apiCreditsOptions; rpl::lifetime lifetimeApi; std::vector> selectedToAward; @@ -344,6 +346,54 @@ void CreateGiveawayBox( state->typeValue.force_assign(GiveawayType::Random); }); } + const auto creditsTypeWrap = contentWrap->entity()->add( + object_ptr(contentWrap->entity())); + const auto fillCreditsTypeWrap = [=] { + if (state->apiCreditsOptions.options().empty()) { + return; + } + constexpr auto kColorIndexCredits = int(1); + constexpr auto kOutdated = 1735689600; + + auto badge = [&] { + if (base::unixtime::now() > kOutdated) { + return QImage(); + } + const auto badge = Ui::CreateChild>( + creditsTypeWrap, + object_ptr( + creditsTypeWrap, + tr::lng_premium_summary_new_badge(tr::now), + st::settingsPremiumNewBadge), + st::settingsPremiumNewBadgePadding); + badge->setAttribute(Qt::WA_TransparentForMouseEvents); + badge->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(badge); + auto hq = PainterHighQualityEnabler(p); + p.setPen(Qt::NoPen); + p.setBrush(st::windowBgActive); + const auto r = st::settingsPremiumNewBadgePadding.left(); + p.drawRoundedRect(badge->rect(), r, r); + }, badge->lifetime()); + badge->show(); + auto result = Ui::GrabWidget(badge).toImage(); + badge->hide(); + return result; + }(); + + const auto row = creditsTypeWrap->add( + object_ptr( + box, + GiveawayType::Credits, + kColorIndexCredits, + tr::lng_credits_summary_title(), + tr::lng_giveaway_create_subtitle(), + std::move(badge))); + row->addRadio(typeGroup); + row->setClickedCallback([=] { + state->typeValue.force_assign(GiveawayType::Credits); + }); + }; if (!prepaid) { const auto row = contentWrap->entity()->add( object_ptr( @@ -1129,10 +1179,19 @@ void CreateGiveawayBox( if (!prepaid) { state->chosenMonths = state->apiOptions.monthsFromPreset(0); } + fillCreditsTypeWrap(); rebuildListOptions(state->typeValue.current(), 1); contentWrap->toggle(true, anim::type::instant); contentWrap->resizeToWidth(box->width()); }; + const auto receivedOptions = [=] { + state->lifetimeApi.destroy(); + state->lifetimeApi = state->apiCreditsOptions.request( + ) | rpl::start_with_error_done([=](const QString &error) { + box->uiShow()->showToast(error); + box->closeBox(); + }, done); + }; if (prepaid) { return done(); } @@ -1140,6 +1199,6 @@ void CreateGiveawayBox( ) | rpl::start_with_error_done([=](const QString &error) { box->uiShow()->showToast(error); box->closeBox(); - }, done); + }, receivedOptions); }, box->lifetime()); } diff --git a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.cpp b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.cpp index 2cfed79a6..56fa79c3d 100644 --- a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.cpp +++ b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.cpp @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/channel_statistics/boosts/giveaway/giveaway_type_row.h" #include "lang/lang_keys.h" +#include "ui/effects/premium_graphics.h" #include "ui/painter.h" #include "ui/rect.h" #include "ui/text/text_options.h" @@ -16,7 +17,67 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_giveaway.h" #include "styles/style_statistics.h" +#include + namespace Giveaway { +namespace { + +[[nodiscard]] QImage CreditsCustomUserpic(int photoSize) { + auto svg = QSvgRenderer(Ui::Premium::Svg()); + auto result = QImage( + Size(photoSize) * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + result.fill(Qt::transparent); + result.setDevicePixelRatio(style::DevicePixelRatio()); + + constexpr auto kPoints = uint(16); + constexpr auto kAngleStep = 2. * M_PI / kPoints; + constexpr auto kOutlineWidth = 1.6; + constexpr auto kStarShift = 3.8; + const auto userpicRect = Rect(Size(photoSize)); + const auto starRect = userpicRect - Margins(userpicRect.width() / 4.); + const auto starSize = starRect.size(); + const auto drawSingle = [&](QPainter &q) { + const auto s = style::ConvertFloatScale(kOutlineWidth); + q.save(); + q.setCompositionMode(QPainter::CompositionMode_Clear); + for (auto i = 0; i < kPoints; ++i) { + const auto angle = i * kAngleStep; + const auto x = s * std::cos(angle); + const auto y = s * std::sin(angle); + svg.render(&q, QRectF(QPointF(x, y), starSize)); + } + q.setCompositionMode(QPainter::CompositionMode_SourceOver); + svg.render(&q, Rect(starSize)); + q.restore(); + }; + { + auto p = QPainter(&result); + p.setPen(Qt::NoPen); + p.setBrush(st::lightButtonFg); + p.translate(starRect.topLeft()); + p.translate(style::ConvertFloatScale(kStarShift) / 2., 0); + drawSingle(p); + { + // Remove the previous star at bottom. + p.setCompositionMode(QPainter::CompositionMode_Clear); + p.save(); + p.resetTransform(); + p.fillRect( + userpicRect.x(), + userpicRect.y(), + userpicRect.width() / 2., + userpicRect.height(), + Qt::transparent); + p.restore(); + } + p.translate(-style::ConvertFloatScale(kStarShift), 0); + drawSingle(p); + } + return result; +} + +} // namespace constexpr auto kColorIndexSpecific = int(4); constexpr auto kColorIndexRandom = int(2); @@ -54,7 +115,9 @@ GiveawayTypeRow::GiveawayTypeRow( QImage badge) : RippleButton(parent, st::defaultRippleAnimation) , _type(type) -, _st((_type == Type::SpecificUsers || _type == Type::Random) +, _st((_type == Type::SpecificUsers + || _type == Type::Random + || _type == Type::Credits) ? st::giveawayTypeListItem : (_type == Type::Prepaid) ? st::boostsListBox.item @@ -63,6 +126,9 @@ GiveawayTypeRow::GiveawayTypeRow( Ui::EmptyUserpic::UserpicColor(Ui::EmptyUserpic::ColorIndex(colorIndex)), QString()) , _badge(std::move(badge)) { + if (_type == Type::Credits) { + _customUserpic = CreditsCustomUserpic(_st.photoSize); + } std::move( subtitle ) | rpl::start_with_next([=] (const QString &s) { @@ -89,7 +155,8 @@ void GiveawayTypeRow::paintEvent(QPaintEvent *e) { const auto isPrepaid = (_type == Type::Prepaid); const auto hasUserpic = (_type == Type::Random) || isSpecific - || isPrepaid; + || isPrepaid + || (!_customUserpic.isNull()); if (paintOver) { p.fillRect(e->rect(), _st.button.textBgOver); @@ -103,16 +170,20 @@ void GiveawayTypeRow::paintEvent(QPaintEvent *e) { outerWidth, _st.photoSize); - const auto &userpic = isSpecific - ? st::giveawayUserpicGroup - : st::giveawayUserpic; const auto userpicRect = QRect( _st.photoPosition - QPoint( isSpecific ? -st::giveawayUserpicSkip : 0, isSpecific ? 0 : st::giveawayUserpicSkip), Size(_st.photoSize)); - userpic.paintInCenter(p, userpicRect); + if (!_customUserpic.isNull()) { + p.drawImage(_st.photoPosition, _customUserpic); + } else { + const auto &userpic = isSpecific + ? st::giveawayUserpicGroup + : st::giveawayUserpic; + userpic.paintInCenter(p, userpicRect); + } } const auto namex = _st.namePosition.x(); diff --git a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.h b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.h index 6cf12411d..3b8efbdd6 100644 --- a/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.h +++ b/Telegram/SourceFiles/info/channel_statistics/boosts/giveaway/giveaway_type_row.h @@ -27,6 +27,8 @@ public: OnlyNewMembers, Prepaid, + + Credits, }; GiveawayTypeRow( @@ -58,6 +60,8 @@ private: Ui::Text::String _status; Ui::Text::String _name; + QImage _customUserpic; + QImage _badge; };