From 990dc0f95cc3f3cc428f409610d39bd41aa83a28 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 3 Apr 2026 11:42:32 +0300 Subject: [PATCH] Improved style of toggle summary button and removed star particles. --- .../view/history_view_transcribe_button.cpp | 114 +++++++++++++----- .../view/history_view_transcribe_button.h | 3 +- Telegram/SourceFiles/ui/chat/chat.style | 3 + 3 files changed, 85 insertions(+), 35 deletions(-) diff --git a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp index 48471c82bc..ea48e7d394 100644 --- a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp @@ -20,15 +20,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/chat/chat_style.h" #include "ui/effects/radial_animation.h" #include "ui/effects/ripple_animation.h" -#include "ui/effects/ministar_particles.h" #include "ui/painter.h" -#include "ui/power_saving.h" #include "ui/rect.h" -#include "ui/ui_utility.h" #include "api/api_transcribes.h" #include "apiwrap.h" #include "styles/style_chat.h" -#include "styles/style_media_view.h" #include "window/window_session_controller.h" namespace HistoryView { @@ -36,6 +32,8 @@ namespace { constexpr auto kInNonChosenOpacity = 0.12; constexpr auto kOutNonChosenOpacity = 0.18; +constexpr auto kArrowPivotNear = 0.345; +constexpr auto kArrowPivotFar = 1. - kArrowPivotNear; void ClipPainterForLock(QPainter &p, bool roundview, const QRect &r) { const auto &pos = roundview @@ -136,42 +134,92 @@ void TranscribeButton::paint( p.drawEllipse(r); if (_summarize) { - if (!_particles) { - _particles = std::make_unique( - Ui::StarParticles::Type::RadialInside, - 7, - st::lineWidth * 4); - _particles->setColor(st::msgServiceFg->c); - _particles->setSpeed(0.2); - } - p.setClipRegion(QRegion(r, QRegion::Ellipse)); - const auto paused = context.paused - || (!_summarizeHovered && !_loading) - || On(PowerSaving::kChatEffects); - _particles->paint(p, r, context.now, paused); - p.setClipping(false); if (hasLock()) { context.st->historyFastTranscribeLock().paint( p, r.topLeft() + st::historyFastSummaryLockPos, r.width()); } - if (!paused) { - const auto session = &_item->history()->session(); - Ui::PostponeCall(session, [=, itemId = _item->fullId()] { - if (const auto i = session->data().message(itemId)) { - session->data().requestItemRepaint(i, r); - } - }); - } if (!staticLoading) [[likely]] { - (_item->history()->session().api().transcribes().summary( - _item).shown - ? st::mediaviewFullScreenButton.icon - : st::mediaviewFullScreenOutIcon).paintInCenter( - p, - r, - st::msgServiceFg->c); + const auto shown = _item->history() + ->session().api().transcribes().summary(_item).shown; + if (_summaryShown != shown) { + _summaryShown = shown; + const auto session = &_item->history()->session(); + _openedAnimation.start( + [=, itemId = _item->fullId()] { + if (const auto i = session->data().message( + itemId)) { + session->data().requestItemRepaint(i); + } + }, + shown ? 0. : 1., + shown ? 1. : 0., + st::fadeWrapDuration); + } + const auto t + = _openedAnimation.value(_summaryShown ? 1. : 0.); + + st::historySummaryStars.paintInCenter(p, r); + + const auto &arrow = st::historySummaryArrows; + const auto sz = r.width(); + const auto cx = r.x() + sz / 2.; + const auto cy = r.y() + sz / 2.; + + // First arrow. + { + p.save(); + if (t < 0.5) { + const auto s = std::abs(t - 0.5) + 0.5; + p.translate(cx, cy); + p.scale(s, s); + p.translate(-cx, -cy); + } + if (t > 0.5) { + const auto s = std::abs(t - 0.5) + 0.5; + const auto px = r.x() + sz * kArrowPivotNear; + const auto py = r.y() + sz * kArrowPivotFar; + p.translate(px, py); + p.scale(-s, -s); + p.translate(-px, -py); + p.translate( + -sz * (1. - s) * 0.4, + sz * (1. - s) * 0.4); + } + arrow.paintInCenter(p, QRectF(r)); + p.restore(); + } + + // Second arrow (rotated 180 degrees). + { + p.save(); + if (t < 0.5) { + const auto s = std::abs(t - 0.5) + 0.5; + p.translate(cx, cy); + p.scale(s, s); + p.translate(-cx, -cy); + } + if (t > 0.5) { + const auto s = std::abs(t - 0.5) + 0.5; + const auto px = r.x() + sz * kArrowPivotFar; + const auto py = r.y() + sz * kArrowPivotNear; + p.translate(px, py); + p.scale(-s, -s); + p.translate(-px, -py); + } + p.translate(cx, cy); + p.rotate(180.); + p.translate(-cx, -cy); + if (t > 0.5) { + const auto s = std::abs(t - 0.5) + 0.5; + p.translate( + -sz * (1. - s) * 0.4, + sz * (1. - s) * 0.4); + } + arrow.paintInCenter(p, QRectF(r)); + p.restore(); + } } } else if (!_loading && hasLock()) { ClipPainterForLock(p, true, r); diff --git a/Telegram/SourceFiles/history/view/history_view_transcribe_button.h b/Telegram/SourceFiles/history/view/history_view_transcribe_button.h index f6f431743b..3b05110f6a 100644 --- a/Telegram/SourceFiles/history/view/history_view_transcribe_button.h +++ b/Telegram/SourceFiles/history/view/history_view_transcribe_button.h @@ -13,7 +13,6 @@ namespace Ui { struct ChatPaintContext; class InfiniteRadialAnimation; class RippleAnimation; -class StarParticles; } // namespace Ui namespace HistoryView { @@ -50,7 +49,6 @@ private: ClickHandlerPtr _link; std::unique_ptr _animation; - std::unique_ptr _particles; std::unique_ptr _ripple; Ui::Animations::Simple _openedAnimation; QString _text; @@ -59,6 +57,7 @@ private: bool _summarizeHovered = false; bool _loading = false; bool _opened = false; + bool _summaryShown = false; }; diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 6a6808299e..6b20b8ac41 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -1538,3 +1538,6 @@ historySummaryHeaderIconSizeInner: 5px; toastCheckIcon: icon {{ "toast/check-36x36", toastFg }}; toastCheckIconPadding: margins(12px, 8px, 12px, 8px); + +historySummaryStars: icon {{ "chat/summary_stars-24x24", msgServiceFg }}; +historySummaryArrows: icon {{ "chat/summary_arrows-24x24", msgServiceFg }};