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