Provided more context for click handlers.

This commit is contained in:
23rd 2021-07-26 19:27:08 +03:00
parent 7c8b1cd5b1
commit 93bcd90fd4
10 changed files with 114 additions and 19 deletions

View file

@ -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<Main::Session*> session, QWidget *parent)
BotKeyboard::BotKeyboard(
not_null<Window::SessionController*> 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<HistoryMessageReplyMarkup>()) {
if (key >= Qt::Key_1 && key <= Qt::Key_2) {
const auto index = int(key - Qt::Key_1);

View file

@ -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<Main::Session*> session, QWidget *parent);
BotKeyboard(
not_null<Window::SessionController*> controller,
QWidget *parent);
bool moderateKeyActivate(int index);
@ -78,7 +80,7 @@ private:
void updateStyle(int newWidth);
void clearSelection();
const not_null<Main::Session*> _session;
const not_null<Window::SessionController*> _controller;
FullMsgId _wasForMsgId;
QString _placeholder;
int _height = 0;

View file

@ -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<InlineBots::Layout::SendClickHandler*>(activated.get())) {
selectInlineResult(_selected, {});
} else {
ActivateClickHandler(window(), activated, e->button());
ActivateClickHandler(window(), activated, {
e->button(),
QVariant::fromValue(ClickHandlerContext{
.sessionWindow = base::make_weak(controller().get()),
})
});
}
}

View file

@ -23,11 +23,15 @@ class SessionController;
[[nodiscard]] bool UrlRequiresConfirmation(const QUrl &url);
class PeerData;
struct ClickHandlerContext {
FullMsgId itemId;
// Is filled from sections.
Fn<HistoryView::ElementDelegate*()> elementDelegate;
base::weak_ptr<Window::SessionController> 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) {

View file

@ -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) {

View file

@ -216,7 +216,7 @@ HistoryWidget::HistoryWidget(
tr::lng_message_ph())
, _kbScroll(this, st::botKbScroll)
, _keyboard(_kbScroll->setOwnedWidget(object_ptr<BotKeyboard>(
&session(),
controller,
this)))
, _membersDropdownShowTimer([=] { showMembersDropdown(); })
, _scrollTimer([=] { scrollByTimer(); })

View file

@ -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;
}

View file

@ -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 <typename T>
bool SetClickContext(
const ClickHandlerPtr &handler,
const ClickContext &context) {
if (const auto casted = dynamic_pointer_cast<T>(handler)) {
casted->T::onClick(context);
return true;
}
return false;
}
object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
auto result = object_ptr<Ui::VerticalLayout>(_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<BotCommandClickHandler>(handler, context)) {
return false;
} else if (SetClickContext<MentionClickHandler>(handler, context)) {
return false;
} else if (SetClickContext<HashtagClickHandler>(handler, context)) {
return false;
} else if (SetClickContext<CashtagClickHandler>(handler, context)) {
return false;
}
return true;
};
auto addInfoLineGeneric = [&](
rpl::producer<QString> &&label,
rpl::producer<TextWithEntities> &&text,
@ -203,6 +241,8 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
textSt,
st::infoProfileLabeledPadding);
tracker.track(result->add(std::move(line.wrap)));
line.text->setClickHandlerFilter(infoClickFilter);
return line.text;
};
auto addInfoLine = [&](

View file

@ -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<SendClickHandler*>(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()),
})
});
}
}

View file

@ -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;
}