diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 47791b964b..f8f477143c 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -810,7 +810,6 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto ms = crl::now(); const auto childListShown = _childListShown.current(); auto context = Ui::PaintContext{ - .quickActionContext = _quickActionContext, .st = _st, .topicJumpCache = _topicJumpCache.get(), .folder = _openedFolder, @@ -839,6 +838,12 @@ void InnerWidget::paintEvent(QPaintEvent *e) { const auto expanding = forum && (key.history()->peer->id == childListShown.peerId); 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.st = (forum ? &st::forumDialogRow : _st.get()); @@ -4995,24 +5000,43 @@ rpl::producer InnerWidget::openBotMainAppRequests() const { return _openBotMainAppRequests.events(); } -void InnerWidget::setSwipeContextData(Ui::Controls::SwipeContextData data) { - _quickActionContext.data = std::move(data); - if (_quickActionContext.data.msgBareId) { +void InnerWidget::setSwipeContextData( + int64 key, + std::optional data) { + if (!key) { + return; + } + if (!data) { + _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(); + } + + context->data = base::take(*data); + if (context->data.msgBareId) { constexpr auto kStartAnimateThreshold = 0.32; constexpr auto kResetAnimateThreshold = 0.24; - if (_quickActionContext.data.ratio > kStartAnimateThreshold) { - if (_quickActionContext.icon - && !_quickActionContext.icon->frameIndex() - && !_quickActionContext.icon->animating()) { - _quickActionContext.icon->animate( + if (context->data.ratio > kStartAnimateThreshold) { + if (context->icon + && !context->icon->frameIndex() + && !context->icon->animating()) { + context->icon->animate( [=] { update(); }, 0, - _quickActionContext.icon->framesCount()); + context->icon->framesCount()); } - } else if (_quickActionContext.data.ratio < kResetAnimateThreshold) { - if (_quickActionContext.icon - && _quickActionContext.icon->frameIndex()) { - _quickActionContext.icon->jumpTo(0, [=] { update(); }); + } else if (context->data.ratio < kResetAnimateThreshold) { + if (context->icon + && context->icon->frameIndex()) { + context->icon->jumpTo(0, [=] { update(); }); } } update(); @@ -5038,23 +5062,25 @@ int64 InnerWidget::calcSwipeKey(int top) { void InnerWidget::prepareQuickAction( int64 key, Dialogs::Ui::QuickDialogAction action) { - if (key) { - const auto peer = session().data().peer(PeerId(key)); - auto name = ResolveQuickDialogLottieIconName(peer, action, _filterId); - _quickActionLottieIcon = Lottie::MakeIcon({ - .name = std::move(name), - .sizeOverride = Size(st::dialogsQuickActionSize), - }); - _quickActionContext.icon = _quickActionLottieIcon.get(); - _quickActionContext.action = 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 { - if (_quickActionContext.icon) { - _quickActionContext = {}; - } - if (_quickActionLottieIcon) { - _quickActionLottieIcon.reset(); - } + context = it->second.get(); } + + 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), + }); + context->action = action; } } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 8b239d4440..e29f1927ef 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -216,7 +216,9 @@ public: [[nodiscard]] rpl::producer openBotMainAppRequests() const; - void setSwipeContextData(Ui::Controls::SwipeContextData data); + void setSwipeContextData( + int64 key, + std::optional data); [[nodiscard]] int64 calcSwipeKey(int top); void prepareQuickAction(int64 key, Dialogs::Ui::QuickDialogAction); @@ -480,6 +482,8 @@ private: void saveChatsFilterScrollState(FilterId filterId); void restoreChatsFilterScrollState(FilterId filterId); + [[nodiscard]] Ui::QuickActionContext *ensureQuickAction(int64 key); + [[nodiscard]] bool lookupIsInBotAppButton( Row *row, QPoint localPosition); @@ -623,8 +627,8 @@ private: rpl::event_stream<> _refreshHashtagsRequests; rpl::event_stream _openBotMainAppRequests; - Dialogs::Ui::QuickActionContext _quickActionContext; - std::unique_ptr _quickActionLottieIcon = nullptr; + using QuickActionPtr = std::unique_ptr; + base::flat_map _quickActions; RowDescriptor _chatPreviewRow; bool _chatPreviewScheduled = false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index ab58ceed76..a2b9413e7c 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -694,7 +694,7 @@ void Widget::setupSwipeBack() { && _inner && (Core::App().settings().quickDialogAction() != Ui::QuickDialogAction::Disabled)) { - _inner->setSwipeContextData(std::move(data)); + _inner->setSwipeContextData(data.msgBareId, std::move(data)); } else { if (!_swipeBackData.callback) { _swipeBackData = Ui::Controls::SetupSwipeBack( @@ -716,7 +716,7 @@ void Widget::setupSwipeBack() { _swipeBackData = {}; } if (_inner) { - _inner->setSwipeContextData({}); + _inner->setSwipeContextData(data.msgBareId, std::nullopt); _inner->update(); } } diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index 8ab33852ef..12ce253ed4 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -395,10 +395,11 @@ void PaintRow( : context.currentBg; auto swipeTranslation = 0; if (history + && context.quickActionContext && (history->peer->id.value - == context.quickActionContext.data.msgBareId)) { - if (context.quickActionContext.data.translation != 0) { - swipeTranslation = context.quickActionContext.data.translation + == context.quickActionContext->data.msgBareId)) { + if (context.quickActionContext->data.translation != 0) { + swipeTranslation = context.quickActionContext->data.translation * -2; } } @@ -883,14 +884,14 @@ void PaintRow( p.setClipRegion(swipeActionRect); const auto labelType = ResolveQuickDialogLabel( history, - context.quickActionContext.action, + context.quickActionContext->action, context.filter); p.fillRect(swipeActionRect, ResolveQuickActionBg(labelType)); - if (context.quickActionContext.data.reachRatio) { + if (context.quickActionContext->data.reachRatio) { p.setPen(Qt::NoPen); p.setBrush(ResolveQuickActionBgActive(labelType)); const auto r = swipeTranslation - * context.quickActionContext.data.reachRatio; + * context.quickActionContext->data.reachRatio; const auto offset = st::dialogsQuickActionSize + st::dialogsQuickActionSize / 2.; p.drawEllipse(QPointF(geometry.width() - offset, offset), r, r); @@ -899,8 +900,8 @@ void PaintRow( - st::dialogsQuickActionSize) / 2; const auto topTranslation = iconOffset / 2.; p.translate(0, -topTranslation); - if (context.quickActionContext.icon) { - context.quickActionContext.icon->paint( + if (context.quickActionContext->icon) { + context.quickActionContext->icon->paint( p, rect::right(geometry) - iconOffset diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h index 848ac257f1..43122350ef 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.h @@ -55,7 +55,7 @@ struct TopicJumpCache { struct PaintContext { RightButton *rightButton = nullptr; std::vector *chatsFilterTags = nullptr; - QuickActionContext quickActionContext; + QuickActionContext *quickActionContext = nullptr; not_null st; TopicJumpCache *topicJumpCache = nullptr; Data::Folder *folder = nullptr; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h b/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h index 945300a8da..fec3a1f622 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_quick_action_context.h @@ -33,7 +33,7 @@ enum class QuickDialogActionLabel { struct QuickActionContext { ::Ui::Controls::SwipeContextData data; - Lottie::Icon *icon = nullptr; + std::unique_ptr icon; QuickDialogAction action; };