Add proof-of-concept webview-bots attach menu.

This commit is contained in:
John Preston 2022-03-29 16:13:54 +04:00
parent 273f2f7ce9
commit 426be943a2
4 changed files with 129 additions and 0 deletions

View File

@ -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,

View File

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

View File

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

View File

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