diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index e500f0cb8..be8a9d21e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2455,6 +2455,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_credits_box_history_entry_gift_examples" = "Examples"; "lng_credits_box_history_entry_ads" = "Ads Platform"; "lng_credits_box_history_entry_premium_bot" = "Stars Top-Up"; +"lng_credits_box_history_entry_api" = "Paid Broadcast"; +"lng_credits_box_history_entry_floodskip_about#one" = "{count} Message"; +"lng_credits_box_history_entry_floodskip_about#other" = "{count} Messages"; +"lng_credits_box_history_entry_floodskip_row" = "Messages"; "lng_credits_box_history_entry_via_premium_bot" = "Premium Bot"; "lng_credits_box_history_entry_id" = "Transaction ID"; "lng_credits_box_history_entry_id_copied" = "Transaction ID copied to clipboard."; diff --git a/Telegram/SourceFiles/api/api_credits.cpp b/Telegram/SourceFiles/api/api_credits.cpp index 8f67c0335..0453cfc4f 100644 --- a/Telegram/SourceFiles/api/api_credits.cpp +++ b/Telegram/SourceFiles/api/api_credits.cpp @@ -115,6 +115,7 @@ constexpr auto kTransactionsLimit = 100; .convertStars = int(stargift ? stargift->data().vconvert_stars().v : 0), + .floodSkip = int(tl.data().vfloodskip_number().value_or(0)), .converted = stargift && incoming, .reaction = tl.data().is_reaction(), .refunded = tl.data().is_refund(), diff --git a/Telegram/SourceFiles/boxes/gift_premium_box.cpp b/Telegram/SourceFiles/boxes/gift_premium_box.cpp index 3e792bbb6..e9e126b90 100644 --- a/Telegram/SourceFiles/boxes/gift_premium_box.cpp +++ b/Telegram/SourceFiles/boxes/gift_premium_box.cpp @@ -1262,6 +1262,14 @@ void AddCreditsHistoryEntryTable( std::move(label), st::giveawayGiftCodeValueMargin); } + if (entry.floodSkip) { + AddTableRow( + table, + tr::lng_credits_box_history_entry_floodskip_row(), + rpl::single( + Ui::Text::WithEntities( + Lang::FormatCountDecimal(entry.floodSkip)))); + } if (!entry.date.isNull()) { AddTableRow( table, diff --git a/Telegram/SourceFiles/data/data_credits.h b/Telegram/SourceFiles/data/data_credits.h index 71e531001..3b99031f8 100644 --- a/Telegram/SourceFiles/data/data_credits.h +++ b/Telegram/SourceFiles/data/data_credits.h @@ -69,6 +69,7 @@ struct CreditsHistoryEntry final { int limitedCount = 0; int limitedLeft = 0; int convertStars = 0; + int floodSkip = 0; bool converted = false; bool anonymous = false; bool savedToProfile = false; diff --git a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp index 0dc51cb07..962096502 100644 --- a/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp +++ b/Telegram/SourceFiles/info/statistics/info_statistics_list_controllers.cpp @@ -854,7 +854,12 @@ void CreditsRow::init() { setSkipPeerBadge(true); PeerListRow::setCustomStatus( langDateTime(_entry.date) - + (_entry.refunded + + (_entry.floodSkip + ? (joiner + tr::lng_credits_box_history_entry_floodskip_about( + tr::now, + lt_count_decimal, + _entry.floodSkip)) + : _entry.refunded ? (joiner + tr::lng_channel_earn_history_return(tr::now)) : _entry.pending ? (joiner + tr::lng_channel_earn_history_pending(tr::now)) @@ -931,7 +936,7 @@ QSize CreditsRow::rightActionSize() const { _rowHeight); } else if (_subscription || _entry) { return QSize( - _rightText.maxWidth() + st::boxRowPadding.right(), + _rightText.maxWidth() + st::boxRowPadding.right() / 2, _rowHeight); } else if (!_entry && !_subscription) { return QSize(); diff --git a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp index c855fac0d..97b6a744c 100644 --- a/Telegram/SourceFiles/ui/effects/credits_graphics.cpp +++ b/Telegram/SourceFiles/ui/effects/credits_graphics.cpp @@ -216,6 +216,8 @@ PaintRoundImageCallback GenerateCreditsPaintUserpicCallback( } const auto bg = [&]() -> EmptyUserpic::BgColors { switch (entry.peerType) { + case Data::CreditsHistoryEntry::PeerType::API: + return { st::historyPeer2UserpicBg, st::historyPeer2UserpicBg2 }; case Data::CreditsHistoryEntry::PeerType::Peer: return EmptyUserpic::UserpicColor(0); case Data::CreditsHistoryEntry::PeerType::AppStore: @@ -237,6 +239,62 @@ PaintRoundImageCallback GenerateCreditsPaintUserpicCallback( Unexpected("Unknown peer type."); }(); const auto userpic = std::make_shared(bg, QString()); + if (entry.peerType == PeerType::API) { + const auto svg = std::make_shared(Ui::Premium::Svg()); + const auto image = std::make_shared(); + return [=](Painter &p, int x, int y, int outer, int size) mutable { + userpic->paintCircle(p, x, y, outer, size); + if (image->isNull()) { + *image = QImage( + Size(size) * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); + image->setDevicePixelRatio(style::DevicePixelRatio()); + image->fill(Qt::transparent); + constexpr auto kSize = 126.; + constexpr auto kBubbleRatio = kSize / ((kSize - 70) / 2.); + const auto rect = QRectF(0, 0, size, size) + - Margins(size / kBubbleRatio); + + auto q = QPainter(image.get()); + const auto hq = PainterHighQualityEnabler(q); + q.setPen(Qt::NoPen); + q.setBrush(st::historyPeerUserpicFg); + q.drawEllipse(rect); + constexpr auto kTailX1 = 4; + constexpr auto kTailY1 = 8; + constexpr auto kTailX2 = 2; + constexpr auto kTailY2 = 0; + constexpr auto kTailX3 = 9; + constexpr auto kTailY3 = 4; + auto path = QPainterPath(); + path.moveTo( + st::lineWidth * kTailX1, + rect.height() - st::lineWidth * kTailY1); + path.lineTo( + st::lineWidth * kTailX2, + rect.height() - st::lineWidth * kTailY2); + path.lineTo( + st::lineWidth * kTailX3, + rect.height() - st::lineWidth * kTailY3); + path.translate(rect.x(), rect.y()); + q.strokePath( + path, + QPen( + st::historyPeerUserpicFg, + st::lineWidth * 2, + Qt::SolidLine, + Qt::RoundCap, + Qt::RoundJoin)); + q.fillPath(path, st::historyPeerUserpicFg); + q.setCompositionMode(QPainter::CompositionMode_Clear); + constexpr auto kStarRatio = kSize / ((kSize - 44) / 2.); + svg->render( + &q, + QRectF(0, 0, size, size) - Margins(size / kStarRatio)); + } + p.drawImage(x, y, *image); + }; + } return [=](Painter &p, int x, int y, int outerWidth, int size) mutable { userpic->paintCircle(p, x, y, outerWidth, size); const auto rect = QRect(x, y, size, size); @@ -487,7 +545,9 @@ Fn)> PaintPreviewCallback( } TextWithEntities GenerateEntryName(const Data::CreditsHistoryEntry &entry) { - return (entry.reaction + return (entry.floodSkip + ? tr::lng_credits_box_history_entry_api + : entry.reaction ? tr::lng_credits_box_history_entry_reaction_name : entry.bareGiveawayMsgId ? tr::lng_credits_box_history_entry_giveaway_name