From dc8b693f1d8a613adf56974e18bda25f29f1bd11 Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Tue, 18 Oct 2022 04:11:42 +0300 Subject: [PATCH] Added context menu to bar of pinned messages with bot button. --- .../SourceFiles/history/history_widget.cpp | 36 ++++++++++++++----- Telegram/SourceFiles/ui/chat/pinned_bar.cpp | 18 ++++++++-- Telegram/SourceFiles/ui/chat/pinned_bar.h | 2 ++ 3 files changed, 45 insertions(+), 11 deletions(-) diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 68f7e12688..926230c03a 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6351,6 +6351,20 @@ void HistoryWidget::setChooseReportMessagesDetails( } void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { + const auto openSection = [=] { + const auto id = _pinnedTracker + ? _pinnedTracker->currentMessageId() + : HistoryView::PinnedId(); + if (!id.message) { + return; + } + controller()->showSection( + std::make_shared( + _history, + ((!_migrated || peerIsChannel(id.message.peer)) + ? id.message.msg + : (id.message.msg - ServerMaxMsgId)))); + }; if (const auto replyMarkup = item ? item->inlineReplyMarkup() : nullptr) { const auto &rows = replyMarkup->data.rows; if ((rows.size() == 1) && (rows.front().size() == 1)) { @@ -6372,6 +6386,18 @@ void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { if (button->width() > st::historyPinnedBotButtonMaxWidth) { button->setFullWidth(st::historyPinnedBotButtonMaxWidth); } + struct State { + base::unique_qptr menu; + }; + const auto state = button->lifetime().make_state(); + _pinnedBar->contextMenuRequested( + ) | rpl::start_with_next([=, raw = button.data()] { + state->menu = base::make_unique_q(raw); + state->menu->addAction( + tr::lng_settings_events_pinned(tr::now), + openSection); + state->menu->popup(QCursor::pos()); + }, button->lifetime()); _pinnedBar->setRightButton(std::move(button)); return; } @@ -6386,15 +6412,7 @@ void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { if (close) { hidePinnedMessage(); } else { - const auto id = _pinnedTracker->currentMessageId(); - if (id.message) { - controller()->showSection( - std::make_shared( - _history, - ((!_migrated || peerIsChannel(id.message.peer)) - ? id.message.msg - : (id.message.msg - ServerMaxMsgId)))); - } + openSection(); } }, button->lifetime()); _pinnedBar->setRightButton(std::move(button)); diff --git a/Telegram/SourceFiles/ui/chat/pinned_bar.cpp b/Telegram/SourceFiles/ui/chat/pinned_bar.cpp index 86268ef474..2e2a0f5982 100644 --- a/Telegram/SourceFiles/ui/chat/pinned_bar.cpp +++ b/Telegram/SourceFiles/ui/chat/pinned_bar.cpp @@ -150,10 +150,12 @@ void PinnedBar::createControls() { _bar->widget()->setCursor(style::cur_pointer); _bar->widget()->events( ) | rpl::filter([=](not_null event) { - return (event->type() == QEvent::MouseButtonPress); + return (event->type() == QEvent::MouseButtonPress) + && (static_cast(event.get())->button() + == Qt::LeftButton); }) | rpl::map([=] { return _bar->widget()->events( - ) | rpl::filter([=](not_null event) { + ) | rpl::filter([](not_null event) { return (event->type() == QEvent::MouseButtonRelease); }) | rpl::take(1) | rpl::filter([=](not_null event) { return _bar->widget()->rect().contains( @@ -247,4 +249,16 @@ rpl::producer<> PinnedBar::barClicks() const { return _barClicks.events(); } +rpl::producer<> PinnedBar::contextMenuRequested() const { + return _wrap.entity()->paintRequest( + ) | rpl::filter([=] { + return _bar && _bar->widget(); + }) | rpl::map([=] { + return _bar->widget()->events( + ) | rpl::filter([](not_null event) { + return (event->type() == QEvent::ContextMenu); + }) | rpl::to_empty; + }) | rpl::flatten_latest(); +} + } // namespace Ui diff --git a/Telegram/SourceFiles/ui/chat/pinned_bar.h b/Telegram/SourceFiles/ui/chat/pinned_bar.h index f48556a426..848b3e3cc8 100644 --- a/Telegram/SourceFiles/ui/chat/pinned_bar.h +++ b/Telegram/SourceFiles/ui/chat/pinned_bar.h @@ -41,6 +41,7 @@ public: [[nodiscard]] int height() const; [[nodiscard]] rpl::producer heightValue() const; [[nodiscard]] rpl::producer<> barClicks() const; + [[nodiscard]] rpl::producer<> contextMenuRequested() const; [[nodiscard]] rpl::lifetime &lifetime() { return _wrap.lifetime(); @@ -63,6 +64,7 @@ private: std::unique_ptr _shadow; Fn _customEmojiPaused; rpl::event_stream<> _barClicks; + rpl::event_stream<> _contextMenuRequested; Fn _shadowGeometryPostprocess; bool _shouldBeShown = false; bool _forceHidden = false;