diff --git a/Telegram/SourceFiles/api/api_bot.cpp b/Telegram/SourceFiles/api/api_bot.cpp index 5ce67ef8ff..03883c9467 100644 --- a/Telegram/SourceFiles/api/api_bot.cpp +++ b/Telegram/SourceFiles/api/api_bot.cpp @@ -276,11 +276,15 @@ bool SwitchInlineBotButtonReceived( samePeerReplyTo); } -void ActivateBotCommand( - not_null controller, - not_null item, - int row, - int column) { +void ActivateBotCommand(ClickHandlerContext context, int row, int column) { + const auto controller = context.sessionWindow.get(); + if (!controller) { + return; + } + const auto item = controller->session().data().message(context.itemId); + if (!item) { + return; + } const auto button = HistoryMessageMarkupButton::Get( &item->history()->owner(), item->fullId(), @@ -330,13 +334,11 @@ void ActivateBotCommand( skipConfirmation = true; } } - const auto context = QVariant::fromValue(ClickHandlerContext{ - .sessionWindow = controller.get(), - }); + const auto variant = QVariant::fromValue(context); if (skipConfirmation) { - UrlClickHandler::Open(url, context); + UrlClickHandler::Open(url, variant); } else { - HiddenUrlClickHandler::Open(url, context); + HiddenUrlClickHandler::Open(url, variant); } } break; diff --git a/Telegram/SourceFiles/api/api_bot.h b/Telegram/SourceFiles/api/api_bot.h index 0c8ecbacd4..198ad926bf 100644 --- a/Telegram/SourceFiles/api/api_bot.h +++ b/Telegram/SourceFiles/api/api_bot.h @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +struct ClickHandlerContext; class HistoryItem; namespace Window { @@ -33,10 +34,6 @@ bool SwitchInlineBotButtonReceived( UserData *samePeerBot = nullptr, MsgId samePeerReplyTo = 0); -void ActivateBotCommand( - not_null controller, - not_null item, - int row, - int column); +void ActivateBotCommand(ClickHandlerContext context, int row, int column); } // namespace Api diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp index 9d14fa556b..1ef82785ae 100644 --- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp +++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp @@ -169,7 +169,9 @@ void BotKeyboard::leaveEventHook(QEvent *e) { clearSelection(); } -bool BotKeyboard::moderateKeyActivate(int key) { +bool BotKeyboard::moderateKeyActivate( + int key, + Fn context) { const auto &data = _controller->session().data(); const auto botCommand = [](int key) { @@ -202,7 +204,11 @@ bool BotKeyboard::moderateKeyActivate(int key) { if (!markup->data.rows.empty() && index >= 0 && index < int(markup->data.rows.front().size())) { - Api::ActivateBotCommand(_controller, item, 0, index); + Api::ActivateBotCommand( + context( + _wasForMsgId).other.value(), + 0, + index); return true; } } else if (const auto user = item->history()->peer->asUser()) { diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.h b/Telegram/SourceFiles/chat_helpers/bot_keyboard.h index 7e30de14d8..6ac69b97ba 100644 --- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.h +++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.h @@ -29,7 +29,7 @@ public: not_null controller, QWidget *parent); - bool moderateKeyActivate(int index); + bool moderateKeyActivate(int index, Fn context); // With force=true the markup is updated even if it is // already shown for the passed history item. diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index b57c9e1618..8a30f29639 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1793,23 +1793,10 @@ void HistoryInner::mouseActionFinish( ? pressedItemView->data()->fullId() : FullMsgId(); const auto weak = base::make_weak(_controller.get()); - ActivateClickHandler(window(), activated, { - button, - QVariant::fromValue(ClickHandlerContext{ - .itemId = pressedItemId, - .elementDelegate = [=]() -> HistoryView::ElementDelegate* { - if (const auto strong = weak.get()) { - auto &data = strong->session().data(); - if (const auto item = data.message(pressedItemId)) { - const auto history = item->history(); - return history->delegateMixin()->delegate(); - } - } - return nullptr; - }, - .sessionWindow = weak, - }) - }); + ActivateClickHandler( + window(), + activated, + prepareClickContext(button, pressedItemId)); return; } if ((_mouseAction == MouseAction::PrepareSelect) @@ -4110,6 +4097,39 @@ void HistoryInner::onParentGeometryChanged() { } } +Fn HistoryInner::elementDelegateFactory( + FullMsgId itemId) const { + const auto weak = base::make_weak(_controller.get()); + return [=]() -> HistoryView::ElementDelegate* { + if (const auto strong = weak.get()) { + auto &data = strong->session().data(); + if (const auto item = data.message(itemId)) { + const auto history = item->history(); + return history->delegateMixin()->delegate(); + } + } + return nullptr; + }; +} + +ClickHandlerContext HistoryInner::prepareClickHandlerContext( + FullMsgId itemId) const { + return ClickHandlerContext{ + .itemId = itemId, + .elementDelegate = elementDelegateFactory(itemId), + .sessionWindow = base::make_weak(_controller.get()), + }; +} + +ClickContext HistoryInner::prepareClickContext( + Qt::MouseButton button, + FullMsgId itemId) const { + return { + button, + QVariant::fromValue(prepareClickHandlerContext(itemId)), + }; +} + auto HistoryInner::DelegateMixin() -> std::unique_ptr { return std::make_unique(); diff --git a/Telegram/SourceFiles/history/history_inner_widget.h b/Telegram/SourceFiles/history/history_inner_widget.h index eaae7ccf72..85fb58afa4 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.h +++ b/Telegram/SourceFiles/history/history_inner_widget.h @@ -15,6 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/scroll_area.h" #include "history/view/history_view_top_bar_widget.h" +struct ClickContext; +struct ClickHandlerContext; + namespace Data { struct Group; class CloudImageView; @@ -189,6 +192,14 @@ public: void onParentGeometryChanged(); + [[nodiscard]] Fn elementDelegateFactory( + FullMsgId itemId) const; + [[nodiscard]] ClickHandlerContext prepareClickHandlerContext( + FullMsgId itemId) const; + [[nodiscard]] ClickContext prepareClickContext( + Qt::MouseButton button, + FullMsgId itemId) const; + [[nodiscard]] static auto DelegateMixin() -> std::unique_ptr; diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index b5b99fd268..6c4de14909 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -523,12 +523,9 @@ void ReplyMarkupClickHandler::onClick(ClickContext context) const { if (context.button != Qt::LeftButton) { return; } - const auto my = context.other.value(); - if (const auto controller = my.sessionWindow.get()) { - if (const auto item = _owner->message(_itemId)) { - Api::ActivateBotCommand(controller, item, _row, _column); - } - } + auto my = context.other.value(); + my.itemId = _itemId; + Api::ActivateBotCommand(my, _row, _column); } // Returns the full text of the corresponding button. diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 9cc03b32dc..c66e77db94 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -428,9 +428,12 @@ HistoryWidget::HistoryWidget( }, lifetime()); _fieldAutocomplete->setModerateKeyActivateCallback([=](int key) { - return _keyboard->isHidden() - ? false - : _keyboard->moderateKeyActivate(key); + const auto context = [=](FullMsgId itemId) { + return _list->prepareClickContext(Qt::LeftButton, itemId); + }; + return !_keyboard->isHidden() && _keyboard->moderateKeyActivate( + key, + context); }); _fieldAutocomplete->choosingProcesses( @@ -6356,6 +6359,7 @@ void HistoryWidget::setupPinnedTracker() { void HistoryWidget::checkPinnedBarState() { Expects(_pinnedTracker != nullptr); + Expects(_list != nullptr); const auto hiddenId = _peer->canPinMessages() ? MsgId(0) @@ -6522,7 +6526,10 @@ void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { Ui::RoundButton::TextTransform::NoTransform); button->setFullRadius(true); button->setClickedCallback([=] { - Api::ActivateBotCommand(controller(), item, 0, 0); + Api::ActivateBotCommand( + _list->prepareClickHandlerContext(item->fullId()), + 0, + 0); }); if (button->width() > st::historyPinnedBotButtonMaxWidth) { button->setFullWidth(st::historyPinnedBotButtonMaxWidth);