diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c808975997..abae3a0571 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -139,6 +139,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_slide_animation.h" #include "window/window_peer_menu.h" #include "inline_bots/inline_results_widget.h" +#include "inline_bots/bot_attach_web_view.h" #include "info/profile/info_profile_values.h" // SharedMediaCountValue. #include "chat_helpers/emoji_suggestions_widget.h" #include "core/crash_reports.h" @@ -478,6 +479,27 @@ HistoryWidget::HistoryWidget( _botKeyboardHide->hide(); _botCommandStart->hide(); + session().attachWebView().requestBots(); + session().attachWebView().attachBotsUpdates( + ) | rpl::start_with_next([=] { + const auto list = [=] { + return session().attachWebView().attachBots(); + }; + if (session().attachWebView().attachBots().empty()) { + _attachBotsMenu = nullptr; + return; + } else if (!_attachBotsMenu) { + _attachBotsMenu = InlineBots::MakeAttachBotsMenu( + this, + controller); + _attachBotsMenu->setOrigin( + Ui::PanelAnimation::Origin::BottomLeft); + if (_history && _history->peer->isUser()) { + _attachToggle->installEventFilter(_attachBotsMenu.get()); + } + } + }, lifetime()); + _botKeyboardShow->addClickHandler([=] { toggleKeyboard(); }); _botKeyboardHide->addClickHandler([=] { toggleKeyboard(); }); _botCommandStart->addClickHandler([=] { startBotCommand(); }); @@ -2329,6 +2351,15 @@ void HistoryWidget::setHistory(History *history) { return; } + const auto was = _attachBotsMenu && _history && _history->peer->isUser(); + const auto now = _attachBotsMenu && history && history->peer->isUser(); + if (was && !now) { + _attachToggle->removeEventFilter(_attachBotsMenu.get()); + _attachBotsMenu->hideFast(); + } else if (now && !was) { + _attachToggle->installEventFilter(_attachBotsMenu.get()); + } + const auto unloadHeavyViewParts = [](History *history) { if (history) { history->owner().unloadHeavyViewParts( @@ -4681,6 +4712,11 @@ void HistoryWidget::moveFieldControls() { if (_tabbedPanel) { _tabbedPanel->moveBottomRight(buttonsBottom, width()); } + if (_attachBotsMenu) { + _attachBotsMenu->moveToLeft( + 0, + buttonsBottom - _attachBotsMenu->height()); + } const auto fullWidthButtonRect = myrtlrect( 0, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 05ad24b63d..5225befc02 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -51,6 +51,7 @@ class ItemBase; class Widget; } // namespace Layout struct ResultSelected; +class AttachBotsList; } // namespace InlineBots namespace Support { @@ -765,6 +766,7 @@ private: object_ptr _inlineResults = { nullptr }; std::unique_ptr _tabbedPanel; + std::unique_ptr _attachBotsMenu; DragArea::Areas _attachDragAreas; diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index 81842e0259..ccdeda14d2 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -14,15 +14,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "storage/storage_domain.h" #include "info/profile/info_profile_values.h" #include "ui/boxes/confirm_box.h" +#include "ui/widgets/dropdown_menu.h" #include "ui/toasts/common_toasts.h" #include "ui/chat/attach/attach_bot_webview.h" #include "window/themes/window_theme.h" #include "window/window_controller.h" +#include "window/window_session_controller.h" #include "core/application.h" +#include "history/history.h" #include "lang/lang_keys.h" #include "base/random.h" #include "base/timer_rpl.h" #include "apiwrap.h" +#include "styles/style_menu_icons.h" namespace InlineBots { namespace { @@ -137,6 +141,38 @@ void AttachWebView::cancel() { _botUsername = QString(); } +void AttachWebView::requestBots() { + if (_botsRequestId) { + return; + } + _botsRequestId = _session->api().request(MTPmessages_GetAttachMenuBots( + MTP_long(_botsHash) + )).done([=](const MTPAttachMenuBots &result) { + _botsRequestId = 0; + result.match([&](const MTPDattachMenuBotsNotModified &) { + }, [&](const MTPDattachMenuBots &data) { + _session->data().processUsers(data.vusers()); + _botsHash = data.vhash().v; + _attachBots.clear(); + _attachBots.reserve(data.vbots().v.size()); + for (const auto &bot : data.vbots().v) { + bot.match([&](const MTPDattachMenuBot &data) { + if (data.is_inactive()) { + return; + } + _attachBots.push_back({ + .user = _session->data().user(data.vbot_id()), + .name = qs(data.vattach_menu_name()), + }); + }); + } + _attachBotsUpdates.fire({}); + }); + }).fail([=] { + _botsRequestId = 0; + }).send(); +} + void AttachWebView::resolve() { if (!_bot) { requestByUsername(); @@ -318,10 +354,37 @@ void AttachWebView::toggleInMenu(bool enabled, Fn callback) { MTP_bool(enabled) )).done([=] { _requestId = 0; + requestBots(); callback(); }).fail([=] { cancel(); }).send(); } +std::unique_ptr MakeAttachBotsMenu( + not_null parent, + not_null controller) { + auto result = std::make_unique( + parent, + st::dropdownMenuWithIcons); + const auto bots = &controller->session().attachWebView(); + const auto raw = result.get(); + const auto refresh = [=] { + raw->clearActions(); + for (const auto &bot : bots->attachBots()) { + raw->addAction(bot.name, [=, bot = bot.user]{ + const auto active = controller->activeChatCurrent(); + if (const auto history = active.history()) { + bots->request(history->peer, bot); + } + }); + } + }; + refresh(); + bots->attachBotsUpdates( + ) | rpl::start_with_next(refresh, raw->lifetime()); + + return result; +} + } // namespace InlineBots diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h index 111deb358c..9143607148 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.h @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { class GenericBox; +class DropdownMenu; } // namespace Ui namespace Ui::BotWebView { @@ -22,8 +23,17 @@ namespace Main { class Session; } // namespace Main +namespace Window { +class SessionController; +} // namespace Window + namespace InlineBots { +struct AttachWebViewBot { + not_null user; + QString name; +}; + class AttachWebView final : public base::has_weak_ptr { public: explicit AttachWebView(not_null session); @@ -44,6 +54,14 @@ public: void cancel(); + void requestBots(); + [[nodiscard]] const std::vector &attachBots() const { + return _attachBots; + } + [[nodiscard]] rpl::producer<> attachBotsUpdates() const { + return _attachBotsUpdates.events(); + } + static void ClearAll(); private: @@ -74,8 +92,18 @@ private: mtpRequestId _requestId = 0; mtpRequestId _prolongId = 0; + uint64 _botsHash = 0; + mtpRequestId _botsRequestId = 0; + + std::vector _attachBots; + rpl::event_stream<> _attachBotsUpdates; + std::unique_ptr _panel; }; +[[nodiscard]] std::unique_ptr MakeAttachBotsMenu( + not_null parent, + not_null controller); + } // namespace InlineBots