From 28d22d2332d01105be7ecba26f93bcd917825a91 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 4 Feb 2026 21:06:22 +0400 Subject: [PATCH] Display lottie on craft failure. --- .../Resources/animations/craft_failed.tgs | Bin 0 -> 6731 bytes .../icons/chat/filled_forge_fail.svg | 7 ------ .../Resources/qrc/telegram/animations.qrc | 1 + .../boxes/star_gift_craft_animation.cpp | 23 +++++++++++------- .../boxes/star_gift_craft_animation.h | 6 ++--- Telegram/SourceFiles/ui/effects/credits.style | 2 +- 6 files changed, 19 insertions(+), 20 deletions(-) create mode 100644 Telegram/Resources/animations/craft_failed.tgs delete mode 100644 Telegram/Resources/icons/chat/filled_forge_fail.svg diff --git a/Telegram/Resources/animations/craft_failed.tgs b/Telegram/Resources/animations/craft_failed.tgs new file mode 100644 index 0000000000000000000000000000000000000000..a64ab0a7ffaf9d4e8732ee5df67086563710b4ce GIT binary patch literal 6731 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 - - Profile / filled_gift_broken - - - - \ No newline at end of file diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 3902bfff8b..3842e925d7 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -55,6 +55,7 @@ ../../animations/passkeys.tgs ../../animations/ban.tgs ../../animations/cocoon.tgs + ../../animations/craft_failed.tgs ../../animations/profile/profile_muting.tgs ../../animations/profile/profile_unmuting.tgs diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp index 0dae0f43f5..7a75148296 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.cpp @@ -454,6 +454,10 @@ std::unique_ptr SetupFailureAnimation( not_null canvas, not_null state) { auto result = std::make_unique(); + result->lottie = Lottie::MakeIcon({ + .name = u"craft_failed"_q, + .sizeOverride = st::craftFailLottieSize, + }); return result; } @@ -491,6 +495,13 @@ void FailureAnimationCheck( } } + const auto lottie = animation->lottie.get(); + if (lottie->framesCount() > 1) { + lottie->animate([=] { + canvas->update(); + }, 0, lottie->framesCount() - 1); + } + state->failureShown = true; state->progressShown = false; } @@ -534,7 +545,7 @@ void FailureAnimationPrepareFrame( } else { p.fillRect(rect, bg); } - st::craftFail.paintInCenter(p, rect, st::white->c); + animation->lottie->paintInCenter(p, rect); p.setOpacity(progress); p.drawImage( st::craftForgePadding, @@ -1317,9 +1328,7 @@ void CraftState::updateForGiftCount(int count, Fn repaint) { } } -CraftState::EmptySide CraftState::prepareEmptySide( - int index, - bool fail) const { +CraftState::EmptySide CraftState::prepareEmptySide(int index) const { const auto size = forgeRect.size(); const auto ratio = style::DevicePixelRatio(); auto result = QImage(size * ratio, QImage::Format_ARGB32_Premultiplied); @@ -1329,11 +1338,7 @@ CraftState::EmptySide CraftState::prepareEmptySide( result.fill(bg); auto p = QPainter(&result); - if (fail) { - st::craftFail.paintInCenter(p, QRect(QPoint(), size), st::white->c); - } else { - st::craftForge.paintInCenter(p, QRect(QPoint(), size), st::white->c); - } + st::craftForge.paintInCenter(p, QRect(QPoint(), size), st::white->c); //#if _DEBUG // p.setFont(st::semiboldFont); diff --git a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h index 0df9d6fed0..c1a1aa58e1 100644 --- a/Telegram/SourceFiles/boxes/star_gift_craft_animation.h +++ b/Telegram/SourceFiles/boxes/star_gift_craft_animation.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_star_gift.h" #include "ui/effects/animations.h" #include "ui/effects/radial_animation.h" +#include "lottie/lottie_icon.h" #include "ui/text/text_custom_emoji.h" namespace ChatHelpers { @@ -135,9 +136,7 @@ struct CraftState { int craftingHeight, float64 slideProgress = 0.); void updateForGiftCount(int count, Fn repaint); - [[nodiscard]] EmptySide prepareEmptySide( - int index, - bool fail = false) const; + [[nodiscard]] EmptySide prepareEmptySide(int index) const; }; struct FacePlacement { @@ -160,6 +159,7 @@ struct CraftDoneAnimation { struct CraftFailAnimation { QImage frame; + std::unique_ptr lottie; bool started = false; int finalCoverIndex = -1; rpl::lifetime lifetime; diff --git a/Telegram/SourceFiles/ui/effects/credits.style b/Telegram/SourceFiles/ui/effects/credits.style index 53fd970399..74613058f8 100644 --- a/Telegram/SourceFiles/ui/effects/credits.style +++ b/Telegram/SourceFiles/ui/effects/credits.style @@ -638,7 +638,7 @@ craftFailureTitleMargin: margins(0px, 88px, 0px, 12px); craftFailureAboutMargin: margins(0px, 0px, 0px, 16px); craftForge: icon{{ "chat/filled_forge-48x48", windowFg }}; -craftFail: icon{{ "chat/filled_forge_fail-36x36", windowFg }}; +craftFailLottieSize: size(36px, 36px); craftForgePadding: 12px; craftForgePercent: CraftRadialPercent { stroke: 4px;