From 3962e5a680581fc21ae09e211072d54367d74971 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 29 Dec 2023 13:09:43 +0300 Subject: [PATCH] Added animation to voice messages with ttl. --- .../Resources/animations/voice_ttl_idle.tgs | Bin 0 -> 4985 bytes .../Resources/animations/voice_ttl_start.tgs | Bin 0 -> 5377 bytes .../Resources/qrc/telegram/animations.qrc | 2 + .../SourceFiles/data/data_media_types.cpp | 4 ++ Telegram/SourceFiles/data/data_media_types.h | 1 + .../view/media/history_view_document.cpp | 54 +++++++++++++++++- .../view/media/history_view_document.h | 4 ++ 7 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 Telegram/Resources/animations/voice_ttl_idle.tgs create mode 100644 Telegram/Resources/animations/voice_ttl_start.tgs diff --git a/Telegram/Resources/animations/voice_ttl_idle.tgs b/Telegram/Resources/animations/voice_ttl_idle.tgs new file mode 100644 index 0000000000000000000000000000000000000000..01661129813aa5be2425883bfb6037a07abaa77b GIT binary patch literal 4985 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 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc index 705b508a24..76ea1ef4a3 100644 --- a/Telegram/Resources/qrc/telegram/animations.qrc +++ b/Telegram/Resources/qrc/telegram/animations.qrc @@ -11,5 +11,7 @@ ../../animations/ttl.tgs ../../animations/discussion.tgs ../../animations/stats.tgs + ../../animations/voice_ttl_idle.tgs + ../../animations/voice_ttl_start.tgs diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 71e2929acc..e9c4dd66e8 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -1140,6 +1140,10 @@ crl::time MediaFile::ttlSeconds() const { return _ttlSeconds; } +bool MediaFile::allowsForward() const { + return !ttlSeconds(); +} + bool MediaFile::updateInlineResultMedia(const MTPMessageMedia &media) { if (media.type() != mtpc_messageMediaDocument) { return false; diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index 27d1718c1c..b2323af8a5 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -281,6 +281,7 @@ public: bool dropForwardedInfo() const override; bool hasSpoiler() const override; crl::time ttlSeconds() const override; + bool allowsForward() const override; bool updateInlineResultMedia(const MTPMessageMedia &media) override; bool updateSentMedia(const MTPMessageMedia &media) override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index df9f0f7518..f1d273d635 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/random.h" #include "lang/lang_keys.h" +#include "lottie/lottie_icon.h" #include "storage/localstorage.h" #include "main/main_session.h" #include "media/player/media_player_float.h" // Media::Player::RoundPainter. @@ -31,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/cached_round_corners.h" #include "ui/painter.h" #include "ui/power_saving.h" +#include "ui/rect.h" #include "ui/ui_utility.h" #include "data/data_session.h" #include "data/data_document.h" @@ -48,6 +50,52 @@ namespace { constexpr auto kAudioVoiceMsgUpdateView = crl::time(100); +[[nodiscard]] HistoryView::TtlPaintCallback CreateTtlPaintCallback( + std::shared_ptr lifetime, + Fn update) { + struct State final { + std::unique_ptr start; + std::unique_ptr idle; + }; + const auto iconSize = Size(std::min( + st::historyFileInPause.width(), + st::historyFileInPause.height())); + const auto state = lifetime->make_state(); + state->start = Lottie::MakeIcon({ + .name = u"voice_ttl_start"_q, + .color = &st::historyFileInIconFg, + .sizeOverride = iconSize, + }); + + const auto animateSingle = [=]( + not_null icon, + Fn next) { + auto callback = [=] { + update(); + if (icon->frameIndex() == icon->framesCount()) { + next(); + } + }; + icon->animate(std::move(callback), 0, icon->framesCount()); + }; + const auto animate = [=](auto reanimate) -> void { + animateSingle(state->idle.get(), [=] { reanimate(reanimate); }); + }; + animateSingle( + state->start.get(), + [=] { + state->idle = Lottie::MakeIcon({ + .name = u"voice_ttl_idle"_q, + .color = &st::historyFileInIconFg, + .sizeOverride = iconSize, + }); + animate(animate); + }); + return [=](QPainter &p, QRect r, QColor c) { + (state->idle ? state->idle : state->start)->paintInCenter(p, r, c); + }; +} + [[nodiscard]] bool OncePlayable(not_null item) { return !item->out() && item->media()->ttlSeconds(); } @@ -249,9 +297,11 @@ Document::Document( Ui::Text::WithEntities) }); if (lifetime) { + _drawTtl = nullptr; base::take(lifetime)->destroy(); } }, *lifetime); + _drawTtl = CreateTtlPaintCallback(lifetime, [=] { repaint(); }); return false; }); @@ -670,7 +720,9 @@ void Document::draw( : nullptr; const auto paintContent = [&](QPainter &q) { - if (previous && radialOpacity > 0. && radialOpacity < 1.) { + if (_drawTtl) { + _drawTtl(q, inner, context.st->historyFileInIconFg()->c); + } else if (previous && radialOpacity > 0. && radialOpacity < 1.) { PaintInterpolatedIcon(q, icon, *previous, radialOpacity, inner); } else { icon.paintInCenter(q, inner); diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.h b/Telegram/SourceFiles/history/view/media/history_view_document.h index 126a7c7778..5e57308ed5 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_document.h @@ -25,6 +25,8 @@ class String; namespace HistoryView { +using TtlPaintCallback = Fn; + class Document final : public File , public RuntimeComposer { @@ -178,6 +180,8 @@ private: mutable TooltipFilename _tooltipFilename; + TtlPaintCallback _drawTtl; + bool _transcribedRound = false; };