diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index d537bfeada..7426ca529b 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -791,3 +791,4 @@ dialogsPopularAppsAbout: FlatLabel(boxDividerLabel) { } dialogsQuickActionSize: 20px; +dialogsQuickActionRippleSize: 80px; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index f8f477143c..28ac0119fa 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -840,9 +840,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { context.rightButton = maybeCacheRightButton(row); if (key.history()) { const auto it = _quickActions.find(key.history()->peer->id.value); - if (it != _quickActions.end()) { - context.quickActionContext = it->second.get(); - } + context.quickActionContext = (it != _quickActions.end()) + ? it->second.get() + : nullptr; } context.st = (forum ? &st::forumDialogRow : _st.get()); @@ -1850,7 +1850,9 @@ void InnerWidget::mousePressEvent(QMouseEvent *e) { }; const auto origin = e->pos() - QPoint(0, dialogsOffset() + _pressed->top()); - if (addBotAppRipple(origin, updateCallback)) { + if ((_pressButton == Qt::MiddleButton) + && addQuickActionRipple(row, updateCallback)) { + } else if (addBotAppRipple(origin, updateCallback)) { } else if (_pressedTopicJump) { row->addTopicJumpRipple( origin, @@ -1922,7 +1924,7 @@ bool InnerWidget::addBotAppRipple(QPoint origin, Fn updateCallback) { _pressedBotAppData->ripple = std::make_unique( st::defaultRippleAnimation, Ui::RippleAnimation::RoundRectMask(size, size.height() / 2), - updateCallback); + std::move(updateCallback)); } const auto shift = QPoint( width() - size.width() - st::dialogRowOpenBotRight, @@ -1931,6 +1933,43 @@ bool InnerWidget::addBotAppRipple(QPoint origin, Fn updateCallback) { return true; } +bool InnerWidget::addQuickActionRipple( + not_null row, + Fn updateCallback) { + const auto action = Core::App().settings().quickDialogAction(); + if (action == Dialogs::Ui::QuickDialogAction::Disabled) { + return false; + } + const auto history = row->history(); + if (!history) { + return false; + } + const auto key = history->peer->id.value; + const auto context = ensureQuickAction(key); + + auto name = ResolveQuickDialogLottieIconName( + history->peer, + action, + _filterId); + context->icon = Lottie::MakeIcon({ + .name = std::move(name), + .sizeOverride = Size(st::dialogsQuickActionSize), + }); + context->action = action; + const auto size = QSize( + st::dialogsQuickActionRippleSize, + row->height()); + if (!context->ripple) { + context->ripple = std::make_unique( + st::defaultRippleAnimation, + Ui::RippleAnimation::RectMask(size), + std::move(updateCallback)); + } + context->ripple->add(QPoint(size.width() / 2, size.height() / 2)); + + return true; +} + const std::vector &InnerWidget::pinnedChatsOrder() const { const auto owner = &session().data(); return _savedSublists @@ -2236,6 +2275,16 @@ void InnerWidget::mousePressReleased( if (_pressedBotAppData && _pressedBotAppData->ripple) { _pressedBotAppData->ripple->lastStop(); } + if (!_quickActions.empty() && pressed) { + if (const auto history = pressed->history()) { + const auto it = _quickActions.find(history->peer->id.value); + if (it != _quickActions.end()) { + if (it->second->ripple) { + it->second->ripple->lastStop(); + } + } + } + } updateSelectedRow(); if (!wasDragging && button == Qt::LeftButton) { if ((collapsedPressed >= 0 && collapsedPressed == _collapsedSelected) @@ -5010,15 +5059,7 @@ void InnerWidget::setSwipeContextData( _quickActions.remove(key); return; } - const auto it = _quickActions.find(key); - auto context = (Ui::QuickActionContext*)(nullptr); - if (it == _quickActions.end()) { - context = _quickActions.emplace( - key, - std::make_unique()).first->second.get(); - } else { - context = it->second.get(); - } + const auto context = ensureQuickAction(key); context->data = base::take(*data); if (context->data.msgBareId) { @@ -5043,6 +5084,19 @@ void InnerWidget::setSwipeContextData( } } +not_null InnerWidget::ensureQuickAction(int64 key) { + Expects(key != 0); + + const auto it = _quickActions.find(key); + if (it == _quickActions.end()) { + return _quickActions.emplace( + key, + std::make_unique()).first->second.get(); + } else { + return it->second.get(); + } +} + int64 InnerWidget::calcSwipeKey(int top) { top -= dialogsOffset(); for (auto it = _shownList->begin(); it != _shownList->end(); ++it) { @@ -5064,21 +5118,12 @@ void InnerWidget::prepareQuickAction( Dialogs::Ui::QuickDialogAction action) { Expects(key != 0); - const auto it = _quickActions.find(key); - auto context = (Ui::QuickActionContext*)(nullptr); - if (it == _quickActions.end()) { - context = _quickActions.emplace( - key, - std::make_unique()).first->second.get(); - } else { - context = it->second.get(); - } - + const auto context = ensureQuickAction(key); const auto peer = session().data().peer(PeerId(key)); auto name = ResolveQuickDialogLottieIconName(peer, action, _filterId); context->icon = Lottie::MakeIcon({ .name = std::move(name), - .sizeOverride = Size(st::dialogsSwipeActionSize), + .sizeOverride = Size(st::dialogsQuickActionSize), }); context->action = action; } diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index e29f1927ef..c3bd31867a 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -352,6 +352,7 @@ private: void repaintDialogRowCornerStatus(not_null history); bool addBotAppRipple(QPoint origin, Fn updateCallback); + bool addQuickActionRipple(not_null row, Fn updateCallback); void setupShortcuts(); RowDescriptor computeJump( @@ -482,7 +483,8 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); - [[nodiscard]] Ui::QuickActionContext *ensureQuickAction(int64 key); + [[nodiscard]] not_null ensureQuickAction( + int64 key); [[nodiscard]] bool lookupIsInBotAppButton( Row *row, diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 12ce253ed4..793de8b605 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -396,6 +396,7 @@ void PaintRow( auto swipeTranslation = 0; if (history && context.quickActionContext + && !context.quickActionContext->ripple && (history->peer->id.value == context.quickActionContext->data.msgBareId)) { if (context.quickActionContext->data.translation != 0) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h b/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h index fec3a1f622..fbd0c363cf 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h @@ -14,6 +14,10 @@ namespace Lottie { class Icon; } // namespace Lottie +namespace Ui { +class RippleAnimation; +} // namespace Ui + namespace Dialogs::Ui { using namespace ::Ui; @@ -34,6 +38,7 @@ enum class QuickDialogActionLabel { struct QuickActionContext { ::Ui::Controls::SwipeContextData data; std::unique_ptr icon; + std::unique_ptr ripple; QuickDialogAction action; };