diff --git a/Telegram/Resources/animations/starref_link.tgs b/Telegram/Resources/animations/starref_link.tgs new file mode 100644 index 000000000..ea6300452 Binary files /dev/null and b/Telegram/Resources/animations/starref_link.tgs differ diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index f60061f99..e66d847b6 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -29,6 +29,7 @@ ../../animations/search.tgs ../../animations/noresults.tgs ../../animations/hello_status.tgs + ../../animations/starref_link.tgs ../../animations/dice/dice_idle.tgs ../../animations/dice/dart_idle.tgs diff --git a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp index d13a584ee..da870cf15 100644 --- a/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp +++ b/Telegram/SourceFiles/info/bot/starref/info_bot_starref_common.cpp @@ -9,7 +9,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "boxes/peers/replace_boost_box.h" // CreateUserpicsTransfer. +#include "chat_helpers/stickers_lottie.h" +#include "data/data_document.h" #include "data/data_session.h" +#include "history/view/media/history_view_sticker.h" +#include "history/view/media/history_view_sticker_player.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "settings/settings_common.h" @@ -52,6 +56,100 @@ void ConnectStarRef( }).send(); } +[[nodiscard]] object_ptr CreateLinkIcon( + not_null parent, + not_null bot, + int users) { + auto result = object_ptr(parent); + const auto raw = result.data(); + + struct State { + not_null icon; + std::shared_ptr media; + std::shared_ptr player; + int counterWidth = 0; + }; + const auto outerSide = st::starrefLinkThumbOuter; + const auto outerSkip = (outerSide - st::starrefLinkThumbInner) / 2; + const auto innerSide = (outerSide - 2 * outerSkip); + const auto add = st::starrefLinkCountAdd; + const auto outer = QSize(outerSide, outerSide + add); + const auto inner = QSize(innerSide, innerSide); + const auto state = raw->lifetime().make_state(State{ + .icon = ChatHelpers::GenerateLocalTgsSticker( + &bot->session(), + u"starref_link"_q), + }); + state->icon->overrideEmojiUsesTextColor(true); + state->media = state->icon->createMediaView(); + state->player = std::make_unique( + ChatHelpers::LottiePlayerFromDocument( + state->media.get(), + ChatHelpers::StickerLottieSize::MessageHistory, + inner, + Lottie::Quality::High)); + const auto player = state->player.get(); + player->setRepaintCallback([=] { raw->update(); }); + + const auto text = users + ? Lang::FormatCountToShort(users).string + : QString(); + const auto length = st::starrefLinkCountFont->width(text); + const auto contents = length + st::starrefLinkCountIcon.width(); + const auto delta = (outer.width() - contents) / 2; + const auto badge = QRect( + delta, + outer.height() - st::starrefLinkCountFont->height - st::lineWidth, + outer.width() - 2 * delta, + st::starrefLinkCountFont->height); + const auto badgeRect = badge.marginsAdded(st::starrefLinkCountPadding); + + raw->paintRequest() | rpl::start_with_next([=] { + auto p = QPainter(raw); + p.setPen(Qt::NoPen); + p.setBrush(st::windowBgActive); + + auto hq = PainterHighQualityEnabler(p); + + const auto left = (raw->width() - outer.width()) / 2; + p.drawEllipse(left, 0, outerSide, outerSide); + + if (!text.isEmpty()) { + const auto rect = badgeRect.translated(left, 0); + const auto textRect = badge.translated(left, 0); + const auto radius = st::starrefLinkCountFont->height / 2.; + p.setPen(st::historyPeerUserpicFg); + p.setBrush(st::historyPeer2UserpicBg2); + p.drawRoundedRect(rect, radius, radius); + + p.setFont(st::starrefLinkCountFont); + const auto shift = QPoint( + st::starrefLinkCountIcon.width(), + st::starrefLinkCountFont->ascent); + st::starrefLinkCountIcon.paint( + p, + textRect.topLeft() + st::starrefLinkCountIconPosition, + raw->width()); + p.drawText(textRect.topLeft() + shift, text); + } + if (player->ready()) { + const auto now = crl::now(); + const auto color = st::windowFgActive->c; + auto info = player->frame(inner, color, false, now, false); + p.drawImage( + QRect(QPoint(left + outerSkip, outerSkip), inner), + info.image); + if (info.index + 1 < player->framesCount()) { + player->markFrameShown(); + } + } + }, raw->lifetime()); + + raw->resize(outer); + + return result; +} + } // namespace QString FormatCommission(ushort commission) { @@ -225,11 +323,7 @@ object_ptr StarRefLinkBox( }); box->addRow( - CreateUserpicsTransfer( - box, - rpl::single(std::vector{ not_null(bot) }), - peer, - UserpicsTransferType::StarRefJoin), + CreateLinkIcon(box, bot, row.state.users), st::boxRowPadding + st::starrefJoinUserpicsPadding); box->addRow( object_ptr>( diff --git a/Telegram/SourceFiles/ui/effects/premium.style b/Telegram/SourceFiles/ui/effects/premium.style index b27cc61a3..39e527437 100644 --- a/Telegram/SourceFiles/ui/effects/premium.style +++ b/Telegram/SourceFiles/ui/effects/premium.style @@ -463,3 +463,10 @@ starrefBottomButtonLabelTop: 5px; starrefBottomButtonSublabelTop: 23px; starrefEndBulletSize: 6px; starrefEndBulletTop: 8px; +starrefLinkThumbOuter: 64px; +starrefLinkThumbInner: 48px; +starrefLinkCountAdd: 6px; +starrefLinkCountIcon: icon{{ "chat/mini_subscribers", historyPeerUserpicFg }}; +starrefLinkCountIconPosition: point(0px, 1px); +starrefLinkCountFont: font(10px bold); +starrefLinkCountPadding: margins(2px, 0px, 3px, 1px); \ No newline at end of file