From c085691c54324e996b708c92f2efb601880118d5 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Fri, 21 Mar 2025 12:26:28 +0300 Subject: [PATCH] Moved out active quick action from total list of quick dialog actions. --- .../dialogs/dialogs_inner_widget.cpp | 95 +++++++++++++------ .../dialogs/dialogs_inner_widget.h | 4 +- .../SourceFiles/dialogs/dialogs_widget.cpp | 51 +++++----- .../SourceFiles/dialogs/ui/dialogs_layout.cpp | 20 ++-- 4 files changed, 106 insertions(+), 64 deletions(-) diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index c18b998478..cd8def62ea 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -831,18 +831,34 @@ void InnerWidget::paintEvent(QPaintEvent *e) { bool mayBeActive) { const auto &key = row->key(); const auto active = mayBeActive && isRowActive(row, activeEntry); - const auto forum = key.history() && key.history()->isForum(); + const auto history = key.history(); + const auto forum = history && history->isForum(); if (forum && !_topicJumpCache) { _topicJumpCache = std::make_unique(); } const auto expanding = forum - && (key.history()->peer->id == childListShown.peerId); + && (history->peer->id == childListShown.peerId); context.rightButton = maybeCacheRightButton(row); - if (key.history()) { - const auto it = _quickActions.find(key.history()->peer->id.value); - context.quickActionContext = (it != _quickActions.end()) - ? it->second.get() - : nullptr; + if (history) { + if (_activeQuickAction + && (_activeQuickAction->data.msgBareId + == history->peer->id.value)) { + context.quickActionContext = _activeQuickAction.get(); + } else if (!_inactiveQuickActions.empty()) { + auto it = _inactiveQuickActions.begin(); + while (it != _inactiveQuickActions.end()) { + const auto raw = it->get(); + if ((!raw->ripple || raw->ripple->empty()) + && (!raw->rippleFg || raw->rippleFg->empty())) { + _inactiveQuickActions.erase(it); + } else { + if (raw->data.msgBareId == history->peer->id.value) { + context.quickActionContext = raw; + } + ++it; + } + } + } } context.st = (forum ? &st::forumDialogRow : _st.get()); @@ -868,7 +884,7 @@ void InnerWidget::paintEvent(QPaintEvent *e) { } if (active && (filter.flags() & Data::ChatFilter::Flag::NoRead) - && !filter.contains(key.history(), true)) { + && !filter.contains(history, true)) { // Hack for History::fakeUnreadWhileOpened(). continue; } @@ -923,6 +939,9 @@ void InnerWidget::paintEvent(QPaintEvent *e) { && _selectedTopicJump && (!_pressed || _pressedTopicJump); Ui::RowPainter::Paint(p, row, validateVideoUserpic(row), context); + if (context.quickActionContext) { + context.quickActionContext = nullptr; + } }; if (_state == WidgetState::Default) { const auto collapsedSkip = collapsedRowsOffset(); @@ -1936,6 +1955,9 @@ bool InnerWidget::addBotAppRipple(QPoint origin, Fn updateCallback) { bool InnerWidget::addQuickActionRipple( not_null row, Fn updateCallback) { + if (_activeQuickAction) { + return false; + } const auto action = Core::App().settings().quickDialogAction(); if (action == Dialogs::Ui::QuickDialogAction::Disabled) { return false; @@ -1950,6 +1972,9 @@ bool InnerWidget::addQuickActionRipple( } const auto key = history->peer->id.value; const auto context = ensureQuickAction(key); + if (context->data) { + return false; + } auto name = ResolveQuickDialogLottieIconName(type); context->icon = Lottie::MakeIcon({ @@ -2305,22 +2330,25 @@ void InnerWidget::mousePressReleased( if (_pressedBotAppData && _pressedBotAppData->ripple) { _pressedBotAppData->ripple->lastStop(); } - if (!_quickActions.empty() && pressed) { + if (_activeQuickAction && pressed && !_activeQuickAction->data) { 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(); - it->second->rippleFg->lastStop(); - } - if (pressed == _selected) { - PerformQuickDialogAction( - _controller, - history->peer, - it->second->action, - _filterId); - } + const auto raw = _activeQuickAction.get(); + if (raw->ripple) { + raw->ripple->lastStop(); } + if (raw->rippleFg) { + raw->rippleFg->lastStop(); + } + + if (pressed == _selected) { + PerformQuickDialogAction( + _controller, + history->peer, + raw->action, + _filterId); + } + _inactiveQuickActions.push_back( + QuickActionPtr{ _activeQuickAction.release() }); } } updateSelectedRow(); @@ -5094,7 +5122,7 @@ void InnerWidget::setSwipeContextData( return; } if (!data) { - _quickActions.remove(key); + _activeQuickAction = nullptr; return; } const auto context = ensureQuickAction(key); @@ -5125,14 +5153,17 @@ 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(); + if (_activeQuickAction) { + if (_activeQuickAction->data.msgBareId == key) { + return _activeQuickAction.get(); + } else { + _inactiveQuickActions.push_back( + QuickActionPtr{ _activeQuickAction.release() }); + } } + _activeQuickAction = std::make_unique(); + _activeQuickAction->data.msgBareId = key; + return _activeQuickAction.get(); } int64 InnerWidget::calcSwipeKey(int top) { @@ -5169,4 +5200,8 @@ void InnerWidget::prepareQuickAction( context->action = action; } +void InnerWidget::clearQuickActions() { + _inactiveQuickActions.clear(); +} + } // namespace Dialogs diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index c3bd31867a..e57dc42f09 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -221,6 +221,7 @@ public: std::optional data); [[nodiscard]] int64 calcSwipeKey(int top); void prepareQuickAction(int64 key, Dialogs::Ui::QuickDialogAction); + void clearQuickActions(); protected: void visibleTopBottomUpdated( @@ -630,7 +631,8 @@ private: rpl::event_stream _openBotMainAppRequests; using QuickActionPtr = std::unique_ptr; - base::flat_map _quickActions; + QuickActionPtr _activeQuickAction; + std::vector _inactiveQuickActions; RowDescriptor _chatPreviewRow; bool _chatPreviewScheduled = false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp index e68d3df901..fe62494c35 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_widget.cpp @@ -729,30 +729,33 @@ void Widget::setupSwipeBack() { const auto isRightToLeft = direction == Qt::RightToLeft; const auto action = Core::App().settings().quickDialogAction(); const auto isDisabled = action == Ui::QuickDialogAction::Disabled; - if (!isRightToLeft && _inner) { - if (const auto key = _inner->calcSwipeKey(top); - key && !isDisabled) { - _inner->prepareQuickAction(key, action); - return Ui::Controls::SwipeHandlerFinishData{ - .callback = [=, session = &session()] { - auto callback = [=, peerId = PeerId(key)] { - const auto peer = session->data().peer(peerId); - PerformQuickDialogAction( - controller(), - peer, - action, - _inner->filterId()); - }; - base::call_delayed( - st::slideWrapDuration, - session, - std::move(callback)); - }, - .msgBareId = key, - .speedRatio = 1., - .reachRatioDuration = crl::time(st::slideWrapDuration), - .provideReachOutRatio = true, - }; + if (_inner) { + _inner->clearQuickActions(); + if (!isRightToLeft) { + if (const auto key = _inner->calcSwipeKey(top); + key && !isDisabled) { + _inner->prepareQuickAction(key, action); + return Ui::Controls::SwipeHandlerFinishData{ + .callback = [=, session = &session()] { + auto callback = [=, peerId = PeerId(key)] { + PerformQuickDialogAction( + controller(), + session->data().peer(peerId), + action, + _inner->filterId()); + }; + base::call_delayed( + st::slideWrapDuration, + session, + std::move(callback)); + }, + .msgBareId = key, + .speedRatio = 1., + .reachRatioDuration = crl::time( + st::slideWrapDuration), + .provideReachOutRatio = true, + }; + } } } if (controller()->openedFolder().current()) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp index c559693051..dd8155f16b 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_layout.cpp @@ -898,15 +898,17 @@ void PaintRow( p.drawEllipse(QPointF(geometry.width() - offset, offset), r, r); } const auto quickWidth = st::dialogsQuickActionSize * 3; - DrawQuickAction( - p, - QRect( - rect::right(geometry) - quickWidth, - geometry.y(), - quickWidth, - geometry.height()), - context.quickActionContext->icon.get(), - labelType); + if (context.quickActionContext->icon) { + DrawQuickAction( + p, + QRect( + rect::right(geometry) - quickWidth, + geometry.y(), + quickWidth, + geometry.height()), + context.quickActionContext->icon.get(), + labelType); + } p.setClipping(false); } if (const auto quick = context.quickActionContext;