From 93bcd90fd4cd73e2856489dc94e6d04de75ede57 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Mon, 26 Jul 2021 19:27:08 +0300 Subject: [PATCH] Provided more context for click handlers. --- .../SourceFiles/chat_helpers/bot_keyboard.cpp | 18 +++++++-- .../SourceFiles/chat_helpers/bot_keyboard.h | 12 +++--- .../chat_helpers/gifs_list_widget.cpp | 8 +++- .../SourceFiles/core/click_handler_types.h | 5 ++- .../admin_log/history_admin_log_inner.cpp | 13 +++++- .../SourceFiles/history/history_widget.cpp | 2 +- .../info/media/info_media_list_widget.cpp | 14 ++++++- .../info/profile/info_profile_actions.cpp | 40 +++++++++++++++++++ .../inline_bots/inline_results_inner.cpp | 8 +++- .../media/view/media_view_overlay_widget.cpp | 13 ++++-- 10 files changed, 114 insertions(+), 19 deletions(-) diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp index 1a9d80fd8..ece1c61f0 100644 --- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp +++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.cpp @@ -7,11 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "chat_helpers/bot_keyboard.h" +#include "core/click_handler_types.h" #include "history/history.h" #include "history/history_item_components.h" #include "data/data_user.h" #include "data/data_session.h" #include "main/main_session.h" +#include "window/window_session_controller.h" #include "ui/cached_round_corners.h" #include "facades.h" #include "styles/style_widgets.h" @@ -98,9 +100,11 @@ int Style::minButtonWidth(HistoryMessageMarkupButton::Type type) const { } // namespace -BotKeyboard::BotKeyboard(not_null session, QWidget *parent) +BotKeyboard::BotKeyboard( + not_null controller, + QWidget *parent) : TWidget(parent) -, _session(session) +, _controller(controller) , _st(&st::botKbButton) { setGeometry(0, 0, _st->margin, st::botKbScroll.deltat); _height = st::botKbScroll.deltat; @@ -137,7 +141,12 @@ void BotKeyboard::mouseReleaseEvent(QMouseEvent *e) { updateSelected(); if (ClickHandlerPtr activated = ClickHandler::unpressed()) { - ActivateClickHandler(window(), activated, e->button()); + ActivateClickHandler(window(), activated, { + e->button(), + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(_controller.get()), + }) + }); } } @@ -151,7 +160,8 @@ void BotKeyboard::leaveEventHook(QEvent *e) { } bool BotKeyboard::moderateKeyActivate(int key) { - if (const auto item = _session->data().message(_wasForMsgId)) { + const auto &data = _controller->session().data(); + if (const auto item = data.message(_wasForMsgId)) { if (const auto markup = item->Get()) { if (key >= Qt::Key_1 && key <= Qt::Key_2) { const auto index = int(key - Qt::Key_1); diff --git a/Telegram/SourceFiles/chat_helpers/bot_keyboard.h b/Telegram/SourceFiles/chat_helpers/bot_keyboard.h index 8a15d2c63..2afa020d7 100644 --- a/Telegram/SourceFiles/chat_helpers/bot_keyboard.h +++ b/Telegram/SourceFiles/chat_helpers/bot_keyboard.h @@ -15,16 +15,18 @@ namespace style { struct BotKeyboardButton; } // namespace style -namespace Main { -class Session; -} // namespace Main +namespace Window { +class SessionController; +} // namespace Window class BotKeyboard : public TWidget , public Ui::AbstractTooltipShower , public ClickHandlerHost { public: - BotKeyboard(not_null session, QWidget *parent); + BotKeyboard( + not_null controller, + QWidget *parent); bool moderateKeyActivate(int index); @@ -78,7 +80,7 @@ private: void updateStyle(int newWidth); void clearSelection(); - const not_null _session; + const not_null _controller; FullMsgId _wasForMsgId; QString _placeholder; int _height = 0; diff --git a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp index 4e9993ace..00e41b1e3 100644 --- a/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/gifs_list_widget.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document_media.h" #include "data/stickers/data_stickers.h" #include "chat_helpers/send_context_menu.h" // SendMenu::FillSendMenu +#include "core/click_handler_types.h" #include "ui/widgets/buttons.h" #include "ui/widgets/input_fields.h" #include "ui/widgets/popup_menu.h" @@ -415,7 +416,12 @@ void GifsListWidget::mouseReleaseEvent(QMouseEvent *e) { if (dynamic_cast(activated.get())) { selectInlineResult(_selected, {}); } else { - ActivateClickHandler(window(), activated, e->button()); + ActivateClickHandler(window(), activated, { + e->button(), + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(controller().get()), + }) + }); } } diff --git a/Telegram/SourceFiles/core/click_handler_types.h b/Telegram/SourceFiles/core/click_handler_types.h index 74ff76e51..a4ff0f8b1 100644 --- a/Telegram/SourceFiles/core/click_handler_types.h +++ b/Telegram/SourceFiles/core/click_handler_types.h @@ -23,11 +23,15 @@ class SessionController; [[nodiscard]] bool UrlRequiresConfirmation(const QUrl &url); +class PeerData; struct ClickHandlerContext { FullMsgId itemId; + // Is filled from sections. Fn elementDelegate; base::weak_ptr sessionWindow; bool skipBotAutoLogin = false; + // Is filled from peer info. + PeerData *peer = nullptr; }; Q_DECLARE_METATYPE(ClickHandlerContext); @@ -169,7 +173,6 @@ private: }; -class PeerData; class BotCommandClickHandler : public TextClickHandler { public: BotCommandClickHandler(const QString &cmd) : _cmd(cmd) { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 67698c4b8..1ea5463f7 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/text/text_utilities.h" #include "ui/inactive_press.h" #include "ui/effects/path_shift_gradient.h" +#include "core/click_handler_types.h" #include "core/file_utilities.h" #include "lang/lang_keys.h" #include "boxes/peers/edit_participant_box.h" @@ -1561,7 +1562,17 @@ void InnerWidget::mouseActionFinish(const QPoint &screenPos, Qt::MouseButton but if (activated) { mouseActionCancel(); - ActivateClickHandler(window(), activated, button); + ActivateClickHandler(window(), activated, { + button, + QVariant::fromValue(ClickHandlerContext{ + .elementDelegate = [weak = Ui::MakeWeak(this)] { + return weak + ? (ElementDelegate*)weak + : nullptr; + }, + .sessionWindow = base::make_weak(_controller.get()), + }) + }); return; } if (_mouseAction == MouseAction::PrepareDrag && !_pressWasInactive && button != Qt::RightButton) { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 8925958e8..96dadd4ab 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -216,7 +216,7 @@ HistoryWidget::HistoryWidget( tr::lng_message_ph()) , _kbScroll(this, st::botKbScroll) , _keyboard(_kbScroll->setOwnedWidget(object_ptr( - &session(), + controller, this))) , _membersDropdownShowTimer([=] { showMembersDropdown(); }) , _scrollTimer([=] { scrollByTimer(); }) diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 8ddde7a70..e8b437a00 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_overview.h" #include "styles/style_info.h" #include "base/platform/base_platform_info.h" +#include "base/weak_ptr.h" #include "media/player/media_player_instance.h" #include "boxes/peer_list_controllers.h" #include "boxes/confirm_box.h" @@ -2290,7 +2291,18 @@ void ListWidget::mouseActionFinish( _wasSelectedText = false; if (activated) { mouseActionCancel(); - ActivateClickHandler(window(), activated, button); + const auto found = findItemById(pressState.itemId); + const auto fullId = found + ? found->layout->getItem()->fullId() + : FullMsgId(); + ActivateClickHandler(window(), activated, { + button, + QVariant::fromValue(ClickHandlerContext{ + .itemId = fullId, + .sessionWindow = base::make_weak( + _controller->parentController().get()), + }) + }); return; } diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 516146bb9..07f1c5a75 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -46,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwindow.h" // MainWindow::controller. #include "main/main_session.h" #include "core/application.h" +#include "core/click_handler_types.h" #include "apiwrap.h" #include "facades.h" #include "styles/style_info.h" @@ -189,9 +190,46 @@ DetailsFiller::DetailsFiller( , _wrap(_parent) { } +template +bool SetClickContext( + const ClickHandlerPtr &handler, + const ClickContext &context) { + if (const auto casted = dynamic_pointer_cast(handler)) { + casted->T::onClick(context); + return true; + } + return false; +} + object_ptr DetailsFiller::setupInfo() { auto result = object_ptr(_wrap); auto tracker = Ui::MultiSlideTracker(); + + // Fill context for a mention / hashtag / bot command link. + const auto infoClickFilter = [=, + peer = _peer.get(), + window = _controller->parentController()]( + const ClickHandlerPtr &handler, + Qt::MouseButton button) { + const auto context = ClickContext{ + button, + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(window.get()), + .peer = peer, + }) + }; + if (SetClickContext(handler, context)) { + return false; + } else if (SetClickContext(handler, context)) { + return false; + } else if (SetClickContext(handler, context)) { + return false; + } else if (SetClickContext(handler, context)) { + return false; + } + return true; + }; + auto addInfoLineGeneric = [&]( rpl::producer &&label, rpl::producer &&text, @@ -203,6 +241,8 @@ object_ptr DetailsFiller::setupInfo() { textSt, st::infoProfileLabeledPadding); tracker.track(result->add(std::move(line.wrap))); + + line.text->setClickHandlerFilter(infoClickFilter); return line.text; }; auto addInfoLine = [&]( diff --git a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp index ef8f78e8b..c161d2765 100644 --- a/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_results_inner.cpp @@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "api/api_common.h" #include "chat_helpers/gifs_list_widget.h" // ChatHelpers::AddGifAction #include "chat_helpers/send_context_menu.h" // SendMenu::FillSendMenu +#include "core/click_handler_types.h" #include "data/data_file_origin.h" #include "data/data_user.h" #include "data/data_changes.h" @@ -237,7 +238,12 @@ void Inner::mouseReleaseEvent(QMouseEvent *e) { if (dynamic_cast(activated.get()) || open) { selectInlineResult(_selected, {}, !!open); } else { - ActivateClickHandler(window(), activated, e->button()); + ActivateClickHandler(window(), activated, { + e->button(), + QVariant::fromValue(ClickHandlerContext{ + .sessionWindow = base::make_weak(_controller.get()), + }) + }); } } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index cea9d6870..f8c1f4415 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "mainwidget.h" #include "mainwindow.h" #include "core/application.h" +#include "core/click_handler_types.h" #include "core/file_utilities.h" #include "core/mime_type.h" #include "core/ui_integration.h" @@ -4299,10 +4300,14 @@ void OverlayWidget::handleMouseRelease( } // There may be a mention / hashtag / bot command link. // For now activate account for all activated links. - if (_session) { - Core::App().domain().activate(&_session->account()); - } - ActivateClickHandler(_widget, activated, button); + // findWindow() will activate account. + ActivateClickHandler(_widget, activated, { + button, + QVariant::fromValue(ClickHandlerContext{ + .itemId = _msgid, + .sessionWindow = base::make_weak(findWindow()), + }) + }); return; }