Add proof-of-concept webview-bots attach menu.
This commit is contained in:
		
							parent
							
								
									273f2f7ce9
								
							
						
					
					
						commit
						426be943a2
					
				
					 4 changed files with 129 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<InlineBots::Layout::Widget> _inlineResults = { nullptr };
 | 
			
		||||
	std::unique_ptr<TabbedPanel> _tabbedPanel;
 | 
			
		||||
	std::unique_ptr<Ui::DropdownMenu> _attachBotsMenu;
 | 
			
		||||
 | 
			
		||||
	DragArea::Areas _attachDragAreas;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<void()> callback) {
 | 
			
		|||
		MTP_bool(enabled)
 | 
			
		||||
	)).done([=] {
 | 
			
		||||
		_requestId = 0;
 | 
			
		||||
		requestBots();
 | 
			
		||||
		callback();
 | 
			
		||||
	}).fail([=] {
 | 
			
		||||
		cancel();
 | 
			
		||||
	}).send();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
 | 
			
		||||
		not_null<QWidget*> parent,
 | 
			
		||||
		not_null<Window::SessionController*> controller) {
 | 
			
		||||
	auto result = std::make_unique<Ui::DropdownMenu>(
 | 
			
		||||
		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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<UserData*> user;
 | 
			
		||||
	QString name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class AttachWebView final : public base::has_weak_ptr {
 | 
			
		||||
public:
 | 
			
		||||
	explicit AttachWebView(not_null<Main::Session*> session);
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +54,14 @@ public:
 | 
			
		|||
 | 
			
		||||
	void cancel();
 | 
			
		||||
 | 
			
		||||
	void requestBots();
 | 
			
		||||
	[[nodiscard]] const std::vector<AttachWebViewBot> &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<AttachWebViewBot> _attachBots;
 | 
			
		||||
	rpl::event_stream<> _attachBotsUpdates;
 | 
			
		||||
 | 
			
		||||
	std::unique_ptr<Ui::BotWebView::Panel> _panel;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
[[nodiscard]] std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
 | 
			
		||||
	not_null<QWidget*> parent,
 | 
			
		||||
	not_null<Window::SessionController*> controller);
 | 
			
		||||
 | 
			
		||||
} // namespace InlineBots
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue