Support attach webview bots in topics.

This commit is contained in:
John Preston 2022-10-28 11:57:09 +04:00
parent b3f9b16eb2
commit aa5f9467f2
11 changed files with 165 additions and 66 deletions

View file

@ -1771,8 +1771,8 @@ messages.searchSentMedia#107e31a0 q:string filter:MessagesFilter limit:int = mes
messages.getAttachMenuBots#16fcc2cb hash:long = AttachMenuBots;
messages.getAttachMenuBot#77216192 bot:InputUser = AttachMenuBotsBot;
messages.toggleBotInAttachMenu#1aee33af bot:InputUser enabled:Bool = Bool;
messages.requestWebView#fc87a53c flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#ea5fbcce flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int send_as:flags.13?InputPeer = Bool;
messages.requestWebView#178b480b flags:# from_bot_menu:flags.4?true silent:flags.5?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#7ff34309 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to_msg_id:flags.0?int top_msg_id:flags.9?int send_as:flags.13?InputPeer = Bool;
messages.requestSimpleWebView#299bec8e flags:# bot:InputUser url:string theme_params:flags.0?DataJSON platform:string = SimpleWebViewResult;
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;

View file

@ -441,7 +441,7 @@ void ActivateBotCommand(ClickHandlerContext context, int row, int column) {
if (const auto bot = item->getMessageBot()) {
bot->session().attachWebView().request(
controller,
bot,
Api::SendAction(bot->owner().history(bot)),
bot,
{ .text = button->text, .url = button->data });
}

View file

@ -2353,6 +2353,7 @@ void HistoryWidget::refreshAttachBotsMenu() {
_attachBotsMenu = InlineBots::MakeAttachBotsMenu(
this,
_history->peer,
[=] { return prepareSendAction({}); },
[=](bool compress) { chooseAttach(compress); });
if (!_attachBotsMenu) {
return;

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Api {
enum class SendProgressType;
struct SendOptions;
struct SendAction;
} // namespace Api
class History;
@ -37,6 +38,7 @@ struct SetHistoryArgs {
required<History*> history;
MsgId topicRootId = 0;
Fn<bool()> showSlowmodeError;
Fn<Api::SendAction()> sendActionFactory;
rpl::producer<int> slowmodeSecondsLeft;
rpl::producer<bool> sendDisabledBySlowmode;
rpl::producer<std::optional<QString>> writeRestriction;

View file

@ -43,6 +43,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/controls/history_view_voice_record_bar.h"
#include "history/view/controls/history_view_ttl_button.h"
#include "history/view/history_view_webpage_preview.h"
#include "inline_bots/bot_attach_web_view.h"
#include "inline_bots/inline_results_widget.h"
#include "inline_bots/inline_bot_result.h"
#include "lang/lang_keys.h"
@ -54,6 +55,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text_options.h"
#include "ui/ui_utility.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/dropdown_menu.h"
#include "ui/text/format_values.h"
#include "ui/controls/emoji_button.h"
#include "ui/controls/send_button.h"
@ -894,6 +896,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
Expects(!_history && *args.history);
_showSlowmodeError = std::move(args.showSlowmodeError);
_sendActionFactory = std::move(args.sendActionFactory);
_topicRootId = args.topicRootId;
_slowmodeSecondsLeft = rpl::single(0)
| rpl::then(std::move(args.slowmodeSecondsLeft));
@ -918,6 +921,7 @@ void ComposeControls::setHistory(SetHistoryArgs &&args) {
updateControlsVisibility();
updateFieldPlaceholder();
updateSendAsButton();
updateAttachBotsMenu();
//if (!_history) {
// return;
//}
@ -1053,9 +1057,9 @@ rpl::producer<MessageToEdit> ComposeControls::editRequests() const {
std::move(submits) | filter | toValue);
}
rpl::producer<> ComposeControls::attachRequests() const {
rpl::producer<std::optional<bool>> ComposeControls::attachRequests() const {
return rpl::merge(
_attachToggle->clicks() | rpl::to_empty,
_attachToggle->clicks() | rpl::map_to(std::optional<bool>()),
_attachRequests.events()
) | rpl::filter([=] {
if (isEditingMessage()) {
@ -1090,6 +1094,9 @@ void ComposeControls::showStarted() {
if (_tabbedPanel) {
_tabbedPanel->hideFast();
}
if (_attachBotsMenu) {
_attachBotsMenu->hideFast();
}
if (_voiceRecordBar) {
_voiceRecordBar->hideFast();
}
@ -1107,6 +1114,9 @@ void ComposeControls::showFinished() {
if (_tabbedPanel) {
_tabbedPanel->hideFast();
}
if (_attachBotsMenu) {
_attachBotsMenu->hideFast();
}
if (_voiceRecordBar) {
_voiceRecordBar->hideFast();
}
@ -1127,6 +1137,9 @@ void ComposeControls::raisePanels() {
if (_tabbedPanel) {
_tabbedPanel->raise();
}
if (_attachBotsMenu) {
_attachBotsMenu->raise();
}
if (_raiseEmojiSuggestions) {
_raiseEmojiSuggestions();
}
@ -1204,6 +1217,9 @@ void ComposeControls::hidePanelsAnimated() {
if (_tabbedPanel) {
_tabbedPanel->hideAnimated();
}
if (_attachBotsMenu) {
_attachBotsMenu->hideAnimated();
}
if (_inlineResults) {
_inlineResults->hideAnimated();
}
@ -1350,6 +1366,11 @@ void ComposeControls::init() {
saveFieldToHistoryLocalDraft();
}, _wrap->lifetime());
session().attachWebView().attachBotsUpdates(
) | rpl::start_with_next([=] {
updateAttachBotsMenu();
}, _wrap->lifetime());
orderControls();
}
@ -2226,10 +2247,12 @@ void ComposeControls::updateOuterGeometry(QRect rect) {
if (_inlineResults) {
_inlineResults->moveBottom(rect.y());
}
const auto bottom = rect.y() + rect.height() - _attachToggle->height();
if (_tabbedPanel) {
_tabbedPanel->moveBottomRight(
rect.y() + rect.height() - _attachToggle->height(),
rect.x() + rect.width());
_tabbedPanel->moveBottomRight(bottom, rect.x() + rect.width());
}
if (_attachBotsMenu) {
_attachBotsMenu->moveToLeft(0, bottom - _attachBotsMenu->height());
}
}
@ -2274,6 +2297,28 @@ bool ComposeControls::updateSendAsButton() {
return true;
}
void ComposeControls::updateAttachBotsMenu() {
_attachBotsMenu = nullptr;
if (!_history || !_sendActionFactory) {
return;
}
_attachBotsMenu = InlineBots::MakeAttachBotsMenu(
_parent,
_history->peer,
_sendActionFactory,
[=](bool compress) { _attachRequests.fire_copy(compress); });
if (!_attachBotsMenu) {
return;
}
_attachBotsMenu->setOrigin(
Ui::PanelAnimation::Origin::BottomLeft);
_attachToggle->installEventFilter(_attachBotsMenu.get());
_attachBotsMenu->heightValue(
) | rpl::start_with_next([=] {
updateOuterGeometry(_wrap->geometry());
}, _attachBotsMenu->lifetime());
}
void ComposeControls::paintBackground(QRect clip) {
Painter p(_wrap.get());

View file

@ -53,6 +53,7 @@ class IconButton;
class EmojiButton;
class SendAsButton;
class SilentToggle;
class DropdownMenu;
} // namespace Ui
namespace Main {
@ -123,7 +124,7 @@ public:
[[nodiscard]] rpl::producer<VoiceToSend> sendVoiceRequests() const;
[[nodiscard]] rpl::producer<QString> sendCommandRequests() const;
[[nodiscard]] rpl::producer<MessageToEdit> editRequests() const;
[[nodiscard]] rpl::producer<> attachRequests() const;
[[nodiscard]] rpl::producer<std::optional<bool>> attachRequests() const;
[[nodiscard]] rpl::producer<FileChosen> fileChosen() const;
[[nodiscard]] rpl::producer<PhotoChosen> photoChosen() const;
[[nodiscard]] rpl::producer<Data::MessagePosition> scrollRequests() const;
@ -215,6 +216,7 @@ private:
void updateSendButtonType();
void updateMessagesTTLShown();
bool updateSendAsButton();
void updateAttachBotsMenu();
void updateHeight();
void updateWrappingVisibility();
void updateControlsVisibility();
@ -287,6 +289,7 @@ private:
const not_null<Window::SessionController*> _window;
History *_history = nullptr;
Fn<bool()> _showSlowmodeError;
Fn<Api::SendAction()> _sendActionFactory;
rpl::variable<int> _slowmodeSecondsLeft;
rpl::variable<bool> _sendDisabledBySlowmode;
rpl::variable<std::optional<QString>> _writeRestriction;
@ -308,6 +311,7 @@ private:
std::unique_ptr<InlineBots::Layout::Widget> _inlineResults;
std::unique_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
std::unique_ptr<Ui::DropdownMenu> _attachBotsMenu;
std::unique_ptr<FieldAutocomplete> _autocomplete;
friend class FieldHeader;
@ -326,7 +330,7 @@ private:
rpl::event_stream<QString> _sendCommandRequests;
rpl::event_stream<not_null<QKeyEvent*>> _scrollKeyEvents;
rpl::event_stream<not_null<QKeyEvent*>> _editLastMessageRequests;
rpl::event_stream<> _attachRequests;
rpl::event_stream<std::optional<bool>> _attachRequests;
rpl::event_stream<ReplyNextRequest> _replyNextRequests;
TextUpdateEvents _textUpdateEvents = TextUpdateEvents()

View file

@ -670,6 +670,7 @@ void RepliesWidget::setupComposeControls() {
_composeControls->setHistory({
.history = _history.get(),
.showSlowmodeError = [=] { return showSlowmodeError(); },
.sendActionFactory = [=] { return prepareSendAction({}); },
.slowmodeSecondsLeft = std::move(slowmodeSecondsLeft),
.sendDisabledBySlowmode = std::move(sendDisabledBySlowmode),
.writeRestriction = std::move(writeRestriction),
@ -720,12 +721,12 @@ void RepliesWidget::setupComposeControls() {
_composeControls->attachRequests(
) | rpl::filter([=] {
return !_choosingAttach;
}) | rpl::start_with_next([=] {
}) | rpl::start_with_next([=](std::optional<bool> overrideCompress) {
_choosingAttach = true;
base::call_delayed(
st::historyAttach.ripple.hideDuration,
this,
[=] { _choosingAttach = false; chooseAttach(); });
[=] { chooseAttach(overrideCompress); });
}, lifetime());
_composeControls->fileChosen(
@ -814,7 +815,9 @@ void RepliesWidget::setupComposeControls() {
}
}
void RepliesWidget::chooseAttach() {
void RepliesWidget::chooseAttach(
std::optional<bool> overrideSendImagesAsPhotos) {
_choosingAttach = false;
if (const auto error = Data::RestrictionError(
_history->peer,
ChatRestriction::SendMedia)) {
@ -827,7 +830,9 @@ void RepliesWidget::chooseAttach() {
return;
}
const auto filter = FileDialog::AllOrImagesFilter();
const auto filter = (overrideSendImagesAsPhotos == true)
? FileDialog::ImagesOrAllFilter()
: FileDialog::AllOrImagesFilter();
FileDialog::GetOpenPaths(this, tr::lng_choose_files(tr::now), filter, crl::guard(this, [=](
FileDialog::OpenResult &&result) {
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
@ -841,7 +846,8 @@ void RepliesWidget::chooseAttach() {
if (!read.image.isNull() && !read.animated) {
confirmSendingFiles(
std::move(read.image),
std::move(result.remoteContent));
std::move(result.remoteContent),
overrideSendImagesAsPhotos);
} else {
uploadFile(result.remoteContent, SendMediaType::File);
}
@ -851,6 +857,7 @@ void RepliesWidget::chooseAttach() {
result.paths,
st::sendMediaPreviewSize,
premium);
list.overrideSendImagesAsPhotos = overrideSendImagesAsPhotos;
confirmSendingFiles(std::move(list));
}
}), nullptr);

View file

@ -230,7 +230,7 @@ private:
not_null<HistoryItem*> item,
Api::SendOptions options,
mtpRequestId *const saveEditMsgRequestId);
void chooseAttach();
void chooseAttach(std::optional<bool> overrideSendImagesAsPhotos);
[[nodiscard]] SendMenu::Type sendMenuType() const;
[[nodiscard]] MsgId replyToId() const;
[[nodiscard]] HistoryItem *lookupRoot() const;

View file

@ -55,6 +55,18 @@ struct ParsedBot {
bool inactive = false;
};
[[nodiscard]] bool IsSame(
const std::optional<Api::SendAction> &a,
const Api::SendAction &b) {
// Check fields that are sent to API in bot attach webview requests.
return a.has_value()
&& (a->history == b.history)
&& (a->replyTo == b.replyTo)
&& (a->topicRootId == b.topicRootId)
&& (a->options.sendAs == b.options.sendAs)
&& (a->options.silent == b.options.silent);
}
[[nodiscard]] DocumentData *ResolveIcon(
not_null<Main::Session*> session,
const MTPDattachMenuBot &data) {
@ -400,14 +412,14 @@ AttachWebView::~AttachWebView() {
}
void AttachWebView::request(
not_null<PeerData*> peer,
const Api::SendAction &action,
const QString &botUsername,
const QString &startCommand) {
if (botUsername.isEmpty()) {
return;
}
const auto username = _bot ? _bot->username() : _botUsername;
if (_peer == peer
if (IsSame(_action, action)
&& username.toLower() == botUsername.toLower()
&& _startCommand == startCommand) {
if (_panel) {
@ -417,7 +429,7 @@ void AttachWebView::request(
}
cancel();
_peer = peer;
_action = action;
_botUsername = botUsername;
_startCommand = startCommand;
resolve();
@ -425,10 +437,10 @@ void AttachWebView::request(
void AttachWebView::request(
Window::SessionController *controller,
not_null<PeerData*> peer,
const Api::SendAction &action,
not_null<UserData*> bot,
const WebViewButton &button) {
if (_peer == peer && _bot == bot) {
if (IsSame(_action, action) && _bot == bot) {
if (_panel) {
_panel->requestActivate();
} else if (_requestId) {
@ -438,7 +450,7 @@ void AttachWebView::request(
cancel();
_bot = bot;
_peer = peer;
_action = action;
if (controller) {
confirmOpen(controller, [=] {
request(button);
@ -449,24 +461,31 @@ void AttachWebView::request(
}
void AttachWebView::request(const WebViewButton &button) {
Expects(_peer != nullptr && _bot != nullptr);
Expects(_action.has_value() && _bot != nullptr);
_startCommand = button.startCommand;
using Flag = MTPmessages_RequestWebView::Flag;
const auto flags = Flag::f_theme_params
| (button.url.isEmpty() ? Flag(0) : Flag::f_url)
| (_startCommand.isEmpty() ? Flag(0) : Flag::f_start_param);
| (_startCommand.isEmpty() ? Flag(0) : Flag::f_start_param)
| (_action->replyTo ? Flag::f_reply_to_msg_id : Flag(0))
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
| (_action->options.silent ? Flag::f_silent : Flag(0));
_requestId = _session->api().request(MTPmessages_RequestWebView(
MTP_flags(flags),
_peer->input,
_action->history->peer->input,
_bot->inputUser,
MTP_bytes(button.url),
MTP_string(_startCommand),
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
MTP_string("tdesktop"),
MTPint(), // reply_to_msg_id
MTPInputPeer() // send_as
MTP_int(_action->replyTo.bare),
MTP_int(_action->topicRootId.bare),
(_action->options.sendAs
? _action->options.sendAs->input
: MTP_inputPeerEmpty())
)).done([=](const MTPWebViewResult &result) {
_requestId = 0;
result.match([&](const MTPDwebViewResultUrl &data) {
@ -485,7 +504,8 @@ void AttachWebView::cancel() {
_session->api().request(base::take(_requestId)).cancel();
_session->api().request(base::take(_prolongId)).cancel();
_panel = nullptr;
_peer = _bot = nullptr;
_action = std::nullopt;
_bot = nullptr;
_botUsername = QString();
_startCommand = QString();
}
@ -523,7 +543,7 @@ void AttachWebView::requestBots() {
}
void AttachWebView::requestAddToMenu(
PeerData *peer,
const std::optional<Api::SendAction> &action,
not_null<UserData*> bot,
const QString &startCommand,
Window::SessionController *controller,
@ -537,7 +557,7 @@ void AttachWebView::requestAddToMenu(
_addToMenuChooseController = base::make_weak(controller);
_addToMenuStartCommand = startCommand;
_addToMenuChooseTypes = chooseTypes;
_addToMenuPeer = peer;
_addToMenuAction = action;
if (_addToMenuId) {
if (_addToMenuBot == bot) {
return;
@ -550,7 +570,7 @@ void AttachWebView::requestAddToMenu(
)).done([=](const MTPAttachMenuBotsBot &result) {
_addToMenuId = 0;
const auto bot = base::take(_addToMenuBot);
const auto contextPeer = base::take(_addToMenuPeer);
const auto contextAction = base::take(_addToMenuAction);
const auto chooseTypes = base::take(_addToMenuChooseTypes);
const auto startCommand = base::take(_addToMenuStartCommand);
const auto chooseController = base::take(_addToMenuChooseController);
@ -558,22 +578,23 @@ void AttachWebView::requestAddToMenu(
if (const auto useTypes = chooseTypes & types) {
if (const auto strong = chooseController.get()) {
const auto callback = [=](not_null<PeerData*> peer) {
strong->showPeerHistory(peer);
const auto history = peer->owner().history(peer);
strong->showPeerHistory(history);
request(
nullptr,
peer,
Api::SendAction(history),
bot,
{ .startCommand = startCommand });
};
ShowChooseBox(strong, useTypes, callback);
}
return true;
} else if (!contextPeer) {
} else if (!contextAction) {
return false;
}
request(
nullptr,
contextPeer,
*contextAction,
bot,
{ .startCommand = startCommand });
return true;
@ -602,7 +623,7 @@ void AttachWebView::requestAddToMenu(
}).fail([=] {
_addToMenuId = 0;
_addToMenuBot = nullptr;
_addToMenuPeer = nullptr;
_addToMenuAction = std::nullopt;
_addToMenuStartCommand = QString();
Ui::ShowMultilineToast({
.text = { tr::lng_bot_menu_not_supported(tr::now) },
@ -627,14 +648,14 @@ void AttachWebView::resolve() {
});
return;
}
requestAddToMenu(_peer, _bot, _startCommand);
requestAddToMenu(_action, _bot, _startCommand);
});
}
void AttachWebView::resolveUsername(
const QString &username,
Fn<void(not_null<PeerData*>)> done) {
if (const auto peer = _peer->owner().peerByUsername(username)) {
if (const auto peer = _session->data().peerByUsername(username)) {
done(peer);
return;
}
@ -644,10 +665,10 @@ void AttachWebView::resolveUsername(
)).done([=](const MTPcontacts_ResolvedPeer &result) {
_requestId = 0;
result.match([&](const MTPDcontacts_resolvedPeer &data) {
_peer->owner().processUsers(data.vusers());
_peer->owner().processChats(data.vchats());
_session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats());
if (const auto peerId = peerFromMTP(data.vpeer())) {
done(_peer->owner().peer(peerId));
done(_session->data().peer(peerId));
}
});
}).fail([=](const MTP::Error &error) {
@ -668,7 +689,7 @@ void AttachWebView::requestSimple(
const WebViewButton &button) {
cancel();
_bot = bot;
_peer = bot;
_action = Api::SendAction(bot->owner().history(bot));
confirmOpen(controller, [=] {
requestSimple(button);
});
@ -698,7 +719,7 @@ void AttachWebView::requestMenu(
not_null<UserData*> bot) {
cancel();
_bot = bot;
_peer = bot;
_action = Api::SendAction(bot->owner().history(bot));
const auto url = bot->botInfo->botMenuButtonUrl;
const auto text = bot->botInfo->botMenuButtonText;
confirmOpen(controller, [=] {
@ -706,15 +727,22 @@ void AttachWebView::requestMenu(
_requestId = _session->api().request(MTPmessages_RequestWebView(
MTP_flags(Flag::f_theme_params
| Flag::f_url
| Flag::f_from_bot_menu),
_bot->input,
| Flag::f_from_bot_menu
| (_action->replyTo? Flag::f_reply_to_msg_id : Flag(0))
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
| (_action->options.silent ? Flag::f_silent : Flag(0))),
_action->history->peer->input,
_bot->inputUser,
MTP_string(url),
MTPstring(), // url
MTP_dataJSON(MTP_bytes(Window::Theme::WebViewParams().json)),
MTP_string("tdesktop"),
MTPint(), // reply_to_msg_id
MTPInputPeer() // send_as
MTP_int(_action->replyTo.bare),
MTP_int(_action->topicRootId.bare),
(_action->options.sendAs
? _action->options.sendAs->input
: MTP_inputPeerEmpty())
)).done([=](const MTPWebViewResult &result) {
_requestId = 0;
result.match([&](const MTPDwebViewResultUrl &data) {
@ -765,13 +793,13 @@ void AttachWebView::show(
uint64 queryId,
const QString &url,
const QString &buttonText) {
Expects(_bot != nullptr && _peer != nullptr);
Expects(_bot != nullptr && _action.has_value());
const auto close = crl::guard(this, [=] {
crl::on_main(this, [=] { cancel(); });
});
const auto sendData = crl::guard(this, [=](QByteArray data) {
if (_peer != _bot || queryId) {
if (!_action || _action->history->peer != _bot || queryId) {
return;
}
const auto randomId = base::RandomValue<uint64>();
@ -832,7 +860,7 @@ void AttachWebView::show(
const auto hasSettings = (attached != end(_attachBots))
&& !attached->inactive
&& attached->hasSettings;
const auto hasOpenBot = (_bot != _peer);
const auto hasOpenBot = !_action || (_bot != _action->history->peer);
const auto hasRemoveFromMenu = (attached != end(_attachBots))
&& !attached->inactive;
const auto buttons = (hasSettings ? Button::Settings : Button::None)
@ -894,7 +922,7 @@ void AttachWebView::show(
}
void AttachWebView::started(uint64 queryId) {
Expects(_peer != nullptr && _bot != nullptr);
Expects(_action.has_value() && _bot != nullptr);
_session->data().webViewResultSent(
) | rpl::filter([=](const Data::Session::WebViewResultSent &sent) {
@ -907,15 +935,21 @@ void AttachWebView::started(uint64 queryId) {
kProlongTimeout
) | rpl::start_with_next([=] {
using Flag = MTPmessages_ProlongWebView::Flag;
auto flags = Flag::f_reply_to_msg_id | Flag::f_silent;
_session->api().request(base::take(_prolongId)).cancel();
_prolongId = _session->api().request(MTPmessages_ProlongWebView(
MTP_flags(flags),
_peer->input,
MTP_flags(Flag(0)
| (_action->replyTo ? Flag::f_reply_to_msg_id : Flag(0))
| (_action->topicRootId ? Flag::f_top_msg_id : Flag(0))
| (_action->options.sendAs ? Flag::f_send_as : Flag(0))
| (_action->options.silent ? Flag::f_silent : Flag(0))),
_action->history->peer->input,
_bot->inputUser,
MTP_long(queryId),
MTP_int(_replyToMsgId.bare),
MTPInputPeer() // send_as
MTP_int(_action->replyTo.bare),
MTP_int(_action->topicRootId.bare),
(_action->options.sendAs
? _action->options.sendAs->input
: MTP_inputPeerEmpty())
)).done([=] {
_prolongId = 0;
}).send();
@ -971,6 +1005,7 @@ void AttachWebView::toggleInMenu(
std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
not_null<QWidget*> parent,
not_null<PeerData*> peer,
Fn<Api::SendAction()> actionFactory,
Fn<void(bool)> attach) {
auto result = std::make_unique<Ui::DropdownMenu>(
parent,
@ -991,7 +1026,7 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
raw,
raw->menu()->st(),
bot,
[=] { bots->request(nullptr, peer, bot.user, {}); });
[=] { bots->request(nullptr, actionFactory(), bot.user, {}); });
action->forceShown(
) | rpl::start_with_next([=](bool shown) {
if (shown) {

View file

@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "api/api_common.h"
#include "mtproto/sender.h"
#include "base/weak_ptr.h"
#include "base/flags.h"
@ -70,12 +71,12 @@ public:
QByteArray url;
};
void request(
not_null<PeerData*> peer,
const Api::SendAction &action,
const QString &botUsername,
const QString &startCommand);
void request(
Window::SessionController *controller,
not_null<PeerData*> peer,
const Api::SendAction &action,
not_null<UserData*> bot,
const WebViewButton &button);
void requestSimple(
@ -97,7 +98,7 @@ public:
}
void requestAddToMenu(
PeerData *peer,
const std::optional<Api::SendAction> &action,
not_null<UserData*> bot,
const QString &startCommand,
Window::SessionController *controller = nullptr,
@ -134,12 +135,11 @@ private:
const not_null<Main::Session*> _session;
PeerData *_peer = nullptr;
std::optional<Api::SendAction> _action;
UserData *_bot = nullptr;
QString _botUsername;
QString _startCommand;
QPointer<Ui::GenericBox> _confirmAddBox;
MsgId _replyToMsgId;
mtpRequestId _requestId = 0;
mtpRequestId _prolongId = 0;
@ -147,7 +147,7 @@ private:
uint64 _botsHash = 0;
mtpRequestId _botsRequestId = 0;
PeerData *_addToMenuPeer = nullptr;
std::optional<Api::SendAction> _addToMenuAction;
UserData *_addToMenuBot = nullptr;
mtpRequestId _addToMenuId = 0;
QString _addToMenuStartCommand;
@ -164,6 +164,7 @@ private:
[[nodiscard]] std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
not_null<QWidget*> parent,
not_null<PeerData*> peer,
Fn<Api::SendAction()> actionFactory,
Fn<void(bool)> attach);
} // namespace InlineBots

View file

@ -394,9 +394,10 @@ void SessionNavigation::showPeerByLinkResolved(
}
if (!attachBotUsername.isEmpty()) {
crl::on_main(this, [=] {
showPeerHistory(peer->id, params, msgId);
const auto history = peer->owner().history(peer);
showPeerHistory(history, params, msgId);
peer->session().attachWebView().request(
peer,
Api::SendAction(history),
attachBotUsername,
info.attachBotToggleCommand.value_or(QString()));
});
@ -410,7 +411,10 @@ void SessionNavigation::showPeerByLinkResolved(
? contextPeer->asUser()
: nullptr;
bot->session().attachWebView().requestAddToMenu(
contextUser,
(contextUser
? Api::SendAction(
contextUser->owner().history(contextUser))
: std::optional<Api::SendAction>()),
bot,
*info.attachBotToggleCommand,
parentController(),