diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 9a0b27fb8..ccaaa25c2 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6389,23 +6389,27 @@ void HistoryWidget::checkPinnedBarState() { &session(), _pinnedTracker->shownMessageId()); _pinnedBar = std::make_unique(this); - _pinnedBar->setContent(std::move(barContent)); - Info::Profile::SharedMediaCountValue( - _peer, - nullptr, - Storage::SharedMediaType::Pinned - ) | rpl::distinct_until_changed( - ) | rpl::map([=](int count) { - if (_pinnedClickedId) { - _pinnedClickedId = FullMsgId(); - _minPinnedId = std::nullopt; - updatePinnedViewer(); - } - return (count > 1); - }) | rpl::distinct_until_changed( - ) | rpl::start_with_next([=](bool many) { - refreshPinnedBarButton(many); + rpl::combine( + Info::Profile::SharedMediaCountValue( + _peer, + nullptr, + Storage::SharedMediaType::Pinned + ) | rpl::distinct_until_changed( + ) | rpl::map([=](int count) { + if (_pinnedClickedId) { + _pinnedClickedId = FullMsgId(); + _minPinnedId = std::nullopt; + updatePinnedViewer(); + } + return (count > 1); + }) | rpl::distinct_until_changed(), + HistoryView::PinnedBarItemWithReplyMarkup( + &session(), + _pinnedTracker->shownMessageId()) + ) | rpl::start_with_next([=](bool many, HistoryItem *item) { + refreshPinnedBarButton(many, item); }, _pinnedBar->lifetime()); + _pinnedBar->setContent(std::move(barContent)); controller()->adaptive().oneColumnValue( ) | rpl::start_with_next([=](bool one) { @@ -6492,7 +6496,30 @@ void HistoryWidget::setChooseReportMessagesDetails( } } -void HistoryWidget::refreshPinnedBarButton(bool many) { +void HistoryWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { + if (const auto replyMarkup = item ? item->inlineReplyMarkup() : nullptr) { + const auto &rows = replyMarkup->data.rows; + if ((rows.size() == 1) && (rows.front().size() == 1)) { + const auto text = rows.front().front().text; + if (!text.isEmpty()) { + auto button = object_ptr( + this, + rpl::single(text), + st::historyPinnedBotButton); + button->setTextTransform( + Ui::RoundButton::TextTransform::NoTransform); + button->setFullRadius(true); + button->setClickedCallback([=] { + App::activateBotCommand(controller(), item, 0, 0); + }); + if (button->width() > st::historyPinnedBotButtonMaxWidth) { + button->setFullWidth(st::historyPinnedBotButtonMaxWidth); + } + _pinnedBar->setRightButton(std::move(button)); + return; + } + } + } const auto close = !many; auto button = object_ptr( this, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 5a0bf8fe1..abb3f75b5 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -512,7 +512,7 @@ private: void updatePinnedViewer(); void setupPinnedTracker(); void checkPinnedBarState(); - void refreshPinnedBarButton(bool many); + void refreshPinnedBarButton(bool many, HistoryItem *item); void checkLastPinnedClickedIdReset( int wasScrollTop, int nowScrollTop); diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp index e48c843c7..f8eb7a8e4 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp +++ b/Telegram/SourceFiles/history/view/history_view_pinned_bar.cpp @@ -154,4 +154,56 @@ rpl::producer PinnedBarContent( }) | rpl::flatten_latest(); } +rpl::producer PinnedBarItemWithReplyMarkup( + not_null session, + rpl::producer id) { + return rpl::make_producer([=, + id = std::move(id)](auto consumer) { + auto lifetime = rpl::lifetime(); + consumer.put_next(nullptr); + + struct State { + HistoryMessageReplyMarkup *previousReplyMarkup = nullptr; + rpl::lifetime lifetime; + }; + const auto state = lifetime.make_state(); + + const auto pushUnique = [=](not_null item) { + const auto replyMarkup = item->inlineReplyMarkup(); + if (state->previousReplyMarkup == replyMarkup) { + return; + } + consumer.put_next(item.get()); + state->previousReplyMarkup = replyMarkup; + }; + + rpl::duplicate( + id + ) | rpl::start_with_next([=](PinnedId current) { + const auto fullId = current.message; + if (!fullId) { + return; + } + const auto messageFlag = [=](not_null item) { + using Update = Data::MessageUpdate; + session->changes().messageFlagsValue( + item, + Update::Flag::ReplyMarkup + ) | rpl::start_with_next([=](const Update &update) { + pushUnique(update.item); + }, state->lifetime); + }; + if (const auto item = session->data().message(fullId)) { + messageFlag(item); + } else { + session->api().requestMessageData( + session->data().peer(fullId.peer), + fullId.msg, + [=] { messageFlag(session->data().message(fullId)); }); + } + }, lifetime); + return lifetime; + }); +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_pinned_bar.h b/Telegram/SourceFiles/history/view/history_view_pinned_bar.h index 1e7c3578f..605091399 100644 --- a/Telegram/SourceFiles/history/view/history_view_pinned_bar.h +++ b/Telegram/SourceFiles/history/view/history_view_pinned_bar.h @@ -49,4 +49,8 @@ struct PinnedId { not_null session, rpl::producer id); +[[nodiscard]] rpl::producer PinnedBarItemWithReplyMarkup( + not_null session, + rpl::producer id); + } // namespace HistoryView diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 549c619bc..ba3942cac 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -477,6 +477,13 @@ historyPinnedShowAll: IconButton(historyReplyCancel) { icon: icon {{ "pinned_show_all", historyReplyCancelFg }}; iconOver: icon {{ "pinned_show_all", historyReplyCancelFgOver }}; } +historyPinnedBotButton: RoundButton(defaultActiveButton) { + width: -34px; + height: 30px; + textTop: 6px; + padding: margins(2px, 10px, 10px, 9px); +} +historyPinnedBotButtonMaxWidth: 150px; msgBotKbDuration: 200; msgBotKbFont: semiboldFont;